LoadProject: extend DLL search path to mingw / libcxx bin dir
All checks were successful
CI / build-test-release (push) Successful in 14m49s

Before LoadLibraryA on the project.dll, point Windows's loader at the
directory we already know holds the runtime DLLs the dll depends on
(libstdc++/libgcc/libwinpthread for mingw-host, c++.dll for msvc-host).
Lets a user run crafter-build.exe straight out of the release zip
without having to prepend C:\msys64\ucrt64\bin (or the libc++ bin
dir) to PATH first.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Jorijn van der Graaf 2026-04-30 05:00:25 +02:00
commit 988c1821af

View file

@ -340,6 +340,14 @@ Configuration Crafter::LoadProject(const fs::path& projectFile, std::span<const
} }
} }
// project.dll links libc++ dynamically (-lc++) and the dll typically lives
// under %LIBCXX_DIR%\lib. Add it to the loader's search path so the user
// doesn't have to put it on PATH manually.
if (const char* libcxx = std::getenv("LIBCXX_DIR"); libcxx && *libcxx) {
fs::path libcxxLib = fs::path(libcxx) / "lib";
SetDllDirectoryA(libcxxLib.string().c_str());
}
HMODULE handle = LoadLibraryA(dllPath.string().c_str()); HMODULE handle = LoadLibraryA(dllPath.string().c_str());
if (!handle) { if (!handle) {
throw std::runtime_error(std::format("Failed to load project {}: error {}", dllPath.string(), GetLastError())); throw std::runtime_error(std::format("Failed to load project {}: error {}", dllPath.string(), GetLastError()));
@ -538,6 +546,14 @@ Configuration Crafter::LoadProject(const fs::path& projectFile, std::span<const
} }
} }
// project.dll is a mingw DLL linking libstdc++-6.dll / libgcc_s_seh-1.dll /
// libwinpthread-1.dll dynamically (LoadProject's compile uses -lstdc++exp
// -lpthread, not -static). We already know where they live from
// MingwPrefix(), so add bin/ to the loader's search path here instead of
// requiring the user to prepend it to PATH manually.
fs::path mingwBin = MingwPrefix() / "bin";
SetDllDirectoryA(mingwBin.string().c_str());
HMODULE handle = LoadLibraryA(dllPath.string().c_str()); HMODULE handle = LoadLibraryA(dllPath.string().c_str());
if (!handle) { if (!handle) {
throw std::runtime_error(std::format( throw std::runtime_error(std::format(