Skip to content

Commit

Permalink
Statically linking coreclr and clrjit in single file host (#43556)
Browse files Browse the repository at this point in the history
* Statically linking coreclr and clrjit in single file host.

* setting g_hmodCoreCLR on Unix

* System.Globalization.Native.lib must build with coreclr to be linkable with it

* Always use system unwind libs on FREEBSD

* no DllMain when coreclr is statically linked

* Handle cases when coreclr configuration is different from libraries

* Adding and using PAL_GetPalHostModule
  • Loading branch information
VSadov authored Oct 26, 2020
1 parent 801ebec commit 320c1cc
Show file tree
Hide file tree
Showing 24 changed files with 268 additions and 270 deletions.
1 change: 1 addition & 0 deletions src/coreclr/src/dlls/mscoree/coreclr/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ target_sources(coreclr PUBLIC $<TARGET_OBJECTS:cee_wks_core>)
target_link_libraries(coreclr PUBLIC ${CORECLR_LIBRARIES} ${CLRJIT_STATIC} cee_wks)
target_sources(coreclr_static PUBLIC $<TARGET_OBJECTS:cee_wks_core>)
target_link_libraries(coreclr_static PUBLIC ${CORECLR_LIBRARIES} clrjit_static cee_wks_mergeable)
target_compile_definitions(coreclr_static PUBLIC CORECLR_EMBEDDED)

# Create the runtime module index header file containing the coreclr build id
# for xplat and the timestamp/size on Windows.
Expand Down
12 changes: 6 additions & 6 deletions src/coreclr/src/dlls/mscoree/mscoree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,13 @@

#include <dbgenginemetrics.h>

// Globals
extern HINSTANCE g_hThisInst;
#if !defined(CROSSGEN_COMPILE) && !defined(CORECLR_EMBEDDED)

// Locals.
BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
HINSTANCE hInst, // Instance handle of the loaded module.
DWORD dwReason, // Reason for loading.
LPVOID lpReserved); // Unused.
LPVOID lpReserved); // Unused.

#ifndef CROSSGEN_COMPILE
//*****************************************************************************
// Handle lifetime of loaded library.
//*****************************************************************************
Expand All @@ -48,7 +45,10 @@ BOOL WINAPI DllMain(HANDLE hInstance, DWORD dwReason, LPVOID lpReserved)
return EEDllMain((HINSTANCE)hInstance, dwReason, lpReserved);
}

#endif // CROSSGEN_COMPILE
#endif // !defined(CROSSGEN_COMPILE) && !defined(CORECLR_EMBEDDED)

// Globals
extern HINSTANCE g_hThisInst;

