Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Xplat static library improvement v3 #2138

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,6 @@ if (CMAKE_CXX_COMPILER_ID STREQUAL AppleClang
add_definitions("-fdiagnostics-color=always")
endif()

if(STATIC_LIBRARY)
add_definitions(-DCHAKRA_STATIC_LIBRARY=1)
endif()

if(CLR_CMAKE_PLATFORM_XPLAT)
add_definitions(-DFEATURE_PAL)
Expand Down
5 changes: 2 additions & 3 deletions bin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
add_subdirectory (ChakraCore)
add_subdirectory (GCStress)
add_subdirectory (ch)
if(NOT STATIC_LIBRARY)
add_subdirectory (ChakraCore)
endif()

117 changes: 106 additions & 11 deletions bin/ChakraCore/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
add_library (ChakraCore SHARED
ChakraCoreCommon.cpp
ChakraCoreDllFunc.cpp
ConfigParserExternals.cpp
TestHooks.cpp
Expand All @@ -13,6 +14,87 @@ target_include_directories (
${CHAKRACORE_SOURCE_DIR}/lib/Jsrt
)


if(BuildJIT)
set(chakra_backend_objects $<TARGET_OBJECTS:Chakra.Backend>)
endif()

add_library (ChakraCoreStatic STATIC
ChakraCoreCommon.cpp
ConfigParserExternals.cpp
TestHooks.cpp
# Do not take this in. We need to control the
# linker order because of global constructors
# and cross dependencies among them
$<TARGET_OBJECTS:Chakra.Pal>
$<TARGET_OBJECTS:Chakra.Common.Core>
$<TARGET_OBJECTS:Chakra.Jsrt.Core>
${chakra_backend_objects}
$<TARGET_OBJECTS:Chakra.Common.Common>
$<TARGET_OBJECTS:Chakra.Common.Codex>
$<TARGET_OBJECTS:Chakra.Common.DataStructures>
$<TARGET_OBJECTS:Chakra.Common.Exceptions>
$<TARGET_OBJECTS:Chakra.Common.Memory>
$<TARGET_OBJECTS:Chakra.Common.Util>
$<TARGET_OBJECTS:Chakra.Runtime.Base>
$<TARGET_OBJECTS:Chakra.Runtime.ByteCode>
$<TARGET_OBJECTS:Chakra.Runtime.Debug>
$<TARGET_OBJECTS:Chakra.Runtime.Language>
$<TARGET_OBJECTS:Chakra.Runtime.Library>
$<TARGET_OBJECTS:Chakra.Runtime.Math>
$<TARGET_OBJECTS:Chakra.Runtime.Types>
$<TARGET_OBJECTS:Chakra.Runtime.PlatformAgnostic>
$<TARGET_OBJECTS:Chakra.Parser>
$<TARGET_OBJECTS:Chakra.Jsrt>
)
unset(chakra_backend_objects CACHE)

target_compile_options(ChakraCoreStatic PRIVATE "-fPIC")

target_compile_definitions(ChakraCoreStatic
PUBLIC
-DCHAKRA_STATIC_LIBRARY=1
)
target_include_directories (
ChakraCoreStatic PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CHAKRACORE_SOURCE_DIR}/lib/Common
${CHAKRACORE_SOURCE_DIR}/lib/Runtime
${CHAKRACORE_SOURCE_DIR}/lib/Runtime/ByteCode
${CHAKRACORE_SOURCE_DIR}/lib/Parser
${CHAKRACORE_SOURCE_DIR}/lib/Jsrt
${CHAKRACORE_SOURCE_DIR}/lib/JITIDL
${CHAKRACORE_SOURCE_DIR}/lib/Backend
)


if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
target_link_libraries(ChakraCoreStatic
pthread
dl
"-framework CoreFoundation"
"-framework Security"
)
endif(CMAKE_SYSTEM_NAME STREQUAL Darwin)

if(CMAKE_SYSTEM_NAME STREQUAL Linux)
if(CC_TARGETS_AMD64)
target_link_libraries(ChakraCoreStatic
unwind-x86_64
)
endif()

target_link_libraries(ChakraCoreStatic
gcc_s
pthread
rt
dl
unwind
unwind-generic
)
endif(CMAKE_SYSTEM_NAME STREQUAL Linux)


#
# Link step for the ChakraCore shared library
#
Expand All @@ -31,36 +113,43 @@ if(CMAKE_SYSTEM_NAME STREQUAL Linux)
-Wl,--no-whole-archive
-Wl,--end-group
)
elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(LINKER_START_GROUP -Wl,-force_load,)
endif()

