Skip to content

Commit af5c252

Browse files
committed
Tools: Compile Tools.cpp and the Tool script in parallel
1 parent 27dc586 commit af5c252

File tree

1 file changed

+201
-111
lines changed

1 file changed

+201
-111
lines changed

Tools/ToolsBootstrap.c

Lines changed: 201 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ extern int pclose(FILE *stream);
2727
#include <dirent.h>
2828
#include <sys/stat.h>
2929
#include <sys/types.h>
30+
#include <sys/wait.h>
3031
#include <unistd.h>
3132
#define POPEN popen
3233
#define PCLOSE pclose
@@ -1077,6 +1078,64 @@ int needsRebuildExe(CompilationInfo* ci) {
10771078
return (toolsObjTime > exeTime || toolObjTime > exeTime);
10781079
}
10791080

1081+
// Helper functions for building compile commands
1082+
void buildCompileCommandPOSIX(CommandLine* cmd, const char* compiler, const char* output, const char* input, int useClang) {
1083+
CommandLine_init(cmd, compiler);
1084+
CommandLine_arg(cmd, "-I../../..");
1085+
CommandLine_arg(cmd, "-std=c++14");
1086+
CommandLine_arg(cmd, "-pthread");
1087+
CommandLine_arg(cmd, "-MMD");
1088+
CommandLine_arg(cmd, "-fstrict-aliasing");
1089+
CommandLine_arg(cmd, "-fvisibility=hidden");
1090+
CommandLine_arg(cmd, "-fvisibility-inlines-hidden");
1091+
CommandLine_arg(cmd, "-fno-rtti");
1092+
CommandLine_arg(cmd, "-fno-exceptions");
1093+
CommandLine_arg(cmd, "-D_DEBUG=1");
1094+
CommandLine_arg(cmd, "-g");
1095+
CommandLine_arg(cmd, "-ggdb");
1096+
CommandLine_arg(cmd, "-O0");
1097+
if (useClang) {
1098+
CommandLine_arg(cmd, "-nostdinc++");
1099+
}
1100+
CommandLine_arg(cmd, "-o");
1101+
CommandLine_argQuoted(cmd, output);
1102+
CommandLine_arg(cmd, "-c");
1103+
CommandLine_argQuoted(cmd, input);
1104+
}
1105+
1106+
void buildCompileCommandWindows(CommandLine* cmd, const char* intermediateDir, const char* output, const char* input, const char* jsonFile, const char* pdbName) {
1107+
CommandLine_init(cmd, "cl.exe");
1108+
CommandLine_arg(cmd, "/nologo");
1109+
CommandLine_arg(cmd, "/I.");
1110+
CommandLine_arg(cmd, "/std:c++14");
1111+
CommandLine_arg(cmd, "/D_DEBUG");
1112+
CommandLine_arg(cmd, "/Zi");
1113+
CommandLine_arg(cmd, "/MTd");
1114+
CommandLine_arg(cmd, "/GS");
1115+
CommandLine_arg(cmd, "/Od");
1116+
CommandLine_arg(cmd, "/permissive-");
1117+
CommandLine_arg(cmd, "/EHsc");
1118+
CommandLine_arg(cmd, "/sourceDependencies");
1119+
CommandLine_argQuoted(cmd, jsonFile);
1120+
CommandLine_arg(cmd, "/c");
1121+
StringBuilder sb1 = StringBuilder_init(256);
1122+
StringBuilder_append(&sb1, "/Fd\"");
1123+
StringBuilder_append(&sb1, intermediateDir);
1124+
StringBuilder_append(&sb1, "/");
1125+
StringBuilder_append(&sb1, pdbName);
1126+
StringBuilder_append(&sb1, ".pdb\"");
1127+
CommandLine_arg(cmd, StringBuilder_get_buffer(&sb1));
1128+
StringBuilder_destroy(&sb1);
1129+
StringBuilder sb2 = StringBuilder_init(256);
1130+
StringBuilder_append(&sb2, "/Fo\"");
1131+
StringBuilder_append(&sb2, output);
1132+
StringBuilder_append(&sb2, "\"");
1133+
CommandLine_arg(cmd, StringBuilder_get_buffer(&sb2));
1134+
StringBuilder_destroy(&sb2);
1135+
CommandLine_argQuoted(cmd, input);
1136+
}
1137+
1138+
#ifndef _WIN32
10801139
int compilePOSIX(CompilationInfo* ci) {
10811140
// Simplified: assume clang++ or g++
10821141
FileSystem_createDirectoryRecursive(ci->intermediateDir);
@@ -1093,71 +1152,63 @@ int compilePOSIX(CompilationInfo* ci) {
10931152
return 1;
10941153
}
10951154

1096-
if (needsRebuildTools(ci)) {
1155+
int needTools = needsRebuildTools(ci);
1156+
int needTool = needsRebuildToolObj(ci);
1157+
1158+
if (needTools && needTool) {
1159+
// Compile both in parallel
1160+
pid_t pid1 = fork();
1161+
if (pid1 == 0) {
1162+
// Compile Tools.cpp
1163+
char* toolsObj = Path_join(ci->intermediateDir, "Tools.o");
1164+
CommandLine cmd;
1165+
buildCompileCommandPOSIX(&cmd, compiler, toolsObj, ci->toolsCpp, useClang);
1166+
int ret = CommandLine_run(&cmd);
1167+
CommandLine_destroy(&cmd);
1168+
free(toolsObj);
1169+
exit(ret);
1170+
}
1171+
pid_t pid2 = fork();
1172+
if (pid2 == 0) {
1173+
// Compile SC-tool.cpp
1174+
char* toolObj = Path_join(ci->intermediateDir, "SC-");
1175+
toolObj = (char*)realloc(toolObj, strlen(toolObj) + strlen(ci->args->toolName) + strlen(".o") + 1);
1176+
sprintf(toolObj + strlen(toolObj), "%s.o", ci->args->toolName);
1177+
CommandLine cmd;
1178+
buildCompileCommandPOSIX(&cmd, compiler, toolObj, ci->toolCpp, useClang);
1179+
int ret = CommandLine_run(&cmd);
1180+
CommandLine_destroy(&cmd);
1181+
free(toolObj);
1182+
exit(ret);
1183+
}
1184+
int status1, status2;
1185+
waitpid(pid1, &status1, 0);
1186+
waitpid(pid2, &status2, 0);
1187+
if (WEXITSTATUS(status1) != 0 || WEXITSTATUS(status2) != 0) return 1;
1188+
printf("Tools.cpp\n");
1189+
printf("SC-%s.cpp\n", ci->args->toolName);
1190+
} else if (needTools) {
10971191
char* toolsObj = Path_join(ci->intermediateDir, "Tools.o");
10981192
CommandLine cmd;
1099-
CommandLine_init(&cmd, compiler);
1100-
CommandLine_arg(&cmd, "-I../../..");
1101-
CommandLine_arg(&cmd, "-std=c++14");
1102-
CommandLine_arg(&cmd, "-pthread");
1103-
CommandLine_arg(&cmd, "-MMD");
1104-
CommandLine_arg(&cmd, "-fstrict-aliasing");
1105-
CommandLine_arg(&cmd, "-fvisibility=hidden");
1106-
CommandLine_arg(&cmd, "-fvisibility-inlines-hidden");
1107-
CommandLine_arg(&cmd, "-fno-rtti");
1108-
CommandLine_arg(&cmd, "-fno-exceptions");
1109-
CommandLine_arg(&cmd, "-D_DEBUG=1");
1110-
CommandLine_arg(&cmd, "-g");
1111-
CommandLine_arg(&cmd, "-ggdb");
1112-
CommandLine_arg(&cmd, "-O0");
1113-
if (useClang) {
1114-
CommandLine_arg(&cmd, "-nostdinc++");
1115-
}
1116-
CommandLine_arg(&cmd, "-o");
1117-
CommandLine_argQuoted(&cmd, toolsObj);
1118-
CommandLine_arg(&cmd, "-c");
1119-
CommandLine_argQuoted(&cmd, ci->toolsCpp);
1193+
buildCompileCommandPOSIX(&cmd, compiler, toolsObj, ci->toolsCpp, useClang);
11201194
printf("Tools.cpp\n");
11211195
int ret = CommandLine_run(&cmd);
11221196
CommandLine_destroy(&cmd);
11231197
free(toolsObj);
11241198
if (ret != 0) return 1;
1125-
} else {
1126-
printf("\"%s\" is up to date\n", ci->toolsCpp);
1127-
}
1128-
1129-
if (needsRebuildToolObj(ci)) {
1199+
} else if (needTool) {
11301200
char* toolObj = Path_join(ci->intermediateDir, "SC-");
11311201
toolObj = (char*)realloc(toolObj, strlen(toolObj) + strlen(ci->args->toolName) + strlen(".o") + 1);
11321202
sprintf(toolObj + strlen(toolObj), "%s.o", ci->args->toolName);
11331203
CommandLine cmd;
1134-
CommandLine_init(&cmd, compiler);
1135-
CommandLine_arg(&cmd, "-I../../..");
1136-
CommandLine_arg(&cmd, "-std=c++14");
1137-
CommandLine_arg(&cmd, "-pthread");
1138-
CommandLine_arg(&cmd, "-MMD");
1139-
CommandLine_arg(&cmd, "-fstrict-aliasing");
1140-
CommandLine_arg(&cmd, "-fvisibility=hidden");
1141-
CommandLine_arg(&cmd, "-fvisibility-inlines-hidden");
1142-
CommandLine_arg(&cmd, "-fno-rtti");
1143-
CommandLine_arg(&cmd, "-fno-exceptions");
1144-
CommandLine_arg(&cmd, "-D_DEBUG=1");
1145-
CommandLine_arg(&cmd, "-g");
1146-
CommandLine_arg(&cmd, "-ggdb");
1147-
CommandLine_arg(&cmd, "-O0");
1148-
if (useClang) {
1149-
CommandLine_arg(&cmd, "-nostdinc++");
1150-
}
1151-
CommandLine_arg(&cmd, "-o");
1152-
CommandLine_argQuoted(&cmd, toolObj);
1153-
CommandLine_arg(&cmd, "-c");
1154-
CommandLine_argQuoted(&cmd, ci->toolCpp);
1204+
buildCompileCommandPOSIX(&cmd, compiler, toolObj, ci->toolCpp, useClang);
11551205
printf("SC-%s.cpp\n", ci->args->toolName);
11561206
int ret = CommandLine_run(&cmd);
11571207
CommandLine_destroy(&cmd);
11581208
free(toolObj);
11591209
if (ret != 0) return 1;
11601210
} else {
1211+
printf("\"%s\" is up to date\n", ci->toolsCpp);
11611212
printf("\"%s\" is up to date\n", ci->toolCpp);
11621213
}
11631214

@@ -1194,6 +1245,7 @@ int compilePOSIX(CompilationInfo* ci) {
11941245
}
11951246
return 0;
11961247
}
1248+
#endif
11971249

11981250
int linkWindows(CompilationInfo* ci) {
11991251
printf("Linking %s\n", ci->args->toolName);
@@ -1327,48 +1379,113 @@ int compileWindows(CompilationInfo* ci, int* objsCompiled) {
13271379
FileSystem_createDirectoryRecursive(ci->intermediateDir);
13281380
FileSystem_createDirectoryRecursive(ci->toolOutputDir);
13291381

1330-
if (needsRebuildTools(ci)) {
1382+
int needTools = needsRebuildTools(ci);
1383+
int needTool = needsRebuildToolObj(ci);
1384+
1385+
if (needTools && needTool) {
1386+
// Compile both in parallel
1387+
#ifdef _WIN32
1388+
HANDLE processes[2];
1389+
int count = 0;
1390+
#endif
1391+
// Spawn Tools.obj compilation
1392+
{
1393+
*objsCompiled = 1;
1394+
char* toolsObj = Path_join(ci->intermediateDir, "Tools.obj");
1395+
char* toolsJson = Path_join(ci->intermediateDir, "Tools.json");
1396+
CommandLine cmd;
1397+
buildCompileCommandWindows(&cmd, ci->intermediateDir, toolsObj, ci->toolsCpp, toolsJson, "Tools");
1398+
#ifdef _WIN32
1399+
char* command = StringVector_join(&cmd.args, " ");
1400+
STARTUPINFOW si = {sizeof(si)};
1401+
PROCESS_INFORMATION pi;
1402+
size_t len = strlen(command);
1403+
int wlen = MultiByteToWideChar(CP_UTF8, 0, command, -1, NULL, 0);
1404+
if (wlen > 0) {
1405+
wchar_t* wcmd = (wchar_t*)malloc(wlen * sizeof(wchar_t));
1406+
if (wcmd) {
1407+
MultiByteToWideChar(CP_UTF8, 0, command, -1, wcmd, wlen);
1408+
if (CreateProcessW(NULL, wcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
1409+
processes[count++] = pi.hProcess;
1410+
CloseHandle(pi.hThread);
1411+
}
1412+
free(wcmd);
1413+
}
1414+
}
1415+
free(command);
1416+
#else
1417+
int ret = CommandLine_run(&cmd);
1418+
if (ret != 0) return 0;
1419+
#endif
1420+
CommandLine_destroy(&cmd);
1421+
free(toolsObj);
1422+
free(toolsJson);
1423+
}
1424+
// Spawn SC-tool.obj compilation
1425+
{
1426+
char* toolObj = Path_join(ci->intermediateDir, "SC-");
1427+
toolObj = (char*)realloc(toolObj, strlen(toolObj) + strlen(ci->args->toolName) + strlen(".obj") + 1);
1428+
sprintf(toolObj + strlen(toolObj), "%s.obj", ci->args->toolName);
1429+
char* toolJson = Path_join(ci->intermediateDir, "SC-");
1430+
toolJson = (char*)realloc(toolJson, strlen(toolJson) + strlen(ci->args->toolName) + strlen(".json") + 1);
1431+
sprintf(toolJson + strlen(toolJson), "%s.json", ci->args->toolName);
1432+
CommandLine cmd;
1433+
buildCompileCommandWindows(&cmd, ci->intermediateDir, toolObj, ci->toolCpp, toolJson, ci->args->toolName);
1434+
#ifdef _WIN32
1435+
char* command = StringVector_join(&cmd.args, " ");
1436+
STARTUPINFOW si = {sizeof(si)};
1437+
PROCESS_INFORMATION pi;
1438+
size_t len = strlen(command);
1439+
int wlen = MultiByteToWideChar(CP_UTF8, 0, command, -1, NULL, 0);
1440+
if (wlen > 0) {
1441+
wchar_t* wcmd = (wchar_t*)malloc(wlen * sizeof(wchar_t));
1442+
if (wcmd) {
1443+
MultiByteToWideChar(CP_UTF8, 0, command, -1, wcmd, wlen);
1444+
if (CreateProcessW(NULL, wcmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) {
1445+
processes[count++] = pi.hProcess;
1446+
CloseHandle(pi.hThread);
1447+
}
1448+
free(wcmd);
1449+
}
1450+
}
1451+
free(command);
1452+
#else
1453+
int ret = CommandLine_run(&cmd);
1454+
if (ret != 0) return 0;
1455+
#endif
1456+
CommandLine_destroy(&cmd);
1457+
free(toolObj);
1458+
free(toolJson);
1459+
}
1460+
#ifdef _WIN32
1461+
// Wait for both
1462+
if (count == 2) {
1463+
WaitForMultipleObjects(2, processes, TRUE, INFINITE);
1464+
DWORD exit1, exit2;
1465+
GetExitCodeProcess(processes[0], &exit1);
1466+
GetExitCodeProcess(processes[1], &exit2);
1467+
CloseHandle(processes[0]);
1468+
CloseHandle(processes[1]);
1469+
if (exit1 != 0 || exit2 != 0) return 0;
1470+
} else {
1471+
return 0;
1472+
}
1473+
#else
1474+
printf("Tools.cpp\n");
1475+
printf("SC-%s.cpp\n", ci->args->toolName);
1476+
#endif
1477+
} else if (needTools) {
13311478
*objsCompiled = 1;
13321479
char* toolsObj = Path_join(ci->intermediateDir, "Tools.obj");
13331480
char* toolsJson = Path_join(ci->intermediateDir, "Tools.json");
13341481
CommandLine cmd;
1335-
CommandLine_init(&cmd, "cl.exe");
1336-
CommandLine_arg(&cmd, "/nologo");
1337-
CommandLine_arg(&cmd, "/I.");
1338-
CommandLine_arg(&cmd, "/std:c++14");
1339-
CommandLine_arg(&cmd, "/D_DEBUG");
1340-
CommandLine_arg(&cmd, "/Zi");
1341-
CommandLine_arg(&cmd, "/MTd");
1342-
CommandLine_arg(&cmd, "/GS");
1343-
CommandLine_arg(&cmd, "/Od");
1344-
CommandLine_arg(&cmd, "/permissive-");
1345-
CommandLine_arg(&cmd, "/EHsc");
1346-
CommandLine_arg(&cmd, "/sourceDependencies");
1347-
CommandLine_argQuoted(&cmd, toolsJson);
1348-
CommandLine_arg(&cmd, "/c");
1349-
StringBuilder sb1 = StringBuilder_init(256);
1350-
StringBuilder_append(&sb1, "/Fd\"");
1351-
StringBuilder_append(&sb1, ci->intermediateDir);
1352-
StringBuilder_append(&sb1, "/Tools.pdb\"");
1353-
CommandLine_arg(&cmd, StringBuilder_get_buffer(&sb1));
1354-
StringBuilder_destroy(&sb1);
1355-
StringBuilder sb2 = StringBuilder_init(256);
1356-
StringBuilder_append(&sb2, "/Fo\"");
1357-
StringBuilder_append(&sb2, toolsObj);
1358-
StringBuilder_append(&sb2, "\"");
1359-
CommandLine_arg(&cmd, StringBuilder_get_buffer(&sb2));
1360-
StringBuilder_destroy(&sb2);
1361-
CommandLine_argQuoted(&cmd, ci->toolsCpp);
1482+
buildCompileCommandWindows(&cmd, ci->intermediateDir, toolsObj, ci->toolsCpp, toolsJson, "Tools");
13621483
int ret = CommandLine_run(&cmd);
13631484
CommandLine_destroy(&cmd);
13641485
free(toolsObj);
13651486
free(toolsJson);
13661487
if (ret != 0) return 0;
1367-
} else {
1368-
printf("\"%s\" is up to date\n", ci->toolsCpp);
1369-
}
1370-
1371-
if (needsRebuildToolObj(ci)) {
1488+
} else if (needTool) {
13721489
*objsCompiled = 1;
13731490
char* toolObj = Path_join(ci->intermediateDir, "SC-");
13741491
toolObj = (char*)realloc(toolObj, strlen(toolObj) + strlen(ci->args->toolName) + strlen(".obj") + 1);
@@ -1377,41 +1494,14 @@ FileSystem_createDirectoryRecursive(ci->intermediateDir);
13771494
toolJson = (char*)realloc(toolJson, strlen(toolJson) + strlen(ci->args->toolName) + strlen(".json") + 1);
13781495
sprintf(toolJson + strlen(toolJson), "%s.json", ci->args->toolName);
13791496
CommandLine cmd;
1380-
CommandLine_init(&cmd, "cl.exe");
1381-
CommandLine_arg(&cmd, "/nologo");
1382-
CommandLine_arg(&cmd, "/I.");
1383-
CommandLine_arg(&cmd, "/std:c++14");
1384-
CommandLine_arg(&cmd, "/D_DEBUG");
1385-
CommandLine_arg(&cmd, "/Zi");
1386-
CommandLine_arg(&cmd, "/MTd");
1387-
CommandLine_arg(&cmd, "/GS");
1388-
CommandLine_arg(&cmd, "/Od");
1389-
CommandLine_arg(&cmd, "/permissive-");
1390-
CommandLine_arg(&cmd, "/EHsc");
1391-
CommandLine_arg(&cmd, "/sourceDependencies");
1392-
CommandLine_argQuoted(&cmd, toolJson);
1393-
CommandLine_arg(&cmd, "/c");
1394-
StringBuilder sb1 = StringBuilder_init(256);
1395-
StringBuilder_append(&sb1, "/Fd\"");
1396-
StringBuilder_append(&sb1, ci->intermediateDir);
1397-
StringBuilder_append(&sb1, "/SC-");
1398-
StringBuilder_append(&sb1, ci->args->toolName);
1399-
StringBuilder_append(&sb1, ".pdb\"");
1400-
CommandLine_arg(&cmd, StringBuilder_get_buffer(&sb1));
1401-
StringBuilder_destroy(&sb1);
1402-
StringBuilder sb2 = StringBuilder_init(256);
1403-
StringBuilder_append(&sb2, "/Fo\"");
1404-
StringBuilder_append(&sb2, toolObj);
1405-
StringBuilder_append(&sb2, "\"");
1406-
CommandLine_arg(&cmd, StringBuilder_get_buffer(&sb2));
1407-
StringBuilder_destroy(&sb2);
1408-
CommandLine_argQuoted(&cmd, ci->toolCpp);
1497+
buildCompileCommandWindows(&cmd, ci->intermediateDir, toolObj, ci->toolCpp, toolJson, ci->args->toolName);
14091498
int ret = CommandLine_run(&cmd);
14101499
CommandLine_destroy(&cmd);
14111500
free(toolObj);
14121501
free(toolJson);
1413-
return ret == 0;
1502+
if (ret != 0) return 0;
14141503
} else {
1504+
printf("\"%s\" is up to date\n", ci->toolsCpp);
14151505
printf("\"%s\" is up to date\n", ci->toolCpp);
14161506
}
14171507
return 1;

0 commit comments

Comments
 (0)