From 6199637e9540627b03d9018ff53a14f005274607 Mon Sep 17 00:00:00 2001 From: Frank Benkstein Date: Fri, 9 Nov 2018 19:14:58 +0100 Subject: configure_file: canonicalize input and output path in dependencies Represent the input file path internally in canonical form. Otherwise multiple `configure_file` calls that share the same input file but specify it relative to different directories (e.g. via `../`) result in multiple copies of the dependency on the rule to re-run CMake. This causes the Ninja generator to emit duplicate phony build statements for these dependencies, which generates an error with `-w dupbuild=err`, which will be default in Ninja 1.9. Also canonicalize the output path for consistency. Add a test case. Fixes: #18584 --- Source/cmConfigureFileCommand.cxx | 14 ++++---------- .../RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake | 5 +++++ Tests/RunCMake/Ninja/RunCMakeTest.cmake | 7 +++++++ Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt | 1 + Tests/RunCMake/configure_file/DirInput-stderr.txt | 2 +- 5 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake create mode 100644 Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt diff --git a/Source/cmConfigureFileCommand.cxx b/Source/cmConfigureFileCommand.cxx index b5a639a..305262d 100644 --- a/Source/cmConfigureFileCommand.cxx +++ b/Source/cmConfigureFileCommand.cxx @@ -20,11 +20,8 @@ bool cmConfigureFileCommand::InitialPass(std::vector const& args, } std::string const& inFile = args[0]; - if (!cmSystemTools::FileIsFullPath(inFile)) { - this->InputFile = this->Makefile->GetCurrentSourceDirectory(); - this->InputFile += "/"; - } - this->InputFile += inFile; + this->InputFile = cmSystemTools::CollapseFullPath( + inFile, this->Makefile->GetCurrentSourceDirectory()); // If the input location is a directory, error out. if (cmSystemTools::FileIsDirectory(this->InputFile)) { @@ -39,11 +36,8 @@ bool cmConfigureFileCommand::InitialPass(std::vector const& args, } std::string const& outFile = args[1]; - if (!cmSystemTools::FileIsFullPath(outFile)) { - this->OutputFile = this->Makefile->GetCurrentBinaryDirectory(); - this->OutputFile += "/"; - } - this->OutputFile += outFile; + this->OutputFile = cmSystemTools::CollapseFullPath( + outFile, this->Makefile->GetCurrentBinaryDirectory()); // If the output location is already a directory put the file in it. if (cmSystemTools::FileIsDirectory(this->OutputFile)) { diff --git a/Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake b/Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake new file mode 100644 index 0000000..505f750 --- /dev/null +++ b/Tests/RunCMake/Ninja/PreventConfigureFileDupBuildRule.cmake @@ -0,0 +1,5 @@ +cmake_minimum_required(VERSION 3.12) +project(Test LANGUAGES C) + +configure_file(PreventConfigureFileDupBuildRule.cmake PreventTargetAliasesDupBuildRule.cmake @ONLY) +add_subdirectory(SubDirConfigureFileDup) diff --git a/Tests/RunCMake/Ninja/RunCMakeTest.cmake b/Tests/RunCMake/Ninja/RunCMakeTest.cmake index 4b366a8..9e1e9a5 100644 --- a/Tests/RunCMake/Ninja/RunCMakeTest.cmake +++ b/Tests/RunCMake/Ninja/RunCMakeTest.cmake @@ -286,3 +286,10 @@ function (run_PreventTargetAliasesDupBuildRule) run_ninja("${RunCMake_TEST_BINARY_DIR}" -w dupbuild=err) endfunction () run_PreventTargetAliasesDupBuildRule() + +function (run_PreventConfigureFileDupBuildRule) + set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/PreventConfigureFileDupBuildRule-build) + run_cmake(PreventConfigureFileDupBuildRule) + run_ninja("${RunCMake_TEST_BINARY_DIR}" -w dupbuild=err) +endfunction() +run_PreventConfigureFileDupBuildRule() diff --git a/Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt b/Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt new file mode 100644 index 0000000..433f77b --- /dev/null +++ b/Tests/RunCMake/Ninja/SubDirConfigureFileDup/CMakeLists.txt @@ -0,0 +1 @@ +configure_file(../PreventConfigureFileDupBuildRule.cmake PreventTargetAliasesDupBuildRule.cmake @ONLY) diff --git a/Tests/RunCMake/configure_file/DirInput-stderr.txt b/Tests/RunCMake/configure_file/DirInput-stderr.txt index 2e0cd14..165ad80 100644 --- a/Tests/RunCMake/configure_file/DirInput-stderr.txt +++ b/Tests/RunCMake/configure_file/DirInput-stderr.txt @@ -1,7 +1,7 @@ CMake Error at DirInput.cmake:[0-9]+ \(configure_file\): configure_file input location - .*/Tests/RunCMake/configure_file/. + .*/Tests/RunCMake/configure_file is a directory but a file was expected. Call Stack \(most recent call first\): -- cgit v0.12