1cmake_minimum_required(VERSION 3.15)
2
3if(NOT CMAKE_BUILD_TYPE)
4 set(CMAKE_BUILD_TYPE "Debug" CACHE STRING
5 "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
6endif()
7
8if(NOT CMAKE_INSTALL_PREFIX)
9 set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_BINARY_DIR}/stage3" CACHE PATH
10 "Directory to install zig to" FORCE)
11endif()
12
13# CMake recognizes the CMAKE_PREFIX_PATH environment variable for some things,
14# and also the CMAKE_PREFIX_PATH cache variable for other things. However, it
15# does not relate these two things, i.e. if the environment variable is set,
16# CMake does not populate the cache variable in a corresponding manner. Some
17# package systems, such as Homebrew, set the environment variable but not the
18# cache variable. Furthermore, the environment variable follows the system path
19# separator, such as ':' on POSIX and ';' on Windows, but the cache variable
20# follows CMake's array behavior, i.e. always ';' for a separator.
21list(APPEND ZIG_CMAKE_PREFIX_PATH "${CMAKE_PREFIX_PATH}")
22if(WIN32)
23 list(APPEND ZIG_CMAKE_PREFIX_PATH $ENV{CMAKE_PREFIX_PATH})
24else()
25 string(REGEX REPLACE ":" ";" ZIG_CMAKE_PREFIX_PATH_STRING "$ENV{CMAKE_PREFIX_PATH}")
26 list(APPEND ZIG_CMAKE_PREFIX_PATH "${ZIG_CMAKE_PREFIX_PATH_STRING}")
27endif()
28
29list(PREPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
30
31project(zig
32 DESCRIPTION
33 "Zig is a general-purpose programming language and toolchain for maintaining robust, optimal and reusable software"
34 HOMEPAGE_URL
35 "https://ziglang.org"
36 LANGUAGES
37 C CXX
38)
39
40set(ZIG_VERSION_MAJOR 0)
41set(ZIG_VERSION_MINOR 17)
42set(ZIG_VERSION_PATCH 0)
43set(ZIG_VERSION "" CACHE STRING "Override Zig version string. Default is to find out with git.")
44
45if("${ZIG_VERSION}" STREQUAL "")
46 set(RESOLVED_ZIG_VERSION "${ZIG_VERSION_MAJOR}.${ZIG_VERSION_MINOR}.${ZIG_VERSION_PATCH}")
47 find_program(GIT_EXE NAMES git NAMES_PER_DIR)
48 if(GIT_EXE AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
49 execute_process(
50 COMMAND ${GIT_EXE} -C "${PROJECT_SOURCE_DIR}" describe --match *.*.* --tags --abbrev=9
51 RESULT_VARIABLE EXIT_STATUS
52 OUTPUT_VARIABLE GIT_DESCRIBE
53 OUTPUT_STRIP_TRAILING_WHITESPACE
54 ERROR_QUIET)
55 if(EXIT_STATUS EQUAL "0")
56 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${PROJECT_SOURCE_DIR}/.git/HEAD")
57 if(GIT_DESCRIBE MATCHES "^v?([0-9]+\\.[0-9]+\\.[0-9]+)$")
58 # Tagged release version.
59 set(GIT_TAG ${CMAKE_MATCH_1})
60 if(NOT GIT_TAG VERSION_EQUAL RESOLVED_ZIG_VERSION)
61 message(SEND_ERROR "Zig version (${RESOLVED_ZIG_VERSION}) does not match Git tag (${GIT_TAG}).")
62 endif()
63 elseif(GIT_DESCRIBE MATCHES "^v?([0-9]+\\.[0-9]+\\.[0-9]+)-([0-9]+)-g(.+)$")
64 # Untagged pre-release. The Zig version is updated to include the number of commits
65 # since the last tagged version and the commit hash. The version is formatted in
66 # accordance with the https://semver.org specification.
67 set(GIT_TAG ${CMAKE_MATCH_1})
68 set(GIT_COMMITS_AFTER_TAG ${CMAKE_MATCH_2})
69 set(GIT_COMMIT ${CMAKE_MATCH_3})
70 if(NOT RESOLVED_ZIG_VERSION VERSION_GREATER GIT_TAG)
71 message(SEND_ERROR "Zig version (${RESOLVED_ZIG_VERSION}) must be greater than tagged ancestor (${GIT_TAG}).")
72 endif()
73 set(RESOLVED_ZIG_VERSION "${RESOLVED_ZIG_VERSION}-dev.${GIT_COMMITS_AFTER_TAG}+${GIT_COMMIT}")
74 else()
75 message(WARNING "Failed to parse version from output of `git describe`.")
76 endif()
77 endif()
78 endif()
79else()
80 set(RESOLVED_ZIG_VERSION "${ZIG_VERSION}")
81endif()
82message(STATUS "Configuring zig version ${RESOLVED_ZIG_VERSION}")
83
84set(ZIG_NO_LIB off CACHE BOOL
85 "Disable copying lib/ files to install prefix during the build phase")
86
87set(ZIG_STATIC off CACHE BOOL "Attempt to build a static zig executable (not compatible with glibc)")
88set(ZIG_SHARED_LLVM off CACHE BOOL "Prefer linking against shared LLVM libraries")
89set(ZIG_STATIC_LLVM ${ZIG_STATIC} CACHE BOOL "Prefer linking against static LLVM libraries")
90set(ZIG_STATIC_ZLIB ${ZIG_STATIC} CACHE BOOL "Prefer linking against static zlib")
91set(ZIG_STATIC_ZSTD ${ZIG_STATIC} CACHE BOOL "Prefer linking against static zstd")
92set(ZIG_STATIC_CURSES OFF CACHE BOOL "Enable static linking against curses")
93set(ZIG_STATIC_LIBXML2 OFF CACHE BOOL "Enable static linking against libxml2")
94
95if (ZIG_SHARED_LLVM AND ZIG_STATIC_LLVM)
96 message(SEND_ERROR "-DZIG_SHARED_LLVM and -DZIG_STATIC_LLVM cannot both be enabled simultaneously")
97endif()
98
99set(ZIG_TARGET_TRIPLE "native" CACHE STRING "arch-os-abi to output binaries for")
100set(ZIG_TARGET_MCPU "native" CACHE STRING "-mcpu parameter to output binaries for")
101set(ZIG_TARGET_DYNAMIC_LINKER "" CACHE STRING
102 "Override the dynamic linker used by the Zig binary. Default is to auto-detect the dynamic linker.")
103set(ZIG_SINGLE_THREADED off CACHE BOOL "limit the zig compiler to use only 1 thread")
104set(ZIG_AR_WORKAROUND off CACHE BOOL "append 'ar' subcommand to CMAKE_AR")
105
106if("${ZIG_TARGET_TRIPLE}" STREQUAL "native")
107 set(ZIG_USE_LLVM_CONFIG ON CACHE BOOL "use llvm-config to find LLVM libraries")
108else()
109 set(ZIG_USE_LLVM_CONFIG OFF CACHE BOOL "use llvm-config to find LLVM libraries")
110endif()
111
112if(ZIG_AR_WORKAROUND)
113 string(REPLACE "<CMAKE_AR>" "<CMAKE_AR> ar" CMAKE_C_ARCHIVE_CREATE ${CMAKE_C_ARCHIVE_CREATE})
114 string(REPLACE "<CMAKE_AR>" "<CMAKE_AR> ar" CMAKE_CXX_ARCHIVE_CREATE ${CMAKE_CXX_ARCHIVE_CREATE})
115endif()
116
117
118option(ZIG_PIE "Produce a position independent zig executable" ${CMAKE_POSITION_INDEPENDENT_CODE})
119include(CheckPIESupported)
120check_pie_supported(
121 OUTPUT_VARIABLE ZIG_PIE_SUPPORTED_BY_CMAKE
122 LANGUAGES C CXX
123)
124if(ZIG_PIE AND NOT CMAKE_CXX_LINK_PIE_SUPPORTED)
125 message(SEND_ERROR "ZIG_PIE was requested but CMake does not support it for \"zigcpp\" target: ${ZIG_PIE_SUPPORTED_BY_CMAKE}")
126endif()
127
128
129# Detect system libcxx name.
130if ("c++" IN_LIST CMAKE_CXX_IMPLICIT_LINK_LIBRARIES)
131 set(ZIG_SYSTEM_LIBCXX "c++" CACHE STRING "system libcxx name for build.zig")
132else()
133 set(ZIG_SYSTEM_LIBCXX "stdc++" CACHE STRING "system libcxx name for build.zig")
134endif()
135
136find_package(llvm 22)
137find_package(clang 22)
138find_package(lld 22)
139
140if(ZIG_STATIC_ZLIB)
141 if (MSVC)
142 list(REMOVE_ITEM LLVM_LIBRARIES "z.lib")
143 else()
144 list(REMOVE_ITEM LLVM_LIBRARIES "-lz")
145 endif()
146
147 find_library(ZLIB NAMES libz.a libzlibstatic.a z zlib libz NAMES_PER_DIR)
148 list(APPEND LLVM_LIBRARIES "${ZLIB}")
149endif()
150
151if(ZIG_STATIC_ZSTD)
152 if (MSVC)
153 list(REMOVE_ITEM LLVM_LIBRARIES "zstd.lib")
154 else()
155 list(REMOVE_ITEM LLVM_LIBRARIES "-lzstd")
156 endif()
157
158 find_library(ZSTD NAMES libzstd.a libzstdstatic.a zstd NAMES_PER_DIR)
159 list(APPEND LLVM_LIBRARIES "${ZSTD}")
160endif()
161
162if (MSVC)
163 if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
164 if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
165 # avoid linking to the debug versions of ucrt by default
166 # as they are not redistributable.
167 set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreadedDLL)
168 endif()
169 endif()
170endif ()
171
172if(ZIG_STATIC_CURSES)
173 list(REMOVE_ITEM LLVM_LIBRARIES "-lcurses")
174 find_library(CURSES NAMES libcurses.a libncurses.a NAMES_PER_DIR
175 PATHS
176 /usr/local/opt/ncurses/lib
177 /opt/homebrew/opt/ncurses/lib)
178 list(APPEND LLVM_LIBRARIES "${CURSES}")
179endif()
180
181if(ZIG_STATIC_LIBXML2)
182 list(REMOVE_ITEM LLVM_LIBRARIES "-lxml2")
183 find_library(LIBXML2 NAMES libxml2.a NAMES_PER_DIR)
184 list(APPEND LLVM_LIBRARIES "${LIBXML2}")
185endif()
186
187find_package(Threads)
188
189set(ZIG_CONFIG_H_OUT "${PROJECT_BINARY_DIR}/config.h")
190set(ZIG_CONFIG_ZIG_OUT "${PROJECT_BINARY_DIR}/config.zig")
191
192set(ZIG_WASM2C_SOURCES
193 stage1/wasm2c.c
194)
195# Sync with "zig_cpp_sources" in build.zig
196set(ZIG_CPP_SOURCES
197 # These are planned to stay even when we are self-hosted.
198 src/zig_llvm.cpp
199 src/zig_llvm-ar.cpp
200 src/zig_clang_driver.cpp
201 src/zig_clang_cc1_main.cpp
202 src/zig_clang_cc1as_main.cpp
203)
204# Needed because we use cmake, not the zig build system, to build zig2.o.
205set(ZIG_STAGE2_SOURCES
206 "${ZIG_CONFIG_ZIG_OUT}"
207 lib/compiler_rt.zig
208 lib/std/BitStack.zig
209 lib/std/Build.zig
210 lib/std/Build/Cache.zig
211 lib/std/Build/Cache/DepTokenizer.zig
212 lib/std/Io.zig
213 lib/std/Io/Reader.zig
214 lib/std/Io/Writer.zig
215 lib/std/Progress.zig
216 lib/std/Random.zig
217 lib/std/Target.zig
218 lib/std/Target/Query.zig
219 lib/std/Target/aarch64.zig
220 lib/std/Target/amdgcn.zig
221 lib/std/Target/arm.zig
222 lib/std/Target/avr.zig
223 lib/std/Target/bpf.zig
224 lib/std/Target/hexagon.zig
225 lib/std/Target/loongarch.zig
226 lib/std/Target/mips.zig
227 lib/std/Target/msp430.zig
228 lib/std/Target/nvptx.zig
229 lib/std/Target/powerpc.zig
230 lib/std/Target/riscv.zig
231 lib/std/Target/s390x.zig
232 lib/std/Target/sparc.zig
233 lib/std/Target/wasm.zig
234 lib/std/Target/x86.zig
235 lib/std/Thread.zig
236 lib/std/array_hash_map.zig
237 lib/std/array_list.zig
238 lib/std/ascii.zig
239 lib/std/atomic.zig
240 lib/std/base64.zig
241 lib/std/buf_map.zig
242 lib/std/lang.zig
243 lib/std/lang/assembly.zig
244 lib/std/c.zig
245 lib/std/coff.zig
246 lib/std/crypto.zig
247 lib/std/crypto/blake3.zig
248 lib/std/crypto/siphash.zig
249 lib/std/debug.zig
250 lib/std/dwarf.zig
251 lib/std/dwarf/AT.zig
252 lib/std/dwarf/ATE.zig
253 lib/std/dwarf/FORM.zig
254 lib/std/dwarf/LANG.zig
255 lib/std/dwarf/OP.zig
256 lib/std/dwarf/TAG.zig
257 lib/std/elf.zig
258 lib/std/fmt.zig
259 lib/std/fmt/parse_float.zig
260 lib/std/fs.zig
261 lib/std/fs/path.zig
262 lib/std/hash.zig
263 lib/std/hash/auto_hash.zig
264 lib/std/hash/wyhash.zig
265 lib/std/hash_map.zig
266 lib/std/heap.zig
267 lib/std/heap/ArenaAllocator.zig
268 lib/std/json.zig
269 lib/std/leb128.zig
270 lib/std/log.zig
271 lib/std/macho.zig
272 lib/std/math.zig
273 lib/std/math/big.zig
274 lib/std/math/big/int.zig
275 lib/std/math/float.zig
276 lib/std/math/frexp.zig
277 lib/std/math/isinf.zig
278 lib/std/math/isnan.zig
279 lib/std/math/log.zig
280 lib/std/math/log10.zig
281 lib/std/math/log2.zig
282 lib/std/math/signbit.zig
283 lib/std/math/sqrt.zig
284 lib/std/mem.zig
285 lib/std/mem/Allocator.zig
286 lib/std/meta.zig
287 lib/std/meta/trailer_flags.zig
288 lib/std/multi_array_list.zig
289 lib/std/os.zig
290 lib/std/os/linux.zig
291 lib/std/os/linux.zig
292 lib/std/os/linux/IoUring.zig
293 lib/std/os/linux/io_uring_sqe.zig
294 lib/std/os/linux/x86_64.zig
295 lib/std/os/linux/x86_64.zig
296 lib/std/os/windows.zig
297 lib/std/os/windows/ntstatus.zig
298 lib/std/os/windows/win32error.zig
299 lib/std/pdb.zig
300 lib/std/process.zig
301 lib/std/process/Child.zig
302 lib/std/sort.zig
303 lib/std/start.zig
304 lib/std/static_string_map.zig
305 lib/std/std.zig
306 lib/std/time.zig
307 lib/std/treap.zig
308 lib/std/unicode.zig
309 lib/std/zig.zig
310 lib/std/zig/Ast.zig
311 lib/std/zig/Ast/Render.zig
312 lib/std/zig/AstGen.zig
313 lib/std/zig/AstRlAnnotate.zig
314 lib/std/zig/LibCInstallation.zig
315 lib/std/zig/Parse.zig
316 lib/std/zig/Server.zig
317 lib/std/zig/WindowsSdk.zig
318 lib/std/zig/Zir.zig
319 lib/std/zig/string_literal.zig
320 lib/std/zig/system.zig
321 lib/std/zig/system/NativePaths.zig
322 lib/std/zig/system/x86.zig
323 lib/std/zig/tokenizer.zig
324 lib/std/zig/llvm.zig
325 lib/std/zig/llvm/BitcodeReader.zig
326 lib/std/zig/llvm/Builder.zig
327 lib/std/zig/llvm/bitcode_writer.zig
328 lib/std/zig/llvm/ir.zig
329 src/Air.zig
330 src/Air/Legalize.zig
331 src/Air/Liveness.zig
332 src/Air/Liveness/Verify.zig
333 src/Air/print.zig
334 src/Builtin.zig
335 src/Compilation.zig
336 src/Compilation/Config.zig
337 src/InternPool.zig
338 src/RangeSet.zig
339 src/Sema.zig
340 src/Sema/reinterpret.zig
341 src/Sema/comptime_ptr_access.zig
342 src/Sema/type_resolution.zig
343 src/Type.zig
344 src/Value.zig
345 src/Zcu.zig
346 src/Zcu/PerThread.zig
347 src/codegen.zig
348 src/codegen/aarch64.zig
349 src/codegen/aarch64/abi.zig
350 src/codegen/aarch64/Assemble.zig
351 src/codegen/aarch64/Disassemble.zig
352 src/codegen/aarch64/encoding.zig
353 src/codegen/aarch64/instructions.zon
354 src/codegen/aarch64/Mir.zig
355 src/codegen/aarch64/Select.zig
356 src/codegen/c.zig
357 src/codegen/c/type.zig
358 src/codegen/c/type/render_defs.zig
359 src/codegen/llvm.zig
360 src/codegen/llvm/bindings.zig
361 src/codegen/loongarch/abi.zig
362 src/codegen/loongarch/encoding.zig
363 src/codegen/loongarch/decode_tree.zon
364 src/codegen/loongarch/inst_formats.zon
365 src/codegen/loongarch/Assemble.zig
366 src/codegen/loongarch/Disassemble.zig
367 src/codegen/loongarch/Mir.zig
368 src/codegen/loongarch/bits.zig
369 src/codegen/loongarch/Select.zig
370 src/codegen/loongarch.zig
371 src/codegen/s390x/abi.zig
372 src/crash_report.zig
373 src/dev.zig
374 src/libs/freebsd.zig
375 src/libs/glibc.zig
376 src/libs/netbsd.zig
377 src/libs/openbsd.zig
378 src/libs/libcxx.zig
379 src/libs/libtsan.zig
380 src/libs/libunwind.zig
381 src/link.zig
382 src/link/C.zig
383 src/link/ConstPool.zig
384 src/link/Coff.zig
385 src/link/Dwarf.zig
386 src/link/Elf.zig
387 src/link/Elf/Archive.zig
388 src/link/Elf/Atom.zig
389 src/link/Elf/AtomList.zig
390 src/link/Elf/LinkerDefined.zig
391 src/link/Elf/Merge.zig
392 src/link/Elf/Object.zig
393 src/link/Elf/SharedObject.zig
394 src/link/Elf/Symbol.zig
395 src/link/Elf/Thunk.zig
396 src/link/Elf/ZigObject.zig
397 src/link/Elf/eh_frame.zig
398 src/link/Elf/file.zig
399 src/link/Elf/gc.zig
400 src/link/Elf/relocatable.zig
401 src/link/Elf/relocation.zig
402 src/link/Elf/synthetic_sections.zig
403 src/link/Elf2.zig
404 src/link/LdScript.zig
405 src/link/Lld.zig
406 src/link/MachO.zig
407 src/link/MachO/Archive.zig
408 src/link/MachO/Atom.zig
409 src/link/MachO/CodeSignature.zig
410 src/link/MachO/DebugSymbols.zig
411 src/link/MachO/Dwarf.zig
412 src/link/MachO/Dylib.zig
413 src/link/MachO/InternalObject.zig
414 src/link/MachO/Object.zig
415 src/link/MachO/Relocation.zig
416 src/link/MachO/Symbol.zig
417 src/link/MachO/UnwindInfo.zig
418 src/link/MachO/ZigObject.zig
419 src/link/MachO/dead_strip.zig
420 src/link/MachO/dyld_info/Rebase.zig
421 src/link/MachO/dyld_info/Trie.zig
422 src/link/MachO/dyld_info/bind.zig
423 src/link/MachO/eh_frame.zig
424 src/link/MachO/fat.zig
425 src/link/MachO/file.zig
426 src/link/MachO/hasher.zig
427 src/link/MachO/load_commands.zig
428 src/link/MachO/relocatable.zig
429 src/link/MachO/synthetic.zig
430 src/link/MachO/Thunk.zig
431 src/link/MachO/uuid.zig
432 src/link/MappedFile.zig
433 src/link/Queue.zig
434 src/link/StringTable.zig
435 src/link/Wasm.zig
436 src/link/Wasm/Archive.zig
437 src/link/Wasm/Flush.zig
438 src/link/Wasm/Object.zig
439 src/link/aarch64.zig
440 src/link/riscv.zig
441 src/link/table_section.zig
442 src/link/tapi.zig
443 src/link/tapi/Tokenizer.zig
444 src/link/tapi/parse.zig
445 src/link/tapi/parse/test.zig
446 src/link/tapi/yaml.zig
447 src/link/tapi/yaml/test.zig
448 src/main.zig
449 src/libs/mingw.zig
450 src/libs/musl.zig
451 src/mutable_value.zig
452 src/print_env.zig
453 src/print_targets.zig
454 src/print_value.zig
455 src/print_zir.zig
456 src/register_manager.zig
457 src/target.zig
458 src/tracy.zig
459 src/libs/wasi_libc.zig
460)
461
462if(MSVC)
463 set(MSVC_DIA_SDK_DIR "$ENV{VSINSTALLDIR}DIA SDK")
464 if(IS_DIRECTORY ${MSVC_DIA_SDK_DIR})
465 set(ZIG_DIA_GUIDS_LIB "${MSVC_DIA_SDK_DIR}/lib/amd64/diaguids.lib")
466 string(REGEX REPLACE "\\\\" "\\\\\\\\" ZIG_DIA_GUIDS_LIB_ESCAPED "${ZIG_DIA_GUIDS_LIB}")
467 endif()
468
469 # The /RTC[c][s][u] flag enables extra runtime checks. ("/RTC1" == "/RTCsu")
470 # The "c" (PossibleDataLoss) and "u" (UninitializeVariable) flags trap on valid C code so we disable
471 # them. The "s" flag seems like it might be OK.
472 string(REPLACE "/RTC1" "/RTCs" CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG}")
473 string(REPLACE "/RTC1" "/RTCs" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
474endif()
475
476configure_file (
477 stage1/config.h.in
478 "${ZIG_CONFIG_H_OUT}"
479)
480configure_file (
481 stage1/config.zig.in
482 "${ZIG_CONFIG_ZIG_OUT}"
483)
484
485# zigcpp target
486
487set(ZIGCPP_OUTPUT_DIR "${PROJECT_BINARY_DIR}/zigcpp")
488
489add_library(zigcpp STATIC ${ZIG_CPP_SOURCES})
490
491# Sync with minimum C++ standard required to build LLVM
492# and with "exe_cflags" in build.zig
493target_compile_features(zigcpp PRIVATE cxx_std_17)
494set_target_properties(zigcpp PROPERTIES POSITION_INDEPENDENT_CODE ${ZIG_PIE})
495
496if(LLVM_LINK_MODE STREQUAL "static")
497 target_compile_definitions(zigcpp PRIVATE
498 LLVM_BUILD_STATIC
499 CLANG_BUILD_STATIC
500 )
501endif()
502
503if(NOT MSVC)
504 if(MINGW)
505 target_compile_options(zigcpp PRIVATE -Wno-format)
506 endif()
507 # Sync content below with "exe_cflags" in build.zig
508 target_compile_definitions(zigcpp PUBLIC
509 __STDC_CONSTANT_MACROS
510 __STDC_FORMAT_MACROS
511 __STDC_LIMIT_MACROS
512
513 _GNU_SOURCE
514 )
515 target_compile_options(zigcpp PRIVATE
516 -fno-exceptions
517 -fno-rtti
518 -fno-stack-protector
519
520 -fvisibility-inlines-hidden
521
522 -Wno-type-limits
523 -Wno-missing-braces
524 -Wno-comment
525 )
526else()
527target_compile_options(zigcpp PRIVATE /Zc:preprocessor)
528set_property(TARGET zigcpp PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
529endif()
530
531target_include_directories(zigcpp PUBLIC
532 ${CLANG_INCLUDE_DIRS}
533 ${LLVM_INCLUDE_DIRS}
534 ${LLD_INCLUDE_DIRS}
535)
536target_link_libraries(zigcpp PUBLIC
537 ${CLANG_LIBRARIES}
538 ${LLD_LIBRARIES}
539 ${LLVM_LIBRARIES}
540 ${CMAKE_THREAD_LIBS_INIT}
541)
542
543# Handle multi-config builds and place each into a common lib. The VS generator
544# for example will append a Debug folder by default if not explicitly specified.
545set_target_properties(zigcpp PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${ZIGCPP_OUTPUT_DIR})
546foreach(CONFIG_TYPE ${CMAKE_CONFIGURATION_TYPES})
547 string(TOUPPER ${CONFIG_TYPE} CONFIG_TYPE)
548 set_target_properties(zigcpp PROPERTIES ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_TYPE} ${ZIGCPP_OUTPUT_DIR})
549endforeach()
550
551# end of zigcpp target
552
553include(CheckSymbolExists)
554
555string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" ZIG_HOST_TARGET_OS)
556if(ZIG_HOST_TARGET_OS STREQUAL "android")
557 set(ZIG_HOST_TARGET_OS "linux")
558 set(ZIG_HOST_TARGET_IS_ANDROID TRUE)
559elseif(ZIG_HOST_TARGET_OS STREQUAL "darwin")
560 set(ZIG_HOST_TARGET_OS "macos")
561elseif(ZIG_HOST_TARGET_OS STREQUAL "gnu")
562 set(ZIG_HOST_TARGET_OS "hurd")
563elseif(ZIG_HOST_TARGET_OS STREQUAL "serenityos")
564 set(ZIG_HOST_TARGET_OS "serenity")
565elseif(ZIG_HOST_TARGET_OS STREQUAL "sunos")
566 set(ZIG_HOST_TARGET_OS "illumos")
567endif()
568
569string(TOLOWER "${CMAKE_HOST_SYSTEM_PROCESSOR}" ZIG_HOST_TARGET_ARCH)
570if(ZIG_HOST_TARGET_ARCH MATCHES "^i[3-9]86$")
571 if (ZIG_HOST_TARGET_OS STREQUAL "illumos")
572 set(ZIG_HOST_TARGET_ARCH "x86_64")
573 else()
574 set(ZIG_HOST_TARGET_ARCH "x86")
575 endif()
576elseif(ZIG_HOST_TARGET_ARCH STREQUAL "amd64")
577 set(ZIG_HOST_TARGET_ARCH "x86_64")
578elseif(ZIG_HOST_TARGET_ARCH STREQUAL "arm64")
579 set(ZIG_HOST_TARGET_ARCH "aarch64")
580elseif(ZIG_HOST_TARGET_ARCH MATCHES "^arm(el)?$" OR ZIG_HOST_TARGET_ARCH MATCHES "^armv[7-8]l$")
581 set(ZIG_HOST_TARGET_ARCH "arm")
582elseif(ZIG_HOST_TARGET_ARCH STREQUAL "armeb" OR ZIG_HOST_TARGET_ARCH MATCHES "^armv[7-8]b$")
583 set(ZIG_HOST_TARGET_ARCH "armeb")
584endif()
585if(ZIG_HOST_TARGET_ARCH MATCHES "^arm(eb)?$")
586 check_symbol_exists(__thumb__ "" ZIG_HOST_TARGET_DEFAULTS_TO_THUMB)
587 if(ZIG_HOST_TARGET_DEFAULTS_TO_THUMB)
588 string(REGEX REPLACE "^arm" "thumb" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")
589 endif()
590endif()
591string(REGEX REPLACE "^ppc((64)?(le)?)$" "powerpc\\1" ZIG_HOST_TARGET_ARCH "${ZIG_HOST_TARGET_ARCH}")
592
593set(ZIG_HOST_TARGET_ABI "")
594if(MSVC)
595 set(ZIG_HOST_TARGET_ABI "-msvc")
596elseif(MINGW)
597 set(ZIG_HOST_TARGET_ABI "-gnu")
598elseif(ZIG_HOST_TARGET_IS_ANDROID)
599 if(ZIG_HOST_TARGET_ARCH STREQUAL "arm")
600 set(ZIG_HOST_TARGET_ABI "-androideabi")
601 else()
602 set(ZIG_HOST_TARGET_ABI "-android")
603 endif()
604endif()
605
606set(ZIG_HOST_TARGET_TRIPLE "${ZIG_HOST_TARGET_ARCH}-${ZIG_HOST_TARGET_OS}${ZIG_HOST_TARGET_ABI}" CACHE STRING "Host zig target triple.")
607
608if(MSVC)
609 set(ZIG_WASM2C_COMPILE_FLAGS "")
610 set(ZIG1_COMPILE_FLAGS "/Os")
611 set(ZIG2_COMPILE_FLAGS "/Od")
612 set(ZIG2_LINK_FLAGS "/STACK:16777216 /FORCE:MULTIPLE")
613else()
614 set(ZIG_WASM2C_COMPILE_FLAGS "-std=c99")
615 set(ZIG1_COMPILE_FLAGS "-std=c99 -Oz -fno-strict-aliasing")
616 set(ZIG2_COMPILE_FLAGS "-std=c99 -Oz -fno-sanitize=undefined -fno-stack-protector -fno-strict-aliasing")
617 if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND ZIG_HOST_TARGET_ARCH STREQUAL "s390x")
618 string(REPLACE -Oz -O0 ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS}") # llvm 22 assertion failure
619 endif()
620 # Must match the condition in build.zig.
621 if(ZIG_HOST_TARGET_ARCH MATCHES "^(arm|thumb)(eb)?$" OR ZIG_HOST_TARGET_ARCH EQUAL "hexagon" OR ZIG_HOST_TARGET_ARCH MATCHES "^powerpc(64)?(le)?$")
622 set(ZIG1_COMPILE_FLAGS "${ZIG1_COMPILE_FLAGS} -ffunction-sections -fdata-sections")
623 set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -ffunction-sections -fdata-sections")
624 endif()
625 if (CMAKE_C_COMPILER_ID STREQUAL "GNU")
626 # Prevent GCC from miscompiling 'zig2.c'. See also 'GCC_BUG_119085_PRESENT' workaround details in 'bootstrap.c'.
627 if (
628 (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "10.0" AND
629 CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "13.4") OR
630 (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "14.0" AND
631 CMAKE_C_COMPILER_VERSION VERSION_LESS_EQUAL "14.3") OR
632 (CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL "15.0" AND
633 CMAKE_C_COMPILER_VERSION VERSION_LESS "15.2")
634 )
635 set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -fno-tree-sra")
636 endif()
637
638 # Prevent GCC from spamming false positive `-Waddress-of-packed-member` warnings in 'zig2.c'.
639 # See also 'GCC_BUG_94081_PRESENT' workaround details in 'bootstrap.c'.
640 set(ZIG2_COMPILE_FLAGS "${ZIG2_COMPILE_FLAGS} -Wno-address-of-packed-member")
641 endif()
642endif()
643
644set(ZIG1_WASM_MODULE "${PROJECT_SOURCE_DIR}/stage1/zig1.wasm")
645set(ZIG1_C_SOURCE "${PROJECT_BINARY_DIR}/zig1.c")
646set(ZIG2_C_SOURCE "${PROJECT_BINARY_DIR}/zig2.c")
647set(ZIG_COMPILER_RT_C_SOURCE "${PROJECT_BINARY_DIR}/compiler_rt.c")
648
649add_executable(zig-wasm2c ${ZIG_WASM2C_SOURCES})
650set_target_properties(zig-wasm2c PROPERTIES COMPILE_FLAGS "${ZIG_WASM2C_COMPILE_FLAGS}")
651
652add_custom_command(
653 OUTPUT "${ZIG1_C_SOURCE}"
654 COMMAND zig-wasm2c "${ZIG1_WASM_MODULE}" "${ZIG1_C_SOURCE}"
655 DEPENDS zig-wasm2c "${ZIG1_WASM_MODULE}"
656 COMMENT "Converting ${ZIG1_WASM_MODULE} to ${ZIG1_C_SOURCE}"
657 WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
658)
659
660add_executable(zig1 ${ZIG1_C_SOURCE} stage1/wasi.c)
661set_target_properties(zig1 PROPERTIES COMPILE_FLAGS ${ZIG1_COMPILE_FLAGS})
662
663if(MSVC)
664 target_link_options(zig1 PRIVATE /STACK:0x10000000)
665else()
666 target_link_libraries(zig1 LINK_PUBLIC m)
667 if(MINGW)
668 target_link_options(zig1 PRIVATE -Wl,--stack,0x10000000)
669 endif()
670endif()
671
672set(BUILD_ZIG2_ARGS
673 "${PROJECT_SOURCE_DIR}/lib"
674 build-exe -ofmt=c -lc -OReleaseSmall
675 --name zig2
676 -femit-bin="${ZIG2_C_SOURCE}"
677 -target "${ZIG_HOST_TARGET_TRIPLE}"
678 --dep "build_options"
679 "-Mroot=src/main.zig"
680 "-Mbuild_options=${ZIG_CONFIG_ZIG_OUT}"
681)
682
683add_custom_command(
684 OUTPUT "${ZIG2_C_SOURCE}"
685 COMMAND zig1 ${BUILD_ZIG2_ARGS}
686 DEPENDS zig1 "${ZIG_STAGE2_SOURCES}"
687 COMMENT "Running zig1.wasm to produce ${ZIG2_C_SOURCE}"
688 WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
689)
690
691set(BUILD_COMPILER_RT_ARGS
692 "${PROJECT_SOURCE_DIR}/lib"
693 build-obj -ofmt=c -OReleaseSmall
694 --name compiler_rt
695 -femit-bin="${ZIG_COMPILER_RT_C_SOURCE}"
696 -target "${ZIG_HOST_TARGET_TRIPLE}"
697 "-Mroot=lib/compiler_rt.zig"
698)
699
700add_custom_command(
701 OUTPUT "${ZIG_COMPILER_RT_C_SOURCE}"
702 COMMAND zig1 ${BUILD_COMPILER_RT_ARGS}
703 DEPENDS zig1 "${ZIG_STAGE2_SOURCES}"
704 COMMENT "Running zig1.wasm to produce ${ZIG_COMPILER_RT_C_SOURCE}"
705 WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}"
706)
707
708add_executable(zig2 ${ZIG2_C_SOURCE} ${ZIG_COMPILER_RT_C_SOURCE})
709set_target_properties(zig2 PROPERTIES
710 COMPILE_FLAGS ${ZIG2_COMPILE_FLAGS}
711 LINK_FLAGS "${ZIG2_LINK_FLAGS}"
712)
713target_include_directories(zig2 PUBLIC stage1)
714target_link_libraries(zig2 LINK_PUBLIC zigcpp)
715
716if(MSVC)
717 target_link_libraries(zig2 LINK_PUBLIC ntdll.lib ws2_32.lib)
718elseif(MINGW)
719 target_link_libraries(zig2 LINK_PUBLIC ntdll ws2_32)
720endif()
721
722if(NOT MSVC)
723 target_link_libraries(zig2 LINK_PUBLIC ${LIBXML2})
724endif()
725
726if(ZIG_DIA_GUIDS_LIB)
727 target_link_libraries(zig2 LINK_PUBLIC ${ZIG_DIA_GUIDS_LIB})
728endif()
729
730if(MSVC OR MINGW)
731 target_link_libraries(zig2 LINK_PUBLIC version)
732endif()
733
734
735set(ZIG_BUILD_ARGS
736 "--zig-lib=${PROJECT_SOURCE_DIR}/lib"
737
738 "-Dversion-string=${RESOLVED_ZIG_VERSION}"
739 "-Dtarget=${ZIG_TARGET_TRIPLE}"
740 "-Dcpu=${ZIG_TARGET_MCPU}"
741
742 -Denable-llvm
743 "-Dconfig_h=${ZIG_CONFIG_H_OUT}"
744)
745
746set(ZIG_EXTRA_BUILD_ARGS "" CACHE STRING "Extra zig build args")
747if(ZIG_EXTRA_BUILD_ARGS)
748 list(APPEND ZIG_BUILD_ARGS ${ZIG_EXTRA_BUILD_ARGS})
749endif()
750
751set(ZIG_RELEASE_SAFE OFF CACHE BOOL "Build Zig as ReleaseSafe (with debug assertions on)")
752
753if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
754 list(APPEND ZIG_BUILD_ARGS -Doptimize=Debug)
755else()
756 if("${CMAKE_BUILD_TYPE}" STREQUAL "MinSizeRel")
757 list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseSmall)
758 else()
759 # Release and RelWithDebInfo
760 if(ZIG_RELEASE_SAFE)
761 list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseSafe)
762 else()
763 list(APPEND ZIG_BUILD_ARGS -Doptimize=ReleaseFast)
764 endif()
765 if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "RelWithDebInfo")
766 list(APPEND ZIG_BUILD_ARGS -Dstrip)
767 endif()
768 endif()
769endif()
770
771if(ZIG_STATIC AND NOT MSVC)
772 list(APPEND ZIG_BUILD_ARGS -Duse-zig-libcxx)
773endif()
774
775if(ZIG_NO_LIB)
776 list(APPEND ZIG_BUILD_ARGS -Dno-lib)
777endif()
778
779if(ZIG_SINGLE_THREADED)
780 list(APPEND ZIG_BUILD_ARGS -Dsingle-threaded)
781endif()
782
783if(ZIG_PIE)
784 list(APPEND ZIG_BUILD_ARGS -Dpie)
785endif()
786
787if(NOT "${ZIG_TARGET_DYNAMIC_LINKER}" STREQUAL "")
788 list(APPEND ZIG_BUILD_ARGS "-Ddynamic-linker=${ZIG_TARGET_DYNAMIC_LINKER}")
789endif()
790
791
792add_custom_target(stage3 ALL
793 DEPENDS "${PROJECT_BINARY_DIR}/stage3/bin/zig"
794)
795
796set(ZIG2_WORKING_DIR "${PROJECT_SOURCE_DIR}")
797
798add_custom_command(
799 OUTPUT "${PROJECT_BINARY_DIR}/stage3/bin/zig"
800 COMMAND zig2 build ${ZIG_BUILD_ARGS} --prefix "${PROJECT_BINARY_DIR}/stage3"
801 COMMENT "Building stage3"
802 WORKING_DIRECTORY "${ZIG2_WORKING_DIR}"
803)
804
805set(ZIG_EXECUTABLE "$<TARGET_FILE:zig2>")
806
807install(CODE "set(ZIG_EXECUTABLE \"${ZIG_EXECUTABLE}\")")
808install(CODE "set(ZIG_BUILD_ARGS \"${ZIG_BUILD_ARGS}\")")
809install(CODE "set(ZIG2_WORKING_DIR \"${ZIG2_WORKING_DIR}\")")
810install(CODE "set(CMAKE_INSTALL_PREFIX \"${CMAKE_INSTALL_PREFIX}\")")
811install(SCRIPT cmake/install.cmake)