From c4af46b4443374f0a0a64bb7db87750454cc3dac Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Wed, 28 May 2014 20:16:39 +0200 Subject: [PATCH] add_custom_command: Normalize OUTPUT and DEPENDS paths. While tracing dependencies of a target, cmTargetTraceDependencies follows sources by full path to determine if the source is to be produced by a custom command. Commit 4959f341 (cmSourceFileLocation: Collapse full path for directory comparisons., 2014-03-27) changed the storage of target sources to be in the form of a normalized path instead of an unnormalized path. The path is followed by looking it up in a mapping via cmMakefile::GetSourceFileWithOutput to acquire an appropriate cmSourceFile. The mapping is populated with the OUTPUT components of add_custom_command invocations, however it is populated with unnormalized paths. This means that the tracing logic does not find appropriate cmSourceFiles, and does not generate appropriate build rules for the generated sources. Normalize the paths in the OUTPUT components of add_custom_command to resolve this. The paths in the DEPENDS component of add_custom_command are also not normalized, leading to the same problem again. Normalize the depends paths after generator evaluation and expansion. --- Source/cmAddCustomCommandCommand.cxx | 4 ++++ Source/cmCustomCommandGenerator.cxx | 12 +++++++++++- Tests/CustomCommand/CMakeLists.txt | 27 +++++++++++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/Source/cmAddCustomCommandCommand.cxx b/Source/cmAddCustomCommandCommand.cxx index d5f00ff12..6a955506d 100644 --- a/Source/cmAddCustomCommandCommand.cxx +++ b/Source/cmAddCustomCommandCommand.cxx @@ -173,6 +173,10 @@ bool cmAddCustomCommandCommand break; } + if (cmSystemTools::FileIsFullPath(filename.c_str())) + { + filename = cmSystemTools::CollapseFullPath(filename); + } switch (doing) { case doing_working_directory: diff --git a/Source/cmCustomCommandGenerator.cxx b/Source/cmCustomCommandGenerator.cxx index cebd9f5d3..ebfbf7c09 100644 --- a/Source/cmCustomCommandGenerator.cxx +++ b/Source/cmCustomCommandGenerator.cxx @@ -103,8 +103,18 @@ std::vector const& cmCustomCommandGenerator::GetDepends() const { cmsys::auto_ptr cge = this->GE->Parse(*i); + std::vector result; cmSystemTools::ExpandListArgument( - cge->Evaluate(this->Makefile, this->Config), this->Depends); + cge->Evaluate(this->Makefile, this->Config), result); + for (std::vector::iterator it = result.begin(); + it != result.end(); ++it) + { + if (cmSystemTools::FileIsFullPath(it->c_str())) + { + *it = cmSystemTools::CollapseFullPath(*it); + } + } + this->Depends.insert(this->Depends.end(), result.begin(), result.end()); } } return this->Depends; diff --git a/Tests/CustomCommand/CMakeLists.txt b/Tests/CustomCommand/CMakeLists.txt index e0854ceaa..b97cd1642 100644 --- a/Tests/CustomCommand/CMakeLists.txt +++ b/Tests/CustomCommand/CMakeLists.txt @@ -456,3 +456,30 @@ add_custom_target(source_in_custom_target SOURCES source_in_custom_target.cpp) set_property(SOURCE source_in_custom_target PROPERTY COMPILE_DEFINITIONS "TEST" ) + +set(gen_path "${CMAKE_CURRENT_BINARY_DIR}//./foo") +set(gen_file "${gen_path}/foo.cxx") + +add_custom_command( + OUTPUT "${gen_file}" + # Make sure the output directory exists before trying to write to it. + COMMAND ${CMAKE_COMMAND} -E make_directory "${gen_path}" + COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}" +) + +add_library(NormOutput "${gen_file}") + +set(gen_path "${gen_path}/bar") +set(gen_file "${gen_path}/bar.cxx") + +add_custom_command( + OUTPUT "${gen_path}" + COMMAND ${CMAKE_COMMAND} -E make_directory "${gen_path}" +) + +add_custom_command( + OUTPUT "${gen_file}" + DEPENDS "${gen_path}" + COMMAND ${CMAKE_COMMAND} -E touch "${gen_file}") + +add_library(NormDepends "${gen_file}")