Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkFunctionCheckCompilerFlags.cmake
Go to the documentation of this file.
1 #
2 # Helper macro allowing to check if the given flags are supported
3 # by the underlying build tool
4 #
5 # If the flag(s) is/are supported, they will be appended to the string identified by RESULT_VAR
6 #
7 # Usage:
8 # mitkFunctionCheckCompilerFlags(FLAGS_TO_CHECK VALID_FLAGS_VAR)
9 #
10 # The above example uses the C++ compiler to check the flags. To individually check with
11 # the C and C++ compiler, use:
12 #
13 # mitkFunctionCheckCompilerFlags2(FLAGS_TO_CHECK VALID_C_FLAGS_VAR VALID_CXX_FLAGS_VAR)
14 #
15 # Example:
16 #
17 # set(myflags)
18 # mitkFunctionCheckCompilerFlags("-fprofile-arcs" myflags)
19 # message(1-myflags:${myflags})
20 # mitkFunctionCheckCompilerFlags("-fauto-bugfix" myflags)
21 # message(2-myflags:${myflags})
22 # mitkFunctionCheckCompilerFlags("-Wall" myflags)
23 # message(1-myflags:${myflags})
24 #
25 # The output will be:
26 # 1-myflags: -fprofile-arcs
27 # 2-myflags: -fprofile-arcs
28 # 3-myflags: -fprofile-arcs -Wall
29 
30 include(CheckCCompilerFlag)
31 include(CheckCXXCompilerFlag)
32 
33 function(mitkFunctionCheckCompilerFlags CXX_FLAG_TO_TEST RESULT_VAR)
34 
35  if(CXX_FLAG_TO_TEST STREQUAL "")
36  message(FATAL_ERROR "CXX_FLAG_TO_TEST shouldn't be empty")
37  endif()
38 
39  # Internally, the macro CMAKE_CXX_ACCEPTS_FLAG calls TRY_COMPILE. To avoid
40  # the cost of compiling the test each time the project is configured, the variable set by
41  # the macro is added to the cache so that following invocation of the macro with
42  # the same variable name skip the compilation step.
43  # For that same reason, the mitkFunctionCheckCompilerFlags function appends a unique suffix to
44  # the HAS_FLAG variable. This suffix is created using a 'clean version' of the flag to test.
45  string(REGEX REPLACE "[, \\$\\+\\*\\{\\}\\(\\)\\#]" "" suffix ${CXX_FLAG_TO_TEST})
46  CHECK_CXX_COMPILER_FLAG(${CXX_FLAG_TO_TEST} HAS_FLAG_${suffix})
47 
48  if(HAS_FLAG_${suffix})
49  set(${RESULT_VAR} "${${RESULT_VAR}} ${CXX_FLAG_TO_TEST}" PARENT_SCOPE)
50  endif()
51 
52 endfunction()
53 
54 function(mitkFunctionCheckCAndCXXCompilerFlags FLAG_TO_TEST C_RESULT_VAR CXX_RESULT_VAR)
55 
56  if(FLAG_TO_TEST STREQUAL "")
57  message(FATAL_ERROR "FLAG_TO_TEST shouldn't be empty")
58  endif()
59 
60  # Save the contents of CXX_RESULT_VAR temporarily.
61  # This is needed of ${CXX_RESULT_VAR} is one of the CMAKE_<LANG>_FLAGS_* variables.
62  set(_saved_c_result_var ${${C_RESULT_VAR}})
63  set(_saved_cxx_result_var ${${CXX_RESULT_VAR}})
64 
65  # Clear all flags. If not, existing flags triggering warnings might lead to
66  # false-negatives when checking for certain compiler flags.
67  set(CMAKE_C_FLAGS )
68  set(CMAKE_C_FLAGS_DEBUG )
69  set(CMAKE_C_FLAGS_MINSIZEREL )
70  set(CMAKE_C_FLAGS_RELEASE )
71  set(CMAKE_C_FLAGS_RELWITHDEBINFO )
72  set(CMAKE_CXX_FLAGS )
73  set(CMAKE_CXX_FLAGS_DEBUG )
74  set(CMAKE_CXX_FLAGS_MINSIZEREL )
75  set(CMAKE_CXX_FLAGS_RELEASE )
76  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO )
77 
78  # Internally, the macro CMAKE_CXX_COMPILER_FLAG calls TRY_COMPILE. To avoid
79  # the cost of compiling the test each time the project is configured, the variable set by
80  # the macro is added to the cache so that following invocation of the macro with
81  # the same variable name skip the compilation step.
82  # For that same reason, the mitkFunctionCheckCompilerFlags2 function appends a unique suffix to
83  # the HAS_CXX_FLAG and HAS_C_FLAG variable. This suffix is created using a 'clean version' of the
84  # flag to test. The value of HAS_C(XX)_FLAG_${suffix} additonally needs to be a valid
85  # pre-processor token because CHECK_CXX_COMPILER_FLAG adds it as a definition to the compiler
86  # arguments. An invalid token triggers compiler warnings, which in case of the "-Werror" flag
87  # leads to false-negative checks.
88  string(REGEX REPLACE "[/-]" "_" suffix ${FLAG_TO_TEST})
89  string(REGEX REPLACE "[, \\$\\+\\*\\{\\}\\(\\)\\#]" "" suffix ${suffix})
90 
91  # workaround for gcc's strange behaviour on -Wno-... options in combination with -Werror
92  # we test the flag without the "no-" prefix because that is more reliable
93  string(REGEX REPLACE "^-Wno-" "-W" FLAG_TO_TEST_FIXED ${FLAG_TO_TEST})
94 
95  CHECK_CXX_COMPILER_FLAG(${FLAG_TO_TEST_FIXED} HAS_CXX_FLAG_${suffix})
96 
97  if(HAS_CXX_FLAG_${suffix})
98  set(${CXX_RESULT_VAR} "${_saved_cxx_result_var} ${FLAG_TO_TEST}" PARENT_SCOPE)
99  endif()
100 
101  CHECK_C_COMPILER_FLAG(${FLAG_TO_TEST_FIXED} HAS_C_FLAG_${suffix})
102 
103  if(HAS_C_FLAG_${suffix})
104  set(${C_RESULT_VAR} "${_saved_c_result_var} ${FLAG_TO_TEST}" PARENT_SCOPE)
105  endif()
106 
107 endfunction()
mitkFunctionCheckCompilerFlags(CXX_FLAG_TO_TEST, RESULT_VAR)
mitkFunctionCheckCAndCXXCompilerFlags(FLAG_TO_TEST, C_RESULT_VAR, CXX_RESULT_VAR)