mirror of
https://github.com/barkeser2002/flower.git
synced 2026-09-25 21:36:21 +03:00
600 lines
27 KiB
CMake
600 lines
27 KiB
CMake
####################################################################################
|
|
# #
|
|
# Copyright (c) 2014 - 2018 Axel Menzel <info@rttr.org> #
|
|
# #
|
|
# This file is part of RTTR (Run Time Type Reflection) #
|
|
# License: MIT License #
|
|
# #
|
|
# Permission is hereby granted, free of charge, to any person obtaining #
|
|
# a copy of this software and associated documentation files (the "Software"), #
|
|
# to deal in the Software without restriction, including without limitation #
|
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense, #
|
|
# and/or sell copies of the Software, and to permit persons to whom the #
|
|
# Software is furnished to do so, subject to the following conditions: #
|
|
# #
|
|
# The above copyright notice and this permission notice shall be included in #
|
|
# all copies or substantial portions of the Software. #
|
|
# #
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, #
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
|
|
# SOFTWARE. #
|
|
# #
|
|
####################################################################################
|
|
|
|
####################################################################################
|
|
# Welcome to the CMake build system for RTTR.
|
|
# This file contains several helper function to make the life easier with cmake.
|
|
####################################################################################
|
|
|
|
####################################################################################
|
|
# create hierarchical source groups, useful for big VS-Projects
|
|
# FILE_LIST <= a list of files with absolute path
|
|
####################################################################################
|
|
function (createSrcGroups FILE_LIST )
|
|
# we want to get the relative path from the
|
|
# current source dir
|
|
string(LENGTH ${CMAKE_CURRENT_SOURCE_DIR} curDirLen)
|
|
set(TMP_FILE_LIST ${${FILE_LIST}})
|
|
|
|
foreach ( SOURCE ${TMP_FILE_LIST} )
|
|
string(LENGTH ${SOURCE} fullPathLen)
|
|
math(EXPR RelPathLen ${fullPathLen}-${curDirLen})
|
|
string(SUBSTRING ${SOURCE} ${curDirLen} ${RelPathLen} curStr)
|
|
|
|
string ( REGEX REPLACE "[\\/]" "\\\\" normPath ${curStr} )
|
|
string ( REGEX MATCH "\\\\(.*)\\\\" ouput ${normPath} )
|
|
if(NOT CMAKE_MATCH_1 STREQUAL "")
|
|
source_group ( ${CMAKE_MATCH_1} FILES ${SOURCE} )
|
|
endif()
|
|
endforeach()
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Create a UnityFile. This is a file which inlcudes all other source files.
|
|
# This is usefull, when you want a fast rebuild.
|
|
# _UNITY_FILE <= The name of the UnityFile
|
|
# _SRC_FILES <= The list of source files
|
|
####################################################################################
|
|
function(generateUnityFile _UNITY_FILE _SRC_FILES)
|
|
set(files ${${_SRC_FILES}})
|
|
# Generate a unique filename for the unity build translation unit
|
|
set(unit_build_file ${CMAKE_CURRENT_BINARY_DIR}/ub_${_UNITY_FILE}.cpp)
|
|
set_source_files_properties(${files} PROPERTIES HEADER_FILE_ONLY true)
|
|
# Open the ub file
|
|
FILE(WRITE ${unit_build_file} "// Unity Build generated by CMake\n")
|
|
# Add include statement for each translation unit
|
|
foreach(sourceFile ${files} )
|
|
#FILE( APPEND ${unit_build_file} "#include <${CMAKE_CURRENT_SOURCE_DIR}/${sourceFile}>\n")
|
|
FILE( APPEND ${unit_build_file} "#include \"${sourceFile}\"\n")
|
|
endforeach()
|
|
# Complement list of translation units with the name of ub
|
|
set(${_UNITY_FILE} ${unit_build_file} PARENT_SCOPE)
|
|
source_group("Generated Files" FILES ${unit_build_file})
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Returns the name of the Directory, where the file in the FILE_PATH is located.
|
|
####################################################################################
|
|
function(getNameOfDir FILE_PATH DIR_NAME)
|
|
get_filename_component(HAS_FILE_IN_PATH ${${FILE_PATH}} EXT)
|
|
if (HAS_FILE_IN_PATH)
|
|
get_filename_component(PATH_WITHOUT_FILENAME ${${FILE_PATH}} PATH)
|
|
get_filename_component(NAME_OF_DIR ${PATH_WITHOUT_FILENAME} NAME)
|
|
set(${DIR_NAME} ${NAME_OF_DIR} PARENT_SCOPE)
|
|
else()
|
|
get_filename_component(NAME_OF_DIR ${${FILE_PATH}} NAME)
|
|
set(${DIR_NAME} ${NAME_OF_DIR} PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Returns relative path from the given file path; starting from CMAKE_CURRENT_SOURCE_DIR
|
|
####################################################################################
|
|
|
|
function(getRelativePath FILE_PATH RELATIVE_PATH)
|
|
string(LENGTH ${CMAKE_CURRENT_SOURCE_DIR} CUR_DIR_LEN)
|
|
get_filename_component(PATH_WITHOUT_FILE ${${FILE_PATH}} PATH)
|
|
string(LENGTH ${PATH_WITHOUT_FILE} FULL_PATH_LEN)
|
|
math(EXPR REL_PATH_LEN ${FULL_PATH_LEN}-${CUR_DIR_LEN})
|
|
math(EXPR REL_PATH_START "${CUR_DIR_LEN}")
|
|
string(SUBSTRING ${PATH_WITHOUT_FILE} ${REL_PATH_START} ${REL_PATH_LEN} REL_PATH)
|
|
string(REGEX REPLACE "^/" "" out_path "${REL_PATH}")
|
|
set(${RELATIVE_PATH} ${out_path} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Loads a FOLDER, which should contain a FOLDER.cmake.
|
|
# In this file all source and header files should be declared.
|
|
# In this cmake files all files have to be declared relative.
|
|
# They will be read with absolut path.
|
|
# FOLDER <= The name of the folder
|
|
# _HEADER_FILES => The list of header files
|
|
# _SOURCE_FILES => The list of source files
|
|
# [OPTIONAL] 3rdArg => performs the installation of the header and source files
|
|
####################################################################################
|
|
function(loadFolder FOLDER _HEADER_FILES _SOURCE_FILES)
|
|
set(FULL_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${FOLDER}.cmake)
|
|
include(${FULL_PATH})
|
|
get_filename_component(ABS_PATH_TO_FILES ${FULL_PATH} PATH)
|
|
set(shouldInstall ${ARGV3})
|
|
set(QT_MOC_HEADERS)
|
|
set(QT_UI_FILES)
|
|
set(QT_QRC_FILES)
|
|
|
|
foreach(headerFile ${HEADER_FILES} )
|
|
if (${headerFile} MATCHES ".*.h.in$")
|
|
string ( REGEX REPLACE ".h.in$" ".h" out_path ${headerFile} )
|
|
configure_file(${headerFile} ${CMAKE_CURRENT_BINARY_DIR}/${out_path} @ONLY)
|
|
set(FULL_HEADER_PATH ${ABS_PATH_TO_FILES}/${headerFile})
|
|
getRelativePath(FULL_HEADER_PATH REL_PATH)
|
|
set(FULL_HEADER_PATH ${CMAKE_CURRENT_BINARY_DIR}/${out_path})
|
|
if (REL_PATH)
|
|
string ( REGEX REPLACE "[\\/]" "\\\\" normalized_path ${REL_PATH} )
|
|
source_group ( ${normalized_path} FILES ${FULL_HEADER_PATH} )
|
|
endif()
|
|
list(APPEND ALL_HPP_FILES ${FULL_HEADER_PATH})
|
|
elseif (${headerFile} MATCHES ".*.rc.in$")
|
|
string ( REGEX REPLACE ".rc.in$" ".rc" out_path ${headerFile} )
|
|
configure_file(${headerFile} ${CMAKE_CURRENT_BINARY_DIR}/${out_path} @ONLY)
|
|
source_group("Generated Files" FILES ${CMAKE_CURRENT_BINARY_DIR}/${out_path})
|
|
list(APPEND ALL_HPP_FILES ${CMAKE_CURRENT_BINARY_DIR}/${out_path})
|
|
elseif (${headerFile} MATCHES ".*.ui$")
|
|
set(FULL_HEADER_PATH ${ABS_PATH_TO_FILES}/${headerFile})
|
|
list(APPEND QT_UI_FILES ${FULL_HEADER_PATH})
|
|
list(APPEND ALL_HPP_FILES ${FULL_HEADER_PATH})
|
|
elseif (${headerFile} MATCHES ".*.qrc$")
|
|
set(FULL_HEADER_PATH ${ABS_PATH_TO_FILES}/${headerFile})
|
|
list(APPEND QT_QRC_FILES ${FULL_HEADER_PATH})
|
|
list(APPEND ALL_HPP_FILES ${FULL_HEADER_PATH})
|
|
else()
|
|
set(FULL_HEADER_PATH ${ABS_PATH_TO_FILES}/${headerFile})
|
|
file(STRINGS ${FULL_HEADER_PATH} var REGEX "Q_OBJECT")
|
|
if(var)
|
|
list(APPEND QT_MOC_HEADERS ${FULL_HEADER_PATH})
|
|
endif()
|
|
|
|
# returns the relative path, from the current source dir
|
|
getRelativePath(FULL_HEADER_PATH REL_PATH)
|
|
list(APPEND HEADER_LIST_OF_CUR_DIR ${FULL_HEADER_PATH})
|
|
endif()
|
|
# get the name of the current directory
|
|
getNameOfDir(CMAKE_CURRENT_SOURCE_DIR DIRNAME)
|
|
if (${shouldInstall})
|
|
if (NOT ${FULL_HEADER_PATH} MATCHES ".*_p.h$") # we don't want to install header files which are marked as private
|
|
install(FILES ${FULL_HEADER_PATH} DESTINATION "include/${DIRNAME}/${REL_PATH}" PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
|
|
# and now the source files
|
|
list(APPEND QML_SOURCES)
|
|
foreach(srcFile ${SOURCE_FILES} )
|
|
# the source_group placement doesn't work at the moment
|
|
if (${srcFile} MATCHES ".*.qml$")
|
|
string(REGEX REPLACE "[\\/]" "_" qrc_resource_file ${srcFile} )
|
|
string(REGEX REPLACE ".qml$" ".qrc" qrc_resource_file ${qrc_resource_file} )
|
|
set(qrc_resource_file ${CMAKE_CURRENT_BINARY_DIR}/${qrc_resource_file})
|
|
file(WRITE ${qrc_resource_file} "<!DOCTYPE RCC><RCC version=\"1.0\"><qresource prefix=\"/\"><file alias=\"${srcFile}\">${ABS_PATH_TO_FILES}/${srcFile}</file></qresource></RCC>")
|
|
qt5_add_resources(compiled_resource_file ${qrc_resource_file})
|
|
source_group("Generated Files" FILES ${compiled_resource_file})
|
|
source_group("Generated Files" FILES ${qrc_resource_file})
|
|
list(APPEND QML_SOURCES ${compiled_resource_file})
|
|
elseif (${srcFile} MATCHES ".*.ui$")
|
|
set(FULL_SRC_PATH ${ABS_PATH_TO_FILES}/${srcFile})
|
|
list(APPEND QT_UI_FILES ${FULL_SRC_PATH})
|
|
list(APPEND SOURCE_LIST_OF_CUR_DIR ${FULL_SRC_PATH})
|
|
elseif (${srcFile} MATCHES ".*.qrc$")
|
|
set(FULL_SRC_PATH ${ABS_PATH_TO_FILES}/${srcFile})
|
|
list(APPEND QT_QRC_FILES ${FULL_SRC_PATH})
|
|
list(APPEND SOURCE_LIST_OF_CUR_DIR ${FULL_SRC_PATH})
|
|
else()
|
|
list(APPEND SOURCE_LIST_OF_CUR_DIR ${ABS_PATH_TO_FILES}/${srcFile})
|
|
endif()
|
|
|
|
list(APPEND SOURCE_LIST_OF_CUR_DIR ${ABS_PATH_TO_FILES}/${srcFile})
|
|
endforeach()
|
|
|
|
list(APPEND QT_MOC_SOURCES)
|
|
|
|
if (QT_MOC_HEADERS)
|
|
qt5_wrap_cpp(QT_MOC_SOURCES ${QT_MOC_HEADERS})
|
|
source_group("Generated Files" FILES ${QT_MOC_SOURCES})
|
|
endif()
|
|
|
|
list(APPEND QT_UI_SOURCES)
|
|
if (QT_UI_FILES)
|
|
qt5_wrap_ui(QT_UI_SOURCES ${QT_UI_FILES})
|
|
source_group("Generated Files" FILES ${QT_UI_SOURCES})
|
|
endif()
|
|
|
|
list(APPEND QT_QRC_SOURCES)
|
|
if (QT_QRC_FILES)
|
|
qt5_add_resources(QT_QRC_SOURCES ${QT_QRC_FILES})
|
|
source_group("Generated Files" FILES ${QT_QRC_SOURCES})
|
|
endif()
|
|
|
|
list(APPEND ALL_HPP_FILES ${${_HEADER_FILES}} ${HEADER_LIST_OF_CUR_DIR})
|
|
list(APPEND ALL_CPP_FILES ${${_SOURCE_FILES}} ${SOURCE_LIST_OF_CUR_DIR} ${QT_MOC_SOURCES} ${QT_UI_SOURCES} ${QT_QRC_SOURCES} ${QML_SOURCES})
|
|
set(${_HEADER_FILES} ${ALL_HPP_FILES} PARENT_SCOPE)
|
|
set(${_SOURCE_FILES} ${ALL_CPP_FILES} PARENT_SCOPE)
|
|
|
|
createSrcGroups(HEADER_LIST_OF_CUR_DIR)
|
|
createSrcGroups(SOURCE_LIST_OF_CUR_DIR)
|
|
message( STATUS "${FOLDER} directory included" )
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# This function checks if the current generator is used for a Viusal Studio build
|
|
# _INPUT This variable will be set to TRUE if its a Visual Studio build, otherwise to FALSE.
|
|
####################################################################################
|
|
function (is_vs_based_build _INPUT)
|
|
if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
|
|
set(${_INPUT} TRUE PARENT_SCOPE)
|
|
else()
|
|
set(${_INPUT} FALSE PARENT_SCOPE)
|
|
endif()
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Copy a release dependency in the correct CMAKE_RUNTIME_OUTPUT_DIRECTORY
|
|
# _INPUT The full path of the dependency incl. FileName
|
|
# _OUTPUT The directory where the libraries should be installed.
|
|
# OPTIONAL: RELATIVE Path - as third argument an optional relative path can be specified
|
|
####################################################################################
|
|
|
|
function(copy_dependency_release _INPUT _OUTPUT)
|
|
is_vs_based_build(VS_BUILD)
|
|
|
|
# when this is a DEBUG build we dont copy the files
|
|
if(NOT VS_BUILD)
|
|
if(${CMAKE_BUILD_TYPE} STREQUAL Debug)
|
|
return()
|
|
endif()
|
|
endif()
|
|
# as third argument an optional relative path can be specified
|
|
set(REL_PATH ${ARGV2})
|
|
set(_PATH ${_INPUT})
|
|
# make the path to normal path with / as dir separator
|
|
string ( REGEX REPLACE "[\\/]" "/" FILE_PATH ${_PATH} )
|
|
get_filename_component(FILE_NAME ${FILE_PATH} NAME)
|
|
|
|
if (VS_BUILD)
|
|
if (IS_DIRECTORY ${_INPUT})
|
|
file(COPY ${_INPUT} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/${REL_PATH})
|
|
else()
|
|
configure_file(${FILE_PATH} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release/${REL_PATH}/${FILE_NAME} COPYONLY)
|
|
configure_file(${FILE_PATH} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/RelWithDebInfo/${REL_PATH}/${FILE_NAME} COPYONLY)
|
|
configure_file(${FILE_PATH} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/MinSizeRel/${REL_PATH}/${FILE_NAME} COPYONLY)
|
|
endif()
|
|
else()
|
|
if (IS_DIRECTORY ${_INPUT})
|
|
file(COPY ${_INPUT} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${REL_PATH})
|
|
else()
|
|
configure_file(${FILE_PATH} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${REL_PATH}/${FILE_NAME} COPYONLY)
|
|
endif()
|
|
endif()
|
|
|
|
if (IS_DIRECTORY ${_INPUT})
|
|
install(DIRECTORY
|
|
${FILE_PATH}
|
|
DESTINATION ${_OUTPUT}/${REL_PATH}
|
|
CONFIGURATIONS Release)
|
|
else()
|
|
install(FILES
|
|
${FILE_PATH}
|
|
DESTINATION ${_OUTPUT}/${REL_PATH}
|
|
CONFIGURATIONS Release)
|
|
endif()
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Copy a debug dependency in the correct CMAKE_RUNTIME_OUTPUT_DIRECTORY
|
|
# _INPUT The full path of the dependency incl. FileName
|
|
# _OUTPUT The directory where the libraries should be installed.
|
|
# OPTIONAL: RELATIVE Path - as third argument an optional relative path can be specified
|
|
####################################################################################
|
|
|
|
function(copy_dependency_debug _INPUT _OUTPUT)
|
|
is_vs_based_build(VS_BUILD)
|
|
|
|
# when this is NOT a DEBUG build we dont copy the files
|
|
if(NOT VS_BUILD)
|
|
if(NOT ${CMAKE_BUILD_TYPE} STREQUAL Debug)
|
|
return()
|
|
endif()
|
|
endif()
|
|
# as third argument an optional relative path can be specified
|
|
set(REL_PATH ${ARGV2})
|
|
set(_PATH ${_INPUT})
|
|
# make the path to normal path with / as dir separator
|
|
string ( REGEX REPLACE "[\\/]" "////" FILE_PATH ${_PATH} )
|
|
get_filename_component(FILE_NAME ${FILE_PATH} NAME)
|
|
|
|
if (VS_BUILD)
|
|
if (IS_DIRECTORY ${_INPUT})
|
|
file(COPY ${_INPUT} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/${REL_PATH})
|
|
else()
|
|
configure_file(${FILE_PATH} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug/${REL_PATH}/${FILE_NAME} COPYONLY)
|
|
endif()
|
|
else()
|
|
if (IS_DIRECTORY ${_INPUT})
|
|
file(COPY ${_INPUT} DESTINATION ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${REL_PATH})
|
|
else()
|
|
configure_file(${FILE_PATH} ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${REL_PATH}/${FILE_NAME} COPYONLY)
|
|
endif()
|
|
endif()
|
|
|
|
if (IS_DIRECTORY ${_INPUT})
|
|
install(DIRECTORY
|
|
${FILE_PATH}
|
|
DESTINATION ${_OUTPUT}/${REL_PATH}
|
|
CONFIGURATIONS Debug)
|
|
else()
|
|
install(FILES
|
|
${FILE_PATH}
|
|
DESTINATION ${_OUTPUT}/${REL_PATH}
|
|
CONFIGURATIONS Debug)
|
|
endif()
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Creates a PreCompiled Header
|
|
# _PRECOMPILED_HEADER The full path of the dependency incl. FileName
|
|
# _SRC_FILES (Only works with CPP files)
|
|
####################################################################################
|
|
function(activate_precompiled_headers _PRECOMPILED_HEADER _SOURCE_FILES)
|
|
set(SRC_FILES ${${_SOURCE_FILES}})
|
|
get_filename_component(pch_basename ${_PRECOMPILED_HEADER} NAME_WE)
|
|
set(pch_abs ${CMAKE_CURRENT_SOURCE_DIR}/${_PRECOMPILED_HEADER})
|
|
set(pch_unity ${CMAKE_CURRENT_BINARY_DIR}/${pch_basename}.cpp)
|
|
|
|
if(MSVC)
|
|
# First specify the name of the PCH file
|
|
# it seems to be that nmake build cant handle the $(IntDir) variable
|
|
if(NOT MSVC_IDE)
|
|
set(pch_bin ${CMAKE_CURRENT_BINARY_DIR}/${pch_basename}.pch)
|
|
else()
|
|
set(pch_bin "$(IntDir)/${pch_basename}.pch")
|
|
endif()
|
|
# Generate precompiled header translation unit
|
|
if (NOT EXISTS ${pch_unity})
|
|
file(WRITE ${pch_unity} "// Precompiled header unity generated by CMake\n")
|
|
file(APPEND ${pch_unity} "#include <${pch_abs}>\n")
|
|
endif()
|
|
# this creates the precompild header
|
|
set_source_files_properties(${pch_unity}
|
|
PROPERTIES COMPILE_FLAGS "/Yc\"${pch_abs}\" /Fp\"${pch_bin}\""
|
|
OBJECT_OUTPUTS "${pch_bin}")
|
|
# Update properties of source files to use the precompiled header.
|
|
# Additionally, force the inclusion of the precompiled header at beginning of each source file.
|
|
set_source_files_properties(${SRC_FILES}
|
|
PROPERTIES COMPILE_FLAGS "/Yu\"${pch_abs}\" /FI\"${pch_abs}\" /Fp\"${pch_bin}\""
|
|
OBJECT_DEPENDS "${pch_bin}")
|
|
# Finally, update the source file collection to contain the precompiled header translation unit
|
|
set(${_SOURCE_FILES} ${pch_unity} ${pch_abs} ${${_SOURCE_FILES}} PARENT_SCOPE)
|
|
|
|
source_group("Generated Files" FILES ${pch_unity})
|
|
get_filename_component(PATH_TO_PCH ${_PRECOMPILED_HEADER} DIRECTORY)
|
|
if (PATH_TO_PCH)
|
|
string ( REGEX REPLACE "[\\/]" "\\\\" normalized_path ${PATH_TO_PCH} )
|
|
source_group(${normalized_path} FILES ${pch_abs})
|
|
endif()
|
|
endif()
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Adds warnings compiler options to the target depending on the category
|
|
# target Target name
|
|
####################################################################################
|
|
function( set_compiler_warnings target)
|
|
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
|
set(WARNINGS "-Werror"
|
|
"-Wall")
|
|
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
set(WARNINGS "-Werror"
|
|
"-Wall")
|
|
elseif(MSVC)
|
|
set(WARNINGS "/WX"
|
|
"/W4")
|
|
endif()
|
|
|
|
target_compile_options(${target} PRIVATE ${WARNINGS})
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# Adds or replace a compiler option
|
|
# _OLD_OPTION The option which should be replaced
|
|
# _NEW_OPTION The new option which should be added
|
|
####################################################################################
|
|
function( replace_compiler_option _OLD_OPTION _NEW_OPTION)
|
|
foreach(flag_var
|
|
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
|
|
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
|
|
if(${flag_var} MATCHES ${_OLD_OPTION})
|
|
# the whitespace after_OLD_OPTION is necessary to really match only the flag and not some sub flag (/MD should match by /MDd)
|
|
string(REGEX REPLACE "${_OLD_OPTION} " "${_NEW_OPTION} " ${flag_var} "${${flag_var}}")
|
|
else()
|
|
set(${flag_var} "${${flag_var}} ${_NEW_OPTION} ")
|
|
endif()
|
|
set(${flag_var} ${${flag_var}} PARENT_SCOPE)
|
|
endforeach()
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# enables or disables the user of RTTI for all following source files.
|
|
# _ENABLE If true, will enable RTTI, otherwise will disable RTTI.
|
|
####################################################################################
|
|
macro(enable_rtti _ENABLE)
|
|
set(enable_rtti_opt "")
|
|
set(disable_rtti_opt "")
|
|
if (MSVC)
|
|
set(enable_rtti_opt "/GR")
|
|
set(disable_rtti_opt "/GR-")
|
|
elseif(CMAKE_COMPILER_IS_GNUCXX )
|
|
set(enable_rtti_opt "-frtti")
|
|
set(disable_rtti_opt "-fno-rtti")
|
|
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
set(enable_rtti_opt "-frtti")
|
|
set(disable_rtti_opt "-fno-rtti")
|
|
else()
|
|
message(FATAL_ERROR "Don't know how to enable/disable RTTI for this compiler.")
|
|
endif()
|
|
|
|
if (${_ENABLE})
|
|
message(STATUS "Enabled: use of RTTI")
|
|
replace_compiler_option("${disable_rtti_opt}" "${enable_rtti_opt}")
|
|
else()
|
|
message(STATUS "Disabled: use of RTTI")
|
|
replace_compiler_option("${enable_rtti_opt}" "${disable_rtti_opt}")
|
|
endif()
|
|
endmacro()
|
|
|
|
|
|
####################################################################################
|
|
# Returns the name of the used compiler.
|
|
# _COMPILER_NAME
|
|
####################################################################################
|
|
function(getCompilerName _COMPILER_NAME)
|
|
if(MSVC_VERSION GREATER 1400)
|
|
set(COMPILER_NAME "vs")
|
|
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|
set(COMPILER_NAME "gcc")
|
|
if(WIN32)
|
|
execute_process(COMMAND "${CMAKE_CXX_COMPILER}" "-dumpversion" OUTPUT_VARIABLE GCC_VERSION_OUTPUT)
|
|
string(REGEX REPLACE "([0-9]+\\.[0-9]+).*" "\\1" GCC_VERSION "${GCC_VERSION_OUTPUT}")
|
|
set(COMPILER_NAME ${COMPILER_NAME}${GCC_VERSION})
|
|
endif()
|
|
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
|
set(COMPILER_NAME "clang")
|
|
else()
|
|
message(WARNING "Can not retrieve compiler name!")
|
|
return()
|
|
endif()
|
|
|
|
set(${_COMPILER_NAME} ${COMPILER_NAME} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
####################################################################################
|
|
# This will install the PDB files also into the "bin" folder of the installation directory
|
|
# _TARGET_NAME The name of the target
|
|
####################################################################################
|
|
|
|
function(install_pdb_files _TARGET_NAME)
|
|
if (MSVC)
|
|
install(FILES $<TARGET_PDB_FILE:${_TARGET_NAME}> DESTINATION "bin" CONFIGURATIONS Debug RelWithDebInfo)
|
|
endif()
|
|
endfunction()
|
|
|
|
|
|
####################################################################################
|
|
# Get environment variable, define it as ENV_$var and make sure backslashes are converted to forward slashes
|
|
# _COMPILER_NAME
|
|
####################################################################################
|
|
macro(getenv_path VAR)
|
|
set(ENV_${VAR} $ENV{${VAR}})
|
|
# replace won't work if var is blank
|
|
if (ENV_${VAR})
|
|
string( REGEX REPLACE "\\\\" "/" ENV_${VAR} ${ENV_${VAR}} )
|
|
endif ()
|
|
endmacro()
|
|
|
|
macro(generateLibraryVersionVariables MAJOR MINOR PATCH PRODUCT_NAME PRODUCT_CPY_RIGHT PRODUCT_LICENSE)
|
|
set(LIBRARY_VERSION_MAJOR ${MAJOR})
|
|
set(LIBRARY_VERSION_MINOR ${MINOR})
|
|
set(LIBRARY_VERSION_PATCH ${PATCH})
|
|
set(LIBRARY_VERSION ${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH})
|
|
set(LIBRARY_VERSION_STR "${LIBRARY_VERSION_MAJOR}.${LIBRARY_VERSION_MINOR}.${LIBRARY_VERSION_PATCH}")
|
|
math(EXPR LIBRARY_VERSION_CALC "${LIBRARY_VERSION_MAJOR}*1000 + ${LIBRARY_VERSION_MINOR}*100 + ${LIBRARY_VERSION_PATCH}")
|
|
set(LIBRARY_PRODUCT_NAME ${PRODUCT_NAME})
|
|
set(LIBRARY_COPYRIGHT ${PRODUCT_CPY_RIGHT})
|
|
set(LIBRARY_LICENSE ${PRODUCT_LICENSE})
|
|
endmacro()
|
|
|
|
function(get_latest_supported_cxx CXX_STANDARD)
|
|
if (POLICY CMP0067)
|
|
cmake_policy(SET CMP0067 NEW)
|
|
endif()
|
|
|
|
# we need to set CMAKE_CXX_STANDARD in order to use the flags for 'check_cxx_source_compiles'
|
|
if(${CMAKE_VERSION} VERSION_LESS "3.8.0")
|
|
set(CMAKE_CXX_STANDARD 14)
|
|
else()
|
|
set(CMAKE_CXX_STANDARD 17)
|
|
endif()
|
|
|
|
include(CheckCXXSourceCompiles)
|
|
|
|
check_cxx_source_compiles("
|
|
#include <type_traits>
|
|
typedef void F();
|
|
typedef void G() noexcept;
|
|
|
|
std::enable_if<
|
|
!std::is_same<F, G>::value,
|
|
int
|
|
>::type i = 42;
|
|
|
|
int main() { return 0; }
|
|
"
|
|
HAS_NO_EXCEPT_TYPE_SIGNATURE_SUPPORT)
|
|
|
|
check_cxx_source_compiles("
|
|
#include <type_traits>
|
|
struct foo { void func() const noexcept {} };
|
|
template<typename T>
|
|
void test_func(T)
|
|
{
|
|
static_assert(std::is_member_function_pointer<T>::value, \"Failed\");
|
|
}
|
|
int main() { test_func(&foo::func); return 0; }
|
|
"
|
|
HAS_STL_NO_EXCEPT_TYPE_SIGNATURE_SUPPORT)
|
|
|
|
check_cxx_source_compiles("
|
|
constexpr int abs(int x)
|
|
{
|
|
if(x < 0) x = -x;
|
|
return x;
|
|
}
|
|
|
|
int main() { }
|
|
"
|
|
HAS_CXX_CONSTEXPR)
|
|
|
|
check_cxx_source_compiles( "
|
|
#include <type_traits>
|
|
template<typename T>
|
|
struct template_type_trait : std::false_type {};
|
|
|
|
template<template < bool > class T, bool N>
|
|
struct template_type_trait<T<N>> : std::true_type {};
|
|
|
|
template<template <std::size_t> class T, std::size_t N>
|
|
struct template_type_trait<T<N>> : std::true_type {};
|
|
|
|
template<std::size_t T>
|
|
struct bar{};
|
|
|
|
int main() { static bool foo = template_type_trait<bar<100>>::value;}
|
|
"
|
|
HAS_PARTIAL_SPECIALIZATION_FOR_ARRAYS)
|
|
|
|
if (HAS_NO_EXCEPT_TYPE_SIGNATURE_SUPPORT AND HAS_STL_NO_EXCEPT_TYPE_SIGNATURE_SUPPORT AND
|
|
HAS_PARTIAL_SPECIALIZATION_FOR_ARRAYS)
|
|
set(MAX_CXX_STD 17)
|
|
else()
|
|
if (HAS_CXX_CONSTEXPR)
|
|
set(MAX_CXX_STD 14)
|
|
else()
|
|
set(MAX_CXX_STD 11)
|
|
endif()
|
|
endif()
|
|
|
|
set(${CXX_STANDARD} ${MAX_CXX_STD} PARENT_SCOPE)
|
|
endfunction()
|
|
|