diff --git a/NEWS.md b/NEWS.md index c00a84e525120..f7f73567b6132 100644 --- a/NEWS.md +++ b/NEWS.md @@ -104,6 +104,10 @@ Build system changes * The build system now contains a pure-make caching system for expanding expensive operations at the latest possible moment, while still expanding it only once. ([#35193]) +* The windows executable now uses a launcher `.exe` to transparently set up environment variables necessary + for the "true" Julia executable to find its dependent libraries, as they are no longer located within the + main `bin` directory. ([#35629]) + New library functions --------------------- diff --git a/contrib/windows/exe_path_wrapper.c b/contrib/windows/exe_path_wrapper.c new file mode 100644 index 0000000000000..d6e8c71fc96b5 --- /dev/null +++ b/contrib/windows/exe_path_wrapper.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include +#define ENVVAR_MAXLEN 32760 + +/* PATH_ENTRIES is our simulated RPATH, usually of the form 'TEXT("../path1"), TEXT("../path2"), ...' */ +#ifndef PATH_ENTRIES +#define PATH_ENTRIES TEXT("") +#endif + +LPWSTR pathEntries[] = { + PATH_ENTRIES +}; + +/* JULIA_EXE_PATH is the relative path to julia.exe */ +#ifndef JULIA_EXE_PATH +#define JULIA_EXE_PATH "../libexec/julia.exe" +#endif + +int wmain(int argc, wchar_t *argv[], wchar_t *envp[]) { + // Determine absolute path to true julia.exe sitting in `libexec/` + WCHAR currFileDir[MAX_PATH]; + WCHAR juliaPath[MAX_PATH]; + GetModuleFileName(NULL, currFileDir, MAX_PATH); + PathRemoveFileSpec(currFileDir); + PathCombine(juliaPath, currFileDir, TEXT(JULIA_EXE_PATH)); + + // On windows, we simulate RPATH by pushing onto PATH + LPWSTR pathVal = (LPWSTR) malloc(ENVVAR_MAXLEN*sizeof(WCHAR)); + DWORD dwRet = GetEnvironmentVariable(TEXT("PATH"), pathVal, ENVVAR_MAXLEN); + DWORD numPathEntries = sizeof(pathEntries)/sizeof(pathEntries[0]); + if (dwRet == 0) { + // If we cannot get PATH, then our job is easy! + pathVal[0] = '\0'; + } else { + // Otherwise, we append, if we have enough space to: + DWORD currFileDirLen = wcslen(currFileDir); + DWORD totalPathLen = dwRet + 1 + currFileDirLen; + for (int env_idx=0; env_idx