# common link deps
set(lib_target "${lib_target}"
set(Chakralib_target "${Chakralib_target}"
-Wl,-undefined,error
${LINKER_START_GROUP}
Chakra.Pal
Chakra.Common.Core
Chakra.Jsrt
Chakra.Jsrt.Singular
${LINKER_END_GROUP}
pthread
stdc++
dl
${ICULIB}
)

if(CMAKE_SYSTEM_NAME STREQUAL Linux)
set(lib_target "${lib_target}"
-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libChakraCoreLib.version

if(CMAKE_SYSTEM_NAME STREQUAL Darwin)
set(Chakralib_target "${Chakralib_target}"
"-Wl,-force_load,\"${CHAKRA_JSRT_BINARY_DIR}/libChakra.Jsrt.Singular.a\""
)
endif()

if(CC_TARGETS_X86)
set(lib_target "${lib_target} -m32")
set(Chakralib_target "${Chakralib_target} -m32")
endif()

target_link_libraries (ChakraCore ${lib_target})
#target_link_libraries (ChakraCoreStatic ${Chakralib_target})
add_dependencies(ChakraCoreStatic Chakra.Pal)


if(CMAKE_SYSTEM_NAME STREQUAL Linux)
set(Chakralib_target "${Chakralib_target}"
-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/libChakraCoreLib.version
)
endif()
target_link_libraries (ChakraCore PRIVATE ${Chakralib_target})

unset(lib_target CACHE )
if(NOT CC_XCODE_PROJECT)
set(CC_LIB_EXT "so")
# Post build step to copy the built shared library
Expand All @@ -74,4 +163,10 @@ if(NOT CC_XCODE_PROJECT)
"${CHAKRACORE_BINARY_DIR}/bin/ChakraCore/libChakraCore.${CC_LIB_EXT}"
${CHAKRACORE_BINARY_DIR}/
)
add_custom_command(TARGET ChakraCoreStatic POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${CHAKRACORE_BINARY_DIR}/bin/ChakraCore/libChakraCoreStatic.a"
${CHAKRACORE_BINARY_DIR}/
)

endif()
3 changes: 2 additions & 1 deletion bin/ChakraCore/ChakraCore.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
<PrecompiledHeader>NotUsing</PrecompiledHeader>
</ClCompile>
<ClCompile Include="$(MsBuildThisFileDirectory)ConfigParserExternals.cpp" />
<ClCompile Include="$(MsBuildThisFileDirectory)ChakraCoreCommon.cpp" />
<ClCompile Include="$(MsBuildThisFileDirectory)ChakraCoreDllFunc.cpp" />
<ClCompile Include="$(MsBuildThisFileDirectory)TestHooks.cpp" />
<None Include="..\CoreCommon.ver" />
Expand Down Expand Up @@ -177,4 +178,4 @@
</ItemGroup>
<Import Project="$(BuildConfigPropsPath)Chakra.Build.targets" Condition="exists('$(BuildConfigPropsPath)Chakra.Build.targets')" />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>
</Project>
154 changes: 154 additions & 0 deletions bin/ChakraCore/ChakraCoreCommon.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
#include "JsrtPch.h"
#include "jsrtHelper.h"
#include "Base/ThreadContextTlsEntry.h"
#include "Base/ThreadBoundThreadContextManager.h"
#include "Core/ConfigParser.h"
#include "Core/AtomLockGuids.h"

#ifdef DYNAMIC_PROFILE_STORAGE
#include "Language/DynamicProfileStorage.h"
#endif

#ifdef VTUNE_PROFILING
#include "Base/VTuneChakraProfile.h"
#endif

#ifdef ENABLE_JS_ETW
#include "Base/EtwTrace.h"
#endif

void ChakraBinaryAutoSystemInfoInit(AutoSystemInfo * autoSystemInfo)
{
autoSystemInfo->buildDateHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__DATE__, _countof(__DATE__));
autoSystemInfo->buildTimeHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__TIME__, _countof(__TIME__));
}

// todo: We need an interface for thread/process exit.
// At the moment we do handle thread exit for non main threads on xplat
// However, it could be nice/necessary to provide an interface to make sure
// we cover additional edge cases.

#ifdef _WIN32
#if defined(CHAKRA_STATIC_LIBRARY)
static ATOM lockedDll = 0;
#else
extern ATOM lockedDll = 0;
#endif
#else
#include <pthread.h>
static pthread_key_t s_threadLocalDummy;
#endif

THREAD_LOCAL bool s_threadWasEntered = false;

_NOINLINE void DISPOSE_CHAKRA_CORE_THREAD(void *_)
{
free(_);
ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();
}

