@@ -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
10801139int 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
11981250int linkWindows (CompilationInfo * ci ) {
11991251 printf ("Linking %s\n" , ci -> args -> toolName );
@@ -1327,48 +1379,113 @@ int compileWindows(CompilationInfo* ci, int* objsCompiled) {
13271379FileSystem_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