瀏覽代碼

cmake: Fix relative path regression in -C

Since commit 4ca0526f8a (cmake: Pass -S and -B into PreLoad.cmake and -C
scripts, 2019-08-20, v3.16.0-rc1~195^2) the value of `CMAKE_SOURCE_DIR`
is the source directory rather than the current working directory.
This was correct on its own, but the place storing that value is also
used as the base for relative paths specified on the command line.
The latter should of course be relative to the current working
directory.

The fix is to switch to use a full path internally, unless a full path
is already specified.  Add tests for the behaviour of `-C` under these
four circumstances:

    {with -S, without -S} x {full path, relative path}

Fixes: #19827
Peter Waller 6 年之前
父節點
當前提交
c9d73b26b0

+ 2 - 0
Source/cmake.cxx

@@ -423,6 +423,8 @@ bool cmake::SetCacheArgs(const std::vector<std::string>& args)
         }
         }
       }
       }
       std::cout << "loading initial cache file " << path << "\n";
       std::cout << "loading initial cache file " << path << "\n";
+      // Resolve script path specified on command line relative to $PWD.
+      path = cmSystemTools::CollapseFullPath(path);
       this->ReadListFile(args, path);
       this->ReadListFile(args, path);
     } else if (arg.find("-P", 0) == 0) {
     } else if (arg.find("-P", 0) == 0) {
       i++;
       i++;

+ 1 - 1
Tests/RunCMake/CommandLine/C-no-file-stderr.txt

@@ -1,3 +1,3 @@
-^CMake Error: Error processing file: nosuchcachefile.txt
+^CMake Error: Error processing file: .*/Tests/RunCMake/CommandLine/C-no-file-build/nosuchcachefile.txt
 CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/C-no-file-build" does not appear to contain CMakeLists.txt.
 CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/C-no-file-build" does not appear to contain CMakeLists.txt.
 Specify --help for usage, or press the help button on the CMake GUI.$
 Specify --help for usage, or press the help button on the CMake GUI.$

+ 4 - 0
Tests/RunCMake/CommandLine/C_basic-stderr.txt

@@ -0,0 +1,4 @@
+initial-cache.txt: CMAKE_SOURCE_DIR: .*/Tests/RunCMake/CommandLine
+initial-cache.txt: CMAKE_BINARY_DIR: .*/Tests/RunCMake/CommandLine/C_basic-build
+CMakeLists.txt: INITIAL_SOURCE_DIR: .*/Tests/RunCMake/CommandLine
+CMakeLists.txt: INITIAL_BINARY_DIR: .*/Tests/RunCMake/CommandLine/C_basic-build

+ 1 - 0
Tests/RunCMake/CommandLine/C_basic-stdout.txt

@@ -0,0 +1 @@
+loading initial cache file ../C_basic_initial-cache.txt

+ 2 - 0
Tests/RunCMake/CommandLine/C_basic.cmake

@@ -0,0 +1,2 @@
+message("CMakeLists.txt: INITIAL_SOURCE_DIR: ${INITIAL_SOURCE_DIR}")
+message("CMakeLists.txt: INITIAL_BINARY_DIR: ${INITIAL_BINARY_DIR}")

+ 4 - 0
Tests/RunCMake/CommandLine/C_basic_fullpath-stderr.txt

@@ -0,0 +1,4 @@
+initial-cache.txt: CMAKE_SOURCE_DIR: .*/Tests/RunCMake/CommandLine
+initial-cache.txt: CMAKE_BINARY_DIR: .*/Tests/RunCMake/CommandLine/C_basic_fullpath-build
+CMakeLists.txt: INITIAL_SOURCE_DIR: .*/Tests/RunCMake/CommandLine
+CMakeLists.txt: INITIAL_BINARY_DIR: .*/Tests/RunCMake/CommandLine/C_basic_fullpath-build

+ 1 - 0
Tests/RunCMake/CommandLine/C_basic_fullpath-stdout.txt

@@ -0,0 +1 @@
+loading initial cache file .*/Tests/RunCMake/CommandLine/C_basic_initial-cache.txt

+ 2 - 0
Tests/RunCMake/CommandLine/C_basic_fullpath.cmake

@@ -0,0 +1,2 @@
+message("CMakeLists.txt: INITIAL_SOURCE_DIR: ${INITIAL_SOURCE_DIR}")
+message("CMakeLists.txt: INITIAL_BINARY_DIR: ${INITIAL_BINARY_DIR}")

+ 5 - 0
Tests/RunCMake/CommandLine/C_basic_initial-cache.txt

@@ -0,0 +1,5 @@
+set(INITIAL_SOURCE_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "defined in initial.cmake")
+set(INITIAL_BINARY_DIR "${CMAKE_BINARY_DIR}" CACHE PATH "defined in initial.cmake")
+
+message("initial-cache.txt: CMAKE_SOURCE_DIR: ${CMAKE_SOURCE_DIR}")
+message("initial-cache.txt: CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR}")

+ 4 - 4
Tests/RunCMake/CommandLine/C_buildsrcdir-stderr.txt

@@ -1,8 +1,8 @@
 initial-cache.txt: CMAKE_SOURCE_DIR: .*/C_buildsrcdir/src
 initial-cache.txt: CMAKE_SOURCE_DIR: .*/C_buildsrcdir/src
-initial-cache.txt: CMAKE_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
+initial-cache.txt: CMAKE_BINARY_DIR: .*/ExplicitDirs-build/DummyBuildDir
 PreLoad.cmake: CMAKE_SOURCE_DIR: .*/C_buildsrcdir/src
 PreLoad.cmake: CMAKE_SOURCE_DIR: .*/C_buildsrcdir/src
-PreLoad.cmake: CMAKE_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
+PreLoad.cmake: CMAKE_BINARY_DIR: .*/ExplicitDirs-build/DummyBuildDir
 CMakeLists.txt: INITIAL_SOURCE_DIR: .*/C_buildsrcdir/src
 CMakeLists.txt: INITIAL_SOURCE_DIR: .*/C_buildsrcdir/src
-CMakeLists.txt: INITIAL_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
+CMakeLists.txt: INITIAL_BINARY_DIR: .*/ExplicitDirs-build/DummyBuildDir
 CMakeLists.txt: PRELOAD_SOURCE_DIR: .*/C_buildsrcdir/src
 CMakeLists.txt: PRELOAD_SOURCE_DIR: .*/C_buildsrcdir/src
-CMakeLists.txt: PRELOAD_BINARY_DIR: .*/C_buildsrcdir-build/DummyBuildDir
+CMakeLists.txt: PRELOAD_BINARY_DIR: .*/ExplicitDirs-build/DummyBuildDir

+ 1 - 1
Tests/RunCMake/CommandLine/C_buildsrcdir-stdout.txt

@@ -1,2 +1,2 @@
-loading initial cache file .*/C_buildsrcdir/initial-cache.txt
+loading initial cache file .*initial-cache.txt
 .*
 .*

+ 1 - 1
Tests/RunCMake/CommandLine/Cno-file-stderr.txt

@@ -1,3 +1,3 @@
-^CMake Error: Error processing file: nosuchcachefile.txt
+^CMake Error: Error processing file: .*/Tests/RunCMake/CommandLine/Cno-file-build/nosuchcachefile.txt
 CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/Cno-file-build" does not appear to contain CMakeLists.txt.
 CMake Error: The source directory ".*/Tests/RunCMake/CommandLine/Cno-file-build" does not appear to contain CMakeLists.txt.
 Specify --help for usage, or press the help button on the CMake GUI.$
 Specify --help for usage, or press the help button on the CMake GUI.$

+ 12 - 3
Tests/RunCMake/CommandLine/RunCMakeTest.cmake

@@ -110,6 +110,14 @@ project(ExplicitDirsMissing LANGUAGES NONE)
   file(REMOVE_RECURSE "${binary_dir}")
   file(REMOVE_RECURSE "${binary_dir}")
   run_cmake_with_options(B-S -B${binary_dir} -S${source_dir})
   run_cmake_with_options(B-S -B${binary_dir} -S${source_dir})
 
 
+  message("copied to ${RunCMake_TEST_BINARY_DIR}/initial-cache.txt")
+  file(COPY ${RunCMake_SOURCE_DIR}/C_buildsrcdir/initial-cache.txt DESTINATION ${RunCMake_TEST_BINARY_DIR})
+
+  # CMAKE_BINARY_DIR should be determined by -B if specified, and CMAKE_SOURCE_DIR determined by -S if specified.
+  # Path to initial-cache.txt is relative to the $PWD, which is normally set to ${RunCMake_TEST_BINARY_DIR}.
+  run_cmake_with_options(C_buildsrcdir -B DummyBuildDir -S ${RunCMake_SOURCE_DIR}/C_buildsrcdir/src -C initial-cache.txt)
+  # Test that full path works, too.
+  run_cmake_with_options(C_buildsrcdir -B DummyBuildDir -S ${RunCMake_SOURCE_DIR}/C_buildsrcdir/src -C ${RunCMake_TEST_BINARY_DIR}/initial-cache.txt)
 endfunction()
 endfunction()
 run_ExplicitDirs()
 run_ExplicitDirs()
 
 
@@ -406,9 +414,10 @@ run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMa
 # Tests the values of CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_SOURCE_DIR.
 # Tests the values of CMAKE_BINARY_DIR CMAKE_CURRENT_BINARY_DIR CMAKE_SOURCE_DIR CMAKE_CURRENT_SOURCE_DIR.
 run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMake_BINARY_DIR}/P_working-dir-build -P ${RunCMake_SOURCE_DIR}/P_working-dir.cmake -S something_else -B something_else_1)
 run_cmake_command(P_working-dir ${CMAKE_COMMAND} -DEXPECTED_WORKING_DIR=${RunCMake_BINARY_DIR}/P_working-dir-build -P ${RunCMake_SOURCE_DIR}/P_working-dir.cmake -S something_else -B something_else_1)
 
 
-# CMAKE_BINARY_DIR should be determined by -B if specified, and CMAKE_SOURCE_DIR determined by -S if specified.
-run_cmake_with_options(C_buildsrcdir -B DummyBuildDir -S ${RunCMake_SOURCE_DIR}/C_buildsrcdir/src -C ${RunCMake_SOURCE_DIR}/C_buildsrcdir/initial-cache.txt)
-
+# Place an initial cache where C_basic will find it when passed the relative path "..".
+file(COPY ${RunCMake_SOURCE_DIR}/C_basic_initial-cache.txt DESTINATION ${RunCMake_BINARY_DIR})
+run_cmake_with_options(C_basic -C ../C_basic_initial-cache.txt)
+run_cmake_with_options(C_basic_fullpath -C ${RunCMake_BINARY_DIR}/C_basic_initial-cache.txt)
 
 
 set(RunCMake_TEST_OPTIONS
 set(RunCMake_TEST_OPTIONS
   "-DFOO=-DBAR:BOOL=BAZ")
   "-DFOO=-DBAR:BOOL=BAZ")