fix: CreateProcess 替代 system() 调 ld.lld,消除 shell 转义问题
This commit is contained in:
+51
-17
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user