2016-04-16 00:50:16 +02:00
# before including this module, the project meta-data must be set
2017-02-11 02:30:46 +01:00
if ( NOT META_PROJECT_NAME )
message ( FATAL_ERROR "No project name (META_PROJECT_NAME) specified." )
endif ( )
if ( NOT META_APP_NAME )
message ( FATAL_ERROR "No project name (META_APP_NAME) specified." )
endif ( )
if ( NOT META_APP_AUTHOR )
message ( FATAL_ERROR "No project name (META_APP_AUTHOR) specified." )
endif ( )
if ( NOT META_APP_DESCRIPTION )
message ( FATAL_ERROR "No project name (META_APP_DESCRIPTION) specified." )
endif ( )
2016-04-16 00:50:16 +02:00
# set project name (displayed in Qt Creator)
2016-11-04 10:41:16 +01:00
message ( STATUS "Configuring project ${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}" )
2016-04-16 00:50:16 +02:00
project ( ${ META_PROJECT_NAME } )
2016-09-29 20:28:02 +02:00
# set META_PROJECT_VARNAME and META_PROJECT_VARNAME_UPPER if not specified explicitely
if ( NOT META_PROJECT_VARNAME )
2016-11-04 14:02:23 +01:00
set ( META_PROJECT_VARNAME "${META_PROJECT_NAME}" )
2016-09-29 20:28:02 +02:00
endif ( )
if ( NOT META_PROJECT_VARNAME_UPPER )
string ( TOUPPER ${ META_PROJECT_VARNAME } META_PROJECT_VARNAME_UPPER )
endif ( )
2017-02-11 02:30:46 +01:00
if ( NOT META_PROJECT_VARNAME_LOWER )
string ( REGEX REPLACE "_+" "" META_PROJECT_VARNAME_LOWER "${META_PROJECT_VARNAME}" )
string ( TOLOWER "${META_PROJECT_VARNAME_LOWER}" META_PROJECT_VARNAME_LOWER )
endif ( )
2016-09-29 20:28:02 +02:00
2016-11-04 14:02:23 +01:00
# set META_GENERIC_NAME to META_APP_NAME if not specified explicitely
if ( NOT META_GENERIC_NAME )
set ( META_GENERIC_NAME "${META_APP_NAME}" )
endif ( )
2017-02-05 19:19:15 +01:00
# set default CXX_STANDARD for all library, application and test targets
2017-02-04 17:44:46 +01:00
if ( NOT META_CXX_STANDARD )
2017-02-05 19:19:15 +01:00
set ( META_CXX_STANDARD 14 )
2017-02-04 17:44:46 +01:00
endif ( )
2017-02-11 02:30:46 +01:00
# set version to 0.0.0 if not specified explicitely
if ( NOT META_VERSION_MAJOR )
set ( META_VERSION_MAJOR 0 )
endif ( )
if ( NOT META_VERSION_MINOR )
set ( META_VERSION_MINOR 0 )
endif ( )
if ( NOT META_VERSION_PATCH )
set ( META_VERSION_PATCH 0 )
endif ( )
2016-04-16 18:32:22 +02:00
# provide variables for other projects built as part of the same subdirs project
# to access files from this project
get_directory_property ( HAS_PARENT PARENT_DIRECTORY )
if ( HAS_PARENT )
2016-09-29 20:28:02 +02:00
set ( ${ META_PROJECT_VARNAME_UPPER } _SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" PARENT_SCOPE )
set ( ${ META_PROJECT_VARNAME_UPPER } _BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE )
2016-04-16 18:32:22 +02:00
set ( ${ META_PROJECT_NAME } _DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE )
2016-07-16 23:04:22 +02:00
if ( CMAKE_FIND_ROOT_PATH AND MINGW )
set ( RUNTIME_LIBRARY_PATH "${CMAKE_CURRENT_BINARY_DIR}" ${ RUNTIME_LIBRARY_PATH } PARENT_SCOPE )
endif ( )
2016-04-16 18:32:22 +02:00
endif ( )
2016-04-16 00:50:16 +02:00
2017-04-15 01:39:04 +02:00
# determine version
set ( META_APP_VERSION ${ META_VERSION_MAJOR } . ${ META_VERSION_MINOR } . ${ META_VERSION_PATCH } )
option ( APPEND_GIT_REVISION "whether the build script should attempt to append the git revision and latest commit to the version displayed via --help" ON )
if ( APPEND_GIT_REVISION )
execute_process (
C O M M A N D g i t r e v - l i s t - - c o u n t H E A D
W O R K I N G _ D I R E C T O R Y " $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } "
O U T P U T _ V A R I A B L E M E T A _ G I T _ R E V _ C O U N T
)
execute_process (
C O M M A N D g i t r e v - p a r s e - - s h o r t H E A D
W O R K I N G _ D I R E C T O R Y " $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } "
O U T P U T _ V A R I A B L E M E T A _ G I T _ L A S T _ C O M M I T _ I D
)
string ( REPLACE "\n" "" META_GIT_REV_COUNT "${META_GIT_REV_COUNT}" )
string ( REPLACE "\n" "" META_GIT_LAST_COMMIT_ID "${META_GIT_LAST_COMMIT_ID}" )
if ( META_GIT_REV_COUNT AND META_GIT_LAST_COMMIT_ID )
set ( META_APP_VERSION ${ META_APP_VERSION } - ${ META_GIT_REV_COUNT } . ${ META_GIT_LAST_COMMIT_ID } )
endif ( )
endif ( )
2016-04-16 00:50:16 +02:00
# stringify the meta data
set ( META_PROJECT_NAME_STR "\" ${ META_PROJECT_NAME } \"")
set ( META_APP_NAME_STR "\" ${ META_APP_NAME } \"")
set ( META_APP_AUTHOR_STR "\" ${ META_APP_AUTHOR } \"")
set ( META_APP_URL_STR "\" ${ META_APP_URL } \"")
set ( META_APP_DESCRIPTION_STR "\" ${ META_APP_DESCRIPTION } \"")
set ( META_APP_VERSION_STR "\" ${ META_APP_VERSION } \"")
2016-07-02 02:04:32 +02:00
# set TARGET_EXECUTABLE which is used to refer to the target executable at its installation location
set ( TARGET_EXECUTABLE "${CMAKE_INSTALL_PREFIX}/bin/${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}" )
2016-04-16 00:50:16 +02:00
# disable new ABI (can't catch ios_base::failure with new ABI)
2016-07-10 00:16:24 +02:00
option ( FORCE_OLD_ABI "specifies whether usage of old ABI should be forced" OFF )
if ( FORCE_OLD_ABI )
2016-11-10 23:24:09 +01:00
list ( APPEND META_PRIVATE_COMPILE_DEFINITIONS _GLIBCXX_USE_CXX11_ABI=0 )
2016-06-14 22:53:19 +02:00
message ( STATUS "Forcing usage of old CXX11 ABI." )
2016-07-16 23:04:22 +02:00
else ( )
message ( STATUS "Using default CXX11 ABI (not forcing old CX11 ABI)." )
2016-06-14 22:53:19 +02:00
endif ( )
2016-04-16 00:50:16 +02:00
# enable debug-only code when doing a debug build
if ( CMAKE_BUILD_TYPE STREQUAL "Debug" )
2016-11-10 23:24:09 +01:00
list ( APPEND META_PRIVATE_COMPILE_DEFINITIONS DEBUG_BUILD )
2016-04-16 00:50:16 +02:00
message ( STATUS "Debug build enabled." )
endif ( )
2016-07-03 22:13:04 +02:00
# enable logging when option is set
2016-07-10 00:16:24 +02:00
option ( LOGGING_ENABLED "specifies whether logging is enabled" OFF )
if ( LOGGING_ENABLED )
2016-11-10 23:24:09 +01:00
list ( APPEND META_PRIVATE_COMPILE_DEFINITIONS LOGGING_ENABLED )
2016-07-10 00:16:24 +02:00
message ( STATUS "Logging is enabled." )
2016-07-03 22:13:04 +02:00
endif ( )
2016-07-22 01:35:32 +02:00
2016-08-19 16:13:41 +02:00
# options for deciding whether to build static and/or shared libraries
2017-02-20 20:03:16 +01:00
if ( ( "${META_PROJECT_TYPE}" STREQUAL "library" ) OR ( "${META_PROJECT_TYPE}" STREQUAL "plugin" ) OR ( "${META_PROJECT_TYPE}" STREQUAL "qtplugin" ) OR ( "${META_PROJECT_TYPE}" STREQUAL "" ) )
2016-09-11 23:10:29 +02:00
option ( ENABLE_STATIC_LIBS "whether building static libraries is enabled (disabled by default)" OFF )
2016-09-06 22:51:00 +02:00
option ( DISABLE_SHARED_LIBS "whether building dynamic libraries is disabled (enabled by default)" OFF )
2016-08-29 15:35:48 +02:00
if ( DISABLE_SHARED_LIBS )
set ( BUILD_SHARED_LIBS OFF )
else ( )
2016-09-06 22:51:00 +02:00
set ( BUILD_SHARED_LIBS ON )
endif ( )
if ( ENABLE_STATIC_LIBS )
set ( BUILD_STATIC_LIBS ON )
else ( )
set ( BUILD_STATIC_LIBS OFF )
2016-08-29 15:35:48 +02:00
endif ( )
2016-08-19 16:13:41 +02:00
endif ( )
2016-07-22 01:35:32 +02:00
# options for forcing static linkage when building applications or dynamic libraries
2017-02-20 20:03:16 +01:00
if ( ( "${META_PROJECT_TYPE}" STREQUAL "library" ) OR ( "${META_PROJECT_TYPE}" STREQUAL "plugin" ) OR ( "${META_PROJECT_TYPE}" STREQUAL "qtplugin" ) OR ( "${META_PROJECT_TYPE}" STREQUAL "" ) )
2016-08-19 16:13:41 +02:00
option ( STATIC_LIBRARY_LINKAGE "forces static linkage when building dynamic libraries" OFF )
elseif ( "${META_PROJECT_TYPE}" STREQUAL "application" )
option ( STATIC_LINKAGE "forces static linkage when building applications" OFF )
endif ( )
# additional linker flags used when static linkage is enables
2017-08-05 18:38:02 +02:00
if ( NOT APPLE )
list ( APPEND META_ADDITIONAL_STATIC_LINK_FLAGS -static )
endif ( )
list ( APPEND META_ADDITIONAL_STATIC_LINK_FLAGS -static-libstdc++ -static-libgcc )
2016-08-14 16:49:40 +02:00
# options for enabling/disabling Qt GUI (if available)
if ( WIDGETS_HEADER_FILES OR WIDGETS_SRC_FILES OR WIDGETS_UI_FILES )
if ( META_GUI_OPTIONAL )
option ( WIDGETS_GUI "enables/disables building the Qt Widgets GUI: yes (default) or no" ON )
else ( )
set ( WIDGETS_GUI ON )
endif ( )
else ( )
set ( WIDGETS_GUI OFF )
endif ( )
if ( QML_HEADER_FILES OR QML_SRC_FILES )
if ( META_GUI_OPTIONAL )
option ( QUICK_GUI "enables/disables building the Qt Quick GUI: yes (default) or no" ON )
else ( )
set ( QUICK_GUI ON )
endif ( )
else ( )
set ( QUICK_GUI OFF )
endif ( )
2017-02-11 02:30:46 +01:00
2017-04-03 23:27:39 +02:00
# find coding style (use style from c++utilities if none included in own project dir)
2017-05-01 03:03:20 +02:00
if ( NOT META_NO_TIDY )
set ( CLANG_FORMAT_RULES "${CMAKE_CURRENT_SOURCE_DIR}/coding-style.clang-format" )
if ( CPP_UTILITIES_SOURCE_DIR AND NOT EXISTS "${CLANG_FORMAT_RULES}" )
set ( CLANG_FORMAT_RULES "${CPP_UTILITIES_SOURCE_DIR}/coding-style.clang-format" )
endif ( )
if ( NOT EXISTS "${CLANG_FORMAT_RULES}" )
set ( CLANG_FORMAT_RULES "${CPP_UTILITIES_CONFIG_DIRS}/codingstyle.clang-format" )
endif ( )
2017-04-03 23:27:39 +02:00
endif ( )
2017-04-04 20:13:13 +02:00
# enable testing
enable_testing ( )
get_directory_property ( HAS_PARENT PARENT_DIRECTORY )
if ( HAS_PARENT )
message ( STATUS "For the check target to work, it is required to call enable_testing() on the source directory root." )
endif ( )
2017-04-03 23:27:39 +02:00
# add target for tidying with clang-format
2017-05-01 03:03:20 +02:00
if ( NOT META_NO_TIDY AND EXISTS "${CLANG_FORMAT_RULES}" )
2017-06-20 23:38:45 +02:00
option ( CLANG_FORMAT_ENABLED "enables creation of tidy target using clang-format" OFF )
if ( CLANG_FORMAT_ENABLED )
find_program ( CLANG_FORMAT_BIN clang-format )
if ( CLANG_FORMAT_BIN )
set ( FORMATABLE_FILES
$ { H E A D E R _ F I L E S } $ { S R C _ F I L E S }
$ { T E S T _ H E A D E R _ F I L E S } $ { T E S T _ S R C _ F I L E S }
$ { W I D G E T S _ H E A D E R _ F I L E S } $ { W I D G E T S _ S R C _ F I L E S }
$ { Q M L _ H E A D E R _ F I L E S } $ { Q M L _ S R C _ F I L E S }
2017-06-01 18:24:14 +02:00
)
2017-06-20 23:38:45 +02:00
if ( FORMATABLE_FILES )
2017-09-09 21:35:55 +02:00
# only tidy C/C++ files (and not eg. QML files)
list ( FILTER FORMATABLE_FILES INCLUDE REGEX ".*\\.(cpp|h)" )
2017-06-20 23:38:45 +02:00
add_custom_command (
O U T P U T " $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / . c l a n g - f o r m a t "
C O M M A N D " $ { C M A K E _ C O M M A N D } " - E c r e a t e _ s y m l i n k " $ { C L A N G _ F O R M A T _ R U L E S } " " $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / . c l a n g - f o r m a t "
C O M M E N T " L i n k i n g c o d i n g s t y l e f r o m $ { C L A N G _ F O R M A T _ R U L E S } "
)
add_custom_target ( "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy"
C O M M A N D " $ { C L A N G _ F O R M A T _ B I N } " - s t y l e = f i l e - i $ { F O R M A T A B L E _ F I L E S }
W O R K I N G _ D I R E C T O R Y " $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } "
C O M M E N T " T i d y i n g $ { M E T A _ P R O J E C T _ N A M E } s o u r c e s u s i n g c l a n g - f o r m a t "
2017-10-24 01:01:29 +02:00
D E P E N D S " $ { F O R M A T A B L E _ F I L E S } ; $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / . c l a n g - f o r m a t "
2017-06-20 23:38:45 +02:00
)
if ( NOT TARGET tidy )
add_custom_target ( tidy )
endif ( )
add_dependencies ( tidy "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy" )
# also add a test to verify whether sources are tidy
add_test ( NAME "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy_test"
C O M M A N D " $ { C L A N G _ F O R M A T _ B I N } " - o u t p u t - r e p l a c e m e n t s - x m l - s t y l e = f i l e $ { F O R M A T A B L E _ F I L E S }
W O R K I N G _ D I R E C T O R Y " $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } "
)
list ( APPEND CHECK_TARGET_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/.clang-format" )
set_tests_properties ( "${TARGET_PREFIX}${META_PROJECT_NAME}${TARGET_SUFFIX}_tidy_test" PROPERTIES
F A I L _ R E G U L A R _ E X P R E S S I O N " < r e p l a c e m e n t . * > . * < / r e p l a c e m e n t > "
R E Q U I R E D _ F I L E S " $ { C M A K E _ C U R R E N T _ S O U R C E _ D I R } / . c l a n g - f o r m a t "
)
2017-04-04 21:00:24 +02:00
endif ( )
2017-06-20 23:38:45 +02:00
else ( )
message ( FATAL_ERROR "Unable to add tidy target; clang-format not found" )
2017-04-03 23:27:39 +02:00
endif ( )
endif ( )
endif ( )
2017-06-01 18:24:14 +02:00
# add autotools-style check target
if ( NOT TARGET check )
set ( CMAKE_CTEST_COMMAND ${ CMAKE_CTEST_COMMAND } -V )
add_custom_target ( check
C O M M A N D $ { C M A K E _ C T E S T _ C O M M A N D }
W O R K I N G _ D I R E C T O R Y $ { C M A K E _ B I N A R Y _ D I R }
D E P E N D S " $ { C H E C K _ T A R G E T _ D E P E N D S } "
)
endif ( )
2017-06-18 16:17:44 +02:00
# enable source code based coverage analysis using clang
2017-06-20 23:38:45 +02:00
option ( CLANG_SOURCE_BASED_COVERAGE_ENABLED "enables creation of coverage targets for source-based coverage with clang" OFF )
if ( CLANG_SOURCE_BASED_COVERAGE_ENABLED )
2017-07-28 17:34:28 +02:00
if ( NOT CMAKE_HOST_UNIX OR NOT "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" )
2017-06-20 23:38:45 +02:00
message ( FATAL_ERROR "Source-based coverage only available under UNIX with Clang" )
endif ( )
2017-07-28 17:34:28 +02:00
if ( NOT META_PROJECT_TYPE STREQUAL "application" AND DISABLE_SHARED_LIBS )
message ( FATAL_ERROR "Source-based coverage not available when only building static libs" )
endif ( )
set ( CLANG_SOURCE_BASED_COVERAGE_AVAILABLE YES )
set ( CLANG_SOURCE_BASED_COVERAGE_FLAGS -fprofile-instr-generate -fcoverage-mapping )
list ( APPEND META_PRIVATE_SHARED_LIB_COMPILE_OPTIONS ${ CLANG_SOURCE_BASED_COVERAGE_FLAGS } )
list ( APPEND META_PRIVATE_STATIC_LIB_COMPILE_OPTIONS ${ CLANG_SOURCE_BASED_COVERAGE_FLAGS } )
list ( APPEND META_ADDITIONAL_SHARED_LINK_FLAGS ${ CLANG_SOURCE_BASED_COVERAGE_FLAGS } )
list ( APPEND META_ADDITIONAL_STATIC_LINK_FLAGS ${ CLANG_SOURCE_BASED_COVERAGE_FLAGS } )
2017-06-18 16:17:44 +02:00
endif ( )
2017-07-20 01:43:10 +02:00
# configure creation of install targets
if ( NOT META_NO_INSTALL_TARGETS )
# install targets have not been disabled on project level
# check whether install targets are disabled by the user
# this might be useful since install targets seem to cause problems under MacOS
option ( ENABLE_INSTALL_TARGETS "enables creation of install targets" ON )
endif ( )
2017-07-11 19:34:38 +02:00
# add install target for extra files
2017-07-20 01:43:10 +02:00
if ( NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS )
foreach ( EXTRA_FILE ${ EXTRA_FILES } )
get_filename_component ( EXTRA_DIR ${ EXTRA_FILE } DIRECTORY )
install (
F I L E S $ { E X T R A _ F I L E }
D E S T I N A T I O N " s h a r e / $ { M E T A _ P R O J E C T _ N A M E } / $ { E X T R A _ D I R } "
C O M P O N E N T e x t r a - f i l e s
)
endforeach ( )
if ( NOT TARGET install-extra-files )
add_custom_target ( install-extra-files
C O M M A N D " $ { C M A K E _ C O M M A N D } " - D C M A K E _ I N S T A L L _ C O M P O N E N T = e x t r a - f i l e s - P " $ { C M A K E _ B I N A R Y _ D I R } / c m a k e _ i n s t a l l . c m a k e "
)
endif ( )
2017-07-11 19:34:38 +02:00
endif ( )
2017-11-12 17:00:07 +01:00
# add a file called "srcdirref" to the build directory; this file contains the path of the sources so tests can easily find test files contained in the source directory
# note: This is also useful when using the TestApplication class in the regular target, so this is created in BasicConfig.cmake (rather than only TestTarget.cmake)
file ( WRITE "${CMAKE_CURRENT_BINARY_DIR}/srcdirref" "${CMAKE_CURRENT_SOURCE_DIR}" )
2017-02-11 02:30:46 +01:00
set ( BASIC_PROJECT_CONFIG_DONE YES )