_NOINLINE bool InitializeProcess()
{
if(s_threadWasEntered) return true;
#if !defined(_WIN32)
pthread_key_create(&s_threadLocalDummy, DISPOSE_CHAKRA_CORE_THREAD);
#endif

// setup the cleanup
// we do not track the main thread. When it exits do the cleanup below
atexit([]() {
ThreadBoundThreadContextManager::DestroyContextAndEntryForCurrentThread();

JsrtRuntime::Uninitialize();

// thread-bound entrypoint should be able to get cleanup correctly, however tlsentry
// for current thread might be left behind if this thread was initialized.
ThreadContextTLSEntry::CleanupThread();
ThreadContextTLSEntry::CleanupProcess();
});

// Attention: shared library is handled under (see ChakraCore/ChakraCoreDllFunc.cpp)
// todo: consolidate similar parts from shared and static library initialization
#ifndef _WIN32
PAL_InitializeChakraCore(0, NULL);
#endif

HMODULE mod = GetModuleHandleW(NULL);

AutoSystemInfo::SaveModuleFileName(mod);

#if defined(_M_IX86) && !defined(__clang__)
// Enable SSE2 math functions in CRT if SSE2 is available
#pragma prefast(suppress:6031, "We don't require SSE2, but will use it if available")
_set_SSE2_enable(TRUE);
#endif

{
CmdLineArgsParser parser;
ConfigParser::ParseOnModuleLoad(parser, mod);
}

#ifdef ENABLE_JS_ETW
EtwTrace::Register();
#endif
ValueType::Initialize();
ThreadContext::GlobalInitialize();

// Needed to make sure that only ChakraCore is loaded into the process
// This is unnecessary on Linux since there aren't other flavors of
// Chakra binaries that can be loaded into the process
#ifdef _WIN32
char16 *engine = szChakraCoreLock;
if (::FindAtom(szChakraLock) != 0)
{
AssertMsg(FALSE, "Expecting to load chakracore.dll but process already loaded chakra.dll");
Binary_Inconsistency_fatal_error();
}
lockedDll = ::AddAtom(engine);
AssertMsg(lockedDll, "Failed to lock chakracore.dll");
#endif // _WIN32

#ifdef ENABLE_BASIC_TELEMETRY
g_TraceLoggingClient = NoCheckHeapNewStruct(TraceLoggingClient);
#endif


return true;
}

_NOINLINE void VALIDATE_ENTER_CURRENT_THREAD()
{

#if defined(CHAKRA_STATIC_LIBRARY) || !defined(_WIN32)
// We do also initialize the process part here
// This is thread safe by the standard
// Let's hope compiler doesn't fail
static bool _has_init = InitializeProcess();

if (!_has_init) // do not assert this.
{
abort();
}

if (s_threadWasEntered) return;
s_threadWasEntered = true;

#ifdef DYNAMIC_PROFILE_STORAGE
DynamicProfileStorage::Initialize();
#endif

#ifdef HEAP_TRACK_ALLOC
HeapAllocator::InitializeThread();
#endif

#ifndef _WIN32
// put something into key to make sure destructor is going to be called
pthread_setspecific(s_threadLocalDummy, malloc(1));
#endif
#endif
}

9 changes: 3 additions & 6 deletions bin/ChakraCore/ChakraCoreDllFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ extern HANDLE g_hInstance;
#ifdef _WIN32
static ATOM lockedDll = 0;
#endif
extern THREAD_LOCAL bool s_threadWasEntered;

#ifdef _MSC_VER
#define EXPORT_FUNC
Expand Down Expand Up @@ -96,6 +97,8 @@ static BOOL AttachProcess(HANDLE hmod)
g_TraceLoggingClient = NoCheckHeapNewStruct(TraceLoggingClient);
#endif

s_threadWasEntered = true;

#ifdef DYNAMIC_PROFILE_STORAGE
return DynamicProfileStorage::Initialize();
#else
Expand Down Expand Up @@ -199,12 +202,6 @@ EXTERN_C BOOL WINAPI DllMain(HINSTANCE hmod, DWORD dwReason, PVOID pvReserved)
}
}

void ChakraBinaryAutoSystemInfoInit(AutoSystemInfo * autoSystemInfo)
{
autoSystemInfo->buildDateHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__DATE__, _countof(__DATE__));
autoSystemInfo->buildTimeHash = JsUtil::CharacterBuffer<char>::StaticGetHashCode(__TIME__, _countof(__TIME__));
}

#if !ENABLE_NATIVE_CODEGEN
EXPORT_FUNC
HRESULT JsInitializeJITServer(
Expand Down
4 changes: 1 addition & 3 deletions bin/GCStress/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ endif()
set(lib_target "${lib_target}"
-Wl,-undefined,error
${LINKER_START_GROUP}
Chakra.Common.Core
Chakra.Pal
Chakra.Jsrt
Chakra.Jsrt.Singular
${LINKER_END_GROUP}
)

Expand Down
Loading