diff --git a/AddQtTest.cmake b/AddQtTest.cmake new file mode 100644 index 0000000..d2fd718 --- /dev/null +++ b/AddQtTest.cmake @@ -0,0 +1,18 @@ +macro(add_qt_test TEST_NAME SRCS) + find_package(Qt5Test REQUIRED) + + add_executable(${TEST_NAME} ${SRCS}) + + add_test(NAME ${TEST_NAME} COMMAND $) + + target_link_libraries(${TEST_NAME} PUBLIC Qt5::Test) +endmacro() + +option(PRIVATE_TESTS_ENABLED "Enable private tests" OFF) +macro(add_private_qt_test TEST_NAME SRCS) + if(DEFINED PRIVATE_TESTS_ENABLED) + if(${PRIVATE_TESTS_ENABLED}) + add_qt_test(${TEST_NAME} ${SRCS}) + endif(${PRIVATE_TESTS_ENABLED}) + endif(DEFINED PRIVATE_TESTS_ENABLED) +endmacro() diff --git a/CodeCoverage.cmake b/CodeCoverage.cmake new file mode 100644 index 0000000..afdac33 --- /dev/null +++ b/CodeCoverage.cmake @@ -0,0 +1,42 @@ +# Enable Code Coverage +# +# USAGE: +# 1. Copy this file into your cmake modules path. +# +# 2. Add the following line to your CMakeLists.txt: +# INCLUDE(CodeCoverage) +# +# 3. Call the function ENABLE_CODE_COVERAGE +# This functions sets compiler flags to turn off optimization and enable coverage: +# SET(CMAKE_CXX_FLAGS_DEBUG "-g -O0 -fprofile-arcs -ftest-coverage") +# +# 4. Build a Debug build: +# cmake -DCMAKE_BUILD_TYPE=Debug .. +# make +# make my_coverage_target +# +# Note: code coverage can only be enabled when in debug build! +# +# Requirements: gcov and gcovr + +# Check prereqs +find_package(Gcov) +find_package(Gcovr) + +function(ENABLE_CODE_COVERAGE) + if (GCOV_FOUND AND GCOVR_FOUND) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0 -fprofile-arcs -ftest-coverage") + if (CMAKE_COMPILER_IS_GNUCXX AND NOT UNIX) + link_libraries(debug gcov) + endif(WIN32 AND NOT UNIX) + if (NOT WIN32) + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fPIC") + endif (NOT WIN32) + + set(CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG} PARENT_SCOPE) + + message(STATUS "Code Coverage Enabled") + else() + message("-- Code Coverage NOT Enabled because gcov and/or gcovr was not found.") + endif() +endfunction() diff --git a/CommonConfig.cmake b/CommonConfig.cmake new file mode 100644 index 0000000..6ae7c77 --- /dev/null +++ b/CommonConfig.cmake @@ -0,0 +1,70 @@ +cmake_minimum_required(VERSION 3.5.2 FATAL_ERROR) + +################# +# Build options # +################# + +if (NOT DEFINED BUILD_SHARED_LIBS) + option(BUILD_SHARED_LIBS "Build as shared library" ON) +endif() +# When set to OFF, the library will be built as a static library +if (${BUILD_SHARED_LIBS}) + add_definitions(-DBUILD_SHARED_LIBS) +endif() + + +# Usage of Qt libraries +# --------------------- +# Point CMake search path to Qt intallation directory +# Either supply QTDIR as -DQTDIR= to cmake or set an environment variable QTDIR pointing to the Qt installation +if ((NOT DEFINED QTDIR) AND DEFINED ENV{QTDIR}) + set(QTDIR $ENV{QTDIR}) +endif ((NOT DEFINED QTDIR) AND DEFINED ENV{QTDIR}) + +if (NOT DEFINED QTDIR) + message(FATAL_ERROR "QTDIR has not been set nor supplied as a define parameter to cmake.") +endif (NOT DEFINED QTDIR) + +if (QTDIR) + list (APPEND CMAKE_PREFIX_PATH ${QTDIR}) +endif (QTDIR) + +# Instruct CMake to run moc automatically when needed. +set(CMAKE_AUTOMOC ON) +# let CMake decide which classes need to be rcc'ed by qmake (Qt) +set(CMAKE_AUTORCC ON) +# let CMake decide which classes need to be uic'ed by qmake (Qt) +set(CMAKE_AUTOUIC ON) + + +# Usage of CMake Packages +# ----------------------- +include(CMakePackageConfigHelpers) + +# Point cmake to the packages of libraries in this tree. +list(APPEND CMAKE_PREFIX_PATH ${CMAKE_BINARY_DIR}/local-exports) + + +# Compiler flags +# -------------- +add_definitions(-Wall -fvisibility=hidden) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Find includes in corresponding build directories +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +# Compile with @rpath option on Apple +if (APPLE) + set(CMAKE_MACOSX_RPATH 1) +endif (APPLE) + + +# Switch testing on +# ----------------- +enable_testing() +add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}) +include(AddQtTest) + +# Common compiler flags +include(CompilerFlags) diff --git a/CompilerFlags.cmake b/CompilerFlags.cmake new file mode 100644 index 0000000..3adaa73 --- /dev/null +++ b/CompilerFlags.cmake @@ -0,0 +1,193 @@ +# Force synchronous PDB writes for Visual Studio +if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + add_compile_options("/FS") +endif() + +# Set default build type to release with debug info +IF(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE RelWithDebInfo) +ENDIF(NOT CMAKE_CONFIGURATION_TYPES AND NOT CMAKE_BUILD_TYPE) + +if(CMAKE_COMPILER_IS_GNUCXX) + set(COMPILER_FLAGS + "-std=c++11" + "-Wall" # turn on all warnings + "-pedantic" + "-Wextra" + "-fno-rtti" # disable runtime type information + "-fno-exceptions" + "-ffor-scope" + "-fuse-cxa-atexit" + "-fno-default-inline" + "-fvisibility=hidden" # do not export symbols by default + "-fvisibility-inlines-hidden" + "-pedantic-errors" + "-Wsign-promo" + "-Wsign-compare" + "-Wnon-virtual-dtor" + "-Wold-style-cast" + "-Woverloaded-virtual" + "-Wswitch" + "-Wswitch-default" + "-Wswitch-enum" + "-Wcast-qual" + "-Wcast-align" + "-Wuninitialized" + "-Wno-float-equal" + "-Wlogical-op" + "-Wpacked" + "-Wredundant-decls" + "-Wdisabled-optimization" + "-Wdeprecated" + "-Wempty-body" + "-Wreturn-type" + "-Wunused-variable" + "-Wno-unknown-pragmas" # suppress unknown pragma warnings + "-Wformat" + "-Wunreachable-code" + "-mfpmath=sse" # needed on Debian 32-bit to get high precision floating point operations + "-msse2" # needed on Debian 32-bit to get high precision floating point operations + + "-Weffc++" # warnings from Effective C++ book; + + "-Werror" + "-Wformat-nonliteral" # const char* argumements could not langer be passed due to this entry +# "-Winline" # gcc on Linux seems to decide frequently not to inline, and warns about it. +# # We don't need to know about it, since not inlining is not a problem. +# "-Wnull-character" # not supported by gcc +# "-Wshadow" # disable shadow warning as gcc generates + # warnings for parameters with same name + # as methods in the class. + # This option is enabled for clang builds, + # so the 'real' shadow variables will be + # caught be clang + "-Wsign-conversion" +# "-Wuseless-cast" +# "-Wzero-as-null-pointer-constant" + ) + if(WIN32) + # Fix for using LxCan sensor SDK + # Since LxNative.dll uses stdcall convention, MinGW expects @.. decoration of the exposed functions, + # which are not present in the DLL. This MinGW option tells the linker to also look for undecorated + # functions. + set(COMPILER_FLAGS "${COMPILER_FLAGS}" "-Wl,--enable-stdcall-fixup") + endif() +elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(COMPILER_FLAGS + "-stdlib=libc++" + "-std=c++11" + "-Wall" # turn on all warnings + "-Wpedantic" + "-Wextra" + "-Weffc++" # turn on warnings from Effective C++ handbook + "-fno-rtti" # disable runtime type information + "-fno-exceptions" + "-ffor-scope" + "-fuse-cxa-atexit" + "-fvisibility=hidden" # do not export symbols by default + "-fvisibility-inlines-hidden" + "-pedantic" # warn about language extensions + "-pedantic-errors" # treat language extension warnings as errors + "-Wsign-promo" + "-Wsign-compare" + "-Wnon-virtual-dtor" + "-Wold-style-cast" + "-Woverloaded-virtual" + "-Wint-to-void-pointer-cast" + "-Wswitch" + "-Wswitch-default" + "-Wswitch-enum" + "-Wcast-qual" + "-Wcast-align" + "-Wuninitialized" + "-Wno-float-equal" + "-Wshadow" + "-Wpacked" + "-Wredundant-decls" + "-Wdisabled-optimization" + "-Wdeprecated" + "-Wdeprecated-declarations" + "-Wempty-body" + "-Wbitwise-op-parentheses" + "-Wlogical-op-parentheses" + "-Wold-style-cast" + "-Wold-style-definition" + "-Wout-of-line-declaration" + "-Waddress-of-temporary" + "-Wbool-conversions" + "-Wbad-function-cast" + "-Wbind-to-temporary-copy" + "-Wdiv-by-zero" + "-Wheader-hygiene" + "-Wnull-dereference" + "-Widiomatic-parentheses" + "-Wparentheses" + "-Winitializer-overrides" + "-Wint-to-pointer-cast" + "-Wpointer-to-int-cast" + "-Wpointer-arith" + "-Wmissing-braces" + "-Wmissing-field-initializers" + "-Wnonnull" + "-Woverflow" + "-Wshorten-64-to-32" + "-Wno-used-but-marked-unused" + "-Weffc++" + "-Wreturn-type" + "-Wnull-character" + "-Wunused-variable" + "-Wselector" + "-Wno-unknown-pragmas" # suppress unknown pragma warnings + "-Wformat" + "-Wformat-nonliteral" + "-Wtautological-compare" + "-Wunreachable-code" + + "-Werror" +# "-Winline" # gcc on Linux seems to decide frequently not to inline, and warns about it. +# # We don't need to know about it, since not inlining is not a problem. + "-Wshadow" + "-Wsign-conversion" +# "-Wuseless-cast" # not supported by Clang +# "-Wzero-as-null-pointer-constant" # not supported by Clang + ) +elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + # Remove /W3 since /W4 will be added (otherwise we get a warning about replacing /W3 with /W4) + string(REPLACE "/W3" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + + # Remove /EHsc since /EHsc- will be added (otherwise we get a warning about replacing /EHsc with /EHsc-) + string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + + # Remove /GR since /GR- will be added (otherwise we get a warning about replacing /GR with /GR-) + string(REPLACE "/GR" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) + + set(COMPILER_FLAGS + "/W4" + "/WX" # treat all warnings as errors +# "/wdxxxx" # suppress specific warnings +# "/wd4820" # suppress warning about padding + "/wd4625" # suppress warning: + # copy constructor could not be generated because a base class + # copy constructor is inaccessible or deleted + "/wd4626" # assignment operator could not be generated because a base + # class assignment operator is inaccessible or deleted + "/wd4127" # suppress warning: conditional expression is constant + "/wd4505" # suppress warning: unreferenced function has been removed + "/wd4206" # suppress warning: translation unit is empty + "/wd4515" # suppress warning: namespace uses itself +# "/wd4512" # suppress warning: assignment operator could not be generated + # A fix is planned in Qt 5.4.2 (https://bugreports.qt.io/browse/QTBUG-7233) + # Check later with Qt >= 5.4.2 if warning suppression can be removed + "/nologo" + "/EHsc-" # disable exceptions + "/GR-" # disable RTTI + ) +endif() + +string(REPLACE ";" " " COMPILER_FLAGS_STRING "${COMPILER_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COMPILER_FLAGS_STRING}") + +# disable compiler optimization which can cause release version to crash when using MinGW +if(WIN32 AND NOT UNIX AND CMAKE_COMPILER_IS_GNUCXX) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-ipa-cp-clone") +endif() diff --git a/Cppcheck.cmake b/Cppcheck.cmake new file mode 100644 index 0000000..e041f2a --- /dev/null +++ b/Cppcheck.cmake @@ -0,0 +1,11 @@ +find_package(Cppcheck) + +if(CPPCHECK_FOUND) + file(GLOB_RECURSE CPPCHECK_FILES RELATIVE ${CMAKE_SOURCE_DIR} *.cpp *.h) + + add_custom_target(cppcheck + COMMAND ${CPPCHECK_EXECUTABLE} "--force" "--quiet" "--error-exitcode=1" ${CPPCHECK_FILES} + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + COMMENT "Running cppcheck..." + VERBATIM) +endif() diff --git a/DefineProject.cmake b/DefineProject.cmake new file mode 100644 index 0000000..e4ab894 --- /dev/null +++ b/DefineProject.cmake @@ -0,0 +1,38 @@ +##################################################### +# Start of configuration # +# Lines below should not be touched in normal cases # +##################################################### + +#======================================= +# Set some variables to be used later on +#======================================= +set(PROJECT_NAME ${PROJECT_NAME_PREFIX}${PROJECT_BASE_NAME}) +set(TARGET_NAME ${PROJECT_BASE_NAME}) +set(PROJECT_NAMESPACE ${PROJECT_NAME_PREFIX}${SO_VERSION}) +set(INSTALL_DIRECTORY_NAME ${PROJECT_NAME}/${PROJECT_NAME_PREFIX}${SO_VERSION}) +set(CMAKE_DIRECTORY_NAME ${PROJECT_NAME_PREFIX}${SO_VERSION}${PROJECT_BASE_NAME}) +set(PACKAGE_NAME ${PROJECT_NAME_PREFIX}${SO_VERSION}${PROJECT_BASE_NAME}) +set(MODULE_NAME ${PROJECT_NAME}) +#base name used for cmake config files: +#Config.cmake +#ConfigVersion.cmake +#Targets.cmake +#Targets_noconfig.cmake +set(CMAKE_CONFIG_FILE_BASE_NAME ${PROJECT_NAME_PREFIX}${SO_VERSION}${PROJECT_BASE_NAME}) + +set(LIB_INSTALL_DIR lib/${INSTALL_DIRECTORY_NAME}) +set(INCLUDE_INSTALL_DIR include/${INSTALL_DIRECTORY_NAME}) +set(BIN_INSTALL_DIR bin) +set(CMAKE_INSTALL_DIR lib/cmake/${CMAKE_DIRECTORY_NAME}) + +project(${PROJECT_NAME}) + +message(STATUS "Libraries will be installed to: ${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}") +message(STATUS "Header files will be installed to: ${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}") +message(STATUS "Executables will be installed in: ${CMAKE_INSTALL_PREFIX}/${BIN_INSTALL_DIR}") +message(STATUS "CMake config-files will be written to: ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DIR}") +message(STATUS "${PROJECT_NAME} import target: ${PROJECT_NAMESPACE}::${TARGET_NAME}") +message(STATUS "Building ${PROJECT_NAME} ${FULL_VERSION} in ${CMAKE_BUILD_TYPE} mode") +if (PRIVATE_TESTS_ENABLED) + message(STATUS "Private tests are enabled") +endif() \ No newline at end of file diff --git a/DeployDependentLibraries.cmake b/DeployDependentLibraries.cmake new file mode 100644 index 0000000..bf6722c --- /dev/null +++ b/DeployDependentLibraries.cmake @@ -0,0 +1,46 @@ +# On a Windows platform, you need a way to reference to the libraries you need. +# Using this, those libraries are copied along the executable. +# +# Usage: +# target_link_libraries(${TARGET_NAME} PUBLIC ...) +# include(DeployDependentLibraries) # This include goes after your last link_libraries. + +if(WIN32) + # Copy dependent libraries to path of executable + get_property(libs TARGET ${TARGET_NAME} PROPERTY LINK_LIBRARIES) + foreach(lib ${libs}) + if(TARGET ${lib}) + # If this is a library, get its transitive dependencies + get_property(trans TARGET ${lib} PROPERTY INTERFACE_LINK_LIBRARIES) + foreach(tran ${trans}) + if(TARGET ${tran}) + get_property(path TARGET ${tran} PROPERTY LOCATION) + list(APPEND ${TARGET_NAME}_deplibs ${path}) + endif() + endforeach() + get_property(path TARGET ${lib} PROPERTY LOCATION) + list(APPEND ${TARGET_NAME}_deplibs ${path}) + else() + list(APPEND ${TARGET_NAME}_deplibs ${lib}) + endif() + endforeach() + + list(REMOVE_DUPLICATES ${TARGET_NAME}_deplibs) + + # Replace all entries ending on .lib to .dll + foreach(lib ${${TARGET_NAME}_deplibs}) + STRING(REGEX REPLACE "lib$" "dll" _replaced_lib ${lib}) + if (DEFINED _replaced_lib) + list(APPEND _${TARGET_NAME}_deplibs ${_replaced_lib}) + else() + list(APPEND _${TARGET_NAME}_deplibs ${lib}) + endif() + endforeach() + set(${TARGET_NAME}_deplibs ${_${TARGET_NAME}_deplibs}) + + foreach(lib ${${TARGET_NAME}_deplibs}) + add_custom_command(TARGET ${TARGET_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_if_different ${lib} ${CMAKE_CURRENT_BINARY_DIR} + VERBATIM) + endforeach() +endif() diff --git a/FindCppcheck.cmake b/FindCppcheck.cmake new file mode 100644 index 0000000..4534bf1 --- /dev/null +++ b/FindCppcheck.cmake @@ -0,0 +1,20 @@ +# Try to find cppcheck tool for Unix platforms +# +# Cache Variables: +# CPPCHECK_EXECUTABLE +# +# Non-cache variables you might use in your CMakeLists.txt: +# CPPCHECK_FOUND +# +# Requires these CMake modules: +# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) + +find_program(CPPCHECK_EXECUTABLE cppcheck PATHS /usr/local/bin) + +set(CPPCHECK_FOUND FALSE CACHE INTERNAL "") + +if(CPPCHECK_EXECUTABLE) + set(CPPCHECK_FOUND TRUE CACHE INTERNAL "") +endif() + +mark_as_advanced(CPPCHECK_EXECUTABLE) diff --git a/FindGcov.cmake b/FindGcov.cmake new file mode 100644 index 0000000..cdc52a1 --- /dev/null +++ b/FindGcov.cmake @@ -0,0 +1,30 @@ +# Try to find gcov tool +# +# Cache Variables: +# GCOV_EXECUTABLE +# +# Non-cache variables you might use in your CMakeLists.txt: +# GCOV_FOUND +# +# Requires these CMake modules: +# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) + +if(GCOV_EXECUTABLE AND NOT EXISTS "${GCOV_EXECUTABLE}") + set(GCOV_EXECUTABLE "notfound" CACHE PATH FORCE "") +endif() + +IF(NOT CMAKE_COMPILER_IS_GNUCXX AND NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + MESSAGE(WARNING "Compiler is not GNU gcc or Clang!") + set(GCOV_EXECUTABLE "notfound" CACHE PATH FORCE "") +ELSEIF( NOT CMAKE_BUILD_TYPE STREQUAL "Debug" ) + MESSAGE(WARNING "Code coverage results with an optimized (non-Debug) build may be misleading" ) + set(GCOV_EXECUTABLE "notfound" CACHE PATH FORCE "") +ELSE() + find_program(GCOV_EXECUTABLE NAMES gcov) +ENDIF(NOT CMAKE_COMPILER_IS_GNUCXX AND NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( Gcov DEFAULT_MSG + GCOV_EXECUTABLE) + +mark_as_advanced(GCOV_EXECUTABLE) diff --git a/FindGcovr.cmake b/FindGcovr.cmake new file mode 100644 index 0000000..cf3b4f0 --- /dev/null +++ b/FindGcovr.cmake @@ -0,0 +1,25 @@ +# Try to find gcovr tool +# +# Cache Variables: +# GCOVR_EXECUTABLE +# +# Non-cache variables you might use in your CMakeLists.txt: +# GCOVR_FOUND +# +# Requires these CMake modules: +# FindPackageHandleStandardArgs (known included with CMake >=2.6.2) +# FindPythonInterp +# FindGcov + +if(GCOVR_EXECUTABLE AND NOT EXISTS "${GCOVR_EXECUTABLE}") + set(GCOVR_EXECUTABLE "notfound" CACHE PATH FORCE "") +endif() +find_program(GCOVR_EXECUTABLE NAMES gcovr) +find_package(PythonInterp) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( Gcovr DEFAULT_MSG + GCOVR_EXECUTABLE + PYTHONINTERP_FOUND) + +mark_as_advanced(GCOVR_EXECUTABLE) \ No newline at end of file diff --git a/GeneratePackage.cmake b/GeneratePackage.cmake new file mode 100644 index 0000000..3227279 --- /dev/null +++ b/GeneratePackage.cmake @@ -0,0 +1,92 @@ +# CMake helper to generate a cmake module package + +set(DEPENDENT_PACKAGES ${${TARGET_NAME}_DEPENDENT_PACKAGES}) +set(TARGET_INCLUDE_INSTALL_DIRS ${${TARGET_NAME}_INCLUDE_DIRS}) + +set_target_properties(${TARGET_NAME} PROPERTIES + VERSION ${FULL_VERSION} + SOVERSION ${SO_VERSION} + PUBLIC_HEADER "${${TARGET_NAME}_PUBLIC_HEADERS}" + PRIVATE_HEADER "${${TARGET_NAME}_PRIVATE_HEADERS}" +) + +################################################################ +# Create and export config packages for usage within this tree # +################################################################ + +# We configure our template. The template is described later. +configure_package_config_file( + ${CMAKE_CURRENT_LIST_DIR}/config.cmake.in + ${CMAKE_BINARY_DIR}/local-exports/${CMAKE_CONFIG_FILE_BASE_NAME}Config.cmake + INSTALL_DESTINATION ${CMAKE_BINARY_DIR} + PATH_VARS TARGET_INCLUDE_INSTALL_DIRS DEPENDENT_PACKAGES +) + +# This file is included in our template: +export(TARGETS ${TARGET_NAME} + FILE "${CMAKE_BINARY_DIR}/local-exports/${CMAKE_CONFIG_FILE_BASE_NAME}Targets.cmake" + NAMESPACE ${PROJECT_NAMESPACE}:: +) + +############################################## +# Create, export and install config packages # +############################################## + +set(TARGET_INCLUDE_INSTALL_DIRS ${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}) + +# Create config file +configure_package_config_file( + ${CMAKE_CURRENT_LIST_DIR}/config.cmake.in + ${CMAKE_BINARY_DIR}/${CMAKE_CONFIG_FILE_BASE_NAME}Config.cmake + INSTALL_DESTINATION ${CMAKE_BINARY_DIR} + PATH_VARS TARGET_INCLUDE_INSTALL_DIRS +) + +# Create a config version file +write_basic_package_version_file( + ${CMAKE_BINARY_DIR}/${CMAKE_CONFIG_FILE_BASE_NAME}ConfigVersion.cmake + VERSION ${FULL_VERSION} + COMPATIBILITY SameMajorVersion +) + +# Create import targets +install(TARGETS ${TARGET_NAME} EXPORT ${TARGET_NAME}Targets + RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/${BIN_INSTALL_DIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR} + PRIVATE_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/${INCLUDE_INSTALL_DIR}/private +) + +# Export the import targets +export(EXPORT ${TARGET_NAME}Targets + FILE "${CMAKE_BINARY_DIR}/${CMAKE_CONFIG_FILE_BASE_NAME}Targets.cmake" + NAMESPACE ${PROJECT_NAMESPACE}:: +) + +# Now install the 3 config files +install(FILES ${CMAKE_BINARY_DIR}/${CMAKE_CONFIG_FILE_BASE_NAME}Config.cmake + ${CMAKE_BINARY_DIR}/${CMAKE_CONFIG_FILE_BASE_NAME}ConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_DIR} +) + +install(EXPORT ${TARGET_NAME}Targets + FILE + ${CMAKE_CONFIG_FILE_BASE_NAME}Targets.cmake + NAMESPACE + ${PROJECT_NAMESPACE}:: + DESTINATION + ${CMAKE_INSTALL_DIR} +) + +# Create and install a global module include file +# This makes it possible to include all header files of the module by using +# #include <${PROJECT_NAME}> +set(GLOBAL_HEADER_FILE ${CMAKE_BINARY_DIR}/${PROJECT_NAME}) +file(WRITE ${GLOBAL_HEADER_FILE} "//Includes all headers of ${PROJECT_NAME}\n\n") + +foreach(header ${${TARGET_NAME}_PUBLIC_HEADERS}) + file(APPEND ${GLOBAL_HEADER_FILE} "#include \"${header}\"\n") +endforeach() + +install(FILES ${GLOBAL_HEADER_FILE} DESTINATION ${INCLUDE_INSTALL_DIR}) diff --git a/config.cmake.in b/config.cmake.in new file mode 100644 index 0000000..7d9ceba --- /dev/null +++ b/config.cmake.in @@ -0,0 +1,33 @@ +# - Config file for the @MODULE_NAME@ module +# To be used as: +# find_package(@PACKAGE_NAME@) +# target_link_libraries(@PROJECT_NAMESPACE@::@PROJECT_BASE_NAME@) +# This will automatically set the correct include directories and link libraries + +#For more information regarding config files see: +#https://cmake.org/cmake/help/v3.5/module/CMakePackageConfigHelpers.html + +@PACKAGE_INIT@ + +cmake_policy(SET CMP0024 OLD) +include("${CMAKE_CURRENT_LIST_DIR}/@CMAKE_CONFIG_FILE_BASE_NAME@Targets.cmake") + +# find_package will silently look for the dependencies and set the correct +# include directories and link libraries +foreach(PACKAGE @DEPENDENT_PACKAGES@) + find_package(${PACKAGE} QUIET) +endforeach() + +foreach(PACKAGE @DEPENDENT_PACKAGES@) + check_required_components(${PACKAGE}) +endforeach() + +# @PROJECT_NAME@ requires C++11 +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +include_directories(@TARGET_INCLUDE_INSTALL_DIRS@) + +if (@BUILD_SHARED_LIBS@) + add_definitions(-DBUILD_SHARED_LIBS) +endif() diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..2a2b0a6 --- /dev/null +++ b/readme.md @@ -0,0 +1,22 @@ +# Common cmake components + +This repository contains very generic cmake components which can be used across other cmake projects. + +# Including in your code. +The common cmake files need to be present when cmake is run. +There are various ways of achieving this. + +## Git submodule +You can fetch the files during your git clone using a submodule. +``` +git submodule add -b git@github.com:barco-healthcare/cmake-common.git path/to/cmake/common +``` + +# Usage + +You can include these files in your CMakeLists.txt +``` +# Include common cmake modules +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/path/to/cmake/common) +include(CommonConfig) +```