Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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)