From de918867123b2a462ebfca847aafb282f086b0c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Fri, 5 Jun 2026 22:07:53 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20CreateProcess=20=E6=9B=BF=E4=BB=A3=20sys?= =?UTF-8?q?tem()=20=E8=B0=83=20ld.lld=EF=BC=8C=E6=B6=88=E9=99=A4=20shell?= =?UTF-8?q?=20=E8=BD=AC=E4=B9=89=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/driver/main.c | 68 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 51 insertions(+), 17 deletions(-) diff --git a/src/driver/main.c b/src/driver/main.c index e67a1da..c9ac57d 100644 --- a/src/driver/main.c +++ b/src/driver/main.c @@ -20,7 +20,9 @@ static void get_exe_dir(char* buf, size_t size) { #ifdef _WIN32 GetModuleFileNameA(NULL, buf, (DWORD)size); - char* last = strrchr(buf, '\\'); + // 反斜杠 → 正斜杠(兼容 MSYS2 和 cmd.exe) + for (char* p = buf; *p; p++) if (*p == '\\') *p = '/'; + char* last = strrchr(buf, '/'); if (last) *last = '\0'; #else buf[0] = '.'; buf[1] = '\0'; @@ -152,29 +154,61 @@ int main(int argc, char** argv) { return 1; } - // 链接:优先安装包自带的 ld.lld + MinGW 库,fallback clang/gcc - char cmd[2048]; + // 链接:优先安装包自带的 ld.lld + MinGW 库,fallback gcc int ret = -1; char exe_dir[512]; get_exe_dir(exe_dir, sizeof(exe_dir)); - // 1) 优先: 安装包自带的 ld.lld + 自带 MinGW 库(完全自包含) - snprintf(cmd, sizeof(cmd), - "\"%s/ld.lld.exe\" -m i386pep " - "\"%s/mingw_lib/crt2.o\" \"%s/mingw_lib/crtbegin.o\" " - "\"%s\" " - "-L \"%s/mingw_lib\" " - "-lmingw32 -lmcfgthread -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt " - "-ladvapi32 -lshell32 -luser32 -lkernel32 -lntdll " - "\"%s/mingw_lib/crtend.o\" " - "-o \"%s\"", - exe_dir, exe_dir, exe_dir, - obj_path, exe_dir, - exe_dir, output); - ret = system(cmd); + // 1) 优先: 安装包自带的 ld.lld + MinGW 库(CreateProcess 避免 shell 转义) + { + char ld_path[512], crt2[512], crtbegin[512], crtend[512]; + char lib_dir[512], out_path[512]; + snprintf(ld_path, sizeof(ld_path), "%s/ld.lld.exe", exe_dir); + snprintf(crt2, sizeof(crt2), "%s/mingw_lib/crt2.o", exe_dir); + snprintf(crtbegin, sizeof(crtbegin), "%s/mingw_lib/crtbegin.o", exe_dir); + snprintf(crtend, sizeof(crtend), "%s/mingw_lib/crtend.o", exe_dir); + snprintf(lib_dir, sizeof(lib_dir), "-L%s/mingw_lib", exe_dir); + snprintf(out_path, sizeof(out_path), "-o%s", output); + + const char* ld_args[] = { + ld_path, "-m", "i386pep", + crt2, crtbegin, obj_path, + lib_dir, + "-lmingw32", "-lmcfgthread", "-lgcc", "-lgcc_eh", + "-lmoldname", "-lmingwex", "-lmsvcrt", + "-ladvapi32", "-lshell32", "-luser32", "-lkernel32", "-lntdll", + crtend, out_path, NULL + }; + int nargs = sizeof(ld_args) / sizeof(ld_args[0]) - 1; + + // 拼成命令行(CreateProcess 需要) + char cmd_line[4096] = {0}; + char* p = cmd_line; + for (int i = 0; i < nargs; i++) { + if (i > 0) *p++ = ' '; + // 路径含空格则加引号 + bool has_space = strchr(ld_args[i], ' ') != NULL; + if (has_space) *p++ = '"'; + p += strlen(strcpy(p, ld_args[i])); + if (has_space) *p++ = '"'; + } + + STARTUPINFOA si = { sizeof(si) }; + PROCESS_INFORMATION pi = {0}; + if (CreateProcessA(NULL, cmd_line, NULL, NULL, FALSE, + CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { + WaitForSingleObject(pi.hProcess, INFINITE); + DWORD exit_code; + GetExitCodeProcess(pi.hProcess, &exit_code); + ret = (int)exit_code; + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + } + } // 2) 最后 fallback: gcc(开发机有 MinGW 时) if (ret != 0) { + char cmd[1024]; snprintf(cmd, sizeof(cmd), "gcc \"%s\" -o \"%s\"", obj_path, output);