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:
@@ -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
|
||||
|
||||
@@ -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!
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user