diff --git a/CMakeLists.txt b/CMakeLists.txt index f5cfeba2ca..1a251ab51f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ openpmd_option(ADIOS2 "ADIOS2 backend (.bp files)" AUTO) openpmd_option(PYTHON "Enable Python bindings" AUTO) option(openPMD_INSTALL "Add installation targets" ON) +option(openPMD_INSTALL_RPATH "Add RPATHs to installed binaries" ON) option(openPMD_HAVE_PKGCONFIG "Generate a .pc file for pkg-config" ON) option(openPMD_USE_INTERNAL_VARIANT "Use internally shipped MPark.Variant" ON) option(openPMD_USE_INTERNAL_CATCH "Use internally shipped Catch2" ON) @@ -136,6 +137,18 @@ option(openPMD_BUILD_CLI_TOOLS "Build the command line tools" ${BUILD_CLI_TOOLS} option(openPMD_BUILD_EXAMPLES "Build the examples" ${BUILD_EXAMPLES}) +# Helper Functions ############################################################ +# +# C++ standard: requirements for a target +function(openpmd_cxx_required target) + target_compile_features(${target} PUBLIC cxx_std_14) + set_target_properties(${target} PROPERTIES + CXX_EXTENSIONS OFF + CXX_STANDARD_REQUIRED ON + ) +endfunction() + + # Dependencies ################################################################ # # external library: MPI (optional) @@ -445,12 +458,8 @@ add_library(openPMD ${_openpmd_lib_type} ${CORE_SOURCE} ${IO_SOURCE}) add_library(openPMD::openPMD ALIAS openPMD) # properties -target_compile_features(openPMD - PUBLIC cxx_std_14 -) +openpmd_cxx_required(openPMD) set_target_properties(openPMD PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON WINDOWS_EXPORT_ALL_SYMBOLS ON ) @@ -527,12 +536,8 @@ endif() if(openPMD_HAVE_ADIOS1) add_library(openPMD.ADIOS1.Serial SHARED ${IO_ADIOS1_SEQUENTIAL_SOURCE}) add_library(openPMD.ADIOS1.Parallel SHARED ${IO_ADIOS1_SOURCE}) - target_compile_features(openPMD.ADIOS1.Serial - PUBLIC cxx_std_14 - ) - target_compile_features(openPMD.ADIOS1.Parallel - PUBLIC cxx_std_14 - ) + openpmd_cxx_required(openPMD.ADIOS1.Serial) + openpmd_cxx_required(openPMD.ADIOS1.Parallel) target_compile_options(openPMD.ADIOS1.Serial PUBLIC ${_msvc_options}) target_compile_options(openPMD.ADIOS1.Parallel PUBLIC ${_msvc_options}) target_link_libraries(openPMD.ADIOS1.Serial PUBLIC openPMD::thirdparty::mpark_variant) @@ -551,8 +556,6 @@ if(openPMD_HAVE_ADIOS1) endif() set_target_properties(openPMD.ADIOS1.Serial PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN ON @@ -578,8 +581,6 @@ if(openPMD_HAVE_ADIOS1) if(openPMD_HAVE_MPI) set_target_properties(openPMD.ADIOS1.Parallel PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON CXX_VISIBILITY_PRESET hidden VISIBILITY_INLINES_HIDDEN 1 @@ -800,11 +801,9 @@ if(openPMD_BUILD_TESTING) test/CatchRunner.cpp) # Always MPI_Init with Serial Fallback add_library(CatchMain ${_openpmd_lib_type} test/CatchMain.cpp) # Serial only - target_compile_features(CatchRunner PUBLIC cxx_std_14) - target_compile_features(CatchMain PUBLIC cxx_std_14) + openpmd_cxx_required(CatchRunner) + openpmd_cxx_required(CatchMain) set_target_properties(CatchRunner CatchMain PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON POSITION_INDEPENDENT_CODE ON WINDOWS_EXPORT_ALL_SYMBOLS ON ) @@ -819,6 +818,7 @@ if(openPMD_BUILD_TESTING) foreach(testname ${openPMD_TEST_NAMES}) add_executable(${testname}Tests test/${testname}Test.cpp) + openpmd_cxx_required(${testname}Tests) if(openPMD_USE_INVASIVE_TESTS) target_compile_definitions(${testname}Tests PRIVATE openPMD_USE_INVASIVE_TESTS=1) @@ -829,22 +829,14 @@ if(openPMD_BUILD_TESTING) else() target_link_libraries(${testname}Tests PRIVATE CatchMain) endif() - - set_target_properties(${testname}Tests PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON - ) endforeach() endif() if(openPMD_BUILD_CLI_TOOLS) foreach(toolname ${openPMD_CLI_TOOL_NAMES}) add_executable(openpmd-${toolname} src/cli/${toolname}.cpp) + openpmd_cxx_required(openpmd-${toolname}) target_link_libraries(openpmd-${toolname} PRIVATE openPMD) - set_target_properties(openpmd-${toolname} PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON - ) endforeach() endif() @@ -853,19 +845,13 @@ if(openPMD_BUILD_EXAMPLES) if(${examplename} MATCHES ".+parallel$") if(openPMD_HAVE_MPI) add_executable(${examplename} examples/${examplename}.cpp) + openpmd_cxx_required(${examplename}) target_link_libraries(${examplename} PRIVATE openPMD) - set_target_properties(${examplename} PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON - ) endif() else() add_executable(${examplename} examples/${examplename}.cpp) + openpmd_cxx_required(${examplename}) target_link_libraries(${examplename} PRIVATE openPMD) - set_target_properties(${examplename} PROPERTIES - CXX_EXTENSIONS OFF - CXX_STANDARD_REQUIRED ON - ) endif() endforeach() endif() @@ -978,6 +964,33 @@ if(openPMD_INSTALL) endforeach() endif() + if(openPMD_INSTALL_RPATH) + set(openPMD_INSTALL_RPATH_TARGET_NAMES ${openPMD_INSTALL_TARGET_NAMES}) + if(openPMD_HAVE_PYTHON) + list(APPEND openPMD_INSTALL_RPATH_TARGET_NAMES openPMD.py) + endif() + if(NOT DEFINED CMAKE_INSTALL_RPATH) + if(APPLE) + set_target_properties(${openPMD_INSTALL_RPATH_TARGET_NAMES} PROPERTIES + INSTALL_RPATH "@loader_path" + ) + elseif(CMAKE_SYSTEM_NAME MATCHES "Linux") + set_target_properties(${openPMD_INSTALL_RPATH_TARGET_NAMES} PROPERTIES + INSTALL_RPATH "$ORIGIN" + ) + endif() + # Windows: has no RPath concept, all interdependent `.dll`s must be in + # %PATH% or in the same dir as the calling executable + endif() + + if(NOT DEFINED CMAKE_INSTALL_RPATH_USE_LINK_PATH) + # those are appended AFTER the paths in INSTALL_RPATH + set_target_properties(${openPMD_INSTALL_RPATH_TARGET_NAMES} PROPERTIES + INSTALL_RPATH_USE_LINK_PATH ON + ) + endif() + endif() + install(TARGETS ${openPMD_INSTALL_TARGET_NAMES} EXPORT openPMDTargets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} @@ -1370,6 +1383,7 @@ message(" C++ Compiler: ${CMAKE_CXX_COMPILER_ID} " message(" ${CMAKE_CXX_COMPILER}") message("") if(openPMD_INSTALL) + message(" Install with RPATHs: ${openPMD_INSTALL_RPATH}") message(" Installation prefix: ${CMAKE_INSTALL_PREFIX}") message(" bin: ${CMAKE_INSTALL_BINDIR}") message(" lib: ${CMAKE_INSTALL_LIBDIR}") diff --git a/README.md b/README.md index 1b542e144f..6662535d6c 100644 --- a/README.md +++ b/README.md @@ -257,6 +257,7 @@ CMake controls options with prefixed `-D`, e.g. `-DopenPMD_USE_MPI=OFF`: | `openPMD_USE_INVASIVE_TESTS` | ON/**OFF** | Enable unit tests that modify source code 1 | | `openPMD_USE_VERIFY` | **ON**/OFF | Enable internal VERIFY (assert) macro independent of build type 2 | | `openPMD_INSTALL` | **ON**/OFF | Add installation targets | +| `openPMD_INSTALL_RPATH` | **ON**/OFF | Add RPATHs to installed binaries | | `Python_EXECUTABLE` | (newest found) | Path to Python executable | 1 *e.g. changes C++ visibility keywords, breaks MSVC* diff --git a/docs/source/dev/buildoptions.rst b/docs/source/dev/buildoptions.rst index 7d1f335da8..ac9c06466f 100644 --- a/docs/source/dev/buildoptions.rst +++ b/docs/source/dev/buildoptions.rst @@ -20,6 +20,7 @@ CMake Option Values Description ``openPMD_USE_INVASIVE_TESTS`` ON/**OFF** Enable unit tests that modify source code :sup:`1` ``openPMD_USE_VERIFY`` **ON**/OFF Enable internal VERIFY (assert) macro independent of build type :sup:`2` ``openPMD_INSTALL`` **ON**/OFF Add installation targets +``openPMD_INSTALL_RPATH`` **ON**/OFF Add RPATHs to installed binaries ``Python_EXECUTABLE`` (newest found) Path to Python executable ============================== =============== ========================================================================