fix: CreateProcess 替代 system() 调 ld.lld,消除 shell 转义问题

This commit is contained in:
2026-06-05 22:07:53 +08:00
parent 39d8bad022
commit de91886712
+51 -17
View File
@@ -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);