HINSTANCE GetModuleInst()
{
Expand Down
5 changes: 5 additions & 0 deletions src/coreclr/src/pal/inc/pal.h
Original file line number Diff line number Diff line change
Expand Up @@ -2490,6 +2490,11 @@ PALAPI
PAL_FreeLibraryDirect(
IN NATIVE_LIBRARY_HANDLE dl_handle);

PALIMPORT
HMODULE
PALAPI
PAL_GetPalHostModule();

PALIMPORT
FARPROC
PALAPI
Expand Down
16 changes: 16 additions & 0 deletions src/coreclr/src/pal/src/loader/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,22 @@ PAL_FreeLibraryDirect(
return retValue;
}

/*++
Function:
PAL_GetPalHostModule
Returns the module that hosts the PAL.
That is typically:
- coreclr.dll when coreclr is dynamically linked
- containing executable in the statically linked case
--*/
HMODULE
PALAPI
PAL_GetPalHostModule()
{
return (HMODULE)LOADGetPalLibrary();
}

/*
Function:
PAL_GetProcAddressDirect
Expand Down
16 changes: 16 additions & 0 deletions src/coreclr/src/vm/ceemain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,18 @@ void EEStartupHelper()
{
g_fEEInit = true;

#if CORECLR_EMBEDDED

#ifdef TARGET_WINDOWS
HINSTANCE curModule = WszGetModuleHandle(NULL);
#else
HINSTANCE curModule = PAL_GetPalHostModule();
#endif

g_hmodCoreCLR = curModule;
g_hThisInst = curModule;
#endif

#ifndef CROSSGEN_COMPILE

// We cache the SystemInfo for anyone to use throughout the life of the EE.
Expand Down Expand Up @@ -1798,6 +1810,8 @@ LONG DllMainFilter(PEXCEPTION_POINTERS p, PVOID pv)
return EXCEPTION_EXECUTE_HANDLER;
}

#if !defined(CORECLR_EMBEDDED)

//*****************************************************************************
// This is the part of the old-style DllMain that initializes the
// stuff that the EE team works on. It's called from the real DllMain
Expand Down Expand Up @@ -1878,6 +1892,8 @@ BOOL STDMETHODCALLTYPE EEDllMain( // TRUE on success, FALSE on error.
return TRUE;
}

#endif // !defined(CORECLR_EMBEDDED)

struct TlsDestructionMonitor
{
~TlsDestructionMonitor()
Expand Down
1 change: 1 addition & 0 deletions src/coreclr/src/vm/threads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,7 @@ void InitThreadManager()

// All patched helpers should fit into one page.
// If you hit this assert on retail build, there is most likely problem with BBT script.
_ASSERTE_ALL_BUILDS("clr/src/VM/threads.cpp", (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart > (ptrdiff_t)0);
_ASSERTE_ALL_BUILDS("clr/src/VM/threads.cpp", (BYTE*)JIT_PatchedCodeLast - (BYTE*)JIT_PatchedCodeStart < (ptrdiff_t)GetOsPageSize());

#ifdef FEATURE_WRITEBARRIER_COPY
Expand Down
2 changes: 1 addition & 1 deletion src/installer/corehost/Windows/gen-buildsys-win.bat
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ popd
:DoGen
set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCMAKE_SYSTEM_VERSION=10.0" "-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=%__LatestCommit%" "-DCLR_CMAKE_HOST_ARCH=%__Arch%"
set __ExtraCmakeParams=%__ExtraCmakeParams% "-DCORECLR_ARTIFACTS=%__CoreClrArtifacts% " "-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% "-DCMAKE_INSTALL_PREFIX=%__CMakeBinDir%" "-DCLI_CMAKE_RESOURCE_DIR=%__ResourcesDir%" "-DCLR_ENG_NATIVE_DIR=%__sourceDir%\..\..\..\eng\native"

Expand Down
1 change: 1 addition & 0 deletions src/installer/corehost/build.cmd
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ if /i [%1] == [rootDir] ( set __rootDir=%2&&shift&&shift&goto Arg_Loop)
if /i [%1] == [coreclrartifacts] (set __CoreClrArtifacts=%2&&shift&&shift&goto Arg_Loop)
if /i [%1] == [nativelibsartifacts] (set __NativeLibsArtifacts=%2&&shift&&shift&goto Arg_Loop)
if /i [%1] == [runtimeflavor] (set __RuntimeFlavor=%2&&shift&&shift&goto Arg_Loop)
if /i [%1] == [runtimeconfiguration] (set __RuntimeConfiguration=%2&&shift&&shift&goto Arg_Loop)


shift
Expand Down
126 changes: 86 additions & 40 deletions src/installer/corehost/cli/apphost/static/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,23 @@ set(SOURCES
../bundle_marker.cpp
./hostfxr_resolver.cpp
./hostpolicy_resolver.cpp
../../hostpolicy/static/coreclr_resolver.cpp
)

set(HEADERS
../bundle_marker.h
../../../hostfxr_resolver.h
)

list(APPEND SOURCES $<TARGET_OBJECTS:libhostfxr_static> $<TARGET_OBJECTS:libhostpolicy_static>)
add_definitions(-D_NO_ASYNCRTIMP)
add_definitions(-D_NO_PPLXIMP)
add_definitions(-DEXPORT_SHARED_API=1)
add_definitions(-DHOSTPOLICY_EMBEDDED)


include(../../fxr/files.cmake)
include(../../hostpolicy/files.cmake)
include(../../hostcommon/files.cmake)

if(CLR_CMAKE_TARGET_WIN32)
list(APPEND SOURCES
Expand All @@ -46,11 +55,50 @@ include(configure.cmake)
add_definitions(-DFEATURE_APPHOST=1)
add_definitions(-DFEATURE_STATIC_HOST=1)

# Disable manifest generation into the file .exe on Windows
if(CLR_CMAKE_TARGET_WIN32)
set_property(TARGET ${PROJECT_NAME} PROPERTY
LINK_FLAGS "/MANIFEST:NO"
# Disable manifest generation into the file .exe on Windows
add_linker_flag("/MANIFEST:NO")

get_property(ALL_COMPILE_OPTIONS TARGET ${PROJECT_NAME} PROPERTY COMPILE_OPTIONS)
string(TOUPPER ${RUNTIME_CONFIG} UPPERCASE_RUNTIME_CONFIG)

# make sure that certain compiler and linker settings match the runtime config
# we need to ensure that to be able to link with coreclr in mixed builds (ex: Debug with Release runtime)
if(UPPERCASE_RUNTIME_CONFIG STREQUAL DEBUG OR UPPERCASE_RUNTIME_CONFIG STREQUAL CHECKED)
# add_compile_options(/MTd)
# per-config options will win, so we have to use this syntax to override
set_property(TARGET ${PROJECT_NAME} PROPERTY
COMPILE_OPTIONS "${ALL_COMPILE_OPTIONS};$<$<CONFIG:DEBUG>:/MTd>"
)

remove_definitions(-DNDEBUG)
add_definitions(-DDEBUG -D_DEBUG -D_DBG)

# ignore runtime libraries that could have been added so far based on the config
add_linker_flag("/NODEFAULTLIB:ucrt.lib")
add_linker_flag("/NODEFAULTLIB:libucrt.lib")
add_linker_flag("/NODEFAULTLIB:libcmt.lib")

# make sure we use statically linked crt
add_linker_flag("/DEFAULTLIB:libucrtd.lib")
else()
# add_compile_options(/MT)
# per-config options will win, so we have to use this syntax to override
set_property(TARGET ${PROJECT_NAME} PROPERTY
COMPILE_OPTIONS "${ALL_COMPILE_OPTIONS};$<$<CONFIG:DEBUG>:/MT>"
)

remove_definitions(-DDEBUG -D_DEBUG -D_DBG)
add_definitions(-DNDEBUG)

# Force uCRT to be dynamically linked for Release build
add_linker_flag("/NODEFAULTLIB:libucrt.lib")
add_linker_flag("/DEFAULTLIB:ucrt.lib")
endif()

# Incremental linking results in the linker inserting extra padding and routing function calls via thunks that can break the
# invariants (e.g. size of region between Jit_PatchedCodeLast-Jit_PatchCodeStart needs to fit in a page).
add_linker_flag("/INCREMENTAL:NO")
endif()

# Specify non-default Windows libs to be used for Arm/Arm64 builds
Expand All @@ -66,10 +114,8 @@ message ("Looking for coreclr_static lib at location: '${CORECLR_STATIC_LIB_LOCA

if(CLR_CMAKE_TARGET_WIN32)
set(CORECLR_LIBRARIES
# Disable superhost on Win32 for now.
# ${CORECLR_STATIC_LIB_LOCATION}/coreclr_static.lib
${STATIC_MT_CRT_LIB}
${STATIC_MT_VCRT_LIB}
${CORECLR_STATIC_LIB_LOCATION}/coreclr_static.lib
${CORECLR_STATIC_LIB_LOCATION}/System.Globalization.Native.lib
kernel32.lib
advapi32.lib
ole32.lib
Expand All @@ -81,46 +127,44 @@ if(CLR_CMAKE_TARGET_WIN32)
bcrypt.lib
RuntimeObject.lib
)
elseif(CLR_CMAKE_TARGET_LINUX)
else()
set(CORECLR_LIBRARIES
${CORECLR_STATIC_LIB_LOCATION}/libcoreclr_static.a
${CORECLR_STATIC_LIB_LOCATION}/libSystem.Globalization.Native.a
${CORECLR_STATIC_LIB_LOCATION}/libcoreclrpal.a
${CORECLR_STATIC_LIB_LOCATION}/libpalrt.a
${CORECLR_STATIC_LIB_LOCATION}/libeventprovider.a
${CORECLR_STATIC_LIB_LOCATION}/libnativeresourcestring.a
)
endif()

# currently linking coreclr into the singlefilehost is only supported on linux
# the following code here would be needed if/when BSD and OSX are supported too
#
# if(CLR_CMAKE_TARGET_OSX)
# find_library(COREFOUNDATION CoreFoundation)
# find_library(CORESERVICES CoreServices)
# find_library(SECURITY Security)
# find_library(SYSTEM System)
#
# LIST(APPEND CORECLR_LIBRARIES
# ${COREFOUNDATION}
# ${CORESERVICES}
# ${SECURITY}
# ${SYSTEM}
# )
# endif(CLR_CMAKE_TARGET_OSX)
#
# if(CLR_CMAKE_TARGET_NETBSD)
# find_library(KVM kvm)
#
# LIST(APPEND CORECLR_LIBRARIES
# ${KVM}
# )
# endif(CLR_CMAKE_TARGET_NETBSD)
endif(CLR_CMAKE_TARGET_WIN32)
if(CLR_CMAKE_TARGET_OSX)
find_library(COREFOUNDATION CoreFoundation)
find_library(CORESERVICES CoreServices)
find_library(SECURITY Security)
find_library(SYSTEM System)

LIST(APPEND CORECLR_LIBRARIES
${COREFOUNDATION}
${CORESERVICES}
${SECURITY}
${SYSTEM}
)
endif(CLR_CMAKE_TARGET_OSX)

if(CLR_CMAKE_TARGET_NETBSD)
find_library(KVM kvm)

LIST(APPEND CORECLR_LIBRARIES
${KVM}
)
endif(CLR_CMAKE_TARGET_NETBSD)

# Path like: artifacts/bin/native/net5.0-Linux-Release-arm/
set(NATIVE_LIBS_LOCATION "${NATIVE_LIBS_ARTIFACTS}")
message ("Looking for native libs at location: '${NATIVE_LIBS_LOCATION}'.")
# On *BSD, we always use the libunwind that's part of the OS
if(CLR_CMAKE_TARGET_FREEBSD)
set(CLR_CMAKE_USE_SYSTEM_LIBUNWIND 1)
endif()

# If/when OSX and *BSD are supported, they should also use the libunwind that's part of the OS
if(CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
find_unwind_libs(UNWIND_LIBS)

Expand All @@ -129,14 +173,17 @@ if(CLR_CMAKE_USE_SYSTEM_LIBUNWIND)
)
endif()

# Path like: artifacts/bin/native/net5.0-Linux-Release-arm/
set(NATIVE_LIBS_LOCATION "${NATIVE_LIBS_ARTIFACTS}")
message ("Looking for native libs at location: '${NATIVE_LIBS_LOCATION}'.")

if(NOT CLR_CMAKE_TARGET_LINUX)
set(NATIVE_LIBS
# Native libs linked into singlefilehost is supported only on Linux for now.
# if/when BSD and OSX are supported too, consider the commented code sections below.
)
else()
set(NATIVE_LIBS
${NATIVE_LIBS_LOCATION}/libSystem.Globalization.Native.a
${NATIVE_LIBS_LOCATION}/libSystem.IO.Compression.Native.a
${NATIVE_LIBS_LOCATION}/libSystem.Native.a
${NATIVE_LIBS_LOCATION}/libSystem.Net.Security.Native.a
Expand Down Expand Up @@ -207,7 +254,6 @@ endif(NOT CLR_CMAKE_TARGET_LINUX)
set_property(TARGET singlefilehost PROPERTY ENABLE_EXPORTS 1)

target_link_libraries(singlefilehost
libhostcommon
${CORECLR_LIBRARIES}

${START_WHOLE_ARCHIVE}
Expand Down
8 changes: 0 additions & 8 deletions src/installer/corehost/cli/common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,6 @@

project(${DOTNET_PROJECT_NAME})

if(CLR_CMAKE_HOST_WIN32)
add_compile_options($<$<CONFIG:RelWithDebInfo>:/MT>)
add_compile_options($<$<CONFIG:Release>:/MT>)
add_compile_options($<$<CONFIG:Debug>:/MTd>)
else()
add_compile_options(-fvisibility=hidden)
endif()

include(${CMAKE_CURRENT_LIST_DIR}/setup.cmake)

# Include directories
Expand Down
1 change: 0 additions & 1 deletion src/installer/corehost/cli/fxr/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the MIT license.

add_subdirectory(static)
add_subdirectory(standalone)
37 changes: 37 additions & 0 deletions src/installer/corehost/cli/fxr/files.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Licensed to the .NET Foundation under one or more agreements.
# The .NET Foundation licenses this file to you under the MIT license.

# Include directories
include_directories(${CMAKE_CURRENT_LIST_DIR}/../json)
include_directories(${CMAKE_CURRENT_LIST_DIR}/../fxr)

# CMake does not recommend using globbing since it messes with the freshness checks
list(APPEND SOURCES
${CMAKE_CURRENT_LIST_DIR}/command_line.cpp
${CMAKE_CURRENT_LIST_DIR}/corehost_init.cpp
${CMAKE_CURRENT_LIST_DIR}/hostfxr.cpp
${CMAKE_CURRENT_LIST_DIR}/fx_muxer.cpp
${CMAKE_CURRENT_LIST_DIR}/fx_resolver.cpp
${CMAKE_CURRENT_LIST_DIR}/fx_resolver.messages.cpp
${CMAKE_CURRENT_LIST_DIR}/framework_info.cpp
${CMAKE_CURRENT_LIST_DIR}/host_context.cpp
${CMAKE_CURRENT_LIST_DIR}/sdk_info.cpp
${CMAKE_CURRENT_LIST_DIR}/sdk_resolver.cpp
)

list(APPEND HEADERS
${CMAKE_CURRENT_LIST_DIR}/../corehost_context_contract.h
${CMAKE_CURRENT_LIST_DIR}/../hostpolicy.h
${CMAKE_CURRENT_LIST_DIR}/../fx_definition.h
${CMAKE_CURRENT_LIST_DIR}/../fx_reference.h
${CMAKE_CURRENT_LIST_DIR}/../roll_fwd_on_no_candidate_fx_option.h
${CMAKE_CURRENT_LIST_DIR}/command_line.h
${CMAKE_CURRENT_LIST_DIR}/corehost_init.h
${CMAKE_CURRENT_LIST_DIR}/fx_muxer.h
${CMAKE_CURRENT_LIST_DIR}/fx_resolver.h
${CMAKE_CURRENT_LIST_DIR}/framework_info.h
${CMAKE_CURRENT_LIST_DIR}/host_context.h
${CMAKE_CURRENT_LIST_DIR}/sdk_info.h
${CMAKE_CURRENT_LIST_DIR}/sdk_resolver.h
)

Loading

0 comments on commit 320c1cc

Please sign in to comment.