From 3e7216f57d66d8e300628cb3db6ca9bc98fd644a Mon Sep 17 00:00:00 2001 From: Patedam Date: Sun, 16 Aug 2026 13:13:51 -0400 Subject: [PATCH] Modified build system to detect pch changes *gemini --- Juliet/include/Core/PCH.h | 2 - Juliet/src/Core/HAL/IO/IOStream_Private.h | 4 +- misc/build.bat | 32 +-- tools/build_system.c | 260 +++++++++++++++++----- 4 files changed, 220 insertions(+), 78 deletions(-) diff --git a/Juliet/include/Core/PCH.h b/Juliet/include/Core/PCH.h index 639f546..e026445 100644 --- a/Juliet/include/Core/PCH.h +++ b/Juliet/include/Core/PCH.h @@ -22,11 +22,9 @@ #include #include #include -#include #include #include #include #include -#include #include #include diff --git a/Juliet/src/Core/HAL/IO/IOStream_Private.h b/Juliet/src/Core/HAL/IO/IOStream_Private.h index daa8165..ad3d60d 100644 --- a/Juliet/src/Core/HAL/IO/IOStream_Private.h +++ b/Juliet/src/Core/HAL/IO/IOStream_Private.h @@ -15,5 +15,5 @@ namespace Juliet namespace Juliet::Internal { - extern JULIET_API IOStream* IOFromFile(String filename, String mode); -} + IOStream* IOFromFile(String filename, String mode); +} // namespace Juliet::Internal diff --git a/misc/build.bat b/misc/build.bat index b206acc..4cf4ac4 100644 --- a/misc/build.bat +++ b/misc/build.bat @@ -9,7 +9,7 @@ cd /d "%~dp0\.." set BUILD_TOOL=misc\build_system.exe set BUILD_SRC=tools\build_system.c -set BUILD_TOOL_VER=1.5 +set BUILD_TOOL_VER=1.6 set COMMAND_GEN_VS=0 @@ -189,13 +189,13 @@ if defined IMGUI_UNITY_SRCS set IMGUI_OBJS=Intermediate\x64-!CFG!\ImGui_Unity*.o :: --- Juliet PCH --- echo STEP Building Juliet PCH [!CFG!]>>"!PLAN_FILE!" -echo OUTPUT Intermediate\x64-!CFG!\Juliet_PCH.obj>>"!PLAN_FILE!" -echo DEPENDS Juliet\src\Core\PCH.cpp>>"!PLAN_FILE!" +echo OUTPUT Intermediate\x64-!CFG!\Juliet_PCH.obj^|Intermediate\x64-!CFG!\Juliet.pch>>"!PLAN_FILE!" +echo DEPENDS Juliet\src\Core\PCH.cpp^|Juliet\include\Core\PCH.h>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /DIMGUI_API=__declspec^(dllexport^) /DJULIET_EXPORT /Yc"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\Juliet.pch" /c Juliet\src\Core\PCH.cpp /Fo"Intermediate\x64-!CFG!\Juliet_PCH.obj">>"!PLAN_FILE!" echo STEP Compiling Juliet Objs [!CFG!]>>"!PLAN_FILE!" echo OUTPUT Intermediate\x64-!CFG!\Juliet_Objs>>"!PLAN_FILE!" -echo DEPENDS Juliet>>"!PLAN_FILE!" +echo DEPENDS Juliet^|Intermediate\x64-!CFG!\Juliet.pch>>"!PLAN_FILE!" echo INC_SRC Intermediate\Juliet>>"!PLAN_FILE!" echo INC_OBJ Intermediate\x64-!CFG!\Juliet_Objs>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /MP /DIMGUI_API=__declspec^(dllexport^) /DJULIET_EXPORT /FI"Core/PCH.h" /Yu"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\Juliet.pch" /c /Fo"Intermediate\x64-!CFG!\Juliet_Objs\\">>"!PLAN_FILE!" @@ -215,13 +215,13 @@ if !BUILD_GAME_DLL! equ 1 ( :: --- Game PCH --- echo STEP Building Game PCH [!CFG!]>>"!PLAN_FILE!" - echo OUTPUT Intermediate\x64-!CFG!\Game_PCH.obj>>"!PLAN_FILE!" - echo DEPENDS Juliet\src\Core\PCH.cpp>>"!PLAN_FILE!" + echo OUTPUT Intermediate\x64-!CFG!\Game_PCH.obj^|Intermediate\x64-!CFG!\Game.pch>>"!PLAN_FILE!" + echo DEPENDS Juliet\src\Core\PCH.cpp^|Juliet\include\Core\PCH.h>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /DIMGUI_API=__declspec^(dllimport^) /DJULIET_EXPORT /Yc"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\Game.pch" /c Juliet\src\Core\PCH.cpp /Fo"Intermediate\x64-!CFG!\Game_PCH.obj">>"!PLAN_FILE!" echo STEP Compiling Game Objs [!CFG!]>>"!PLAN_FILE!" echo OUTPUT Intermediate\x64-!CFG!\Game_Objs>>"!PLAN_FILE!" - echo DEPENDS Game^|Juliet>>"!PLAN_FILE!" + echo DEPENDS Game^|Juliet^|Intermediate\x64-!CFG!\Game.pch>>"!PLAN_FILE!" echo INC_SRC Intermediate\Game>>"!PLAN_FILE!" echo INC_OBJ Intermediate\x64-!CFG!\Game_Objs>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /MP /DIMGUI_API=__declspec^(dllimport^) /DJULIET_EXPORT /FI"Core/PCH.h" /Yu"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\Game.pch" /c /Fo"Intermediate\x64-!CFG!\Game_Objs\\">>"!PLAN_FILE!" @@ -238,13 +238,13 @@ if !BUILD_GAME_DLL! equ 1 ( if !TARGET_JULIET! equ 1 ( :: --- JulietApp PCH --- echo STEP Building JulietApp PCH [!CFG!]>>"!PLAN_FILE!" - echo OUTPUT Intermediate\x64-!CFG!\JulietApp_PCH.obj>>"!PLAN_FILE!" - echo DEPENDS Juliet\src\Core\PCH.cpp>>"!PLAN_FILE!" + echo OUTPUT Intermediate\x64-!CFG!\JulietApp_PCH.obj^|Intermediate\x64-!CFG!\JulietApp.pch>>"!PLAN_FILE!" + echo DEPENDS Juliet\src\Core\PCH.cpp^|Juliet\include\Core\PCH.h>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /DIMGUI_API=__declspec^(dllimport^) /Yc"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\JulietApp.pch" /c Juliet\src\Core\PCH.cpp /Fo"Intermediate\x64-!CFG!\JulietApp_PCH.obj">>"!PLAN_FILE!" echo STEP Compiling JulietApp Objs [!CFG!]>>"!PLAN_FILE!" echo OUTPUT Intermediate\x64-!CFG!\JulietApp_Objs>>"!PLAN_FILE!" - echo DEPENDS JulietApp^|Juliet>>"!PLAN_FILE!" + echo DEPENDS JulietApp^|Juliet^|Intermediate\x64-!CFG!\JulietApp.pch>>"!PLAN_FILE!" echo INC_SRC Intermediate\JulietApp>>"!PLAN_FILE!" echo INC_OBJ Intermediate\x64-!CFG!\JulietApp_Objs>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /MP /DIMGUI_API=__declspec^(dllimport^) /FI"Core/PCH.h" /Yu"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\JulietApp.pch" /c /Fo"Intermediate\x64-!CFG!\JulietApp_Objs\\">>"!PLAN_FILE!" @@ -261,13 +261,13 @@ if !TARGET_JULIET! equ 1 ( if !TARGET_ROMEO! equ 1 ( :: --- Romeo PCH --- echo STEP Building Romeo PCH [!CFG!]>>"!PLAN_FILE!" - echo OUTPUT Intermediate\x64-!CFG!\Romeo_PCH.obj>>"!PLAN_FILE!" - echo DEPENDS Juliet\src\Core\PCH.cpp>>"!PLAN_FILE!" + echo OUTPUT Intermediate\x64-!CFG!\Romeo_PCH.obj^|Intermediate\x64-!CFG!\Romeo.pch>>"!PLAN_FILE!" + echo DEPENDS Juliet\src\Core\PCH.cpp^|Juliet\include\Core\PCH.h>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /DIMGUI_API=__declspec^(dllimport^) /Yc"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\Romeo.pch" /c Juliet\src\Core\PCH.cpp /Fo"Intermediate\x64-!CFG!\Romeo_PCH.obj">>"!PLAN_FILE!" echo STEP Compiling Romeo Objs [!CFG!]>>"!PLAN_FILE!" echo OUTPUT Intermediate\x64-!CFG!\Romeo_Objs>>"!PLAN_FILE!" - echo DEPENDS Romeo^|Juliet>>"!PLAN_FILE!" + echo DEPENDS Romeo^|Juliet^|Intermediate\x64-!CFG!\Romeo.pch>>"!PLAN_FILE!" echo INC_SRC Intermediate\Romeo>>"!PLAN_FILE!" echo INC_OBJ Intermediate\x64-!CFG!\Romeo_Objs>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /MP /DIMGUI_API=__declspec^(dllimport^) /FI"Core/PCH.h" /Yu"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\Romeo.pch" /c /Fo"Intermediate\x64-!CFG!\Romeo_Objs\\">>"!PLAN_FILE!" @@ -284,13 +284,13 @@ if !TARGET_ROMEO! equ 1 ( if !TARGET_SHADER! equ 1 ( :: --- JulietShaderCompiler PCH --- echo STEP Building JulietShaderCompiler PCH [!CFG!]>>"!PLAN_FILE!" - echo OUTPUT Intermediate\x64-!CFG!\JulietShaderCompiler_PCH.obj>>"!PLAN_FILE!" - echo DEPENDS Juliet\src\Core\PCH.cpp>>"!PLAN_FILE!" + echo OUTPUT Intermediate\x64-!CFG!\JulietShaderCompiler_PCH.obj^|Intermediate\x64-!CFG!\JulietShaderCompiler.pch>>"!PLAN_FILE!" + echo DEPENDS Juliet\src\Core\PCH.cpp^|Juliet\include\Core\PCH.h>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /DIMGUI_API=__declspec^(dllimport^) /IJulietShaderCompiler /Yc"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\JulietShaderCompiler.pch" /c Juliet\src\Core\PCH.cpp /Fo"Intermediate\x64-!CFG!\JulietShaderCompiler_PCH.obj">>"!PLAN_FILE!" echo STEP Compiling JulietShaderCompiler Objs [!CFG!]>>"!PLAN_FILE!" echo OUTPUT Intermediate\x64-!CFG!\JulietShaderCompiler_Objs>>"!PLAN_FILE!" - echo DEPENDS JulietShaderCompiler^|Juliet>>"!PLAN_FILE!" + echo DEPENDS JulietShaderCompiler^|Juliet^|Intermediate\x64-!CFG!\JulietShaderCompiler.pch>>"!PLAN_FILE!" echo INC_SRC Intermediate\JulietShaderCompiler>>"!PLAN_FILE!" echo INC_OBJ Intermediate\x64-!CFG!\JulietShaderCompiler_Objs>>"!PLAN_FILE!" echo COMMAND %COMPILER% %COMPILER_FLAGS% /MP /DIMGUI_API=__declspec^(dllimport^) /IJulietShaderCompiler /FI"Core/PCH.h" /Yu"Core/PCH.h" /Fp"Intermediate\x64-!CFG!\JulietShaderCompiler.pch" /c /Fo"Intermediate\x64-!CFG!\JulietShaderCompiler_Objs\\">>"!PLAN_FILE!" diff --git a/tools/build_system.c b/tools/build_system.c index d89e531..183d6b0 100644 --- a/tools/build_system.c +++ b/tools/build_system.c @@ -185,19 +185,26 @@ static int64_t GetNewestSourceTimeRecursive(const char* dirPath) if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { int64_t subNewest = GetNewestSourceTimeRecursive(fullPath); - if (subNewest > newest) newest = subNewest; + if (subNewest > newest) + { + newest = subNewest; + } } else { if (EndsWithNoCase(findData.cFileName, ".cpp") || EndsWithNoCase(findData.cFileName, ".h") || EndsWithNoCase(findData.cFileName, ".hpp") || EndsWithNoCase(findData.cFileName, ".inl") || - EndsWithNoCase(findData.cFileName, ".c")) + EndsWithNoCase(findData.cFileName, ".c") || EndsWithNoCase(findData.cFileName, ".obj") || + EndsWithNoCase(findData.cFileName, ".pch") || EndsWithNoCase(findData.cFileName, ".lib")) { ULARGE_INTEGER li; li.LowPart = findData.ftLastWriteTime.dwLowDateTime; li.HighPart = findData.ftLastWriteTime.dwHighDateTime; int64_t ft = (int64_t)li.QuadPart; - if (ft > newest) newest = ft; + if (ft > newest) + { + newest = ft; + } } } } @@ -510,23 +517,41 @@ typedef struct { char Path[MAX_PATH_LEN]; int64_t Time; -} DirCacheEntry; +} PathCacheEntry; -static DirCacheEntry g_DirCache[64]; -static int g_DirCacheCount = 0; +static PathCacheEntry g_PathCache[256]; +static int g_PathCacheCount = 0; -static int64_t GetDirTime(const char* dir) +static void ClearPathCache(void) { - for (int k = 0; k < g_DirCacheCount; k++) + g_PathCacheCount = 0; +} + +static int64_t GetPathTime(const char* path) +{ + for (int k = 0; k < g_PathCacheCount; k++) { - if (_stricmp(g_DirCache[k].Path, dir) == 0) return g_DirCache[k].Time; + if (_stricmp(g_PathCache[k].Path, path) == 0) + { + return g_PathCache[k].Time; + } } - int64_t t = GetNewestSourceTimeRecursive(dir); - if (g_DirCacheCount < 64) + + int64_t t = 0; + if (DirectoryExists(path)) { - strncpy_s(g_DirCache[g_DirCacheCount].Path, MAX_PATH_LEN, dir, _TRUNCATE); - g_DirCache[g_DirCacheCount].Time = t; - g_DirCacheCount++; + t = GetNewestSourceTimeRecursive(path); + } + else if (FileExists(path)) + { + t = GetFileModTimeInt64(path); + } + + if (g_PathCacheCount < 256) + { + strncpy_s(g_PathCache[g_PathCacheCount].Path, MAX_PATH_LEN, path, _TRUNCATE); + g_PathCache[g_PathCacheCount].Time = t; + g_PathCacheCount++; } return t; } @@ -552,34 +577,58 @@ static int ExecuteIncrementalCompile(const char* srcDir, const char* objDir, con snprintf(objSearchPath, sizeof(objSearchPath), "%s\\*.obj", objDir); WIN32_FIND_DATAA findData; HANDLE hFind = FindFirstFileA(objSearchPath, &findData); - if (hFind != INVALID_HANDLE_VALUE) { - do { - if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue; + if (hFind != INVALID_HANDLE_VALUE) + { + do + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + continue; + } char baseName[256]; strcpy_s(baseName, sizeof(baseName), findData.cFileName); char* ext = strrchr(baseName, '.'); - if (ext) *ext = '\0'; + if (ext) + { + *ext = '\0'; + } bool foundSrc = false; - for (int i = 0; i < cppFiles->Count; i++) { + for (int i = 0; i < cppFiles->Count; i++) + { const char* srcPath = cppFiles->Paths[i]; const char* srcFile = strrchr(srcPath, '\\'); - if (!srcFile) srcFile = strrchr(srcPath, '/'); - if (!srcFile) srcFile = srcPath; else srcFile++; + if (!srcFile) + { + srcFile = strrchr(srcPath, '/'); + } + if (!srcFile) + { + srcFile = srcPath; + } + else + { + srcFile++; + } char srcBase[256]; strcpy_s(srcBase, sizeof(srcBase), srcFile); char* srcExt = strrchr(srcBase, '.'); - if (srcExt) *srcExt = '\0'; + if (srcExt) + { + *srcExt = '\0'; + } - if (_stricmp(baseName, srcBase) == 0) { + if (_stricmp(baseName, srcBase) == 0) + { foundSrc = true; break; } } - if (!foundSrc) { + if (!foundSrc) + { char fullObjPath[MAX_PATH_LEN]; snprintf(fullObjPath, sizeof(fullObjPath), "%s\\%s", objDir, findData.cFileName); DeleteFileA(fullObjPath); @@ -596,32 +645,54 @@ static int ExecuteIncrementalCompile(const char* srcDir, const char* objDir, con { const char* srcPath = cppFiles->Paths[i]; const char* fileName = strrchr(srcPath, '\\'); - if (!fileName) fileName = strrchr(srcPath, '/'); - if (!fileName) fileName = srcPath; else fileName++; + if (!fileName) + { + fileName = strrchr(srcPath, '/'); + } + if (!fileName) + { + fileName = srcPath; + } + else + { + fileName++; + } char objPath[MAX_PATH_LEN]; sprintf_s(objPath, sizeof(objPath), "%s\\%s", objDir, fileName); char* ext = strrchr(objPath, '.'); - if (ext) strcpy_s(ext, sizeof(objPath) - (ext - objPath), ".obj"); + if (ext) + { + strcpy_s(ext, sizeof(objPath) - (ext - objPath), ".obj"); + } bool dirty = false; - if (!FileExists(objPath)) { + if (!FileExists(objPath)) + { dirty = true; - } else { + } + else + { int64_t objTime = GetFileModTimeInt64(objPath); - if (GetFileModTimeInt64(srcPath) > objTime || maxDepTime > objTime) { + if (GetFileModTimeInt64(srcPath) > objTime || maxDepTime > objTime) + { dirty = true; } } - if (dirty) { - if (dirtyCount > 0) strcat_s(dirtyFiles, MAX_FILES, " "); + if (dirty) + { + if (dirtyCount > 0) + { + strcat_s(dirtyFiles, MAX_FILES, " "); + } strcat_s(dirtyFiles, MAX_FILES, srcPath); dirtyCount++; } } - if (dirtyCount == 0) { + if (dirtyCount == 0) + { printf("[SKIP / UP-TO-DATE] %s [All objects up to date]\n", objDir); return 0; } @@ -846,7 +917,7 @@ static int CommandRunPlan(int argc, char* argv[]) printf("Compiling Targets [%s]...\n", cfg->Name); printf("==============================================================================\n"); - g_DirCacheCount = 0; + ClearPathCache(); bool anyNeedBuild = false; for (int j = 0; j < cfg->StepCount; j++) @@ -857,39 +928,81 @@ static int CommandRunPlan(int argc, char* argv[]) while (*cur) { const char* nextPipe = strchr(cur, '|'); - char dirPath[MAX_PATH_LEN] = { 0 }; + char depPath[MAX_PATH_LEN] = { 0 }; if (nextPipe) { int dLen = (int)(nextPipe - cur); - if (dLen >= (int)sizeof(dirPath)) dLen = (int)sizeof(dirPath) - 1; - memcpy(dirPath, cur, dLen); - dirPath[dLen] = '\0'; + if (dLen >= (int)sizeof(depPath)) + { + dLen = (int)sizeof(depPath) - 1; + } + memcpy(depPath, cur, dLen); + depPath[dLen] = '\0'; cur = nextPipe + 1; } else { - strcpy_s(dirPath, sizeof(dirPath), cur); + strcpy_s(depPath, sizeof(depPath), cur); cur += strlen(cur); } - if (dirPath[0] != '\0') + if (depPath[0] != '\0') { - int64_t t = GetDirTime(dirPath); - if (t > maxTime) maxTime = t; + int64_t t = GetPathTime(depPath); + if (t > maxTime) + { + maxTime = t; + } } } bool needCompile = unityChanged; if (!needCompile) { - if (!FileExists(step->OutputFile)) + const char* outCur = step->OutputFile; + int64_t minOutTime = 0x7FFFFFFFFFFFFFFFLL; + bool hasOutputs = false; + + while (*outCur) + { + const char* nextPipe = strchr(outCur, '|'); + char singleOut[MAX_PATH_LEN] = { 0 }; + if (nextPipe) + { + int oLen = (int)(nextPipe - outCur); + if (oLen >= (int)sizeof(singleOut)) + { + oLen = (int)sizeof(singleOut) - 1; + } + memcpy(singleOut, outCur, oLen); + singleOut[oLen] = '\0'; + outCur = nextPipe + 1; + } + else + { + strcpy_s(singleOut, sizeof(singleOut), outCur); + outCur += strlen(outCur); + } + + if (singleOut[0] != '\0') + { + hasOutputs = true; + if (!FileExists(singleOut) && !DirectoryExists(singleOut)) + { + needCompile = true; + break; + } + int64_t oTime = GetPathTime(singleOut); + if (oTime < minOutTime) + { + minOutTime = oTime; + } + } + } + + if (!needCompile && hasOutputs && minOutTime < maxTime) { needCompile = true; } - else - { - int64_t outTime = GetFileModTimeInt64(step->OutputFile); - if (outTime < maxTime) needCompile = true; - } } printf("\n--- %s ---\n", step->StepName); @@ -901,12 +1014,14 @@ static int CommandRunPlan(int argc, char* argv[]) int res = ExecuteIncrementalCompile(step->IncSrc, step->IncObj, step->Command, maxTime); QueryPerformanceCounter(&tEnd); AppendTiming(step->StepName, (double)(tEnd.QuadPart - tStart.QuadPart) / (double)perfFreq.QuadPart); - if (res != 0) { + if (res != 0) + { printf("[BUILD FAILED] Command failed with exit code %d.\n", res); return res; } + ClearPathCache(); anyNeedBuild = true; - anyBuilt = true; + anyBuilt = true; continue; } @@ -932,17 +1047,46 @@ static int CommandRunPlan(int argc, char* argv[]) return res; } - char builtOut[MAX_PATH_LEN + 2]; - sprintf_s(builtOut, sizeof(builtOut), "%s\n", step->OutputFile); + ClearPathCache(); - HANDLE hFile = CreateFileA("Intermediate\\built_outputs.tmp", FILE_APPEND_DATA, FILE_SHARE_READ, NULL, - OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (hFile != INVALID_HANDLE_VALUE) + const char* outCur = step->OutputFile; + while (*outCur) { - DWORD written = 0; - WriteFile(hFile, builtOut, (DWORD)strlen(builtOut), &written, NULL); - CloseHandle(hFile); + const char* nextPipe = strchr(outCur, '|'); + char singleOut[MAX_PATH_LEN] = { 0 }; + if (nextPipe) + { + int oLen = (int)(nextPipe - outCur); + if (oLen >= (int)sizeof(singleOut)) + { + oLen = (int)sizeof(singleOut) - 1; + } + memcpy(singleOut, outCur, oLen); + singleOut[oLen] = '\0'; + outCur = nextPipe + 1; + } + else + { + strcpy_s(singleOut, sizeof(singleOut), outCur); + outCur += strlen(outCur); + } + + if (singleOut[0] != '\0') + { + char builtOut[MAX_PATH_LEN + 2]; + sprintf_s(builtOut, sizeof(builtOut), "%s\n", singleOut); + + HANDLE hFile = CreateFileA("Intermediate\\built_outputs.tmp", FILE_APPEND_DATA, FILE_SHARE_READ, NULL, + OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (hFile != INVALID_HANDLE_VALUE) + { + DWORD written = 0; + WriteFile(hFile, builtOut, (DWORD)strlen(builtOut), &written, NULL); + CloseHandle(hFile); + } + } } + anyBuilt = true; } }