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) {
|
static void get_exe_dir(char* buf, size_t size) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
GetModuleFileNameA(NULL, buf, (DWORD)size);
|
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';
|
if (last) *last = '\0';
|
||||||
#else
|
#else
|
||||||
buf[0] = '.'; buf[1] = '\0';
|
buf[0] = '.'; buf[1] = '\0';
|
||||||
@@ -152,29 +154,61 @@ int main(int argc, char** argv) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 链接:优先安装包自带的 ld.lld + MinGW 库,fallback clang/gcc
|
// 链接:优先安装包自带的 ld.lld + MinGW 库,fallback gcc
|
||||||
char cmd[2048];
|
|
||||||
int ret = -1;
|
int ret = -1;
|
||||||
char exe_dir[512];
|
char exe_dir[512];
|
||||||
get_exe_dir(exe_dir, sizeof(exe_dir));
|
get_exe_dir(exe_dir, sizeof(exe_dir));
|
||||||
|
|
||||||
// 1) 优先: 安装包自带的 ld.lld + 自带 MinGW 库(完全自包含)
|
// 1) 优先: 安装包自带的 ld.lld + MinGW 库(CreateProcess 避免 shell 转义)
|
||||||
snprintf(cmd, sizeof(cmd),
|
{
|
||||||
"\"%s/ld.lld.exe\" -m i386pep "
|
char ld_path[512], crt2[512], crtbegin[512], crtend[512];
|
||||||
"\"%s/mingw_lib/crt2.o\" \"%s/mingw_lib/crtbegin.o\" "
|
char lib_dir[512], out_path[512];
|
||||||
"\"%s\" "
|
snprintf(ld_path, sizeof(ld_path), "%s/ld.lld.exe", exe_dir);
|
||||||
"-L \"%s/mingw_lib\" "
|
snprintf(crt2, sizeof(crt2), "%s/mingw_lib/crt2.o", exe_dir);
|
||||||
"-lmingw32 -lmcfgthread -lgcc -lgcc_eh -lmoldname -lmingwex -lmsvcrt "
|
snprintf(crtbegin, sizeof(crtbegin), "%s/mingw_lib/crtbegin.o", exe_dir);
|
||||||
"-ladvapi32 -lshell32 -luser32 -lkernel32 -lntdll "
|
snprintf(crtend, sizeof(crtend), "%s/mingw_lib/crtend.o", exe_dir);
|
||||||
"\"%s/mingw_lib/crtend.o\" "
|
snprintf(lib_dir, sizeof(lib_dir), "-L%s/mingw_lib", exe_dir);
|
||||||
"-o \"%s\"",
|
snprintf(out_path, sizeof(out_path), "-o%s", output);
|
||||||
exe_dir, exe_dir, exe_dir,
|
|
||||||
obj_path, exe_dir,
|
const char* ld_args[] = {
|
||||||
exe_dir, output);
|
ld_path, "-m", "i386pep",
|
||||||
ret = system(cmd);
|
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 时)
|
// 2) 最后 fallback: gcc(开发机有 MinGW 时)
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
|
char cmd[1024];
|
||||||
snprintf(cmd, sizeof(cmd),
|
snprintf(cmd, sizeof(cmd),
|
||||||
"gcc \"%s\" -o \"%s\"",
|
"gcc \"%s\" -o \"%s\"",
|
||||||
obj_path, output);
|
obj_path, output);
|
||||||
|
|||||||
Reference in New Issue
Block a user