Imported Upstream version 3.25.0
[platform/upstream/cmake.git] / Tests / RunCMake / ExternalProject / RunCMakeTest.cmake
1 cmake_minimum_required(VERSION 3.12)
2 include(RunCMake)
3
4 # We do not contact any remote URLs, but may use a local one.
5 # Remove any proxy configuration that may change behavior.
6 unset(ENV{http_proxy})
7 unset(ENV{https_proxy})
8
9 if(RunCMake_GENERATOR STREQUAL "Borland Makefiles" OR
10    RunCMake_GENERATOR STREQUAL "Watcom WMake")
11   set(fs_delay 3)
12 else()
13   set(fs_delay 1.125)
14 endif()
15
16 run_cmake(BadIndependentStep1)
17 run_cmake(BadIndependentStep2)
18 run_cmake(NoOptions)
19 run_cmake(SourceEmpty)
20 run_cmake(SourceMissing)
21 run_cmake(CMAKE_CACHE_ARGS)
22 run_cmake(CMAKE_CACHE_DEFAULT_ARGS)
23 run_cmake(CMAKE_CACHE_mix)
24 if(NOT XCODE_VERSION OR XCODE_VERSION VERSION_LESS 12)
25   run_cmake(NO_DEPENDS-CMP0114-WARN)
26   run_cmake(NO_DEPENDS-CMP0114-OLD)
27 endif()
28 run_cmake(NO_DEPENDS-CMP0114-NEW)
29 run_cmake(NO_DEPENDS-CMP0114-NEW-Direct)
30 run_cmake(Add_StepDependencies)
31 run_cmake(Add_StepDependencies_iface)
32 run_cmake(Add_StepDependencies_iface_step)
33 run_cmake(Add_StepDependencies_no_target)
34 run_cmake(UsesTerminal)
35 if(XCODE_VERSION AND XCODE_VERSION VERSION_GREATER_EQUAL 12)
36   run_cmake(Xcode-CMP0114)
37 endif()
38
39 macro(check_steps_missing proj)
40   set(steps "${ARGN}")
41   foreach(step ${steps})
42     if(EXISTS ${RunCMake_TEST_BINARY_DIR}/${proj}-${step}-mark)
43       string(APPEND RunCMake_TEST_FAILED "${proj} '${step}' step ran but should not have\n")
44     endif()
45   endforeach()
46 endmacro()
47
48 macro(check_steps_present proj)
49   set(steps "${ARGN}")
50   foreach(step ${steps})
51     if(NOT EXISTS ${RunCMake_TEST_BINARY_DIR}/${proj}-${step}-mark)
52       string(APPEND RunCMake_TEST_FAILED "${proj} '${step}' step did not run but should have\n")
53     endif()
54   endforeach()
55 endmacro()
56
57 function(run_steps_CMP0114 val)
58   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/Steps-CMP0114-${val}-build)
59   run_cmake(Steps-CMP0114-${val})
60   set(RunCMake_TEST_NO_CLEAN 1)
61   run_cmake_command(Steps-CMP0114-${val}-build-download ${CMAKE_COMMAND} --build . --target proj1-download)
62   run_cmake_command(Steps-CMP0114-${val}-build-update ${CMAKE_COMMAND} --build . --target proj1-update)
63   run_cmake_command(Steps-CMP0114-${val}-build-install ${CMAKE_COMMAND} --build . --target proj1-install)
64   run_cmake_command(Steps-CMP0114-${val}-build-test ${CMAKE_COMMAND} --build . --target proj1-test)
65 endfunction()
66 if(NOT XCODE_VERSION OR XCODE_VERSION VERSION_LESS 12)
67   run_steps_CMP0114(OLD)
68 endif()
69 run_steps_CMP0114(NEW)
70
71 function(__ep_test_source_dir_change)
72   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/SourceDirChange-build)
73   set(RunCMake_TEST_NO_CLEAN 1)
74   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
75   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
76   run_cmake(SourceDirChange)
77   run_cmake_command(SourceDirChange-build1 ${CMAKE_COMMAND} --build .)
78   # Because some file systems have timestamps with only one second resolution,
79   # we have to ensure we don't re-run the configure stage too quickly after the
80   # first build. Otherwise, the modified RepositoryInfo.txt files the next
81   # configure writes might still have the same timestamp as the previous one.
82   execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${fs_delay})
83   run_cmake_command(SourceDirChange-change ${CMAKE_COMMAND} -DSOURCE_DIR_CHANGE=YES .)
84   run_cmake_command(SourceDirChange-build2 ${CMAKE_COMMAND} --build .)
85 endfunction()
86 __ep_test_source_dir_change()
87
88 # Run both cmake and build steps. We always do a clean before the
89 # build to ensure that the download step re-runs each time.
90 function(__ep_test_with_build testName)
91   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${testName}-build)
92   set(RunCMake_TEST_NO_CLEAN 1)
93   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
94   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
95   run_cmake(${testName})
96   run_cmake_command(${testName}-clean ${CMAKE_COMMAND} --build . --target clean)
97   run_cmake_command(${testName}-build ${CMAKE_COMMAND} --build .)
98 endfunction()
99
100 find_package(Python3)
101 function(__ep_test_with_build_with_server testName)
102   if(NOT Python3_EXECUTABLE)
103     return()
104   endif()
105   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${testName}-build)
106   set(RunCMake_TEST_NO_CLEAN 1)
107   set(RunCMake_TEST_TIMEOUT 20)
108   set(RunCMake_TEST_OUTPUT_MERGE TRUE)
109   file(REMOVE_RECURSE "${RunCMake_TEST_BINARY_DIR}")
110   file(MAKE_DIRECTORY "${RunCMake_TEST_BINARY_DIR}")
111   set(URL_FILE ${RunCMake_BINARY_DIR}/${testName}.url)
112   if(EXISTS "${URL_FILE}")
113     file(REMOVE "${URL_FILE}")
114   endif()
115   if(NOT DOWNLOAD_SERVER_TIMEOUT)
116     set(DOWNLOAD_SERVER_TIMEOUT 30)
117   endif()
118   execute_process(
119     COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/DownloadServer.py --file "${URL_FILE}" ${ARGN}
120     OUTPUT_FILE ${RunCMake_BINARY_DIR}/${testName}-python.txt
121     ERROR_FILE ${RunCMake_BINARY_DIR}/${testName}-python.txt
122     RESULT_VARIABLE result
123     TIMEOUT "${DOWNLOAD_SERVER_TIMEOUT}"
124     )
125   if(NOT result EQUAL 0)
126     message(FATAL_ERROR "Failed to start download server:\n  ${result}")
127   endif()
128
129   foreach(i RANGE 1 8)
130     if(EXISTS ${URL_FILE})
131       break()
132     endif()
133     execute_process(COMMAND ${CMAKE_COMMAND} -E sleep ${i})
134   endforeach()
135
136   if(NOT EXISTS ${URL_FILE})
137     message(FATAL_ERROR "Failed to load download server URL from:\n  ${URL_FILE}")
138   endif()
139
140   file(READ ${URL_FILE} SERVER_URL)
141   message(STATUS "URL : ${URL_FILE} - ${SERVER_URL}")
142   run_cmake_with_options(${testName} -DSERVER_URL=${SERVER_URL})
143   run_cmake_command(${testName}-clean ${CMAKE_COMMAND} --build . --target clean)
144   run_cmake_command(${testName}-build ${CMAKE_COMMAND} --build .)
145 endfunction()
146
147 __ep_test_with_build(MultiCommand)
148
149 set(RunCMake_TEST_OUTPUT_MERGE 1)
150 __ep_test_with_build(PreserveEmptyArgs)
151 set(RunCMake_TEST_OUTPUT_MERGE 0)
152
153 # Output is not predictable enough to be able to verify it reliably
154 # when using the various different Visual Studio generators
155 if(NOT RunCMake_GENERATOR MATCHES "Visual Studio")
156   __ep_test_with_build(LogOutputOnFailure)
157   __ep_test_with_build(LogOutputOnFailureMerged)
158   __ep_test_with_build(DownloadTimeout)
159   __ep_test_with_build_with_server(DownloadInactivityTimeout --speed_limit --limit_duration 40)
160   __ep_test_with_build_with_server(DownloadInactivityResume --speed_limit --limit_duration 1)
161 endif()
162
163 # We can't test the substitution when using the old MSYS due to
164 # make/sh mangling the paths (substitution is performed correctly,
165 # but the mangling means we can't reliably test the output).
166 # There is no such issue when using the newer MSYS though. Therefore,
167 # we need to bypass the substitution test if using old MSYS.
168 # See merge request 1537 for discussion.
169 set(doSubstitutionTest YES)
170 if(RunCMake_GENERATOR STREQUAL "MSYS Makefiles")
171   execute_process(COMMAND uname OUTPUT_VARIABLE uname)
172   if(uname MATCHES "^MINGW32_NT")
173       set(doSubstitutionTest NO)
174   endif()
175 endif()
176 if(doSubstitutionTest)
177     __ep_test_with_build(Substitutions)
178 endif()
179
180 function(__ep_test_BUILD_ALWAYS)
181   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/BUILD_ALWAYS-build)
182   run_cmake(BUILD_ALWAYS)
183   set(RunCMake_TEST_NO_CLEAN 1)
184   file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-configure.cmake" [[message(STATUS "once: configure")]])
185   file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-build.cmake" [[message(STATUS "once: build")]])
186   file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-install.cmake" [[message(STATUS "once: install")]])
187   file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-configure.cmake" [[message(STATUS "always: configure")]])
188   file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-build.cmake" [[message(STATUS "always: build")]])
189   file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-install.cmake" [[message(STATUS "always: install")]])
190   run_cmake_command(BUILD_ALWAYS-build1 ${CMAKE_COMMAND} --build . --target always)
191   file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-configure.cmake" [[message(FATAL_ERROR "once: configure should not run again")]])
192   file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-build.cmake" [[message(FATAL_ERROR "once: build should not run again")]])
193   file(WRITE "${RunCMake_TEST_BINARY_DIR}/once-install.cmake" [[message(FATAL_ERROR "once: install should not run again")]])
194   if(NOT RunCMake_GENERATOR MATCHES "^(Xcode|Visual Studio 9 )")
195     # The Xcode and VS 9 build systems decide to run this every time.
196     file(WRITE "${RunCMake_TEST_BINARY_DIR}/always-configure.cmake" [[message(FATAL_ERROR "always: configure should not run again")]])
197   endif()
198   run_cmake_command(BUILD_ALWAYS-build2 ${CMAKE_COMMAND} --build . --target always)
199 endfunction()
200 __ep_test_BUILD_ALWAYS()
201
202 function(__ep_test_CONFIGURE_HANDLED_BY_BUILD)
203   set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/CONFIGURE_HANDLED_BY_BUILD-build)
204   run_cmake(CONFIGURE_HANDLED_BY_BUILD)
205
206   if(RunCMake_GENERATOR_IS_MULTI_CONFIG)
207     set(BUILD_CONFIG --config Debug)
208     set(STAMP_DIR "${RunCMake_TEST_BINARY_DIR}/stamp/Debug")
209   else()
210     set(BUILD_CONFIG "")
211     set(STAMP_DIR "${RunCMake_TEST_BINARY_DIR}/stamp")
212   endif()
213
214   set(RunCMake_TEST_NO_CLEAN 1)
215   run_cmake_command(CONFIGURE_HANDLED_BY_BUILD-build ${CMAKE_COMMAND} --build . ${BUILD_CONFIG})
216
217   # Calculate timestamps before rebuilding so we can compare before and after in
218   # CONFIGURE_HANDLED_BY_BUILD-rebuild-check.cmake
219
220   file(TIMESTAMP "${STAMP_DIR}/proj1-configure" PROJ1_CONFIGURE_TIMESTAMP_BEFORE "%s")
221   # When BUILD_ALWAYS is set, the build stamp is never created.
222   file(TIMESTAMP "${STAMP_DIR}/proj2-configure" PROJ2_CONFIGURE_TIMESTAMP_BEFORE "%s")
223   file(TIMESTAMP "${STAMP_DIR}/proj2-build" PROJ2_BUILD_TIMESTAMP_BEFORE "%s")
224
225   run_cmake_command(CONFIGURE_HANDLED_BY_BUILD-rebuild ${CMAKE_COMMAND} --build . ${BUILD_CONFIG})
226 endfunction()
227
228 if(NOT RunCMake_GENERATOR MATCHES "Visual Studio 9 ")
229   __ep_test_CONFIGURE_HANDLED_BY_BUILD()
230 endif()
231
232 find_package(Git QUIET)
233 if(GIT_EXECUTABLE)
234   # Note that there appear to be differences in where git writes its output to
235   # on some platforms. It may go to stdout or stderr, so force it to be merged.
236   set(RunCMake_TEST_OUTPUT_MERGE TRUE)
237   run_cmake(FetchGitRefs)
238   set(RunCMake_TEST_OUTPUT_MERGE FALSE)
239 endif()