Skip to content

Commit 3371470

Browse files
committed
CMake: Build zigcpp as a shared library when LLVM/Clang are shared libraries
This change intends to avoid the "Static Initialization Order Fiasco" In general static initialization order is not guaranteed by C/C++, but as @kubkon helpfully explained to me today (thanks!), there are some guarantees provided by the linker (either static or dynamic) w.r.t. initialization order that LLVM/Clang may depend upon. These guarantees are apparently preserved when one shared library resolves static symbols in another, but they break down when resolving static symbols in a shared library from the main application. The concern in this case is that the static initializers from the library may be executed after those of the main executable. In order to restore this ordering guarantee, we have to ensure any code that references a static variable of a dynamically-loaded library is not statically linked to the main application. This means that `zigcpp` needs to be compiled as a shared library, and linked dynamically.
1 parent 7acbb91 commit 3371470

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

CMakeLists.txt

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -899,7 +899,12 @@ if(ZIG_TEST_COVERAGE)
899899
set(EXE_LDFLAGS "${EXE_LDFLAGS} -fprofile-arcs -ftest-coverage")
900900
endif()
901901

902-
add_library(zigcpp STATIC ${ZIG_CPP_SOURCES})
902+
if (LLVM_LINK_MODE STREQUAL "shared")
903+
add_library(zigcpp SHARED ${ZIG_CPP_SOURCES})
904+
else()
905+
add_library(zigcpp STATIC ${ZIG_CPP_SOURCES})
906+
endif()
907+
903908
set_target_properties(zigcpp PROPERTIES
904909
COMPILE_FLAGS ${EXE_CFLAGS}
905910
)
@@ -1005,6 +1010,17 @@ else()
10051010
)
10061011
endif()
10071012

1013+
if(LLVM_LINK_MODE STREQUAL "shared")
1014+
if(APPLE)
1015+
set(RPATH_BASE @loader_path)
1016+
else()
1017+
set(RPATH_BASE $ORIGIN)
1018+
endif()
1019+
1020+
set(CMAKE_MACOSX_RPATH 1)
1021+
set(CMAKE_INSTALL_RPATH "${RPATH_BASE}/../lib")
1022+
endif()
1023+
10081024
# cmake won't let us configure an executable without C sources.
10091025
add_executable(zig "${CMAKE_SOURCE_DIR}/src/stage1/empty.cpp" "${ZIG1_OBJECT}")
10101026

@@ -1019,7 +1035,14 @@ elseif(MINGW)
10191035
target_link_libraries(zig ntdll)
10201036
endif()
10211037

1022-
install(TARGETS zig DESTINATION bin)
1038+
if(LLVM_LINK_MODE STREQUAL "shared")
1039+
install(TARGETS zig zigcpp
1040+
RUNTIME DESTINATION bin
1041+
LIBRARY DESTINATION lib)
1042+
else()
1043+
install(TARGETS zig DESTINATION bin)
1044+
endif()
1045+
10231046

10241047
set(ZIG_SKIP_INSTALL_LIB_FILES off CACHE BOOL
10251048
"Disable copying lib/ files to install prefix during the build phase")

0 commit comments

Comments
 (0)