GtsamBuildTypes.cmake 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. include(CheckCXXCompilerFlag) # for check_cxx_compiler_flag()
  2. # Set cmake policy to recognize the AppleClang compiler
  3. # independently from the Clang compiler.
  4. if(POLICY CMP0025)
  5. cmake_policy(SET CMP0025 NEW)
  6. endif()
  7. # function: list_append_cache(var [new_values ...])
  8. # Like "list(APPEND ...)" but working for CACHE variables.
  9. # -----------------------------------------------------------
  10. function(list_append_cache var)
  11. set(cur_value ${${var}})
  12. list(APPEND cur_value ${ARGN})
  13. get_property(MYVAR_DOCSTRING CACHE ${var} PROPERTY HELPSTRING)
  14. set(${var} "${cur_value}" CACHE STRING "${MYVAR_DOCSTRING}" FORCE)
  15. endfunction()
  16. # function: append_config_if_not_empty(TARGET_VARIABLE build_type)
  17. # Auxiliary function used to merge configuration-specific flags into the
  18. # global variables that will actually be send to cmake targets.
  19. # -----------------------------------------------------------
  20. function(append_config_if_not_empty TARGET_VARIABLE_ build_type)
  21. string(TOUPPER "${build_type}" build_type_toupper)
  22. set(flags_variable_name "${TARGET_VARIABLE_}_${build_type_toupper}")
  23. set(flags_ ${${flags_variable_name}})
  24. if (NOT "${flags_}" STREQUAL "")
  25. if (${build_type_toupper} STREQUAL "COMMON")
  26. # Special "COMMON" configuration type, just append without CMake expression:
  27. list_append_cache(${TARGET_VARIABLE_} "${flags_}")
  28. else()
  29. # Regular configuration type:
  30. list_append_cache(${TARGET_VARIABLE_} "$<$<CONFIG:${build_type}>:${flags_}>")
  31. endif()
  32. endif()
  33. endfunction()
  34. # Add install prefix to search path
  35. list(APPEND CMAKE_PREFIX_PATH "${CMAKE_INSTALL_PREFIX}")
  36. # Set up build types for MSVC and XCode
  37. set(GTSAM_CMAKE_CONFIGURATION_TYPES Debug Release Timing Profiling RelWithDebInfo MinSizeRel
  38. CACHE STRING "Build types available to MSVC and XCode")
  39. mark_as_advanced(FORCE GTSAM_CMAKE_CONFIGURATION_TYPES)
  40. set(CMAKE_CONFIGURATION_TYPES ${GTSAM_CMAKE_CONFIGURATION_TYPES} CACHE STRING "Build configurations" FORCE)
  41. # Default to Release mode
  42. if(NOT CMAKE_BUILD_TYPE AND NOT MSVC AND NOT XCODE_VERSION)
  43. set(GTSAM_CMAKE_BUILD_TYPE "Release" CACHE STRING
  44. "Choose the type of build, options are: None Debug Release Timing Profiling RelWithDebInfo.")
  45. set(CMAKE_BUILD_TYPE ${GTSAM_CMAKE_BUILD_TYPE} CACHE STRING
  46. "Choose the type of build, options are: None Debug Release Timing Profiling RelWithDebInfo." FORCE)
  47. endif()
  48. # Add option for using build type postfixes to allow installing multiple build modes
  49. option(GTSAM_BUILD_TYPE_POSTFIXES "Enable/Disable appending the build type to the name of compiled libraries" ON)
  50. # Define all cache variables, to be populated below depending on the OS/compiler:
  51. set(GTSAM_COMPILE_OPTIONS_PRIVATE "" CACHE INTERNAL "(Do not edit) Private compiler flags for all build configurations." FORCE)
  52. set(GTSAM_COMPILE_OPTIONS_PUBLIC "" CACHE INTERNAL "(Do not edit) Public compiler flags (exported to user projects) for all build configurations." FORCE)
  53. set(GTSAM_COMPILE_DEFINITIONS_PRIVATE "" CACHE INTERNAL "(Do not edit) Private preprocessor macros for all build configurations." FORCE)
  54. set(GTSAM_COMPILE_DEFINITIONS_PUBLIC "" CACHE INTERNAL "(Do not edit) Public preprocessor macros for all build configurations." FORCE)
  55. mark_as_advanced(GTSAM_COMPILE_OPTIONS_PRIVATE)
  56. mark_as_advanced(GTSAM_COMPILE_OPTIONS_PUBLIC)
  57. mark_as_advanced(GTSAM_COMPILE_DEFINITIONS_PRIVATE)
  58. mark_as_advanced(GTSAM_COMPILE_DEFINITIONS_PUBLIC)
  59. foreach(build_type ${GTSAM_CMAKE_CONFIGURATION_TYPES})
  60. string(TOUPPER "${build_type}" build_type_toupper)
  61. # Define empty cache variables for "public". "private" are created below.
  62. set(GTSAM_COMPILE_OPTIONS_PUBLIC_${build_type_toupper} "" CACHE STRING "(User editable) Public compiler flags (exported to user projects) for `${build_type_toupper}` configuration.")
  63. set(GTSAM_COMPILE_DEFINITIONS_PUBLIC_${build_type_toupper} "" CACHE STRING "(User editable) Public preprocessor macros for `${build_type_toupper}` configuration.")
  64. endforeach()
  65. # Common preprocessor macros for each configuration:
  66. set(GTSAM_COMPILE_DEFINITIONS_PRIVATE_DEBUG "_DEBUG;EIGEN_INITIALIZE_MATRICES_BY_NAN" CACHE STRING "(User editable) Private preprocessor macros for Debug configuration.")
  67. set(GTSAM_COMPILE_DEFINITIONS_PRIVATE_RELWITHDEBINFO "NDEBUG" CACHE STRING "(User editable) Private preprocessor macros for RelWithDebInfo configuration.")
  68. set(GTSAM_COMPILE_DEFINITIONS_PRIVATE_RELEASE "NDEBUG" CACHE STRING "(User editable) Private preprocessor macros for Release configuration.")
  69. set(GTSAM_COMPILE_DEFINITIONS_PRIVATE_PROFILING "NDEBUG" CACHE STRING "(User editable) Private preprocessor macros for Profiling configuration.")
  70. set(GTSAM_COMPILE_DEFINITIONS_PRIVATE_TIMING "NDEBUG;ENABLE_TIMING" CACHE STRING "(User editable) Private preprocessor macros for Timing configuration.")
  71. if(MSVC)
  72. # Common to all configurations:
  73. list_append_cache(GTSAM_COMPILE_DEFINITIONS_PRIVATE
  74. WINDOWS_LEAN_AND_MEAN
  75. NOMINMAX
  76. )
  77. # Avoid literally hundreds to thousands of warnings:
  78. list_append_cache(GTSAM_COMPILE_OPTIONS_PUBLIC
  79. /wd4267 # warning C4267: 'initializing': conversion from 'size_t' to 'int', possible loss of data
  80. )
  81. endif()
  82. # Other (non-preprocessor macros) compiler flags:
  83. if(MSVC)
  84. # Common to all configurations, next for each configuration:
  85. set(GTSAM_COMPILE_OPTIONS_PRIVATE_COMMON /W3 /GR /EHsc /MP CACHE STRING "(User editable) Private compiler flags for all configurations.")
  86. set(GTSAM_COMPILE_OPTIONS_PRIVATE_DEBUG /MDd /Zi /Ob0 /Od /RTC1 CACHE STRING "(User editable) Private compiler flags for Debug configuration.")
  87. set(GTSAM_COMPILE_OPTIONS_PRIVATE_RELWITHDEBINFO /MD /O2 /D /Zi /d2Zi+ CACHE STRING "(User editable) Private compiler flags for RelWithDebInfo configuration.")
  88. set(GTSAM_COMPILE_OPTIONS_PRIVATE_RELEASE /MD /O2 CACHE STRING "(User editable) Private compiler flags for Release configuration.")
  89. set(GTSAM_COMPILE_OPTIONS_PRIVATE_PROFILING /MD /O2 /Zi CACHE STRING "(User editable) Private compiler flags for Profiling configuration.")
  90. set(GTSAM_COMPILE_OPTIONS_PRIVATE_TIMING /MD /O2 CACHE STRING "(User editable) Private compiler flags for Timing configuration.")
  91. else()
  92. # Common to all configurations, next for each configuration:
  93. if (NOT MSVC)
  94. check_cxx_compiler_flag(-Wsuggest-override COMPILER_HAS_WSUGGEST_OVERRIDE)
  95. check_cxx_compiler_flag(-Wmissing COMPILER_HAS_WMISSING_OVERRIDE)
  96. if (COMPILER_HAS_WSUGGEST_OVERRIDE)
  97. set(flag_override_ -Wsuggest-override) # -Werror=suggest-override: Add again someday
  98. elseif(COMPILER_HAS_WMISSING_OVERRIDE)
  99. set(flag_override_ -Wmissing-override) # -Werror=missing-override: Add again someday
  100. endif()
  101. endif()
  102. set(GTSAM_COMPILE_OPTIONS_PRIVATE_COMMON
  103. -Wall # Enable common warnings
  104. -fPIC # ensure proper code generation for shared libraries
  105. $<$<CXX_COMPILER_ID:GNU>:-Wreturn-local-addr -Werror=return-local-addr> # Error: return local address
  106. $<$<CXX_COMPILER_ID:Clang>:-Wreturn-stack-address -Werror=return-stack-address> # Error: return local address
  107. -Wreturn-type -Werror=return-type # Error on missing return()
  108. -Wformat -Werror=format-security # Error on wrong printf() arguments
  109. $<$<COMPILE_LANGUAGE:CXX>:${flag_override_}> # Enforce the use of the override keyword
  110. #
  111. CACHE STRING "(User editable) Private compiler flags for all configurations.")
  112. set(GTSAM_COMPILE_OPTIONS_PRIVATE_DEBUG -g -fno-inline CACHE STRING "(User editable) Private compiler flags for Debug configuration.")
  113. set(GTSAM_COMPILE_OPTIONS_PRIVATE_RELWITHDEBINFO -g -O3 CACHE STRING "(User editable) Private compiler flags for RelWithDebInfo configuration.")
  114. set(GTSAM_COMPILE_OPTIONS_PRIVATE_RELEASE -O3 CACHE STRING "(User editable) Private compiler flags for Release configuration.")
  115. set(GTSAM_COMPILE_OPTIONS_PRIVATE_PROFILING -O3 CACHE STRING "(User editable) Private compiler flags for Profiling configuration.")
  116. set(GTSAM_COMPILE_OPTIONS_PRIVATE_TIMING -g -O3 CACHE STRING "(User editable) Private compiler flags for Timing configuration.")
  117. endif()
  118. # Enable C++11:
  119. if (NOT CMAKE_VERSION VERSION_LESS 3.8)
  120. set(GTSAM_COMPILE_FEATURES_PUBLIC "cxx_std_11" CACHE STRING "CMake compile features property for all gtsam targets.")
  121. # See: https://cmake.org/cmake/help/latest/prop_tgt/CXX_EXTENSIONS.html
  122. # This is to enable -std=c++11 instead of -std=g++11
  123. set(CMAKE_CXX_EXTENSIONS OFF)
  124. else()
  125. # Old cmake versions:
  126. if (NOT MSVC)
  127. list_append_cache(GTSAM_COMPILE_OPTIONS_PUBLIC $<$<COMPILE_LANGUAGE:CXX>:-std=c++11>)
  128. endif()
  129. endif()
  130. # Merge all user-defined flags into the variables that are to be actually used by CMake:
  131. foreach(build_type "common" ${GTSAM_CMAKE_CONFIGURATION_TYPES})
  132. append_config_if_not_empty(GTSAM_COMPILE_OPTIONS_PRIVATE ${build_type})
  133. append_config_if_not_empty(GTSAM_COMPILE_OPTIONS_PUBLIC ${build_type})
  134. append_config_if_not_empty(GTSAM_COMPILE_DEFINITIONS_PRIVATE ${build_type})
  135. append_config_if_not_empty(GTSAM_COMPILE_DEFINITIONS_PUBLIC ${build_type})
  136. endforeach()
  137. # Linker flags:
  138. set(GTSAM_CMAKE_SHARED_LINKER_FLAGS_TIMING "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}" CACHE STRING "Linker flags during timing builds.")
  139. set(GTSAM_CMAKE_MODULE_LINKER_FLAGS_TIMING "${CMAKE_MODULE_LINKER_FLAGS_RELEASE}" CACHE STRING "Linker flags during timing builds.")
  140. set(GTSAM_CMAKE_EXE_LINKER_FLAGS_TIMING "${CMAKE_EXE_LINKER_FLAGS_RELEASE}" CACHE STRING "Linker flags during timing builds.")
  141. set(GTSAM_CMAKE_SHARED_LINKER_FLAGS_PROFILING "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}" CACHE STRING "Linker flags during profiling builds.")
  142. set(GTSAM_CMAKE_MODULE_LINKER_FLAGS_PROFILING "${CMAKE_MODULE_LINKER_FLAGS_RELEASE}" CACHE STRING "Linker flags during profiling builds.")
  143. set(GTSAM_CMAKE_EXE_LINKER_FLAGS_PROFILING "${CMAKE_EXE_LINKER_FLAGS_RELEASE}" CACHE STRING "Linker flags during profiling builds.")
  144. mark_as_advanced(GTSAM_CMAKE_EXE_LINKER_FLAGS_TIMING
  145. GTSAM_CMAKE_SHARED_LINKER_FLAGS_TIMING GTSAM_CMAKE_MODULE_LINKER_FLAGS_TIMING
  146. GTSAM_CMAKE_C_FLAGS_PROFILING GTSAM_ GTSAM_CMAKE_EXE_LINKER_FLAGS_PROFILING
  147. GTSAM_CMAKE_SHARED_LINKER_FLAGS_PROFILING GTSAM_CMAKE_MODULE_LINKER_FLAGS_PROFILING)
  148. set(CMAKE_SHARED_LINKER_FLAGS_TIMING ${GTSAM_CMAKE_SHARED_LINKER_FLAGS_TIMING})
  149. set(CMAKE_MODULE_LINKER_FLAGS_TIMING ${GTSAM_CMAKE_MODULE_LINKER_FLAGS_TIMING})
  150. set(CMAKE_EXE_LINKER_FLAGS_TIMING ${GTSAM_CMAKE_EXE_LINKER_FLAGS_TIMING})
  151. set(CMAKE_SHARED_LINKER_FLAGS_PROFILING ${GTSAM_CMAKE_SHARED_LINKER_FLAGS_PROFILING})
  152. set(CMAKE_MODULE_LINKER_FLAGS_PROFILING ${GTSAM_CMAKE_MODULE_LINKER_FLAGS_PROFILING})
  153. set(CMAKE_EXE_LINKER_FLAGS_PROFILING ${GTSAM_CMAKE_EXE_LINKER_FLAGS_PROFILING})
  154. # Clang uses a template depth that is less than standard and is too small
  155. if(${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
  156. # Apple Clang before 5.0 does not support -ftemplate-depth.
  157. if(NOT (APPLE AND "${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "5.0"))
  158. list_append_cache(GTSAM_COMPILE_OPTIONS_PUBLIC "-ftemplate-depth=1024")
  159. endif()
  160. endif()
  161. if (NOT MSVC)
  162. option(GTSAM_BUILD_WITH_MARCH_NATIVE "Enable/Disable building with all instructions supported by native architecture (binary may not be portable!)" ON)
  163. if(GTSAM_BUILD_WITH_MARCH_NATIVE)
  164. # Add as public flag so all dependant projects also use it, as required
  165. # by Eigen to avid crashes due to SIMD vectorization:
  166. list_append_cache(GTSAM_COMPILE_OPTIONS_PUBLIC "-march=native")
  167. endif()
  168. endif()
  169. # Set up build type library postfixes
  170. if(GTSAM_BUILD_TYPE_POSTFIXES)
  171. foreach(build_type Debug Timing Profiling RelWithDebInfo MinSizeRel)
  172. string(TOUPPER "${build_type}" build_type_toupper)
  173. set(CMAKE_${build_type_toupper}_POSTFIX ${build_type})
  174. endforeach()
  175. endif()
  176. # Make common binary output directory when on Windows
  177. if(WIN32)
  178. set(RUNTIME_OUTPUT_PATH "${GTSAM_BINARY_DIR}/bin")
  179. set(EXECUTABLE_OUTPUT_PATH "${GTSAM_BINARY_DIR}/bin")
  180. set(LIBRARY_OUTPUT_PATH "${GTSAM_BINARY_DIR}/lib")
  181. endif()
  182. # Set up build type list for cmake-gui
  183. if(NOT "${CMAKE_BUILD_TYPE}" STREQUAL "")
  184. if(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_GREATER 2.8 OR ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} VERSION_EQUAL 2.8)
  185. set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS None Debug Release Timing Profiling RelWithDebInfo MinSizeRel)
  186. endif()
  187. endif()
  188. # Check build types
  189. string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower)
  190. if( NOT cmake_build_type_tolower STREQUAL ""
  191. AND NOT cmake_build_type_tolower STREQUAL "none"
  192. AND NOT cmake_build_type_tolower STREQUAL "debug"
  193. AND NOT cmake_build_type_tolower STREQUAL "release"
  194. AND NOT cmake_build_type_tolower STREQUAL "timing"
  195. AND NOT cmake_build_type_tolower STREQUAL "profiling"
  196. AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo"
  197. AND NOT cmake_build_type_tolower STREQUAL "minsizerel")
  198. message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are None, Debug, Release, Timing, Profiling, RelWithDebInfo, MinSizeRel (case-insensitive).")
  199. endif()
  200. # Enable Visual Studio solution folders
  201. set_property(GLOBAL PROPERTY USE_FOLDERS On)
  202. # Function for automatically assigning source folders
  203. function(gtsam_assign_source_folders)
  204. set(FILES ${ARGV})
  205. foreach(file ${FILES})
  206. file(RELATIVE_PATH relative_file "${CMAKE_CURRENT_SOURCE_DIR}" "${file}")
  207. get_filename_component(relative_path "${relative_file}" PATH)
  208. file(TO_NATIVE_PATH "${relative_path}" relative_path)
  209. source_group("${relative_path}" FILES "${file}")
  210. endforeach()
  211. endfunction()
  212. # Find and assign all source and header files
  213. function(gtsam_assign_all_source_folders)
  214. file(GLOB_RECURSE all_c_srcs "*.c")
  215. file(GLOB_RECURSE all_cpp_srcs "*.cpp")
  216. file(GLOB_RECURSE all_headers "*.h")
  217. gtsam_assign_source_folders("${all_c_srcs};${all_cpp_srcs};${all_headers}")
  218. endfunction()
  219. # Applies the per-config build flags to the given target (e.g. gtsam, wrap_lib)
  220. function(gtsam_apply_build_flags target_name_)
  221. # To enable C++11: the use of target_compile_features() is preferred since
  222. # it will be not in conflict with a more modern C++ standard, if used in a
  223. # client program.
  224. if (NOT "${GTSAM_COMPILE_FEATURES_PUBLIC}" STREQUAL "")
  225. target_compile_features(${target_name_} PUBLIC ${GTSAM_COMPILE_FEATURES_PUBLIC})
  226. endif()
  227. target_compile_definitions(${target_name_} PRIVATE ${GTSAM_COMPILE_DEFINITIONS_PRIVATE})
  228. target_compile_definitions(${target_name_} PUBLIC ${GTSAM_COMPILE_DEFINITIONS_PUBLIC})
  229. if (NOT "${GTSAM_COMPILE_OPTIONS_PUBLIC}" STREQUAL "")
  230. target_compile_options(${target_name_} PUBLIC ${GTSAM_COMPILE_OPTIONS_PUBLIC})
  231. endif()
  232. target_compile_options(${target_name_} PRIVATE ${GTSAM_COMPILE_OPTIONS_PRIVATE})
  233. endfunction(gtsam_apply_build_flags)
  234. if(NOT MSVC AND NOT XCODE_VERSION)
  235. # Set the build type to upper case for downstream use
  236. string(TOUPPER "${CMAKE_BUILD_TYPE}" CMAKE_BUILD_TYPE_UPPER)
  237. # Set the GTSAM_BUILD_TAG variable.
  238. # If build type is Release, set to blank (""), else set to the build type.
  239. if(${CMAKE_BUILD_TYPE_UPPER} STREQUAL "RELEASE")
  240. set(GTSAM_BUILD_TAG "") # Don't create release mode tag on installed directory
  241. else()
  242. set(GTSAM_BUILD_TAG "${CMAKE_BUILD_TYPE}")
  243. endif()
  244. endif()