attempting to fix compilation issues on windows and ENSURE it actually finds cl.exe instead of saying, 'uh, where the HELL IS THE cl.exe???'

This commit is contained in:
2026-01-25 00:15:24 -05:00
parent 673dc6a799
commit 3b93049a34
3 changed files with 144 additions and 5 deletions

View File

@@ -62,7 +62,14 @@ find_package(OpenGL REQUIRED)
option(MODULARITY_USE_MONO "Enable Mono embedding for managed scripts" ON)
if(MODULARITY_USE_MONO)
set(MONO_ROOT ${PROJECT_SOURCE_DIR}/src/ThirdParty/mono CACHE PATH "Mono root directory")
set(MONO_ROOT "" CACHE PATH "Mono root directory")
if(NOT MONO_ROOT)
if(DEFINED ENV{MONO_ROOT} AND NOT "$ENV{MONO_ROOT}" STREQUAL "")
set(MONO_ROOT "$ENV{MONO_ROOT}" CACHE PATH "Mono root directory" FORCE)
else()
set(MONO_ROOT "${PROJECT_SOURCE_DIR}/src/ThirdParty/mono" CACHE PATH "Mono root directory" FORCE)
endif()
endif()
find_path(MONO_INCLUDE_DIR mono/jit/jit.h
HINTS
${MONO_ROOT}/include/mono-2.0

View File

@@ -33,6 +33,9 @@ if %errorlevel%==0 (
echo [INFO] ccache detected. Normalizing paths for cross-build cache hits.
)
set "MONO_ROOT_ARG="
if defined MONO_ROOT set "MONO_ROOT_ARG=-DMONO_ROOT=%MONO_ROOT%"
:: Clean old build (optional)
if exist build if %CLEAN_BUILD%==1 (
echo [INFO] Cleaning existing build directory...
@@ -44,7 +47,7 @@ if not exist build mkdir build
pushd build
echo [INFO] Configuring with CMake (Visual Studio 18 2026)...
cmake -A x64 .. -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
cmake -A x64 .. -DCMAKE_BUILD_TYPE=%BUILD_TYPE% %MONO_ROOT_ARG%
if errorlevel 1 (
echo.
@@ -84,7 +87,7 @@ if exist "%PLAYER_CACHE_DIR%" if %CLEAN_BUILD%==1 (
if not exist "%PLAYER_CACHE_DIR%" mkdir "%PLAYER_CACHE_DIR%"
echo [INFO] Configuring player cache build...
cmake -S . -B "%PLAYER_CACHE_DIR%" -DMODULARITY_BUILD_EDITOR=OFF -DCMAKE_BUILD_TYPE=%BUILD_TYPE%
cmake -S . -B "%PLAYER_CACHE_DIR%" -DMODULARITY_BUILD_EDITOR=OFF -DCMAKE_BUILD_TYPE=%BUILD_TYPE% %MONO_ROOT_ARG%
if errorlevel 1 (
echo.
echo [ERROR] Player cache CMake configuration failed!

View File

@@ -20,6 +20,124 @@ namespace {
}
return normalized;
}
std::string trimCopy(const std::string& value) {
size_t start = 0;
while (start < value.size() && std::isspace(static_cast<unsigned char>(value[start]))) {
start++;
}
size_t end = value.size();
while (end > start && std::isspace(static_cast<unsigned char>(value[end - 1]))) {
end--;
}
return value.substr(start, end - start);
}
// why does windows need all of this :sob:
#if defined(_WIN32)
std::string getEnvValue(const char* name) {
const char* value = std::getenv(name);
return value ? std::string(value) : std::string();
}
std::string runCapture(const std::string& command) {
std::array<char, 256> buffer{};
std::string output;
FILE* pipe = _popen(command.c_str(), "r");
if (!pipe) return output;
while (fgets(buffer.data(), static_cast<int>(buffer.size()), pipe) != nullptr) {
output += buffer.data();
}
_pclose(pipe);
return output;
}
std::string findVsDevCmd() {
std::string vsInstall = getEnvValue("VSINSTALLDIR");
if (!vsInstall.empty()) {
fs::path candidate = fs::path(vsInstall) / "Common7" / "Tools" / "VsDevCmd.bat";
if (fs::exists(candidate)) return candidate.string();
}
std::string programFilesX86 = getEnvValue("ProgramFiles(x86)");
if (programFilesX86.empty()) {
programFilesX86 = getEnvValue("ProgramFiles");
}
if (programFilesX86.empty()) return std::string();
fs::path vswhere = fs::path(programFilesX86) / "Microsoft Visual Studio" / "Installer" / "vswhere.exe";
if (!fs::exists(vswhere)) return std::string();
std::ostringstream cmd;
cmd << "\"" << vswhere.string() << "\" -latest -products * -requires Microsoft.Component.MSBuild "
<< "-property installationPath";
std::string installPath = trimCopy(runCapture(cmd.str()));
if (installPath.empty()) return std::string();
fs::path devCmd = fs::path(installPath) / "Common7" / "Tools" / "VsDevCmd.bat";
if (fs::exists(devCmd)) return devCmd.string();
return std::string();
}
// well, that's one way to make VS Harder to implement, For God's Sake, MICROSOFT!!!!
std::string findVsTool(const char* toolName) {
std::string programFilesX86 = getEnvValue("ProgramFiles(x86)");
if (programFilesX86.empty()) {
programFilesX86 = getEnvValue("ProgramFiles");
}
if (programFilesX86.empty()) return std::string();
fs::path vswhere = fs::path(programFilesX86) / "Microsoft Visual Studio" / "Installer" / "vswhere.exe";
if (fs::exists(vswhere)) {
std::ostringstream cmd;
cmd << "\"" << vswhere.string() << "\" -latest -products * "
<< "-requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 "
<< "-find \"VC\\Tools\\MSVC\\**\\bin\\Hostx64\\x64\\" << toolName << "\"";
std::string found = trimCopy(runCapture(cmd.str()));
if (!found.empty() && fs::exists(found)) {
return found;
}
}
std::string vsInstall = getEnvValue("VSINSTALLDIR");
if (!vsInstall.empty()) {
fs::path fallback = fs::path(vsInstall) / "VC" / "Tools" / "MSVC";
if (fs::exists(fallback)) {
for (const auto& entry : fs::directory_iterator(fallback)) {
if (!entry.is_directory()) continue;
fs::path candidate = entry.path() / "bin" / "Hostx64" / "x64" / toolName;
if (fs::exists(candidate)) return candidate.string();
}
}
}
return std::string();
}
std::string applyToolOverride(const std::string& command, const char* toolName,
const std::string& toolPath) {
if (toolPath.empty()) return command;
std::string prefix = std::string(toolName) + " ";
if (command.rfind(prefix, 0) != 0) return command;
std::ostringstream replaced;
replaced << "\"" << toolPath << "\" " << command.substr(prefix.size());
return replaced.str();
}
std::string wrapWithVsDevCmdIfNeeded(const std::string& command) {
std::string includeEnv = getEnvValue("INCLUDE");
if (!includeEnv.empty()) return command;
std::string vsDevCmd = findVsDevCmd();
if (vsDevCmd.empty()) return command;
std::ostringstream wrapped;
wrapped << "cmd /c \"\""
<< vsDevCmd
<< "\" -arch=x64 -host_arch=x64 >nul && "
<< command
<< "\"";
return wrapped.str();
}
#endif
}
std::string ScriptCompiler::trim(const std::string& value) {
@@ -384,8 +502,19 @@ bool ScriptCompiler::makeCommands(const ScriptBuildConfig& config, const fs::pat
}
#endif
outCommands.compile = compileCmd.str();
outCommands.link = linkCmd.str();
std::string compileStr = compileCmd.str();
std::string linkStr = linkCmd.str();
#ifdef _WIN32
const std::string clPath = findVsTool("cl.exe");
const std::string linkPath = findVsTool("link.exe");
compileStr = applyToolOverride(compileStr, "cl", clPath);
linkStr = applyToolOverride(linkStr, "link", linkPath);
compileStr = wrapWithVsDevCmdIfNeeded(compileStr);
linkStr = wrapWithVsDevCmdIfNeeded(linkStr);
#endif
outCommands.compile = compileStr;
outCommands.link = linkStr;
outCommands.objectPath = objectPath;
outCommands.binaryPath = binaryPath;
outCommands.wrapperPath = wrapperPath;