@@ -35,8 +35,7 @@ if(NOT _zig_version_result EQUAL 0)
3535 message (FATAL_ERROR "Zig Toolchain: Zig compiler found at '${_zig_compiler_exe} ' but failed to retrieve its version." )
3636endif ()
3737
38- # Parse version string into components for version-gated logic
39- # Handles both release ("0.16.0") and dev ("0.16.0-dev.1484+d0ba6642b") formats
38+ # Parse version string — handles both release ("0.16.0") and dev ("0.16.0-dev.1484+abc") formats
4039if (ZIG_COMPILER_VERSION MATCHES "^([0-9]+)\\ .([0-9]+)\\ .([0-9]+)" )
4140 set (ZIG_VERSION_MAJOR "${CMAKE_MATCH_1} " )
4241 set (ZIG_VERSION_MINOR "${CMAKE_MATCH_2} " )
4746 set (ZIG_VERSION_MINOR 0)
4847 set (ZIG_VERSION_PATCH 0)
4948endif ()
50- # Capture optional pre-release/dev suffix (e.g. "dev.1484+d0ba6642b")
5149if (ZIG_COMPILER_VERSION MATCHES "-(.+)$" )
5250 set (ZIG_VERSION_DEV "${CMAKE_MATCH_1} " )
5351else ()
@@ -60,11 +58,14 @@ if(ZIG_COMPILER_VERSION VERSION_LESS "0.15.0")
6058 "Toolchain behaviour is untested on this version." )
6159endif ()
6260
61+ set (_zig_cc_prefix "" )
62+
6363unset (_zig_ccache_exe CACHE )
6464if (ZIG_USE_CCACHE)
6565 find_program (_zig_ccache_exe ccache )
6666 if (_zig_ccache_exe)
6767 message (STATUS "Zig Toolchain: ccache enabled at ${_zig_ccache_exe} " )
68+ set (_zig_cc_prefix "\" ${_zig_ccache_exe} \" " )
6869 else ()
6970 message (WARNING "Zig Toolchain: ZIG_USE_CCACHE is ON but 'ccache' was not found in PATH." )
7071 endif ()
@@ -77,12 +78,14 @@ if(NOT ZIG_TARGET)
7778 if (NOT CMAKE_SYSTEM_PROCESSOR )
7879 set (CMAKE_SYSTEM_PROCESSOR "${CMAKE_HOST_SYSTEM_PROCESSOR} " )
7980 endif ()
81+
8082 string (TOLOWER "${CMAKE_SYSTEM_PROCESSOR} " ZIG_ARCH)
8183 if (ZIG_ARCH MATCHES "arm64|aarch64" )
8284 set (ZIG_ARCH "aarch64" )
8385 elseif (ZIG_ARCH MATCHES "x64|x86_64|amd64" )
8486 set (ZIG_ARCH "x86_64" )
8587 endif ()
88+
8689 string (TOLOWER "${CMAKE_SYSTEM_NAME} " ZIG_OS)
8790 set (ZIG_ABI "gnu" )
8891 if (ZIG_OS MATCHES "darwin|macos" )
@@ -93,6 +96,7 @@ if(NOT ZIG_TARGET)
9396 elseif (ZIG_OS MATCHES "linux" )
9497 set (ZIG_OS "linux" )
9598 endif ()
99+
96100 set (ZIG_TARGET "${ZIG_ARCH} -${ZIG_OS} -${ZIG_ABI} " )
97101else ()
98102 if (NOT ZIG_TARGET MATCHES "^([^-]+)-([^-]+)(-(.+))?$" )
@@ -102,7 +106,7 @@ else()
102106 set (ZIG_OS "${CMAKE_MATCH_2} " )
103107endif ()
104108
105- # Dummy version satisfies CMake's cross-compilation requirements without affecting Zig's behaviour
109+ # Satisfy CMake cross-compilation bookkeeping
106110set (CMAKE_SYSTEM_VERSION 1)
107111set (CMAKE_SYSTEM_PROCESSOR "${ZIG_ARCH} " )
108112set (CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
@@ -120,150 +124,69 @@ endif()
120124
121125message (STATUS "Zig Toolchain: v${ZIG_COMPILER_VERSION} → ${ZIG_TARGET} " )
122126
123- # Build base compilation flags list
124- set (_zig_target_flags "-target" " ${ZIG_TARGET} " )
127+ # Build the flags string that gets baked into every cc/c++ wrapper
128+ set (_zig_target_flags "-target ${ZIG_TARGET} " )
125129if (ZIG_MCPU)
126- list (APPEND _zig_target_flags "-mcpu=${ZIG_MCPU}${ZIG_MCPU_FEATURES} " )
130+ string (APPEND _zig_target_flags " -mcpu=${ZIG_MCPU}${ZIG_MCPU_FEATURES} " )
127131endif ()
128132if (ZIG_COMPILER_FLAGS)
129- separate_arguments (_zig_extra_flags NATIVE_COMMAND "${ZIG_COMPILER_FLAGS} " )
130- list (APPEND _zig_target_flags ${_zig_extra_flags} )
133+ string (APPEND _zig_target_flags " ${ZIG_COMPILER_FLAGS} " )
131134endif ()
135+ string (STRIP "${_zig_target_flags} " _zig_target_flags)
132136
133- if (CMAKE_HOST_WIN32 )
134- set (_zig_wrapper_ext ".exe" )
135- set (_zig_host_win32 1)
136- else ()
137- set (_zig_wrapper_ext "" )
138- set (_zig_host_win32 0)
137+ if (_zig_target_flags AND NOT _zig_target_flags STREQUAL "-target ${ZIG_TARGET} " )
138+ message (STATUS "Zig Toolchain: Extra compiler flags → ${_zig_target_flags} " )
139139endif ()
140140
141141set (_zig_shims_dir "${CMAKE_BINARY_DIR} /.zig-shims" )
142142file (MAKE_DIRECTORY "${_zig_shims_dir} " )
143143
144- # Use bracket argument [=[ ... ]=] to avoid escaping hell
145- set (_zig_shim_template [=[
146- // @_zig_tool_name@ wrapper for Zig toolchain
147- #include <stdio.h>
148- #include <stdlib.h>
149- #if @_zig_host_win32@
150- #include <process.h>
151- #else
152- #include <unistd.h>
153- #endif
154- int main(int argc, char** argv) {
155- // User args (argc - 1) + NULL terminator (1) + Injected args count
156- const char* exargv[argc + @_zig_extra_args_count@];
157- const char **p = exargv;
158- @_zig_ccache_stmt@
159- *p++ = "@_zig_compiler_exe_escaped@";
160- *p++ = "@_zig_subcommand@";
161- @_zig_flags_stmts@
162- for (int i = 1; i < argc; ++i) { *p++ = argv[i]; }
163- *p = NULL;
164- #if @_zig_host_win32@
165- return (int)_spawnvp(_P_WAIT, exargv[0], (const char* const*)exargv);
166- #else
167- execvp(exargv[0], (char* const*)exargv);
168- perror("execvp failed");
169- return 1;
170- #endif
171- }
172- ]=] )
173-
174- function (_zig_generate_shim tool_name subcommand inject_flags use_ccache )
175- set (_zig_tool_name "${tool_name} " )
176- set (_zig_subcommand "${subcommand} " )
177-
178- # 2 baseline injected args: zig executable + subcommand
179- set (_zig_extra_args_count 2)
180- set (_zig_ccache_stmt "" )
181- set (_zig_flags_stmts "" )
182-
183- # Escape executable path for C string literal
184- string (REPLACE "\\ " "\\\\ " _zig_compiler_exe_escaped "${_zig_compiler_exe} " )
144+ if (CMAKE_HOST_WIN32 )
145+ set (_zig_wrapper_ext ".cmd" )
146+ else ()
147+ set (_zig_wrapper_ext "" )
148+ endif ()
185149
186- # Inject ccache prefix if requested
187- if (use_ccache AND _zig_ccache_exe )
188- string ( REPLACE " \\ " " \\\\ " _zig_ccache_exe_escaped " ${_zig_ccache_exe } " )
189- set (_zig_ccache_stmt " *p++ = \" ${_zig_ccache_exe_escaped} \" ;" )
190- math ( EXPR _zig_extra_args_count " ${_zig_extra_args_count} + 1 " )
150+ function ( _zig_write_script name subcommand inject_flags use_ccache )
151+ if (use_ccache AND _zig_cc_prefix )
152+ set (_prefix " ${_zig_cc_prefix } " )
153+ else ( )
154+ set (_prefix " " )
191155 endif ()
192156
193- # Inject target/cpu/extra flags
194157 if (inject_flags)
195- foreach (_flag IN LISTS _zig_target_flags)
196- string (REPLACE "\\ " "\\\\ " _flag_escaped "${_flag} " )
197- string (REPLACE "\" " "\\\" " _flag_escaped "${_flag_escaped} " )
198- string (APPEND _zig_flags_stmts " *p++ = \" ${_flag_escaped} \" ;\n " )
199- math (EXPR _zig_extra_args_count "${_zig_extra_args_count} + 1" )
200- endforeach ()
201- endif ()
202-
203- # Render C source from template
204- string (CONFIGURE "${_zig_shim_template} " _shim_content @ONLY)
205-
206- set (_shim_src "${_zig_shims_dir} /${tool_name} .c" )
207- set (_shim_exe "${_zig_shims_dir} /${tool_name}${_zig_wrapper_ext} " )
208- set (_shim_hash "${_zig_shims_dir} /${tool_name} .hash" )
209-
210- # Skip recompilation when content is unchanged
211- string (MD5 _new_hash "${_shim_content} " )
212- if (EXISTS "${_shim_hash} " AND EXISTS "${_shim_exe} " )
213- file (READ "${_shim_hash} " _old_hash )
214- string (STRIP "${_old_hash} " _old_hash)
215- if (_old_hash STREQUAL _new_hash)
216- return ()
217- endif ()
158+ set (_flags " ${_zig_target_flags} " )
159+ else ()
160+ set (_flags "" )
218161 endif ()
219162
220- file (WRITE "${_shim_src} " "${_shim_content} " )
221- message (STATUS "Zig Toolchain: Compiling native wrapper for '${tool_name} '..." )
222-
223- if (CMAKE_HOST_APPLE )
224- set (_shim_compile_cmd
225- "${_zig_compiler_exe} " cc -O2 -std=c11 -march=native -target native-macos
226- "${_shim_src} " -o "${_shim_exe} "
163+ if (CMAKE_HOST_WIN32 )
164+ set (_script_path "${_zig_shims_dir} /${name}${_zig_wrapper_ext} " )
165+ file (WRITE "${_script_path} "
166+ "@echo off\n "
167+ "${_prefix} \" ${_zig_compiler_exe} \" ${subcommand}${_flags} %*\n "
227168 )
228169 else ()
229- set (_shim_compile_cmd
230- "${_zig_compiler_exe} " cc -O2 -std=c11 -march=native -s
231- "${_shim_src} " -o "${_shim_exe} "
170+ set (_script_path "${_zig_shims_dir} /${name}${_zig_wrapper_ext} " )
171+ file (WRITE "${_script_path} "
172+ "#!/bin/sh\n "
173+ "${_prefix} \" ${_zig_compiler_exe} \" ${subcommand}${_flags} \" $@\"\n "
232174 )
233- endif ()
234- execute_process (
235- COMMAND ${_shim_compile_cmd}
236- RESULT_VARIABLE _compile_result
237- ERROR_VARIABLE _compile_stderr
238- OUTPUT_QUIET
239- )
240-
241- if (NOT _compile_result EQUAL 0)
242- message (FATAL_ERROR
243- "Zig Toolchain: Failed to compile wrapper for '${tool_name} '.\n "
244- "${_compile_stderr} "
245- )
246- endif ()
247-
248- if (NOT CMAKE_HOST_WIN32 )
249175 execute_process (
250- COMMAND chmod +x "${_shim_exe} "
251- OUTPUT_QUIET
252- ERROR_QUIET
176+ COMMAND chmod +x "${_script_path} "
177+ OUTPUT_QUIET ERROR_QUIET
253178 )
254179 endif ()
255-
256- file (WRITE "${_shim_hash} " "${_new_hash} " )
257180endfunction ()
258181
259- _zig_generate_shim ("zig-cc" "cc" TRUE TRUE )
260- _zig_generate_shim ("zig-c++" "c++" TRUE TRUE )
261- _zig_generate_shim ("zig-ar" "ar" FALSE FALSE )
262- _zig_generate_shim ("zig-rc" "rc" FALSE FALSE )
263- _zig_generate_shim ("zig-ranlib" "ranlib" FALSE FALSE )
264- _zig_generate_shim ("zig-nm" "nm" FALSE FALSE )
265- _zig_generate_shim ("zig-objcopy" "objcopy" FALSE FALSE )
266- _zig_generate_shim ("zig-strip" "strip" FALSE FALSE )
182+ _zig_write_script ("zig-cc" "cc" TRUE TRUE )
183+ _zig_write_script ("zig-c++" "c++" TRUE TRUE )
184+ _zig_write_script ("zig-ar" "ar" FALSE FALSE )
185+ _zig_write_script ("zig-rc" "rc" FALSE FALSE )
186+ _zig_write_script ("zig-ranlib" "ranlib" FALSE FALSE )
187+ _zig_write_script ("zig-nm" "nm" FALSE FALSE )
188+ _zig_write_script ("zig-objcopy" "objcopy" FALSE FALSE )
189+ _zig_write_script ("zig-strip" "strip" FALSE FALSE )
267190
268191set (CMAKE_C_COMPILER "${_zig_shims_dir} /zig-cc${_zig_wrapper_ext} " )
269192set (CMAKE_CXX_COMPILER "${_zig_shims_dir} /zig-c++${_zig_wrapper_ext} " )
0 commit comments