From 89704795358426a25d6518f5197762bdab19d007 Mon Sep 17 00:00:00 2001 From: Ben Morgan <Ben.Morgan@warwick.ac.uk> Date: Tue, 8 Sep 2020 11:56:13 +0100 Subject: [PATCH] Enable SHARED and STATIC build of single library Rephrase option to BUILD_SINGLE_LIB to reflect ability to build both types of library. Build static object libraries with standard options so they are non-PIC by default. Change single library name to "geant4_{shared,static}" for clarity. Bump minimum required CMake version to 3.12 in order to allow direct linking between OBJECT libraries. From 10.6 Geant4 passes all usage requirements through target properties. This version bump allows a significant simplification to the single library build and reuses all internal/external dependency knowledge already in the Geant4 scripts. Should ATLAS need to support CMake < 3.12, then additional logic would be required in G4SingleLibrary.cmake to track and extract include directories etc from the external library targets used (e.g. CLHEP). Update Geant4Config.cmake template to use single libraries when built. As with modular libraries, the shared/static variants can be chosen to fill Geant4_LIBRARIES using the "static" component. --- CMakeLists.txt | 2 +- cmake/Modules/G4BuildSettings.cmake | 10 +- cmake/Modules/G4DeveloperAPI_OLD.cmake | 76 +++++---- cmake/Modules/G4SingleLibrary.cmake | 96 +++++------ cmake/Templates/Geant4Config.cmake.in | 213 +++++++++++++------------ 5 files changed, 214 insertions(+), 183 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cfdaea695..a4d0b4e301 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ endif() #----------------------------------------------------------------------- # - Define CMake requirements and override make rules as needed # -cmake_minimum_required(VERSION 3.8 FATAL_ERROR) +cmake_minimum_required(VERSION 3.12 FATAL_ERROR) # - Any policy requirements should go here diff --git a/cmake/Modules/G4BuildSettings.cmake b/cmake/Modules/G4BuildSettings.cmake index 7d04e253ac..ddf6cf8a39 100644 --- a/cmake/Modules/G4BuildSettings.cmake +++ b/cmake/Modules/G4BuildSettings.cmake @@ -340,20 +340,16 @@ endif() # both types. If neither is selected, an error is emitted. # option(BUILD_SHARED_LIBS "Build Geant4 shared libraries" ON) -option(BUILD_SHARED_SINGLE_LIB "Build Geant4 into a single dynamic library" OFF) #CM option(BUILD_STATIC_LIBS "Build Geant4 static libraries" OFF) -mark_as_advanced(BUILD_SHARED_LIBS BUILD_SHARED_SINGLE_LIB BUILD_STATIC_LIBS) #CM +option(BUILD_SINGLE_LIB "Build Geant4 into a single library" OFF) +mark_as_advanced(BUILD_SHARED_LIBS BUILD_SINGLE_LIB BUILD_STATIC_LIBS) # Because both could be switched off accidently, FATAL_ERROR if neither # option has been selected. -if(NOT BUILD_STATIC_LIBS AND NOT BUILD_SHARED_LIBS AND NOT BUILD_SHARED_SINGLE_LIB) #CM +if(NOT BUILD_STATIC_LIBS AND NOT BUILD_SHARED_LIBS) message(FATAL_ERROR "Neither static nor shared libraries will be built") endif() -if(BUILD_SHARED_SINGLE_LIB) #CM - set(BUILD_SHARED_LIBS ON) -endif() - # Always build global libraries - always FATAL_ERROR if old # granular library switch is set, e.g. from command line if(GEANT4_BUILD_GRANULAR_LIBS) diff --git a/cmake/Modules/G4DeveloperAPI_OLD.cmake b/cmake/Modules/G4DeveloperAPI_OLD.cmake index 6eb7b205c6..5dc8e7674d 100644 --- a/cmake/Modules/G4DeveloperAPI_OLD.cmake +++ b/cmake/Modules/G4DeveloperAPI_OLD.cmake @@ -230,21 +230,26 @@ macro(geant4_library_target) "NAME" "SOURCES;GEANT4_LINK_LIBRARIES;LINK_LIBRARIES" ${ARGN} ) - if(BUILD_SHARED_SINGLE_LIB AND BUILD_SHARED_LIBS) - set_property(GLOBAL APPEND PROPERTY ALL_LIBS_NAME "${G4LIBTARGET_NAME}") - set_property(GLOBAL APPEND PROPERTY ALL_LIBS_OBJ "$<TARGET_OBJECTS:${G4LIBTARGET_NAME}>") - set_property(GLOBAL APPEND PROPERTY ALL_LIBS_GEANT4_LINK_LIBRARIES "${G4LIBTARGET_GEANT4_LINK_LIBRARIES} ") - set_property(GLOBAL APPEND PROPERTY ALL_LIBS_LINK_LIBRARIES "${G4LIBTARGET_LINK_LIBRARIES} ") - add_library(${G4LIBTARGET_NAME} OBJECT ${G4LIBTARGET_SOURCES}) - #target_compile_definitions(${G4LIBTARGET_NAME} PUBLIC ${G4LIBTARGET_NAME}) + + # Need to store for use later to ensure final linking of single library to externals + if(BUILD_SINGLE_LIB) + set_property(GLOBAL APPEND PROPERTY ALL_LIBS_LINK_LIBRARIES "${G4LIBTARGET_LINK_LIBRARIES}") endif() geant4_format_target(NAME ${G4LIBTARGET_NAME}-format SOURCES ${G4LIBTARGET_SOURCES}) - if(BUILD_SHARED_LIBS AND NOT BUILD_SHARED_SINGLE_LIB) + if(BUILD_SHARED_LIBS) # Add the shared library target and link its dependencies # - Common shared lib commands - add_library(${G4LIBTARGET_NAME} SHARED ${G4LIBTARGET_SOURCES}) + if(NOT BUILD_SINGLE_LIB) + add_library(${G4LIBTARGET_NAME} SHARED ${G4LIBTARGET_SOURCES}) + else() + add_library(${G4LIBTARGET_NAME} OBJECT ${G4LIBTARGET_SOURCES}) + set_property(TARGET ${G4LIBTARGET_NAME} PROPERTY POSITION_INDEPENDENT_CODE ON) + set_property(GLOBAL APPEND PROPERTY ALL_LIBS_NAME "${G4LIBTARGET_NAME}") + set_property(GLOBAL APPEND PROPERTY ALL_LIBS_OBJ "$<TARGET_OBJECTS:${G4LIBTARGET_NAME}>") + endif() + target_compile_definitions(${G4LIBTARGET_NAME} PRIVATE GEANT4_DEVELOPER_$<CONFIG>) target_compile_features(${G4LIBTARGET_NAME} PUBLIC ${GEANT4_TARGET_COMPILE_FEATURES}) target_link_libraries(${G4LIBTARGET_NAME} @@ -277,18 +282,20 @@ macro(geant4_library_target) ) endif() - # Alias the library for transparent internal use in build or link contexts - add_library(Geant4::${G4LIBTARGET_NAME} ALIAS ${G4LIBTARGET_NAME}) - - # Install the library - note the use of RUNTIME, LIBRARY and ARCHIVE - # this helps with later DLL builds. - # Export to standard depends file for later install - install(TARGETS ${G4LIBTARGET_NAME} - EXPORT Geant4LibraryDepends - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) + if(NOT BUILD_SINGLE_LIB) + # Alias the library for transparent internal use in build or link contexts + add_library(Geant4::${G4LIBTARGET_NAME} ALIAS ${G4LIBTARGET_NAME}) + + # Install the library - note the use of RUNTIME, LIBRARY and ARCHIVE + # this helps with later DLL builds. + # Export to standard depends file for later install + install(TARGETS ${G4LIBTARGET_NAME} + EXPORT Geant4LibraryDepends + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) + endif() endif() # @@ -298,7 +305,14 @@ macro(geant4_library_target) # name. Link its dependencies, and ensure we actually link to the # -static targets (We should strictly do this for the external # libraries as well if we want a pure static build). - add_library(${G4LIBTARGET_NAME}-static STATIC ${G4LIBTARGET_SOURCES}) + if(NOT BUILD_SINGLE_LIB) + add_library(${G4LIBTARGET_NAME}-static STATIC ${G4LIBTARGET_SOURCES}) + else() + add_library(${G4LIBTARGET_NAME}-static OBJECT ${G4LIBTARGET_SOURCES}) + set_property(GLOBAL APPEND PROPERTY ALL_LIBS_NAME_STATIC "${G4LIBTARGET_NAME}-static") + set_property(GLOBAL APPEND PROPERTY ALL_LIBS_OBJ_STATIC "$<TARGET_OBJECTS:${G4LIBTARGET_NAME}-static>") + endif() + target_compile_definitions(${G4LIBTARGET_NAME}-static PRIVATE GEANT4_DEVELOPER_$<CONFIG>) target_compile_features(${G4LIBTARGET_NAME}-static PUBLIC ${GEANT4_TARGET_COMPILE_FEATURES}) target_include_directories(${G4LIBTARGET_NAME}-static PUBLIC "$<BUILD_INTERFACE:${${G4LIBTARGET_NAME}_BUILDTREE_INCLUDES}>") @@ -333,15 +347,17 @@ macro(geant4_library_target) set_target_properties(${G4LIBTARGET_NAME}-static PROPERTIES CLEAN_DIRECT_OUTPUT 1) - # Alias the library for transparent internal use in build or link contexts - add_library(Geant4::${G4LIBTARGET_NAME}-static ALIAS ${G4LIBTARGET_NAME}-static) + if(NOT BUILD_SINGLE_LIB) + # Alias the library for transparent internal use in build or link contexts + add_library(Geant4::${G4LIBTARGET_NAME}-static ALIAS ${G4LIBTARGET_NAME}-static) - install(TARGETS ${G4LIBTARGET_NAME}-static - EXPORT Geant4LibraryDepends - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development - INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) + install(TARGETS ${G4LIBTARGET_NAME}-static + EXPORT Geant4LibraryDepends + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) + endif() endif() endmacro() diff --git a/cmake/Modules/G4SingleLibrary.cmake b/cmake/Modules/G4SingleLibrary.cmake index 3dfadf22b2..66e0836646 100644 --- a/cmake/Modules/G4SingleLibrary.cmake +++ b/cmake/Modules/G4SingleLibrary.cmake @@ -5,57 +5,63 @@ else() return() endif() -if (BUILD_SHARED_SINGLE_LIB) +if(BUILD_SINGLE_LIB) + # Filter out internal targets as these are contained in the single library + # We have to relink here because some libraries may rely on transitive linkage + # to pick up external libraries. + get_property(__geant4_all_libs_link_libs GLOBAL PROPERTY ALL_LIBS_LINK_LIBRARIES) + set(__geant4_single_link_list) + foreach(__g4link ${__geant4_all_libs_link_libs}) + if((NOT (__g4link MATCHES "^G4")) AND (NOT TARGET __g4link)) + list(APPEND __geant4_single_link_list "${__g4link}") + endif() + endforeach() - message(STATUS "===========================================================================") - message(STATUS "Starting SingleLibrary section") + if(__geant4_single_link_list) + list(REMOVE_DUPLICATES __geant4_single_link_list) + endif() - get_property(__geant4_all_libs_name GLOBAL PROPERTY ALL_LIBS_NAME) + # Get overall include directory settings + get_property(__geant4_buildtree_include_dirs GLOBAL PROPERTY GEANT4_BUILDTREE_INCLUDE_DIRS) + + if(BUILD_SHARED_LIBS) get_property(__geant4_all_libs_obj GLOBAL PROPERTY ALL_LIBS_OBJ) - get_property(__geant4_all_libs_g4_link_libs GLOBAL PROPERTY ALL_LIBS_GEANT4_LINK_LIBRARIES) - get_property(__geant4_all_libs_link_libs GLOBAL PROPERTY ALL_LIBS_LINK_LIBRARIES) - - - message(STATUS ${__geant4_all_libs_obj}) - add_library(single_dynamic SHARED ${__geant4_all_libs_obj}) - - - geant4_compile_definitions_config(single_dynamic) - target_compile_features(single_dynamic PUBLIC ${GEANT4_TARGET_COMPILE_FEATURES}) -# target_link_libraries(single_dynamic PUBLIC ${__geant4_all_libs_name}) -# target_link_libraries(single_dynamic ${__geant4_all_libs_link_libs}) -# ${__geant4_all_libs_g4_link_libs} -# ${__geant4_all_libs_link_libs}) - message(STATUS "===========================================================================") - message(STATUS ${__geant4_all_libs_link_libs}) - message(STATUS "===========================================================================") - message(STATUS ${__geant4_all_libs_g4_link_libs}) - target_link_libraries(single_dynamic /usr/lib64/libfreetype.so - /data/cmarcon/Libraries/libexpat/install/lib64/libexpat.so - /usr/lib64/libXm.so - /usr/lib64/libSM.so - /usr/lib64/libICE.so - /usr/lib64/libX11.so - /usr/lib64/libXext.so - /usr/lib64/libXt.so - /usr/lib64/libXmu.so - /data/cmarcon/Libraries/libxerces/install/lib/libxerces-c.so - /usr/lib64/libGL.so - /usr/lib64/libGLU.so) - target_compile_definitions(single_dynamic PUBLIC G4LIB_BUILD_DLL) - set_target_properties(single_dynamic PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) - set_target_properties(single_dynamic PROPERTIES CLEAN_DIRECT_OUTPUT 1) - set_target_properties(single_dynamic PROPERTIES MACOSX_RPATH 1) - - install(TARGETS single_dynamic + add_library(geant4_shared SHARED ${__geant4_all_libs_obj}) + target_compile_definitions(geant4_shared PUBLIC G4LIB_BUILD_DLL) + target_compile_features(geant4_shared PUBLIC ${GEANT4_TARGET_COMPILE_FEATURES}) + target_include_directories(geant4_shared PUBLIC $<BUILD_INTERFACE:${__geant4_buildtree_include_dirs}>) + target_link_libraries(geant4_shared PUBLIC ${__geant4_single_link_list}) + set_target_properties(geant4_shared + PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON + CLEAN_DIRECT_OUTPUT 1 + MACOSX_RPATH 1) + + install(TARGETS geant4_shared EXPORT Geant4LibraryDepends RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development) + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) + + set_property(GLOBAL APPEND PROPERTY GEANT4_EXPORTED_TARGETS geant4_shared) + set_property(TARGET geant4_shared PROPERTY POSITION_INDEPENDENT_CODE ON) + endif() + + if(BUILD_STATIC_LIBS) + get_property(__geant4_all_libs_obj GLOBAL PROPERTY ALL_LIBS_OBJ_STATIC) + add_library(geant4_static STATIC ${__geant4_all_libs_obj}) + target_compile_features(geant4_static PUBLIC ${GEANT4_TARGET_COMPILE_FEATURES}) + target_include_directories(geant4_static PUBLIC $<BUILD_INTERFACE:${__geant4_buildtree_include_dirs}>) + target_link_libraries(geant4_static PUBLIC ${__geant4_single_link_list}) + set_target_properties(geant4_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) - set_property(GLOBAL APPEND PROPERTY GEANT4_EXPORTED_TARGETS single_dynamic) - set_property(TARGET single_dynamic PROPERTY POSITION_INDEPENDENT_CODE ON) + install(TARGETS geant4_static + EXPORT Geant4LibraryDepends + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT Runtime + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Runtime + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}) - message(STATUS "End of SingleLibrary section") - message(STATUS "===========================================================================") + set_property(GLOBAL APPEND PROPERTY GEANT4_EXPORTED_TARGETS geant4_static) + endif() endif() diff --git a/cmake/Templates/Geant4Config.cmake.in b/cmake/Templates/Geant4Config.cmake.in index fa9c1598a2..5fc1d4cfc8 100644 --- a/cmake/Templates/Geant4Config.cmake.in +++ b/cmake/Templates/Geant4Config.cmake.in @@ -556,113 +556,126 @@ if(("static" IN_LIST Geant4_FIND_COMPONENTS) AND Geant4_static_FOUND) set(_geant4_lib_use_suffix "-static") endif() -# The list of libraries probably should be autogenerated, but we hard code -# for now. We don't have to divide the list of shared libraries, but we -# do so for consistency with the way we'll need to do it for static. -# - Always on Vis Components -set(_geant4_internal_libraries - Geant4::G4Tree${_geant4_lib_use_suffix} - Geant4::G4FR${_geant4_lib_use_suffix} - Geant4::G4GMocren${_geant4_lib_use_suffix} - Geant4::G4visHepRep${_geant4_lib_use_suffix} - Geant4::G4RayTracer${_geant4_lib_use_suffix} - Geant4::G4VRML${_geant4_lib_use_suffix} - ) - -# - G4OpenGL if it's requested. -if(_geant4_use_opengl_library) - list(APPEND _geant4_internal_libraries - Geant4::G4OpenGL${_geant4_lib_use_suffix} - Geant4::G4gl2ps${_geant4_lib_use_suffix} +# Library list depends on whether we built multi/single lib +set(Geant4_single_library_FOUND @BUILD_SINGLE_LIB@) + +if(NOT Geant4_single_library_FOUND) + # The list of libraries probably should be autogenerated, but we hard code + # for now. We don't have to divide the list of shared libraries, but we + # do so for consistency with the way we'll need to do it for static. + # - Always on Vis Components + set(_geant4_internal_libraries + Geant4::G4Tree${_geant4_lib_use_suffix} + Geant4::G4FR${_geant4_lib_use_suffix} + Geant4::G4GMocren${_geant4_lib_use_suffix} + Geant4::G4visHepRep${_geant4_lib_use_suffix} + Geant4::G4RayTracer${_geant4_lib_use_suffix} + Geant4::G4VRML${_geant4_lib_use_suffix} ) - list(APPEND Geant4_DEFINITIONS -DG4VIS_USE_OPENGL) -endif() -# - G4OpenInventor if it's requested. -if(_geant4_use_inventor_library) - list(APPEND _geant4_internal_libraries - Geant4::G4OpenInventor${_geant4_lib_use_suffix} - ) -endif() + # - G4OpenGL if it's requested. + if(_geant4_use_opengl_library) + list(APPEND _geant4_internal_libraries + Geant4::G4OpenGL${_geant4_lib_use_suffix} + Geant4::G4gl2ps${_geant4_lib_use_suffix} + ) + list(APPEND Geant4_DEFINITIONS -DG4VIS_USE_OPENGL) + endif() -# - G3toG4 if it's requested -if(_geant4_use_g3tog4_library) - set(_geant4_g3tog4_library Geant4::G3toG4${_geant4_lib_use_suffix}) -endif() - -# - link to timemory library if activated -if(_geant4_use_timemory_library) - list(APPEND _geant4_internal_libraries ${timemory_LIBRARIES}) -endif() - -# - Factory registration mechanism in physics_lists requires whole -# archive to be linked when using static libs, so requires wrapping -# with suitable compiler dependent flags -# 2016-05-24: use an alternate means of forcing linking of references for -# static builds. --whole-archive never was implemented for _WIN32 -# (appears not to even be possible) -# In order re-implement whole-archive, switch Geant4_FORCE_WHOLE_ARCHIVE ON -set(_geant4_physicslists_library Geant4::G4physicslists${_geant4_lib_use_suffix}) - -set(Geant4_FORCE_WHOLE_ARCHIVE OFF) -if( Geant4_FORCE_WHOLE_ARCHIVE ) -if(_geant4_lib_use_suffix STREQUAL "-static") - # - Use CMAKE_CXX_COMPILER_ID, which should be reliable enough... - # Though the GNU/Clang/Intel compilers/linkers *should* use identical - # flags,keep their sections separate until behaviour confirmed - # - if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(_geant4_physicslists_library -Wl,--whole-archive Geant4::G4physicslists${_geant4_lib_use_suffix} -Wl,--no-whole-archive) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(_geant4_physicslists_library -Wl,-force_load Geant4::G4physicslists${_geant4_lib_use_suffix}) - elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") - set(_geant4_physicslists_library -Wl,--whole-archive Geant4::G4physicslists${_geant4_lib_use_suffix} -Wl,--no-whole-archive) - else() - # Needs determination of other compiler options. - # NB: MSVC has /OPT:NOREF, but may apply globally... - # reading up on this ... doesn't seem that it applies for subtle reasons - # only real way is to actually reference the static variables - set(_geant4_physicslists_library Geant4::G4physicslists${_geant4_lib_use_suffix}) + # - G4OpenInventor if it's requested. + if(_geant4_use_inventor_library) + list(APPEND _geant4_internal_libraries + Geant4::G4OpenInventor${_geant4_lib_use_suffix} + ) + endif() + + # - G3toG4 if it's requested + if(_geant4_use_g3tog4_library) + set(_geant4_g3tog4_library Geant4::G3toG4${_geant4_lib_use_suffix}) + endif() + + # - link to timemory library if activated + if(_geant4_use_timemory_library) + list(APPEND _geant4_internal_libraries ${timemory_LIBRARIES}) endif() -endif() -endif() -# - 'Kernel' libraries -list(APPEND _geant4_internal_libraries - Geant4::G4vis_management${_geant4_lib_use_suffix} - Geant4::G4modeling${_geant4_lib_use_suffix} - Geant4::G4interfaces${_geant4_lib_use_suffix} - Geant4::G4persistency${_geant4_lib_use_suffix} - ${_geant4_g3tog4_library} - Geant4::G4analysis${_geant4_lib_use_suffix} - Geant4::G4error_propagation${_geant4_lib_use_suffix} - Geant4::G4readout${_geant4_lib_use_suffix} - ${_geant4_physicslists_library} - Geant4::G4run${_geant4_lib_use_suffix} - Geant4::G4event${_geant4_lib_use_suffix} - Geant4::G4tracking${_geant4_lib_use_suffix} - Geant4::G4parmodels${_geant4_lib_use_suffix} - Geant4::G4processes${_geant4_lib_use_suffix} - Geant4::G4digits_hits${_geant4_lib_use_suffix} - Geant4::G4track${_geant4_lib_use_suffix} - Geant4::G4particles${_geant4_lib_use_suffix} - Geant4::G4geometry${_geant4_lib_use_suffix} - Geant4::G4materials${_geant4_lib_use_suffix} - Geant4::G4graphics_reps${_geant4_lib_use_suffix} - Geant4::G4intercoms${_geant4_lib_use_suffix} - Geant4::G4global${_geant4_lib_use_suffix} - ) - -# - Any externals built by Geant4 -foreach(_extlib @GEANT4_EXTERNALS_TARGETS@) - list(APPEND - _geant4_internal_libraries - Geant4::${_extlib}${_geant4_lib_use_suffix} + # - Factory registration mechanism in physics_lists requires whole + # archive to be linked when using static libs, so requires wrapping + # with suitable compiler dependent flags + # 2016-05-24: use an alternate means of forcing linking of references for + # static builds. --whole-archive never was implemented for _WIN32 + # (appears not to even be possible) + # In order re-implement whole-archive, switch Geant4_FORCE_WHOLE_ARCHIVE ON + set(_geant4_physicslists_library Geant4::G4physicslists${_geant4_lib_use_suffix}) + + set(Geant4_FORCE_WHOLE_ARCHIVE OFF) + if( Geant4_FORCE_WHOLE_ARCHIVE ) + if(_geant4_lib_use_suffix STREQUAL "-static") + # - Use CMAKE_CXX_COMPILER_ID, which should be reliable enough... + # Though the GNU/Clang/Intel compilers/linkers *should* use identical + # flags,keep their sections separate until behaviour confirmed + # + if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") + set(_geant4_physicslists_library -Wl,--whole-archive Geant4::G4physicslists${_geant4_lib_use_suffix} -Wl,--no-whole-archive) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(_geant4_physicslists_library -Wl,-force_load Geant4::G4physicslists${_geant4_lib_use_suffix}) + elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") + set(_geant4_physicslists_library -Wl,--whole-archive Geant4::G4physicslists${_geant4_lib_use_suffix} -Wl,--no-whole-archive) + else() + # Needs determination of other compiler options. + # NB: MSVC has /OPT:NOREF, but may apply globally... + # reading up on this ... doesn't seem that it applies for subtle reasons + # only real way is to actually reference the static variables + set(_geant4_physicslists_library Geant4::G4physicslists${_geant4_lib_use_suffix}) + endif() + endif() + endif() + + # - 'Kernel' libraries + list(APPEND _geant4_internal_libraries + Geant4::G4vis_management${_geant4_lib_use_suffix} + Geant4::G4modeling${_geant4_lib_use_suffix} + Geant4::G4interfaces${_geant4_lib_use_suffix} + Geant4::G4persistency${_geant4_lib_use_suffix} + ${_geant4_g3tog4_library} + Geant4::G4analysis${_geant4_lib_use_suffix} + Geant4::G4error_propagation${_geant4_lib_use_suffix} + Geant4::G4readout${_geant4_lib_use_suffix} + ${_geant4_physicslists_library} + Geant4::G4run${_geant4_lib_use_suffix} + Geant4::G4event${_geant4_lib_use_suffix} + Geant4::G4tracking${_geant4_lib_use_suffix} + Geant4::G4parmodels${_geant4_lib_use_suffix} + Geant4::G4processes${_geant4_lib_use_suffix} + Geant4::G4digits_hits${_geant4_lib_use_suffix} + Geant4::G4track${_geant4_lib_use_suffix} + Geant4::G4particles${_geant4_lib_use_suffix} + Geant4::G4geometry${_geant4_lib_use_suffix} + Geant4::G4materials${_geant4_lib_use_suffix} + Geant4::G4graphics_reps${_geant4_lib_use_suffix} + Geant4::G4intercoms${_geant4_lib_use_suffix} + Geant4::G4global${_geant4_lib_use_suffix} ) -endforeach() -# - Now set them to Geant4_LIBRARIES -set(Geant4_LIBRARIES ${_geant4_internal_libraries}) + # - Any externals built by Geant4 + foreach(_extlib @GEANT4_EXTERNALS_TARGETS@) + list(APPEND + _geant4_internal_libraries + Geant4::${_extlib}${_geant4_lib_use_suffix} + ) + endforeach() + + # - Now set them to Geant4_LIBRARIES + set(Geant4_LIBRARIES ${_geant4_internal_libraries}) +else() + # Have a single library, default is dynamic + set(Geant4_LIBRARIES Geant4::geant4_shared) + + # ... unless we requested static + if(_geant4_lib_use_suffix STREQUAL "-static") + set(Geant4_LIBRARIES Geant4::geant4_static) + endif() +endif() #----------------------------------------------------------------------- # Remove any duplicates from the Geant4_{DEFINITIONS,INCLUDE_DIRS,LIBRARIES} -- GitLab