diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d4792ca5..1c24793e5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,11 +7,12 @@ project (liblsl ) set(CMAKE_CXX_VISIBILITY_PRESET hidden) +set(CMAKE_VISIBILITY_INLINES_HIDDEN ON) if(NOT MSVC_VERSION VERSION_LESS 1700) set(CMAKE_CXX_STANDARD 14) endif() +# generate a compilation database (compile_commands.json) for clang tooling set(CMAKE_EXPORT_COMPILE_COMMANDS ON) -set(LSL_LIB_TYPE SHARED) option(LSL_DEBUGLOG "Enable (lots of) additional debug messages" OFF) option(LSL_UNIXFOLDERS "Use the unix folder layout for install targets" On) @@ -19,6 +20,7 @@ option(LSL_FORCE_FANCY_LIBNAME "Add library name decorations (32/64/-debug)" OFF option(LSL_BUILD_EXAMPLES "Build example programs in examples/" OFF) option(LSL_BUILD_STATIC "Build LSL as static library." OFF) option(LSL_LEGACY_CPP_ABI "Build legacy C++ ABI into lsl-static" OFF) +option(LSL_OPTIMIZATIONS "Enable some more compiler optimizations" ON) option(LSL_UNITTESTS "Build LSL library unit tests" OFF) option(LSL_BUNDLED_PUGIXML "Use the bundled pugixml by default" ON) @@ -28,6 +30,8 @@ set(LSL_WINVER "0x0601" CACHE STRING if(LSL_BUILD_STATIC) set(LSL_LIB_TYPE STATIC) else() + set(LSL_LIB_TYPE SHARED) + # shared libraries require relocatable symbols so we enable them by default set(CMAKE_POSITION_INDEPENDENT_CODE ON) endif() @@ -106,7 +110,7 @@ if(LSL_BUNDLED_PUGIXML) message(STATUS "Using bundled pugixml") target_sources(lslobj PRIVATE thirdparty/pugixml/pugixml.cpp) target_include_directories(lslobj SYSTEM PUBLIC - $) + ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/pugixml) else() message(STATUS "Using system pugixml") find_package(pugixml REQUIRED) @@ -138,90 +142,104 @@ else() set(lslgitrevision "unknown") set(lslgitbranch "unknown") endif() + +# generate a version information string that can be retrieved with the exported +# lsl_library_info() function set(LSL_VERSION_INFO "git:${lslgitrevision}/branch:${lslgitbranch}/build:${CMAKE_BUILD_TYPE}/compiler:${CMAKE_CXX_COMPILER_ID}-${CMAKE_CXX_COMPILER_VERSION}") +set_source_files_properties("src/buildinfo.cpp" + PROPERTIES COMPILE_DEFINITIONS + LSL_LIBRARY_INFO_STR="${LSL_VERSION_INFO}/link:${LSL_LIB_TYPE}" +) set_source_files_properties("thirdparty/loguru/loguru.cpp" PROPERTIES COMPILE_DEFINITIONS LOGURU_STACKTRACES=$) -## create the lslboost target +find_package(Threads REQUIRED) + +# create the lslboost target add_library(lslboost OBJECT - lslboost/asio_objects.cpp lslboost/serialization_objects.cpp ) - -if(UNIX) - include(CheckSymbolExists) - # look for clock_gettime, if not we need to link against librt - check_symbol_exists(clock_gettime time.h HAS_GETTIME) - if(NOT HAS_GETTIME) - set(NEEDS_LIBRT ON CACHE INTERNAL "Link to librt") - endif() -endif() - -find_package(Threads REQUIRED) -target_link_libraries(lslboost - PUBLIC - Threads::Threads - PRIVATE - $<$:bcrypt> - $<$:mswsock> - $<$:ws2_32> - ) +target_link_libraries(lslboost PUBLIC Threads::Threads) target_compile_features(lslboost PUBLIC cxx_std_11 cxx_lambda_init_captures) target_compile_definitions(lslboost PUBLIC BOOST_ALL_NO_LIB BOOST_ASIO_STANDALONE - BOOST_ASIO_SEPARATE_COMPILATION BOOST_THREAD_DONT_PROVIDE_INTERRUPTIONS - $<$:_WIN32_WINNT=${LSL_WINVER}> - PRIVATE - $<$:BOOST_THREAD_BUILD_DLL> ) target_include_directories(lslboost SYSTEM PUBLIC - $) + ${CMAKE_CURRENT_SOURCE_DIR}/lslboost) - -target_link_libraries(lslobj - PRIVATE - lslboost - $<$:iphlpapi> - $<$:winmm> - PUBLIC - $<$,$>:dl> - $<$:rt> - ) +# target configuration for the internal lslobj target +target_link_libraries(lslobj PRIVATE lslboost) target_include_directories(lslobj PUBLIC $ ) target_include_directories(lslobj SYSTEM PUBLIC $ ) -target_compile_definitions(lslobj - PRIVATE LIBLSL_EXPORTS $<$:_CRT_SECURE_NO_WARNINGS> - LOGURU_DEBUG_LOGGING=$ - INTERFACE LSLNOAUTOLINK # don't use #pragma(lib) in CMake builds +target_compile_definitions(lslobj PRIVATE + LIBLSL_EXPORTS + LOGURU_DEBUG_LOGGING=$ ) +# platform specific configuration +if(UNIX) + include(CheckSymbolExists) + # check that clock_gettime is present in the stdlib, link against librt otherwise + check_symbol_exists(clock_gettime time.h HAS_GETTIME) + if(NOT HAS_GETTIME) + target_link_libraries(lslobj PRIVATE rt) + endif() + if(LSL_DEBUGLOG AND NOT APPLE) + target_link_libraries(lslobj PRIVATE dl) + endif() +elseif(WIN32) + target_link_libraries(lslobj PRIVATE iphlpapi winmm) + target_link_libraries(lslboost PRIVATE bcrypt mswsock ws2_32) + target_compile_definitions(lslobj + PRIVATE _CRT_SECURE_NO_WARNINGS + PUBLIC LSLNOAUTOLINK # don't use #pragma(lib) in CMake builds + ) + target_compile_definitions(lslboost + PUBLIC _WIN32_WINNT=${LSL_WINVER} + PRIVATE BOOST_THREAD_BUILD_DLL + ) +endif() + +# the "real" liblsl library. It contains one source with the version info +# string because some generators require it. The remaining source code is +# built in the lslobj target and later linked into this library add_library(lsl ${LSL_LIB_TYPE} src/buildinfo.cpp) # defines for LSL_CPP_API export header (shared: dllimport/dllexport) target_compile_definitions(lsl PUBLIC $,LIBLSL_STATIC,LIBLSL_EXPORTS> + $<$:LSLNOAUTOLINK> # don't use #pragma(lib) in CMake builds ) - -set_source_files_properties("src/buildinfo.cpp" - PROPERTIES COMPILE_DEFINITIONS - LSL_LIBRARY_INFO_STR="${LSL_VERSION_INFO}/link:${LSL_LIB_TYPE}" +target_link_libraries(lsl PRIVATE lslobj lslboost) +target_include_directories(lsl INTERFACE + $ + $ ) - -target_link_libraries(lsl - PUBLIC lslobj - PRIVATE lslboost) set_target_properties(lsl PROPERTIES VERSION ${liblsl_VERSION_MAJOR}.${liblsl_VERSION_MINOR}.${liblsl_VERSION_PATCH} ) +# enable some additional expensive compiler optimizations +if(LSL_OPTIMIZATIONS) + # enable LTO (https://en.wikipedia.org/wiki/Interprocedural_optimization + set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) +else() + # build one object file for Asio instead of once every time an Asio function is called. See + # https://think-async.com/Asio/asio-1.18.2/doc/asio/using.html#asio.using.optional_separate_compilation + target_sources(lslboost PRIVATE lslboost/asio_objects.cpp) + target_compile_definitions(lslboost PUBLIC BOOST_ASIO_SEPARATE_COMPILATION) +endif() + + + if(LSL_FORCE_FANCY_LIBNAME) math(EXPR lslplatform "8 * ${CMAKE_SIZEOF_VOID_P}") set_target_properties(lsl PROPERTIES @@ -246,7 +264,7 @@ write_basic_package_version_file( COMPATIBILITY AnyNewerVersion ) -install(TARGETS lsl lslobj lslboost +install(TARGETS lsl EXPORT LSLTargets COMPONENT liblsl RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index 64dafefe9..433add672 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.12) project(lslexamples LANGUAGES C CXX VERSION 0.2.0) diff --git a/testing/CMakeLists.txt b/testing/CMakeLists.txt index d3ed4f7dc..ae970d67a 100644 --- a/testing/CMakeLists.txt +++ b/testing/CMakeLists.txt @@ -25,7 +25,8 @@ add_executable(lsl_test_exported test_ext_streaminfo.cpp test_ext_time.cpp ) -target_link_libraries(lsl_test_exported PRIVATE lsl catch_main) + +target_link_libraries(lsl_test_exported PRIVATE lsl catch_main Threads::Threads) find_package(Threads REQUIRED)