diff --git a/.gitignore b/.gitignore index 7caaace..c28c55c 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,6 @@ out-* cmake-build-* build +install CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt index c7ca819..eb6ae24 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,85 +1,118 @@ -cmake_minimum_required(VERSION 3.22...3.25) +cmake_minimum_required(VERSION 3.22...4.2) -project(DynamicLoad LANGUAGES CXX) +set(DYNLOAD_VERSION 0.3) -set(DYNLOAD_DEVELOP OFF CACHE BOOL "Turn ON during library development to get proper compiler warnings and testing") +project(DynamicLoad LANGUAGES CXX VERSION ${DYNLOAD_VERSION}) + +set(DYNLOAD_DEVELOP ${PROJECT_IS_TOP_LEVEL} CACHE BOOL "Turn ON during library development to get proper compiler warnings and testing") set(DYNLOAD_USE_EXCEPTIONS ON CACHE BOOL "Standard C++ uses exceptions, thus, this is enabled by default. Turn off if no exceptions are allowed.") set(DYNLOAD_IMPORT ON CACHE BOOL "Set to true if needing importing part of DYNLOAD") set(DYNLOAD_EXPORT ON CACHE BOOL "Set to true if needing exporting part of DYNLOAD") set(DYNLOAD_COMPILE_PLATFORM ON CACHE BOOL "If true, dynl will be automatically compiled for the target platform. Set to false if custom backend is needed.") set(DYNLOAD_HEADERONLY OFF CACHE BOOL "Set to true to use dynload as a header-only library") -add_library(dynl_compile_opts INTERFACE) -add_library(dynl::compile_opts ALIAS dynl_compile_opts) -target_compile_options(dynl_compile_opts INTERFACE ${DYNL_COMPILE_FLAGS}) - -set(DYNLOAD_DEV_LINK dynl_compile_opts) if (DYNLOAD_DEVELOP) - set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD 20) enable_testing() include(use_google_test.cmake) add_subdirectory(tests) + + set(DYNLOAD_INTERNAL_COMPILE_OPTS ${DYNL_COMPILE_FLAGS}) endif () -if (DYNLOAD_IMPORT) - add_library(dynl_headers INTERFACE) - add_library(dynl::dynl_headers ALIAS dynl_headers) - target_include_directories(dynl_headers INTERFACE - include - ) - target_compile_features(dynl_headers INTERFACE cxx_std_20) - if (DYNLOAD_USE_EXCEPTIONS) - else () - target_compile_definitions(dynl_shared PRIVATE - "DYNLOAD_NO_EXCEPTIONS=1" - ) - endif () +if (DYNLOAD_HEADERONLY) + set(DYNLOAD_LIB_TYPE INTERFACE) + set(DYNLOAD_PUBLIC_LINK_TYPE INTERFACE) +else () + set(DYNLOAD_LIB_TYPE "") + set(DYNLOAD_PUBLIC_LINK_TYPE PUBLIC) +endif () - if (DYNLOAD_HEADERONLY) - set(DYNLOAD_LIB_TYPE INTERFACE) - set(DYNLOAD_PUBLIC_LINK_TYPE INTERFACE) - else () - set(DYNLOAD_LIB_TYPE "") - set(DYNLOAD_PUBLIC_LINK_TYPE PUBLIC) - endif () +add_library(dynl) +add_library(dynl::dynl ALIAS dynl) +target_compile_options(dynl PUBLIC + ${DYNLOAD_INTERNAL_COMPILE_OPTS} +) +target_compile_features(dynl PUBLIC cxx_std_20) +add_library(dynl_headers INTERFACE) +add_library(dynl::dynl_headers ALIAS dynl_headers) +target_compile_options(dynl INTERFACE + ${DYNLOAD_INTERNAL_COMPILE_OPTS} +) +target_compile_features(dynl_headers INTERFACE cxx_std_20) - add_library(dynl ${DYNLOAD_LIB_TYPE}) - add_library(dynl::dynl ALIAS dynl) - target_link_libraries(dynl ${DYNLOAD_PUBLIC_LINK_TYPE} - dynl::dynl_headers - ${DYNLOAD_DEV_LINK} +target_include_directories(dynl PUBLIC + $ + $ +) +target_include_directories(dynl_headers INTERFACE + $ + $ +) +if (NOT DYNLOAD_USE_EXCEPTIONS) + target_compile_definitions(dynl PUBLIC + "DYNLOAD_NO_EXCEPTIONS=1" ) - if (DYNLOAD_COMPILE_PLATFORM) - if (WIN32) - set(DYNL_SRC src/dynl_win32.cpp) - set(DYNL_PLATFORM DYNL_WINDOWS=1) - set(DYNL_EXTRA_LINK "") - elseif (UNIX) - set(DYNL_SRC src/dynl_unix.cpp) - set(DYNL_PLATFORM DYNL_UNIX=1) - set(DYNL_EXTRA_LINK dl) - else () - message(SEND_ERROR "Dynload: no automatic backend available! Use custom defined source file") - endif () - else () - message(STATUS "Dynload: no automatic backend. Custom defined source-file(-s) for 'dynl' required") - set(DYNL_SRC "") - set(DYNL_PLATFORM "") - endif () - if (DYNLOAD_HEADERONLY) - target_compile_definitions(dynl INTERFACE DYNLOAD_HEADERONLY=1 ${DYNL_PLATFORM}) - target_link_libraries(dynl INTERFACE ${DYNL_EXTRA_LINK}) + target_compile_definitions(dynl_headers INTERFACE + "DYNLOAD_NO_EXCEPTIONS=1" + ) +endif () +if (DYNLOAD_COMPILE_PLATFORM) + if (WIN32) + set(DYNL_SRC src/dynl_win32.cpp) + set(DYNL_PLATFORM DYNL_WINDOWS=1) + set(DYNL_EXTRA_LINK "") + elseif (UNIX) + set(DYNL_SRC src/dynl_unix.cpp) + set(DYNL_PLATFORM DYNL_UNIX=1) + set(DYNL_EXTRA_LINK dl) else () - target_sources(dynl PRIVATE ${DYNL_SRC}) - target_link_libraries(dynl PRIVATE ${DYNL_EXTRA_LINK}) + message(SEND_ERROR "Dynload: no automatic backend available! Use custom defined source file") endif () +else () + message(STATUS "Dynload: no automatic backend. Custom defined source-file(-s) for 'dynl' required") + set(DYNL_SRC "") + set(DYNL_PLATFORM "") endif () -if (DYNLOAD_EXPORT) - add_library(dynl_export INTERFACE) - add_library(dynl::dynl_export ALIAS dynl_export) - target_include_directories(dynl_export INTERFACE - export_include - ) -endif () +target_compile_definitions(dynl_headers INTERFACE DYNLOAD_HEADERONLY=1 ${DYNL_PLATFORM}) +target_link_libraries(dynl_headers INTERFACE ${DYNL_EXTRA_LINK}) + +target_sources(dynl PRIVATE ${DYNL_SRC}) +target_link_libraries(dynl PRIVATE ${DYNL_EXTRA_LINK}) + +add_library(dynl_export INTERFACE) +add_library(dynl::dynl_export ALIAS dynl_export) +target_include_directories(dynl_export INTERFACE + $ + $ +) + +include(CMakePackageConfigHelpers) +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/DynloadConfigVersion.cmake" + VERSION ${DYNLOAD_VERSION} + COMPATIBILITY AnyNewerVersion +) +configure_package_config_file( + "${PROJECT_SOURCE_DIR}/cmake/DynloadConfig.cmake.in" + "${PROJECT_BINARY_DIR}/DynloadConfig.cmake" + INSTALL_DESTINATION lib/cmake/Dynload +) + +install(TARGETS dynl dynl_headers dynl_export + EXPORT dynlTargets + LIBRARY DESTINATION lib COMPONENT Runtime + ARCHIVE DESTINATION lib COMPONENT Development + RUNTIME DESTINATION bin COMPONENT Runtime + PUBLIC_HEADER DESTINATION include COMPONENT Development + BUNDLE DESTINATION bin COMPONENT Runtime +) + +install(EXPORT dynlTargets DESTINATION lib/cmake/Dynload) +install(FILES "${PROJECT_BINARY_DIR}/DynloadConfigVersion.cmake" + "${PROJECT_BINARY_DIR}/DynloadConfig.cmake" + DESTINATION lib/cmake/Dynload) +install(DIRECTORY ${PROJECT_SOURCE_DIR}/include/ DESTINATION include) + diff --git a/cmake/DynloadConfig.cmake.in b/cmake/DynloadConfig.cmake.in new file mode 100644 index 0000000..2224fb2 --- /dev/null +++ b/cmake/DynloadConfig.cmake.in @@ -0,0 +1,4 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/dynlTargets.cmake") +check_required_components("@PROJECT_NAME@") diff --git a/export_include/dynl/dynl_export.hpp b/include/dynl/dynl_export.hpp similarity index 100% rename from export_include/dynl/dynl_export.hpp rename to include/dynl/dynl_export.hpp diff --git a/use_google_test.cmake b/use_google_test.cmake index d34fdad..d0e8633 100644 --- a/use_google_test.cmake +++ b/use_google_test.cmake @@ -1,10 +1,11 @@ include(FetchContent) -set(DYNLOAD_GTEST_VERSION "v1.14.0") +set(DYNLOAD_GTEST_VERSION "v1.17.0") FetchContent_Declare( googletest + SYSTEM URL https://github.com/google/googletest/archive/refs/tags/${DYNLOAD_GTEST_VERSION}.zip ) # For Windows: Prevent overriding the parent project's compiler/linker settings