diff --git a/eng/native/build-commons.sh b/eng/native/build-commons.sh index bf2863e15c1d225b99a09b0144706c0999941f2a..0b2caf94c663f2ffc0e1404900dd408921c8a6da 100755 --- a/eng/native/build-commons.sh +++ b/eng/native/build-commons.sh @@ -146,9 +146,7 @@ EOF scan_build=scan-build fi - engNativeDir="$__RepoRootDir/eng/native" - cmakeArgs="-DCLR_ENG_NATIVE_DIR=\"$engNativeDir\" $cmakeArgs" - nextCommand="\"$engNativeDir/gen-buildsys.sh\" \"$cmakeDir\" \"$tryrunDir\" \"$intermediatesDir\" $platformArch $__Compiler \"$__CompilerMajorVersion\" \"$__CompilerMinorVersion\" $__BuildType \"$generator\" $scan_build $cmakeArgs" + nextCommand="\"$__RepoRootDir/eng/native/gen-buildsys.sh\" \"$cmakeDir\" \"$tryrunDir\" \"$intermediatesDir\" $platformArch $__Compiler \"$__CompilerMajorVersion\" \"$__CompilerMinorVersion\" $__BuildType \"$generator\" $scan_build $cmakeArgs" echo "Invoking $nextCommand" eval $nextCommand diff --git a/eng/native/configurepaths.cmake b/eng/native/configurepaths.cmake new file mode 100644 index 0000000000000000000000000000000000000000..e19b95aa04008c3ca9f53ada0a90c193ccb2e805 --- /dev/null +++ b/eng/native/configurepaths.cmake @@ -0,0 +1,7 @@ +get_filename_component(CLR_REPO_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR}/../.. ABSOLUTE) +set(CLR_ENG_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR}) +get_filename_component(CLR_SRC_NATIVE_DIR ${CMAKE_CURRENT_LIST_DIR}/../../src/native ABSOLUTE) + +# TO_NATIVE_PATH so it uses backslashes in Windows to avoid getting error, +# as CLR_SRC_NATIVE_DIR is used to specify source files. +file (TO_NATIVE_PATH ${CLR_SRC_NATIVE_DIR} CLR_SRC_NATIVE_DIR) diff --git a/src/coreclr/CMakeLists.txt b/src/coreclr/CMakeLists.txt index e6495e0250876ca8900d871e3022dc02782d5f7b..ddd5734ce92ed088fbf9f31731d50dee0f3d1843 100644 --- a/src/coreclr/CMakeLists.txt +++ b/src/coreclr/CMakeLists.txt @@ -8,6 +8,7 @@ endif() # Set the project name project(CoreCLR) +include(../../eng/native/configurepaths.cmake) include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake) if(MSVC) diff --git a/src/coreclr/build-runtime.cmd b/src/coreclr/build-runtime.cmd index ca32712554db5d492f3e14c8e8f8d78c8b81b7ad..dd14dceec4f834e99d65abfb73ba079e4a716d0c 100644 --- a/src/coreclr/build-runtime.cmd +++ b/src/coreclr/build-runtime.cmd @@ -450,10 +450,10 @@ if %__BuildCrossArchNative% EQU 1 ( set "__CMakeBinDir=!__CMakeBinDir:\=/!" if %__Ninja% EQU 1 ( - set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" + set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" ) - set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%" %__CMakeArgs% + set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" %__CMakeArgs% call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectDir%" "%__CrossCompIntermediatesDir%" %__VSVersion% %__CrossArch% !__ExtraCmakeArgs! if not !errorlevel! == 0 ( @@ -512,22 +512,22 @@ if %__BuildCrossArchNative% EQU 1 ( if /i "%__CrossArch2%" == "x86" ( set __VCBuildArch=x86 ) if /i "%__CrossArch2%" == "x64" ( set __VCBuildArch=x86_amd64 ) - + echo %__MsgPrefix%Using environment: "%__VCToolsRoot%\vcvarsall.bat" !__VCBuildArch! call "%__VCToolsRoot%\vcvarsall.bat" !__VCBuildArch! @if defined _echo @echo on - + if not exist "%__CrossComp2IntermediatesDir%" md "%__CrossComp2IntermediatesDir%" if defined __SkipConfigure goto SkipConfigureCrossBuild2 set __CMakeBinDir="%__CrossComponent2BinDir%" set "__CMakeBinDir=!__CMakeBinDir:\=/!" - + if %__Ninja% EQU 1 ( - set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" + set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" ) - set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" "-DCMAKE_SYSTEM_VERSION=10.0" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%" %__CMakeArgs% + set __ExtraCmakeArgs=!__ExtraCmakeArgs! %__CMakeClrBuildSubsetArgs% "-DCLR_CROSS_COMPONENTS_BUILD=1" "-DCLR_CMAKE_TARGET_ARCH=%__BuildArch%" "-DCLR_CMAKE_TARGET_OS=%__TargetOS%" "-DCLR_CMAKE_PGO_INSTRUMENT=0" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=0" "-DCMAKE_SYSTEM_VERSION=10.0" %__CMakeArgs% call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectDir%" "%__CrossComp2IntermediatesDir%" %__VSVersion% %__CrossArch2% !__ExtraCmakeArgs! if not !errorlevel! == 0 ( @@ -620,10 +620,10 @@ if %__BuildNative% EQU 1 ( echo %__MsgPrefix%Regenerating the Visual Studio solution if %__Ninja% EQU 1 ( - set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" + set __ExtraCmakeArgs="-DCMAKE_BUILD_TYPE=!__BuildType!" ) - set __ExtraCmakeArgs=!__ExtraCmakeArgs! !___CrossBuildDefine! %__CMakeClrBuildSubsetArgs% "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" "-DCLR_REPO_ROOT_DIR=%__RepoRootDir%" %__CMakeArgs% + set __ExtraCmakeArgs=!__ExtraCmakeArgs! !___CrossBuildDefine! %__CMakeClrBuildSubsetArgs% "-DCLR_CMAKE_PGO_INSTRUMENT=%__PgoInstrument%" "-DCLR_CMAKE_OPTDATA_PATH=%__PgoOptDataPath%" "-DCLR_CMAKE_PGO_OPTIMIZE=%__PgoOptimize%" %__CMakeArgs% call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectDir%" "%__IntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs! if not !errorlevel! == 0 ( echo %__ErrMsgPrefix%%__MsgPrefix%Error: failed to generate native component build project! diff --git a/src/coreclr/build-runtime.sh b/src/coreclr/build-runtime.sh index a2e7313f4f3db2f8a6ca4d3b77ff9966a8414a90..91c0b445c7565080fffe4e0dca18224db5022e2e 100755 --- a/src/coreclr/build-runtime.sh +++ b/src/coreclr/build-runtime.sh @@ -246,7 +246,7 @@ check_prereqs restore_optdata # Build the coreclr (native) components. -__CMakeArgs="-DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument -DCLR_CMAKE_OPTDATA_PATH=$__PgoOptDataPath -DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize -DCLR_REPO_ROOT_DIR=\"$__RepoRootDir\" $__CMakeArgs" +__CMakeArgs="-DCLR_CMAKE_PGO_INSTRUMENT=$__PgoInstrument -DCLR_CMAKE_OPTDATA_PATH=$__PgoOptDataPath -DCLR_CMAKE_PGO_OPTIMIZE=$__PgoOptimize $__CMakeArgs" __CMakeArgs="-DCLR_CMAKE_BUILD_SUBSET_JIT=$__BuildJit -DCLR_CMAKE_BUILD_SUBSET_ALLJITS=$__BuildAllJits -DCLR_CMAKE_BUILD_SUBSET_RUNTIME=$__BuildRuntime $__CMakeArgs" __CMakeArgs="-DCLR_CMAKE_BUILD_TESTS=$__BuildPALTests $__CMakeArgs" diff --git a/src/coreclr/src/hosts/CMakeLists.txt b/src/coreclr/src/hosts/CMakeLists.txt index 6cf6866bdab93b569cb39d1467678dc7fe3cf06a..e7afb6db1de4585bd5d30c50088c70b4b4b5aa7e 100644 --- a/src/coreclr/src/hosts/CMakeLists.txt +++ b/src/coreclr/src/hosts/CMakeLists.txt @@ -5,6 +5,5 @@ if(CLR_CMAKE_HOST_WIN32) add_subdirectory(coreshim) else(CLR_CMAKE_HOST_WIN32) add_definitions(-D_FILE_OFFSET_BITS=64) - add_subdirectory(unixcoreruncommon) add_subdirectory(unixcorerun) endif(CLR_CMAKE_HOST_WIN32) diff --git a/src/coreclr/src/hosts/corerun/CMakeLists.txt b/src/coreclr/src/hosts/corerun/CMakeLists.txt index d8fb5ff6f273cdbcbbcd8221f19b78a107956c86..f149bb9059e65562ad45f91c7520f768f83dfe36 100644 --- a/src/coreclr/src/hosts/corerun/CMakeLists.txt +++ b/src/coreclr/src/hosts/corerun/CMakeLists.txt @@ -1,38 +1,21 @@ project(CoreRun) set(CMAKE_INCLUDE_CURRENT_DIR ON) - -set(CoreRun_SOURCES corerun.cpp logger.cpp) -set(CoreRun_RESOURCES native.rc) - add_definitions(-DFX_VER_INTERNALNAME_STR=CoreRun.exe) -if(CLR_CMAKE_HOST_UNIX) - # This does not compile on Linux yet - if(CAN_BE_COMPILED_ON_LINUX) - _add_executable(CoreRun - ${CoreRun_SOURCES} - ${CoreRun_RESOURCES} - ) - endif(CAN_BE_COMPILED_ON_LINUX) - -else() - _add_executable(CoreRun - ${CoreRun_SOURCES} - ${CoreRun_RESOURCES} - ) - - target_link_libraries(CoreRun - utilcodestaticnohost - advapi32.lib - oleaut32.lib - uuid.lib - user32.lib - ${STATIC_MT_CRT_LIB} - ${STATIC_MT_VCRT_LIB} - ) - - # Can't compile on linux yet so only add for windows - install_clr(TARGETS CoreRun) - -endif(CLR_CMAKE_HOST_UNIX) +_add_executable(CoreRun + corerun.cpp logger.cpp + native.rc +) + +target_link_libraries(CoreRun + utilcodestaticnohost + advapi32.lib + oleaut32.lib + uuid.lib + user32.lib + ${STATIC_MT_CRT_LIB} + ${STATIC_MT_VCRT_LIB} +) + +install_clr(TARGETS CoreRun) diff --git a/src/coreclr/src/hosts/unixcorerun/CMakeLists.txt b/src/coreclr/src/hosts/unixcorerun/CMakeLists.txt index 53d9e526f3d826aaeccf3330a14e7fd0bcacb3bc..9e768f97707d351a14687dbe0260701f22e2f8f7 100644 --- a/src/coreclr/src/hosts/unixcorerun/CMakeLists.txt +++ b/src/coreclr/src/hosts/unixcorerun/CMakeLists.txt @@ -1,33 +1,17 @@ project(unixcorerun) -include_directories(../unixcoreruncommon) +include_directories("${CLR_SRC_NATIVE_DIR}/common") +include(configure.cmake) -set(CORERUN_SOURCES - corerun.cpp -) +set(CMAKE_INCLUDE_CURRENT_DIR ON) -_add_executable(corerun - ${CORERUN_SOURCES} -) +_add_executable(corerun corerun.cpp) -# FreeBSD and NetBSD implement dlopen(3) in libc -if(NOT CLR_CMAKE_TARGET_FREEBSD AND NOT CLR_CMAKE_TARGET_NETBSD) - target_link_libraries(corerun - dl - ) -endif(NOT CLR_CMAKE_TARGET_FREEBSD AND NOT CLR_CMAKE_TARGET_NETBSD) - -# Libc turns locks into no-ops if pthread was not loaded into process yet. Loading -# pthread by the process executable ensures that all locks are initialized properly. -target_link_libraries(corerun - unixcoreruncommon -) +target_link_libraries(corerun ${CMAKE_DL_LIBS}) # Android implements pthread natively if(NOT CLR_CMAKE_TARGET_ANDROID) - target_link_libraries(corerun - pthread - ) + target_link_libraries(corerun pthread) endif() install_clr(TARGETS corerun) diff --git a/src/coreclr/src/hosts/unixcoreruncommon/config.h.in b/src/coreclr/src/hosts/unixcorerun/config.h.in similarity index 100% rename from src/coreclr/src/hosts/unixcoreruncommon/config.h.in rename to src/coreclr/src/hosts/unixcorerun/config.h.in diff --git a/src/coreclr/src/hosts/unixcoreruncommon/configure.cmake b/src/coreclr/src/hosts/unixcorerun/configure.cmake similarity index 100% rename from src/coreclr/src/hosts/unixcoreruncommon/configure.cmake rename to src/coreclr/src/hosts/unixcorerun/configure.cmake diff --git a/src/coreclr/src/hosts/unixcorerun/corerun.cpp b/src/coreclr/src/hosts/unixcorerun/corerun.cpp index c96ec8b059e457e999d6045d31442eda4a8e2457..8e00aeac409fb1ec460038132dbfa84f436b420a 100644 --- a/src/coreclr/src/hosts/unixcorerun/corerun.cpp +++ b/src/coreclr/src/hosts/unixcorerun/corerun.cpp @@ -1,10 +1,432 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -#include +#include +#include +#include +#include +#include +#include +#include #include #include #include +#include "coreclrhost.h" +#include +#ifndef SUCCEEDED +#define SUCCEEDED(Status) ((Status) >= 0) +#endif // !SUCCEEDED + +#include +#include + +#if !HAVE_DIRENT_D_TYPE +#define DT_UNKNOWN 0 +#define DT_DIR 4 +#define DT_REG 8 +#define DT_LNK 10 +#endif + +// Name of the environment variable controlling server GC. +// If set to 1, server GC is enabled on startup. If 0, server GC is +// disabled. Server GC is off by default. +static const char* serverGcVar = "COMPlus_gcServer"; + +// Name of environment variable to control "System.Globalization.Invariant" +// Set to 1 for Globalization Invariant mode to be true. Default is false. +static const char* globalizationInvariantVar = "CORECLR_GLOBAL_INVARIANT"; + +bool GetAbsolutePath(const char* path, std::string& absolutePath) +{ + bool result = false; + + char realPath[PATH_MAX]; + if (realpath(path, realPath) != nullptr && realPath[0] != '\0') + { + absolutePath.assign(realPath); + // realpath should return canonicalized path without the trailing slash + assert(absolutePath.back() != '/'); + + result = true; + } + + return result; +} + +bool GetDirectory(const char* absolutePath, std::string& directory) +{ + directory.assign(absolutePath); + size_t lastSlash = directory.rfind('/'); + if (lastSlash != std::string::npos) + { + directory.erase(lastSlash); + return true; + } + + return false; +} + +bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath) +{ + std::string clrFilesRelativePath; + const char* clrFilesPathLocal = clrFilesPath; + if (clrFilesPathLocal == nullptr) + { + // There was no CLR files path specified, use the folder of the corerun/coreconsole + if (!GetDirectory(currentExePath, clrFilesRelativePath)) + { + perror("Failed to get directory from argv[0]"); + return false; + } + + clrFilesPathLocal = clrFilesRelativePath.c_str(); + + // TODO: consider using an env variable (if defined) as a fall-back. + // The windows version of the corerun uses core_root env variable + } + + if (!GetAbsolutePath(clrFilesPathLocal, clrFilesAbsolutePath)) + { + perror("Failed to convert CLR files path to absolute path"); + return false; + } + + return true; +} + +void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList) +{ + const char * const tpaExtensions[] = { + ".ni.dll", // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir + ".dll", + ".ni.exe", + ".exe", + }; + + DIR* dir = opendir(directory); + if (dir == nullptr) + { + return; + } + + std::set addedAssemblies; + + // Walk the directory for each extension separately so that we first get files with .ni.dll extension, + // then files with .dll extension, etc. + for (size_t extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++) + { + const char* ext = tpaExtensions[extIndex]; + int extLength = strlen(ext); + + struct dirent* entry; + + // For all entries in the directory + while ((entry = readdir(dir)) != nullptr) + { +#if HAVE_DIRENT_D_TYPE + int dirEntryType = entry->d_type; +#else + int dirEntryType = DT_UNKNOWN; +#endif + + // We are interested in files only + switch (dirEntryType) + { + case DT_REG: + break; + + // Handle symlinks and file systems that do not support d_type + case DT_LNK: + case DT_UNKNOWN: + { + std::string fullFilename; + + fullFilename.append(directory); + fullFilename.append("/"); + fullFilename.append(entry->d_name); + + struct stat sb; + if (stat(fullFilename.c_str(), &sb) == -1) + { + continue; + } + + if (!S_ISREG(sb.st_mode)) + { + continue; + } + } + break; + + default: + continue; + } + + std::string filename(entry->d_name); + + // Check if the extension matches the one we are looking for + int extPos = filename.length() - extLength; + if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0)) + { + continue; + } + + std::string filenameWithoutExt(filename.substr(0, extPos)); + + // Make sure if we have an assembly with multiple extensions present, + // we insert only one version of it. + if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end()) + { + addedAssemblies.insert(filenameWithoutExt); + + tpaList.append(directory); + tpaList.append("/"); + tpaList.append(filename); + tpaList.append(":"); + } + } + + // Rewind the directory stream to be able to iterate over it for the next extension + rewinddir(dir); + } + + closedir(dir); +} + +const char* GetEnvValueBoolean(const char* envVariable) +{ + const char* envValue = std::getenv(envVariable); + if (envValue == nullptr) + { + envValue = "0"; + } + // CoreCLR expects strings "true" and "false" instead of "1" and "0". + return (std::strcmp(envValue, "1") == 0 || strcasecmp(envValue, "true") == 0) ? "true" : "false"; +} + +static void *TryLoadHostPolicy(const char *hostPolicyPath) +{ +#if defined(__APPLE__) + static const char LibrarySuffix[] = ".dylib"; +#else // Various Linux-related OS-es + static const char LibrarySuffix[] = ".so"; +#endif + + std::string hostPolicyCompletePath(hostPolicyPath); + hostPolicyCompletePath.append(LibrarySuffix); + + void *libraryPtr = dlopen(hostPolicyCompletePath.c_str(), RTLD_LAZY); + if (libraryPtr == nullptr) + { + fprintf(stderr, "Failed to load mock hostpolicy at path '%s'. Error: %s", hostPolicyCompletePath.c_str(), dlerror()); + } + + return libraryPtr; +} + +int ExecuteManagedAssembly( + const char* currentExeAbsolutePath, + const char* clrFilesAbsolutePath, + const char* managedAssemblyAbsolutePath, + int managedAssemblyArgc, + const char** managedAssemblyArgv) +{ + // Indicates failure + int exitCode = -1; + +#ifdef HOST_ARM + // libunwind library is used to unwind stack frame, but libunwind for ARM + // does not support ARM vfpv3/NEON registers in DWARF format correctly. + // Therefore let's disable stack unwinding using DWARF information + // See https://github.com/dotnet/runtime/issues/6479 + // + // libunwind use following methods to unwind stack frame. + // UNW_ARM_METHOD_ALL 0xFF + // UNW_ARM_METHOD_DWARF 0x01 + // UNW_ARM_METHOD_FRAME 0x02 + // UNW_ARM_METHOD_EXIDX 0x04 + putenv(const_cast("UNW_ARM_UNWIND_METHOD=6")); +#endif // HOST_ARM + +#if defined(__APPLE__) + static const char* const coreClrDll = "libcoreclr.dylib"; +#else + static const char* const coreClrDll = "libcoreclr.so"; +#endif + + std::string coreClrDllPath(clrFilesAbsolutePath); + coreClrDllPath.append("/"); + coreClrDllPath.append(coreClrDll); + + if (coreClrDllPath.length() >= PATH_MAX) + { + fprintf(stderr, "Absolute path to libcoreclr.so too long\n"); + return -1; + } + + // Get just the path component of the managed assembly path + std::string appPath; + GetDirectory(managedAssemblyAbsolutePath, appPath); + + std::string tpaList; + // Construct native search directory paths + std::string nativeDllSearchDirs(appPath); + char *coreLibraries = getenv("CORE_LIBRARIES"); + if (coreLibraries) + { + nativeDllSearchDirs.append(":"); + nativeDllSearchDirs.append(coreLibraries); + if (std::strcmp(coreLibraries, clrFilesAbsolutePath) != 0) + { + AddFilesFromDirectoryToTpaList(coreLibraries, tpaList); + } + } + nativeDllSearchDirs.append(":"); + nativeDllSearchDirs.append(clrFilesAbsolutePath); + + void* hostpolicyLib = nullptr; + char* mockHostpolicyPath = getenv("MOCK_HOSTPOLICY"); + if (mockHostpolicyPath) + { + hostpolicyLib = TryLoadHostPolicy(mockHostpolicyPath); + if (hostpolicyLib == nullptr) + { + return -1; + } + } + + AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList); + + void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL); + if (coreclrLib != nullptr) + { + coreclr_initialize_ptr initializeCoreCLR = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize"); + coreclr_execute_assembly_ptr executeAssembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly"); + coreclr_shutdown_2_ptr shutdownCoreCLR = (coreclr_shutdown_2_ptr)dlsym(coreclrLib, "coreclr_shutdown_2"); + + if (initializeCoreCLR == nullptr) + { + fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n"); + } + else if (executeAssembly == nullptr) + { + fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n"); + } + else if (shutdownCoreCLR == nullptr) + { + fprintf(stderr, "Function coreclr_shutdown_2 not found in the libcoreclr.so\n"); + } + else + { + // Check whether we are enabling server GC (off by default) + const char* useServerGc = GetEnvValueBoolean(serverGcVar); + + // Check Globalization Invariant mode (false by default) + const char* globalizationInvariant = GetEnvValueBoolean(globalizationInvariantVar); + + // Allowed property names: + // APPBASE + // - The base path of the application from which the exe and other assemblies will be loaded + // + // TRUSTED_PLATFORM_ASSEMBLIES + // - The list of complete paths to each of the fully trusted assemblies + // + // APP_PATHS + // - The list of paths which will be probed by the assembly loader + // + // APP_NI_PATHS + // - The list of additional paths that the assembly loader will probe for ngen images + // + // NATIVE_DLL_SEARCH_DIRECTORIES + // - The list of paths that will be probed for native DLLs called by PInvoke + // + const char *propertyKeys[] = { + "TRUSTED_PLATFORM_ASSEMBLIES", + "APP_PATHS", + "APP_NI_PATHS", + "NATIVE_DLL_SEARCH_DIRECTORIES", + "System.GC.Server", + "System.Globalization.Invariant", + }; + const char *propertyValues[] = { + // TRUSTED_PLATFORM_ASSEMBLIES + tpaList.c_str(), + // APP_PATHS + appPath.c_str(), + // APP_NI_PATHS + appPath.c_str(), + // NATIVE_DLL_SEARCH_DIRECTORIES + nativeDllSearchDirs.c_str(), + // System.GC.Server + useServerGc, + // System.Globalization.Invariant + globalizationInvariant, + }; + + void* hostHandle; + unsigned int domainId; + + int st = initializeCoreCLR( + currentExeAbsolutePath, + "unixcorerun", + sizeof(propertyKeys) / sizeof(propertyKeys[0]), + propertyKeys, + propertyValues, + &hostHandle, + &domainId); + + if (!SUCCEEDED(st)) + { + fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st); + exitCode = -1; + } + else + { + st = executeAssembly( + hostHandle, + domainId, + managedAssemblyArgc, + managedAssemblyArgv, + managedAssemblyAbsolutePath, + (unsigned int*)&exitCode); + + if (!SUCCEEDED(st)) + { + fprintf(stderr, "coreclr_execute_assembly failed - status: 0x%08x\n", st); + exitCode = -1; + } + + int latchedExitCode = 0; + st = shutdownCoreCLR(hostHandle, domainId, &latchedExitCode); + if (!SUCCEEDED(st)) + { + fprintf(stderr, "coreclr_shutdown failed - status: 0x%08x\n", st); + exitCode = -1; + } + + if (exitCode != -1) + { + exitCode = latchedExitCode; + } + } + } + } + else + { + const char* error = dlerror(); + fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error); + } + + if (hostpolicyLib) + { + if(dlclose(hostpolicyLib) != 0) + { + fprintf(stderr, "Warning - dlclose of mock hostpolicy failed.\n"); + } + } + + return exitCode; +} // Display the command line options void DisplayUsage() @@ -125,13 +547,16 @@ int main(const int argc, const char* argv[]) } // Make sure we have a full path for argv[0]. - std::string argv0AbsolutePath; - if (!GetEntrypointExecutableAbsolutePath(argv0AbsolutePath)) + char* path = getexepath(); + if (!path) { perror("Could not get full path"); return -1; } + std::string argv0AbsolutePath(path); + free(path); + std::string clrFilesAbsolutePath; if(!GetClrFilesAbsolutePath(argv0AbsolutePath.c_str(), clrFilesPath, clrFilesAbsolutePath)) { diff --git a/src/coreclr/src/hosts/unixcoreruncommon/CMakeLists.txt b/src/coreclr/src/hosts/unixcoreruncommon/CMakeLists.txt deleted file mode 100644 index 7e6930f6eeb666d6e54fa1221d6ad49a466d8982..0000000000000000000000000000000000000000 --- a/src/coreclr/src/hosts/unixcoreruncommon/CMakeLists.txt +++ /dev/null @@ -1,14 +0,0 @@ -project(unixcoreruncommon) - -set(CMAKE_INCLUDE_CURRENT_DIR ON) - -include(configure.cmake) - -_add_library(unixcoreruncommon - STATIC - coreruncommon.cpp -) - -if(CLR_CMAKE_HOST_LINUX) - target_link_libraries(unixcoreruncommon dl) -endif(CLR_CMAKE_HOST_LINUX) diff --git a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp deleted file mode 100644 index 5971175804d922792885bf296017cce1e107f530..0000000000000000000000000000000000000000 --- a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.cpp +++ /dev/null @@ -1,550 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -// -// Code that is used by both the Unix corerun and coreconsole. -// - -#include "config.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__FreeBSD__) -#include -#include -#endif -#if HAVE_GETAUXVAL -#include -#endif -#if defined(HAVE_SYS_SYSCTL_H) || defined(__FreeBSD__) -#include -#endif -#include "coreruncommon.h" -#include "coreclrhost.h" -#include -#ifndef SUCCEEDED -#define SUCCEEDED(Status) ((Status) >= 0) -#endif // !SUCCEEDED - -#if !HAVE_DIRENT_D_TYPE -#define DT_UNKNOWN 0 -#define DT_DIR 4 -#define DT_REG 8 -#define DT_LNK 10 -#endif - -// Name of the environment variable controlling server GC. -// If set to 1, server GC is enabled on startup. If 0, server GC is -// disabled. Server GC is off by default. -static const char* serverGcVar = "COMPlus_gcServer"; - -// Name of environment variable to control "System.Globalization.Invariant" -// Set to 1 for Globalization Invariant mode to be true. Default is false. -static const char* globalizationInvariantVar = "CORECLR_GLOBAL_INVARIANT"; - -#if defined(__linux__) -#define symlinkEntrypointExecutable "/proc/self/exe" -#elif !defined(__APPLE__) -#define symlinkEntrypointExecutable "/proc/curproc/exe" -#endif - -bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable) -{ - bool result = false; - - entrypointExecutable.clear(); - - // Get path to the executable for the current process using - // platform specific means. -#if defined(__APPLE__) - - // On Mac, we ask the OS for the absolute path to the entrypoint executable - uint32_t lenActualPath = 0; - if (_NSGetExecutablePath(nullptr, &lenActualPath) == -1) - { - // OSX has placed the actual path length in lenActualPath, - // so re-attempt the operation - std::string resizedPath(lenActualPath, '\0'); - char *pResizedPath = const_cast(resizedPath.c_str()); - if (_NSGetExecutablePath(pResizedPath, &lenActualPath) == 0) - { - entrypointExecutable.assign(pResizedPath); - result = true; - } - } -#elif defined (__FreeBSD__) - static const int name[] = { - CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 - }; - char path[PATH_MAX]; - size_t len; - - len = sizeof(path); - if (sysctl(name, 4, path, &len, nullptr, 0) == 0) - { - entrypointExecutable.assign(path); - result = true; - } - else - { - // ENOMEM - result = false; - } -#elif defined(__NetBSD__) && defined(KERN_PROC_PATHNAME) - static const int name[] = { - CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME, - }; - char path[MAXPATHLEN]; - size_t len; - - len = sizeof(path); - if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) - { - entrypointExecutable.assign(path); - result = true; - } - else - { - result = false; - } -#elif defined(__sun) - const char *path; - if ((path = getexecname()) == NULL) - { - result = false; - } - else if (*path != '/') - { - char *cwd; - if ((cwd = getcwd(NULL, PATH_MAX)) == NULL) - { - result = false; - } - else - { - entrypointExecutable - .assign(cwd) - .append("/") - .append(path); - result = true; - free(cwd); - } - } - else - { - entrypointExecutable.assign(path); - result = true; - } -#else - -#if HAVE_GETAUXVAL && defined(AT_EXECFN) - const char *execfn = (const char *)getauxval(AT_EXECFN); - - if (execfn) - { - entrypointExecutable.assign(execfn); - result = true; - } - else -#endif - // On other OSs, return the symlink that will be resolved by GetAbsolutePath - // to fetch the entrypoint EXE absolute path, inclusive of filename. - result = GetAbsolutePath(symlinkEntrypointExecutable, entrypointExecutable); -#endif - - return result; -} - -bool GetAbsolutePath(const char* path, std::string& absolutePath) -{ - bool result = false; - - char realPath[PATH_MAX]; - if (realpath(path, realPath) != nullptr && realPath[0] != '\0') - { - absolutePath.assign(realPath); - // realpath should return canonicalized path without the trailing slash - assert(absolutePath.back() != '/'); - - result = true; - } - - return result; -} - -bool GetDirectory(const char* absolutePath, std::string& directory) -{ - directory.assign(absolutePath); - size_t lastSlash = directory.rfind('/'); - if (lastSlash != std::string::npos) - { - directory.erase(lastSlash); - return true; - } - - return false; -} - -bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath) -{ - std::string clrFilesRelativePath; - const char* clrFilesPathLocal = clrFilesPath; - if (clrFilesPathLocal == nullptr) - { - // There was no CLR files path specified, use the folder of the corerun/coreconsole - if (!GetDirectory(currentExePath, clrFilesRelativePath)) - { - perror("Failed to get directory from argv[0]"); - return false; - } - - clrFilesPathLocal = clrFilesRelativePath.c_str(); - - // TODO: consider using an env variable (if defined) as a fall-back. - // The windows version of the corerun uses core_root env variable - } - - if (!GetAbsolutePath(clrFilesPathLocal, clrFilesAbsolutePath)) - { - perror("Failed to convert CLR files path to absolute path"); - return false; - } - - return true; -} - -void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList) -{ - const char * const tpaExtensions[] = { - ".ni.dll", // Probe for .ni.dll first so that it's preferred if ni and il coexist in the same dir - ".dll", - ".ni.exe", - ".exe", - }; - - DIR* dir = opendir(directory); - if (dir == nullptr) - { - return; - } - - std::set addedAssemblies; - - // Walk the directory for each extension separately so that we first get files with .ni.dll extension, - // then files with .dll extension, etc. - for (size_t extIndex = 0; extIndex < sizeof(tpaExtensions) / sizeof(tpaExtensions[0]); extIndex++) - { - const char* ext = tpaExtensions[extIndex]; - int extLength = strlen(ext); - - struct dirent* entry; - - // For all entries in the directory - while ((entry = readdir(dir)) != nullptr) - { -#if HAVE_DIRENT_D_TYPE - int dirEntryType = entry->d_type; -#else - int dirEntryType = DT_UNKNOWN; -#endif - - // We are interested in files only - switch (dirEntryType) - { - case DT_REG: - break; - - // Handle symlinks and file systems that do not support d_type - case DT_LNK: - case DT_UNKNOWN: - { - std::string fullFilename; - - fullFilename.append(directory); - fullFilename.append("/"); - fullFilename.append(entry->d_name); - - struct stat sb; - if (stat(fullFilename.c_str(), &sb) == -1) - { - continue; - } - - if (!S_ISREG(sb.st_mode)) - { - continue; - } - } - break; - - default: - continue; - } - - std::string filename(entry->d_name); - - // Check if the extension matches the one we are looking for - int extPos = filename.length() - extLength; - if ((extPos <= 0) || (filename.compare(extPos, extLength, ext) != 0)) - { - continue; - } - - std::string filenameWithoutExt(filename.substr(0, extPos)); - - // Make sure if we have an assembly with multiple extensions present, - // we insert only one version of it. - if (addedAssemblies.find(filenameWithoutExt) == addedAssemblies.end()) - { - addedAssemblies.insert(filenameWithoutExt); - - tpaList.append(directory); - tpaList.append("/"); - tpaList.append(filename); - tpaList.append(":"); - } - } - - // Rewind the directory stream to be able to iterate over it for the next extension - rewinddir(dir); - } - - closedir(dir); -} - -const char* GetEnvValueBoolean(const char* envVariable) -{ - const char* envValue = std::getenv(envVariable); - if (envValue == nullptr) - { - envValue = "0"; - } - // CoreCLR expects strings "true" and "false" instead of "1" and "0". - return (std::strcmp(envValue, "1") == 0 || strcasecmp(envValue, "true") == 0) ? "true" : "false"; -} - -static void *TryLoadHostPolicy(const char *hostPolicyPath) -{ -#if defined(__APPLE__) - static const char LibrarySuffix[] = ".dylib"; -#else // Various Linux-related OS-es - static const char LibrarySuffix[] = ".so"; -#endif - - std::string hostPolicyCompletePath(hostPolicyPath); - hostPolicyCompletePath.append(LibrarySuffix); - - void *libraryPtr = dlopen(hostPolicyCompletePath.c_str(), RTLD_LAZY); - if (libraryPtr == nullptr) - { - fprintf(stderr, "Failed to load mock hostpolicy at path '%s'. Error: %s", hostPolicyCompletePath.c_str(), dlerror()); - } - - return libraryPtr; -} - -int ExecuteManagedAssembly( - const char* currentExeAbsolutePath, - const char* clrFilesAbsolutePath, - const char* managedAssemblyAbsolutePath, - int managedAssemblyArgc, - const char** managedAssemblyArgv) -{ - // Indicates failure - int exitCode = -1; - -#ifdef HOST_ARM - // libunwind library is used to unwind stack frame, but libunwind for ARM - // does not support ARM vfpv3/NEON registers in DWARF format correctly. - // Therefore let's disable stack unwinding using DWARF information - // See https://github.com/dotnet/runtime/issues/6479 - // - // libunwind use following methods to unwind stack frame. - // UNW_ARM_METHOD_ALL 0xFF - // UNW_ARM_METHOD_DWARF 0x01 - // UNW_ARM_METHOD_FRAME 0x02 - // UNW_ARM_METHOD_EXIDX 0x04 - putenv(const_cast("UNW_ARM_UNWIND_METHOD=6")); -#endif // HOST_ARM - - std::string coreClrDllPath(clrFilesAbsolutePath); - coreClrDllPath.append("/"); - coreClrDllPath.append(coreClrDll); - - if (coreClrDllPath.length() >= PATH_MAX) - { - fprintf(stderr, "Absolute path to libcoreclr.so too long\n"); - return -1; - } - - // Get just the path component of the managed assembly path - std::string appPath; - GetDirectory(managedAssemblyAbsolutePath, appPath); - - std::string tpaList; - // Construct native search directory paths - std::string nativeDllSearchDirs(appPath); - char *coreLibraries = getenv("CORE_LIBRARIES"); - if (coreLibraries) - { - nativeDllSearchDirs.append(":"); - nativeDllSearchDirs.append(coreLibraries); - if (std::strcmp(coreLibraries, clrFilesAbsolutePath) != 0) - { - AddFilesFromDirectoryToTpaList(coreLibraries, tpaList); - } - } - nativeDllSearchDirs.append(":"); - nativeDllSearchDirs.append(clrFilesAbsolutePath); - - void* hostpolicyLib = nullptr; - char* mockHostpolicyPath = getenv("MOCK_HOSTPOLICY"); - if (mockHostpolicyPath) - { - hostpolicyLib = TryLoadHostPolicy(mockHostpolicyPath); - if (hostpolicyLib == nullptr) - { - return -1; - } - } - - AddFilesFromDirectoryToTpaList(clrFilesAbsolutePath, tpaList); - - void* coreclrLib = dlopen(coreClrDllPath.c_str(), RTLD_NOW | RTLD_LOCAL); - if (coreclrLib != nullptr) - { - coreclr_initialize_ptr initializeCoreCLR = (coreclr_initialize_ptr)dlsym(coreclrLib, "coreclr_initialize"); - coreclr_execute_assembly_ptr executeAssembly = (coreclr_execute_assembly_ptr)dlsym(coreclrLib, "coreclr_execute_assembly"); - coreclr_shutdown_2_ptr shutdownCoreCLR = (coreclr_shutdown_2_ptr)dlsym(coreclrLib, "coreclr_shutdown_2"); - - if (initializeCoreCLR == nullptr) - { - fprintf(stderr, "Function coreclr_initialize not found in the libcoreclr.so\n"); - } - else if (executeAssembly == nullptr) - { - fprintf(stderr, "Function coreclr_execute_assembly not found in the libcoreclr.so\n"); - } - else if (shutdownCoreCLR == nullptr) - { - fprintf(stderr, "Function coreclr_shutdown_2 not found in the libcoreclr.so\n"); - } - else - { - // Check whether we are enabling server GC (off by default) - const char* useServerGc = GetEnvValueBoolean(serverGcVar); - - // Check Globalization Invariant mode (false by default) - const char* globalizationInvariant = GetEnvValueBoolean(globalizationInvariantVar); - - // Allowed property names: - // APPBASE - // - The base path of the application from which the exe and other assemblies will be loaded - // - // TRUSTED_PLATFORM_ASSEMBLIES - // - The list of complete paths to each of the fully trusted assemblies - // - // APP_PATHS - // - The list of paths which will be probed by the assembly loader - // - // APP_NI_PATHS - // - The list of additional paths that the assembly loader will probe for ngen images - // - // NATIVE_DLL_SEARCH_DIRECTORIES - // - The list of paths that will be probed for native DLLs called by PInvoke - // - const char *propertyKeys[] = { - "TRUSTED_PLATFORM_ASSEMBLIES", - "APP_PATHS", - "APP_NI_PATHS", - "NATIVE_DLL_SEARCH_DIRECTORIES", - "System.GC.Server", - "System.Globalization.Invariant", - }; - const char *propertyValues[] = { - // TRUSTED_PLATFORM_ASSEMBLIES - tpaList.c_str(), - // APP_PATHS - appPath.c_str(), - // APP_NI_PATHS - appPath.c_str(), - // NATIVE_DLL_SEARCH_DIRECTORIES - nativeDllSearchDirs.c_str(), - // System.GC.Server - useServerGc, - // System.Globalization.Invariant - globalizationInvariant, - }; - - void* hostHandle; - unsigned int domainId; - - int st = initializeCoreCLR( - currentExeAbsolutePath, - "unixcorerun", - sizeof(propertyKeys) / sizeof(propertyKeys[0]), - propertyKeys, - propertyValues, - &hostHandle, - &domainId); - - if (!SUCCEEDED(st)) - { - fprintf(stderr, "coreclr_initialize failed - status: 0x%08x\n", st); - exitCode = -1; - } - else - { - st = executeAssembly( - hostHandle, - domainId, - managedAssemblyArgc, - managedAssemblyArgv, - managedAssemblyAbsolutePath, - (unsigned int*)&exitCode); - - if (!SUCCEEDED(st)) - { - fprintf(stderr, "coreclr_execute_assembly failed - status: 0x%08x\n", st); - exitCode = -1; - } - - int latchedExitCode = 0; - st = shutdownCoreCLR(hostHandle, domainId, &latchedExitCode); - if (!SUCCEEDED(st)) - { - fprintf(stderr, "coreclr_shutdown failed - status: 0x%08x\n", st); - exitCode = -1; - } - - if (exitCode != -1) - { - exitCode = latchedExitCode; - } - } - } - } - else - { - const char* error = dlerror(); - fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error); - } - - if (hostpolicyLib) - { - if(dlclose(hostpolicyLib) != 0) - { - fprintf(stderr, "Warning - dlclose of mock hostpolicy failed.\n"); - } - } - - return exitCode; -} diff --git a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.h b/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.h deleted file mode 100644 index b6bc17bd4631467f974c976da4f63d57bbc3052c..0000000000000000000000000000000000000000 --- a/src/coreclr/src/hosts/unixcoreruncommon/coreruncommon.h +++ /dev/null @@ -1,55 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -#include - -// Get the path to entrypoint executable -bool GetEntrypointExecutableAbsolutePath(std::string& entrypointExecutable); - -// Get absolute path from the specified path. -// Return true in case of a success, false otherwise. -bool GetAbsolutePath(const char* path, std::string& absolutePath); - -// Get directory of the specified path. -// Return true in case of a success, false otherwise. -bool GetDirectory(const char* absolutePath, std::string& directory); - -// -// Get the absolute path to use to locate libcoreclr.so and the CLR assemblies are stored. If clrFilesPath is provided, -// this function will return the absolute path to it. Otherwise, the directory of the current executable is used. -// -// Return true in case of a success, false otherwise. -// -bool GetClrFilesAbsolutePath(const char* currentExePath, const char* clrFilesPath, std::string& clrFilesAbsolutePath); - -// Add all *.dll, *.ni.dll, *.exe, and *.ni.exe files from the specified directory to the tpaList string. -void AddFilesFromDirectoryToTpaList(const char* directory, std::string& tpaList); - -// -// Execute the specified managed assembly. -// -// Parameters: -// currentExePath - Path to the current executable -// clrFilesAbsolutePath - Absolute path to the folder where the libcoreclr.so and CLR managed assemblies are stored -// managedAssemblyPath - Path to the managed assembly to execute -// managedAssemblyArgc - Number of arguments passed to the executed assembly -// managedAssemblyArgv - Array of arguments passed to the executed assembly -// -// Returns: -// ExitCode of the assembly -// -int ExecuteManagedAssembly( - const char* currentExeAbsolutePath, - const char* clrFilesAbsolutePath, - const char* managedAssemblyAbsolutePath, - int managedAssemblyArgc, - const char** managedAssemblyArgv); - - -#if defined(__APPLE__) -#include -static const char * const coreClrDll = "libcoreclr.dylib"; -#else -static const char * const coreClrDll = "libcoreclr.so"; -#endif - diff --git a/src/coreclr/src/pal/src/CMakeLists.txt b/src/coreclr/src/pal/src/CMakeLists.txt index a47da800441235866b59a5aa9bdb3cba4a706328..890d440dc7b1d7f0bb7009fb35b3c64149e749e5 100644 --- a/src/coreclr/src/pal/src/CMakeLists.txt +++ b/src/coreclr/src/pal/src/CMakeLists.txt @@ -117,6 +117,8 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU") add_compile_options(-Wa,--divide) endif() +include_directories("${CLR_SRC_NATIVE_DIR}/common") + set(SOURCES cruntime/file.cpp cruntime/filecrt.cpp diff --git a/src/coreclr/src/pal/src/config.h.in b/src/coreclr/src/pal/src/config.h.in index 728c49d350ba185169aafa52add9d94520479ab9..7b097c99ced43a968e97cfd6dd52ead0b161c84f 100644 --- a/src/coreclr/src/pal/src/config.h.in +++ b/src/coreclr/src/pal/src/config.h.in @@ -1,5 +1,5 @@ -#ifndef _PAL_CONFIG_H_INCLUDED -#define _PAL_CONFIG_H_INCLUDED 1 +#ifndef PAL_CONFIG_H_INCLUDED +#define PAL_CONFIG_H_INCLUDED #cmakedefine01 HAVE_VM_FLAGS_SUPERPAGE_SIZE_ANY #cmakedefine01 HAVE_MAP_HUGETLB @@ -170,4 +170,5 @@ #define SIGWAIT_FAILS_WHEN_PASSED_FULL_SIGSET 0 #define WRITE_0_BYTES_HANGS_TTY 0 #define HAVE_FTRUNCATE_LARGE_LENGTH_SUPPORT 1 -#endif + +#endif // PAL_CONFIG_H_INCLUDED diff --git a/src/coreclr/src/pal/src/init/pal.cpp b/src/coreclr/src/pal/src/init/pal.cpp index 708d369f1dd1210210c2984fc896818cdcee3932..fee6957306635e7b4732da4d233dee7b19f30464 100644 --- a/src/coreclr/src/pal/src/init/pal.cpp +++ b/src/coreclr/src/pal/src/init/pal.cpp @@ -3,8 +3,6 @@ /*++ - - Module Name: init/pal.cpp @@ -13,8 +11,6 @@ Abstract: Implementation of PAL exported functions not part of the Win32 API. - - --*/ #include "pal/dbgmsg.h" @@ -43,6 +39,7 @@ SET_DEFAULT_DEBUG_CHANNEL(PAL); // some headers have code with asserts, so do th #include "pal/numa.h" #include "pal/stackstring.hpp" #include "pal/cgroup.h" +#include #if HAVE_MACH_EXCEPTIONS #include "../exception/machexception.h" @@ -91,15 +88,6 @@ int CacheLineSize; #endif #endif -#if defined(__FreeBSD__) -#include -#include -#include -#endif -#if HAVE_GETAUXVAL -#include -#endif - #include using namespace CorUnix; @@ -378,7 +366,7 @@ Initialize( gPID = getpid(); gSID = getsid(gPID); - // Initialize the thread local storage + // Initialize the thread local storage if (FALSE == TLSInitialize()) { palError = ERROR_PALINIT_TLS; @@ -1266,139 +1254,6 @@ static LPWSTR INIT_FormatCommandLine (int argc, const char * const *argv) return retval; } -#if defined(__linux__) -#define symlinkEntrypointExecutable "/proc/self/exe" -#elif !defined(__APPLE__) -#define symlinkEntrypointExecutable "/proc/curproc/exe" -#endif - -bool GetAbsolutePath(const char* path, PathCharString& absolutePath) -{ - bool result = false; - - char realPath[PATH_MAX]; - if (realpath(path, realPath) != nullptr && realPath[0] != '\0') - { - absolutePath.Set(realPath, strlen(realPath)); - // realpath should return canonicalized path without the trailing slash - _ASSERTE(absolutePath[absolutePath.GetCount() - 1] != '/'); - - result = true; - } - - return result; -} - -bool GetEntrypointExecutableAbsolutePath(PathCharString& entrypointExecutable) -{ - bool result = false; - - entrypointExecutable.Clear(); - - // Get path to the executable for the current process using - // platform specific means. -#if defined(__APPLE__) - - // On Mac, we ask the OS for the absolute path to the entrypoint executable - uint32_t lenActualPath = 0; - if (_NSGetExecutablePath(nullptr, &lenActualPath) == -1) - { - // OSX has placed the actual path length in lenActualPath, - // so re-attempt the operation - PathCharString resizedPath; - char *pResizedPath = resizedPath.OpenStringBuffer(lenActualPath); - if (_NSGetExecutablePath(pResizedPath, &lenActualPath) == 0) - { - resizedPath.CloseBuffer(lenActualPath - 1); - entrypointExecutable.Set(resizedPath); - result = true; - } - } -#elif defined (__FreeBSD__) - static const int name[] = - { - CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 - }; - char path[PATH_MAX]; - size_t len; - - len = sizeof(path); - if (sysctl(name, 4, path, &len, nullptr, 0) == 0) - { - entrypointExecutable.Set(path, len); - result = true; - } - else - { - // ENOMEM - result = false; - } -#elif defined(__NetBSD__) && defined(KERN_PROC_PATHNAME) - static const int name[] = - { - CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME, - }; - char path[MAXPATHLEN]; - size_t len; - - len = sizeof(path); - if (sysctl(name, __arraycount(name), path, &len, NULL, 0) != -1) - { - entrypointExecutable.Set(path, len); - result = true; - } - else - { - result = false; - } -#elif defined(__sun) - const char *path; - if ((path = getexecname()) == NULL) - { - result = false; - } - else if (*path != '/') - { - char *cwd; - if ((cwd = getcwd(NULL, PATH_MAX)) == NULL) - { - result = false; - } - else - { - entrypointExecutable.Set(cwd, strlen(cwd)); - entrypointExecutable.Append('/'); - entrypointExecutable.Append(path, strlen(path)); - - result = true; - free(cwd); - } - } - else - { - entrypointExecutable.Set(path, strlen(path)); - result = true; - } -#else - -#if HAVE_GETAUXVAL && defined(AT_EXECFN) - const char *execfn = (const char *)getauxval(AT_EXECFN); - - if (execfn) - { - entrypointExecutable.Set(execfn, strlen(execfn)); - result = true; - } - else -#endif - // On other OSs, return the symlink that will be resolved by GetAbsolutePath - // to fetch the entrypoint EXE absolute path, inclusive of filename. - result = GetAbsolutePath(symlinkEntrypointExecutable, entrypointExecutable); -#endif - - return result; -} - /*++ Function: INIT_GetCurrentEXEPath @@ -1413,16 +1268,20 @@ Return: --*/ static LPWSTR INIT_GetCurrentEXEPath() { - PathCharString real_path; LPWSTR return_value; INT return_size; - if (!GetEntrypointExecutableAbsolutePath(real_path)) + char* path = getexepath(); + if (!path) { ERROR( "Cannot get current exe path\n" ); return NULL; } + PathCharString real_path; + real_path.Set(path, strlen(path)); + free(path); + return_size = MultiByteToWideChar(CP_ACP, 0, real_path, -1, NULL, 0); if (0 == return_size) { diff --git a/src/installer/corehost/CMakeLists.txt b/src/installer/corehost/CMakeLists.txt index 546f17b5d9f52c772ce8120440e736f2a53b86f2..e8ba7ae21c961aad085a4e9caa39603caa02c0db 100644 --- a/src/installer/corehost/CMakeLists.txt +++ b/src/installer/corehost/CMakeLists.txt @@ -6,6 +6,7 @@ endif() project(corehost) +include(../../../eng/native/configurepaths.cmake) include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake) if(MSVC) diff --git a/src/installer/corehost/build.cmd b/src/installer/corehost/build.cmd index ba6e4e058732f6f96ddf508741f9ebabc6be167d..91adf50e7b3cc2b64f8fbceb8137620c3b6f8683 100644 --- a/src/installer/corehost/build.cmd +++ b/src/installer/corehost/build.cmd @@ -154,9 +154,9 @@ echo "Computed RID for native build is %cm_BaseRid%" set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_HOST_VER=%__HostVersion%" "-DCLI_CMAKE_COMMON_HOST_VER=%__AppHostVersion%" "-DCLI_CMAKE_HOST_FXR_VER=%__HostFxrVersion%" set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_HOST_POLICY_VER=%__HostPolicyVersion%" "-DCLI_CMAKE_PKG_RID=%cm_BaseRid%" "-DCLI_CMAKE_COMMIT_HASH=%__CommitSha%" -set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCORECLR_ARTIFACTS=%__CoreClrArtifacts% " "-DRUNTIME_CONFIG=%__RuntimeConfiguration%" "-DNATIVE_LIBS_ARTIFACTS=%__NativeLibsArtifacts%" +set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCORECLR_ARTIFACTS=%__CoreClrArtifacts% " "-DRUNTIME_CONFIG=%__RuntimeConfiguration%" "-DNATIVE_LIBS_ARTIFACTS=%__NativeLibsArtifacts%" set __ExtraCmakeParams=%__ExtraCmakeParams% "-DRUNTIME_FLAVOR=%__RuntimeFlavor% " -set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_RESOURCE_DIR=%__ResourcesDir%" "-DCLR_ENG_NATIVE_DIR=%__engNativeDir%" "-DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%" +set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCLI_CMAKE_RESOURCE_DIR=%__ResourcesDir%" "-DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE%" :: Regenerate the native build files echo Calling "%__engNativeDir%\gen-buildsys.cmd "%__sourceDir%" "%__IntermediatesDir%" %__VSVersion% %__BuildArch% %__ExtraCmakeParams%" diff --git a/src/installer/corehost/cli/hostmisc/config.h.in b/src/installer/corehost/cli/hostmisc/config.h.in index 3b1dc149f8d24a4a0456e019d6084463ff4f4bec..1c94adc998b0f1687d229cb74ffcc2289c65ff89 100644 --- a/src/installer/corehost/cli/hostmisc/config.h.in +++ b/src/installer/corehost/cli/hostmisc/config.h.in @@ -1,6 +1,7 @@ -#ifndef _PAL_CONFIG_H_INCLUDED -#define _PAL_CONFIG_H_INCLUDED 1 +#ifndef PAL_HOST_MISC_CONFIG_H_INCLUDED +#define PAL_HOST_MISC_CONFIG_H_INCLUDED #cmakedefine01 HAVE_DIRENT_D_TYPE +#cmakedefine01 HAVE_GETAUXVAL -#endif +#endif // PAL_HOST_MISC_CONFIG_H_INCLUDED diff --git a/src/installer/corehost/cli/hostmisc/configure.cmake b/src/installer/corehost/cli/hostmisc/configure.cmake index 1998dc6b26f0274b0c141419c60fbc97d2af7c46..f5828c7204331774cce6187c47eb37f6b4dd62cc 100644 --- a/src/installer/corehost/cli/hostmisc/configure.cmake +++ b/src/installer/corehost/cli/hostmisc/configure.cmake @@ -1,5 +1,7 @@ include(CheckStructHasMember) +include(CheckSymbolExists) check_struct_has_member("struct dirent" d_type dirent.h HAVE_DIRENT_D_TYPE) configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) +check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL) diff --git a/src/installer/corehost/cli/hostmisc/hostmisc.cmake b/src/installer/corehost/cli/hostmisc/hostmisc.cmake index 55670fc9dc3720439a35af8a54d2a4f6b8e1b856..2eb250bded93a8673611b555a9fceee2bf3a7a32 100644 --- a/src/installer/corehost/cli/hostmisc/hostmisc.cmake +++ b/src/installer/corehost/cli/hostmisc/hostmisc.cmake @@ -3,6 +3,7 @@ include(${CMAKE_CURRENT_LIST_DIR}/configure.cmake) include_directories(${CMAKE_CURRENT_BINARY_DIR}) +include_directories("${CLR_SRC_NATIVE_DIR}/common") if(CLR_CMAKE_TARGET_OS_ILLUMOS) add_definitions(-DTARGET_ILLUMOS) diff --git a/src/installer/corehost/cli/hostmisc/pal.unix.cpp b/src/installer/corehost/cli/hostmisc/pal.unix.cpp index 20774cb9e11f9339654d151cbeaccf41eaf34a8f..6883dcd07fc2e4eedcead66458d3a05acff1bba5 100644 --- a/src/installer/corehost/cli/hostmisc/pal.unix.cpp +++ b/src/installer/corehost/cli/hostmisc/pal.unix.cpp @@ -5,6 +5,7 @@ #define _WITH_GETLINE #endif +#include #include "pal.h" #include "utils.h" #include "trace.h" @@ -28,12 +29,6 @@ #include #endif -#if defined(TARGET_LINUX) -#define symlinkEntrypointExecutable "/proc/self/exe" -#elif !defined(TARGET_OSX) -#define symlinkEntrypointExecutable "/proc/curproc/exe" -#endif - #if !HAVE_DIRENT_D_TYPE #define DT_UNKNOWN 0 #define DT_DIR 4 @@ -793,90 +788,18 @@ pal::string_t pal::get_current_os_rid_platform() } #endif -#if defined(TARGET_OSX) -bool pal::get_own_executable_path(pal::string_t* recv) -{ - uint32_t path_length = 0; - if (_NSGetExecutablePath(nullptr, &path_length) == -1) - { - char path_buf[path_length]; - if (_NSGetExecutablePath(path_buf, &path_length) == 0) - { - recv->assign(path_buf); - return true; - } - } - return false; -} -#elif defined(TARGET_FREEBSD) -bool pal::get_own_executable_path(pal::string_t* recv) -{ - int mib[4]; - mib[0] = CTL_KERN; - mib[1] = KERN_PROC; - mib[2] = KERN_PROC_PATHNAME; - mib[3] = -1; - char buf[PATH_MAX]; - size_t cb = sizeof(buf); - int error_code = 0; - error_code = sysctl(mib, 4, buf, &cb, NULL, 0); - if (error_code == 0) - { - recv->assign(buf); - return true; - } - - // ENOMEM - if (error_code == ENOMEM) - { - size_t len = sysctl(mib, 4, NULL, NULL, NULL, 0); - std::unique_ptr buffer (new (std::nothrow) char[len]); - - if (buffer == NULL) - { - return false; - } - - error_code = sysctl(mib, 4, buffer.get(), &len, NULL, 0); - if (error_code == 0) - { - recv->assign(buffer.get()); - return true; - } - } - return false; -} -#elif defined(__sun) bool pal::get_own_executable_path(pal::string_t* recv) { - const char *path; - if ((path = getexecname()) == NULL) + char* path = getexepath(); + if (!path) { return false; } - else if (*path != '/') - { - if (!getcwd(recv)) - { - return false; - } - - recv->append("/").append(path); - return true; - } recv->assign(path); + free(path); return true; } -#else -bool pal::get_own_executable_path(pal::string_t* recv) -{ - // Just return the symlink to the exe from /proc - // We'll call realpath on it later - recv->assign(symlinkEntrypointExecutable); - return true; -} -#endif bool pal::get_own_module_path(string_t* recv) { diff --git a/src/libraries/Native/Unix/CMakeLists.txt b/src/libraries/Native/Unix/CMakeLists.txt index e86ffd8b627ee11f54ceb713c9293a72fef91607..3bc41e406561acc21b5f4c34f848f538a0086ea3 100644 --- a/src/libraries/Native/Unix/CMakeLists.txt +++ b/src/libraries/Native/Unix/CMakeLists.txt @@ -1,18 +1,19 @@ cmake_minimum_required(VERSION 3.6.2) include(CheckCCompilerFlag) -if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) - # CMake 3.14.5 contains bug fixes for iOS - cmake_minimum_required(VERSION 3.14.5) - endif() +if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) + # CMake 3.14.5 contains bug fixes for iOS + cmake_minimum_required(VERSION 3.14.5) + endif() cmake_policy(SET CMP0042 NEW) project(CoreFX C) +include(../../../../eng/native/configurepaths.cmake) include(${CLR_ENG_NATIVE_DIR}/configuretools.cmake) set(CMAKE_MACOSX_RPATH ON) -if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) +if(CLR_CMAKE_TARGET_IOS OR CLR_CMAKE_TARGET_TVOS) set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR ON) set(CMAKE_INSTALL_NAME_DIR "@rpath") endif() diff --git a/src/libraries/Native/Unix/Common/pal_config.h.in b/src/libraries/Native/Unix/Common/pal_config.h.in index 792e695a68584165a3285de994bfbf84dabc957a..0439c8922b3ccb1fe1b722df543526afeccf413a 100644 --- a/src/libraries/Native/Unix/Common/pal_config.h.in +++ b/src/libraries/Native/Unix/Common/pal_config.h.in @@ -94,6 +94,7 @@ #cmakedefine01 HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X #cmakedefine01 HAVE_HEIMDAL_HEADERS #cmakedefine01 HAVE_NSGETENVIRON +#cmakedefine01 HAVE_GETAUXVAL #cmakedefine01 HAVE_CRT_EXTERNS_H #cmakedefine01 HAVE_GETDOMAINNAME #cmakedefine01 HAVE_UNAME diff --git a/src/libraries/Native/Unix/System.Native/CMakeLists.txt b/src/libraries/Native/Unix/System.Native/CMakeLists.txt index c7a34a8ba4ed9a9d0e462942a9f6c995a14bbfe0..517628d8fc3321696b234000370d76e546acfd45 100644 --- a/src/libraries/Native/Unix/System.Native/CMakeLists.txt +++ b/src/libraries/Native/Unix/System.Native/CMakeLists.txt @@ -4,6 +4,8 @@ if (NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS) add_definitions(-DHAS_CONSOLE_SIGNALS) endif () +include_directories("${CLR_SRC_NATIVE_DIR}/common") + set(NATIVE_SOURCES pal_errno.c pal_interfaceaddresses.c diff --git a/src/libraries/Native/Unix/System.Native/pal_process.c b/src/libraries/Native/Unix/System.Native/pal_process.c index fce3c5fcd07ac873345aebdd7332720eafb45311..94c74e00c3b822db05d2ff4d8ebea327f871f298 100644 --- a/src/libraries/Native/Unix/System.Native/pal_process.c +++ b/src/libraries/Native/Unix/System.Native/pal_process.c @@ -38,6 +38,8 @@ #include #endif +#include + // Validate that our SysLogPriority values are correct for the platform c_static_assert(PAL_LOG_EMERG == LOG_EMERG); c_static_assert(PAL_LOG_ALERT == LOG_ALERT); @@ -868,56 +870,7 @@ int32_t SystemNative_SchedGetAffinity(int32_t pid, intptr_t* mask) } #endif -// Returns the full path to the executable for the current process, resolving symbolic links. -// The caller is responsible for releasing the buffer. Returns null on error. char* SystemNative_GetProcessPath() { -#if defined(__APPLE__) - uint32_t path_length = 0; - if (_NSGetExecutablePath(NULL, &path_length) != -1) - { - errno = EINVAL; - return NULL; - } - - char path_buf[path_length]; - if (_NSGetExecutablePath(path_buf, &path_length) != 0) - { - errno = EINVAL; - return NULL; - } - - return realpath(path_buf, NULL); -#elif defined(__FreeBSD__) - static const int name[] = - { - CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 - }; - - char path[PATH_MAX]; - size_t len; - - len = sizeof(path); - if (sysctl(name, 4, path, &len, NULL, 0) != 0) - { - return NULL; - } - - return strdup(path); -#elif defined(__sun) - const char* path = getexecname(); - if (path == NULL) - return NULL; - return realpath(path, NULL); -#else - -#ifdef __linux__ - const char* symlinkEntrypointExecutable = "/proc/self/exe"; -#else - const char* symlinkEntrypointExecutable = "/proc/curproc/exe"; -#endif - - // Resolve the symlink to the executable from /proc - return realpath(symlinkEntrypointExecutable, NULL); -#endif + return getexepath(); } diff --git a/src/libraries/Native/Unix/configure.cmake b/src/libraries/Native/Unix/configure.cmake index eef61c4c356df0ba2562e0cdd08c799542b6fc77..a0d547d868e17cb8bc0f49309c32c19d4ca99b7d 100644 --- a/src/libraries/Native/Unix/configure.cmake +++ b/src/libraries/Native/Unix/configure.cmake @@ -938,6 +938,7 @@ else () HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X) endif () +check_symbol_exists(getauxval sys/auxv.h HAVE_GETAUXVAL) check_include_files(crt_externs.h HAVE_CRT_EXTERNS_H) if (HAVE_CRT_EXTERNS_H) diff --git a/src/native/common/getexepath.h b/src/native/common/getexepath.h new file mode 100644 index 0000000000000000000000000000000000000000..e918dadcb8e55e9d63e88457e89e43fbc8c44b8e --- /dev/null +++ b/src/native/common/getexepath.h @@ -0,0 +1,85 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#ifndef GETEXEPATH_H +#define GETEXEPATH_H + +#include +#include +#include + +#if defined(__APPLE__) +#include +#elif defined(__FreeBSD__) +#include +#include +#include +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// Returns the full path to the executable for the current process, resolving symbolic links. +// The caller is responsible for releasing the buffer. Returns null on error. +extern inline char* getexepath(void) +{ +#if defined(__APPLE__) + uint32_t path_length = 0; + if (_NSGetExecutablePath(NULL, &path_length) != -1) + { + errno = EINVAL; + return NULL; + } + + char path_buf[path_length]; + if (_NSGetExecutablePath(path_buf, &path_length) != 0) + { + errno = EINVAL; + return NULL; + } + + return realpath(path_buf, NULL); +#elif defined(__FreeBSD__) + static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 }; + char path[PATH_MAX]; + size_t len = sizeof(path); + if (sysctl(name, 4, path, &len, NULL, 0) != 0) + { + return NULL; + } + + return strdup(path); +#elif defined(__sun) + const char* path = getexecname(); + if (path == NULL) + { + return NULL; + } + + return realpath(path, NULL); +#else +#if HAVE_GETAUXVAL && defined(AT_EXECFN) + const char* path = (const char *)getauxval(AT_EXECFN); + if (path) + { + return realpath(path, NULL); + } +#endif // HAVE_GETAUXVAL && defined(AT_EXECFN) +#ifdef __linux__ + const char* symlinkEntrypointExecutable = "/proc/self/exe"; +#else + const char* symlinkEntrypointExecutable = "/proc/curproc/exe"; +#endif + + // Resolve the symlink to the executable from /proc + return realpath(symlinkEntrypointExecutable, NULL); +#endif // defined(__APPLE__) +} + +#ifdef __cplusplus +} +#endif // extern "C" + +#endif // GETEXEPATH_H diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 421f0fd2e51bfe8b6f67be829629a9d2a9f5e596..9eccdfd5aa267258c5c681bc7612e41eceb1a4da 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -6,6 +6,7 @@ if (CMAKE_VERSION VERSION_GREATER 3.15 OR CMAKE_VERSION VERSION_EQUAL 3.15) endif() project(Tests) +include(../../eng/native/configurepaths.cmake) include(${CLR_ENG_NATIVE_DIR}/configurecompiler.cmake) # Add this subdir. We install the headers for the jit. diff --git a/src/tests/build.cmd b/src/tests/build.cmd index 3dca37ac6543b39c78ccbb92250e7dc535f06374..02ba6b5a49c85b13d424528994efe89e6e6b28a0 100644 --- a/src/tests/build.cmd +++ b/src/tests/build.cmd @@ -223,7 +223,7 @@ if not defined VSINSTALLDIR ( ) if not exist "%VSINSTALLDIR%DIA SDK" goto NoDIA -set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0" "-DCLR_ENG_NATIVE_DIR=%__RepoRootDir%/eng/native" +set __ExtraCmakeArgs="-DCMAKE_SYSTEM_VERSION=10.0" call "%__RepoRootDir%\eng\native\gen-buildsys.cmd" "%__ProjectFilesDir%" "%__NativeTestIntermediatesDir%" %__VSVersion% %__BuildArch% !__ExtraCmakeArgs! if not !errorlevel! == 0 (