1cmake_policy(SET CMP0057 NEW)
2include(RunCMake)
3
4run_cmake(NotAFeature)
5run_cmake(NotAFeatureGenex)
6run_cmake(NotAFeatureTransitive)
7run_cmake(NotAFeature_OriginDebug)
8run_cmake(NotAFeature_OriginDebugGenex)
9run_cmake(NotAFeature_OriginDebugTransitive)
10run_cmake(NotAFeature_OriginDebugCommand)
11
12run_cmake(compiler_introspection)
13include("${RunCMake_BINARY_DIR}/compiler_introspection-build/info.cmake")
14
15if (NOT C_FEATURES)
16  run_cmake(NoSupportedCFeatures)
17  run_cmake(NoSupportedCFeaturesGenex)
18endif()
19
20if (NOT CXX_FEATURES)
21  run_cmake(NoSupportedCxxFeatures)
22  run_cmake(NoSupportedCxxFeaturesGenex)
23elseif (cxx_std_98 IN_LIST CXX_FEATURES AND cxx_std_11 IN_LIST CXX_FEATURES)
24  if(CXX_STANDARD_DEFAULT EQUAL 98)
25    run_cmake(LinkImplementationFeatureCycle)
26  endif()
27  run_cmake(LinkImplementationFeatureCycleSolved)
28
29  if (cxx_final IN_LIST CXX_FEATURES)
30    set(RunCMake_TEST_OPTIONS "-DHAVE_FINAL=1")
31  endif()
32  run_cmake(NonValidTarget1)
33  run_cmake(NonValidTarget2)
34  unset(RunCMake_TEST_OPTIONS)
35endif()
36
37configure_file("${RunCMake_SOURCE_DIR}/CMakeLists.txt" "${RunCMake_BINARY_DIR}/CMakeLists.txt" COPYONLY)
38
39function(test_build)
40  set(test ${name}-${lang})
41
42  configure_file("${RunCMake_SOURCE_DIR}/${name}.cmake" "${RunCMake_BINARY_DIR}/${test}.cmake" @ONLY)
43  if(EXISTS "${RunCMake_SOURCE_DIR}/${name}-build-check.cmake")
44    configure_file("${RunCMake_SOURCE_DIR}/${name}-build-check.cmake" "${RunCMake_BINARY_DIR}/${test}-build-check.cmake" @ONLY)
45  endif()
46  if(EXISTS "${RunCMake_SOURCE_DIR}/${name}-stderr.txt")
47    configure_file("${RunCMake_SOURCE_DIR}/${name}-stderr.txt" "${RunCMake_BINARY_DIR}/${test}-stderr.txt" @ONLY)
48  endif()
49
50  set(RunCMake_SOURCE_DIR "${RunCMake_BINARY_DIR}")
51  set(RunCMake_TEST_BINARY_DIR "${RunCMake_BINARY_DIR}/${test}-build")
52  run_cmake(${test})
53  set(RunCMake_TEST_NO_CLEAN 1)
54  run_cmake_command(${test}-build ${CMAKE_COMMAND} --build . ${ARGN})
55endfunction()
56
57# Mangle flags such as they're in verbose build output.
58macro(mangle_flags variable)
59  set(result "${${variable}}")
60
61  if(RunCMake_GENERATOR MATCHES "Visual Studio" AND MSVC_TOOLSET_VERSION GREATER_EQUAL 141)
62    string(REPLACE "-" "/" result "${result}")
63  elseif(RunCMake_GENERATOR STREQUAL "Xcode" AND CMAKE_XCODE_BUILD_SYSTEM GREATER_EQUAL 12)
64    string(REPLACE "=" [[\\=]] result "${result}")
65  endif()
66
67  string(REPLACE ";" " " result "${result}")
68  list(APPEND flags "${result}")
69endmacro()
70
71function(test_extensions_opposite)
72  if(extensions_opposite)
73    set(flag_ext "_EXT")
74  endif()
75
76  set(flag "${${lang}${${lang}_STANDARD_DEFAULT}${flag_ext}_FLAG}")
77
78  if(NOT flag)
79    return()
80  endif()
81
82  mangle_flags(flag)
83
84  # Make sure we enable/disable extensions when:
85  # 1. LANG_STANDARD is unset.
86  set(name ExtensionsStandardUnset)
87  set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW)
88  test_build(--verbose)
89
90  # 2. LANG_STANDARD matches CMAKE_LANG_STANDARD_DEFAULT.
91  set(name ExtensionsStandardDefault)
92  test_build(--verbose)
93endfunction()
94
95function(test_no_unnecessary_flag)
96  set(standard_flag "${${lang}${${lang}_STANDARD_DEFAULT}_FLAG}")
97  set(extension_flag "${${lang}${${lang}_STANDARD_DEFAULT}_EXT_FLAG}")
98
99  if(NOT standard_flag AND NOT extension_flag)
100    return()
101  endif()
102
103  mangle_flags(standard_flag)
104  mangle_flags(extension_flag)
105
106  set(name NoUnnecessaryFlag)
107  set(RunCMake_TEST_OPTIONS -DCMAKE_POLICY_DEFAULT_CMP0128=NEW)
108  test_build(--verbose)
109endfunction()
110
111function(test_cmp0128_warn_match)
112  set(name CMP0128WarnMatch)
113  test_build()
114endfunction()
115
116function(test_cmp0128_warn_unset)
117  # For compilers that had CMAKE_<LANG>_EXTENSION_COMPILE_OPTION (only IAR)
118  # there is no behavioural change and thus no warning.
119  if(NOT "${${lang}_EXT_FLAG}" STREQUAL "")
120    return()
121  endif()
122
123  if(extensions_opposite)
124    set(opposite "enabled")
125  else()
126    set(opposite "disabled")
127  endif()
128
129  set(name CMP0128WarnUnset)
130  test_build()
131endfunction()
132
133function(test_lang lang ext)
134  if(CMake_NO_${lang}_STANDARD)
135    return()
136  endif()
137
138  set(extensions_default "${${lang}_EXTENSIONS_DEFAULT}")
139  set(standard_default "${${lang}_STANDARD_DEFAULT}")
140
141  if(extensions_default)
142    set(extensions_opposite OFF)
143  else()
144    set(extensions_opposite ON)
145  endif()
146
147  test_extensions_opposite()
148  test_no_unnecessary_flag()
149  test_cmp0128_warn_match()
150  test_cmp0128_warn_unset()
151endfunction()
152
153if(C_STANDARD_DEFAULT)
154  test_lang(C c)
155endif()
156
157if(CXX_STANDARD_DEFAULT)
158  run_cmake(NotAStandard)
159
160  foreach(standard 98 11)
161    if (CXX${standard}_FLAG STREQUAL NOTFOUND)
162      run_cmake(RequireCXX${standard})
163      run_cmake(RequireCXX${standard}Variable)
164    endif()
165    if (CXX${standard}_EXT_FLAG STREQUAL NOTFOUND)
166      run_cmake(RequireCXX${standard}Ext)
167      run_cmake(RequireCXX${standard}ExtVariable)
168    endif()
169  endforeach()
170
171  test_lang(CXX cpp)
172endif()
173