Makefiles: Add support of DEPFILE for add_custom_command
Issue: #20286 Fixes: #21415
This commit is contained in:
parent
a526f71266
commit
cfd8a5ac1f
@ -201,6 +201,10 @@ The options are:
|
||||
Note that the ``IMPLICIT_DEPENDS`` option is currently supported
|
||||
only for Makefile generators and will be ignored by other generators.
|
||||
|
||||
.. note::
|
||||
|
||||
This option cannot be specified at the same time as ``DEPFILE`` option.
|
||||
|
||||
``JOB_POOL``
|
||||
.. versionadded:: 3.15
|
||||
|
||||
@ -263,15 +267,26 @@ The options are:
|
||||
``DEPFILE``
|
||||
.. versionadded:: 3.7
|
||||
|
||||
Specify a ``.d`` depfile for the :generator:`Ninja` generator.
|
||||
Specify a ``.d`` depfile for the :generator:`Ninja` generator and
|
||||
:ref:`Makefile Generators`.
|
||||
A ``.d`` file holds dependencies usually emitted by the custom
|
||||
command itself.
|
||||
Using ``DEPFILE`` with other generators than Ninja is an error.
|
||||
Using ``DEPFILE`` with other generators than :generator:`Ninja` or
|
||||
:ref:`Makefile Generators` is an error.
|
||||
|
||||
.. versionadded:: 3.20
|
||||
Added the support of :ref:`Makefile Generators`.
|
||||
|
||||
If the ``DEPFILE`` argument is relative, it should be relative to
|
||||
:variable:`CMAKE_CURRENT_BINARY_DIR`, and any relative paths inside the
|
||||
``DEPFILE`` should also be relative to :variable:`CMAKE_CURRENT_BINARY_DIR`
|
||||
(see policy :policy:`CMP0116`.)
|
||||
(see policy :policy:`CMP0116`. This policy is always ``NEW`` for
|
||||
:ref:`Makefile Generators`).
|
||||
|
||||
.. note::
|
||||
|
||||
For :ref:`Makefile Generators`, this option cannot be specified at the
|
||||
same time as ``IMPLICIT_DEPENDS`` option.
|
||||
|
||||
Examples: Generating Files
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
5
Help/release/dev/makefile-depfile.rst
Normal file
5
Help/release/dev/makefile-depfile.rst
Normal file
@ -0,0 +1,5 @@
|
||||
makefile-depfile
|
||||
----------------
|
||||
|
||||
* The :command:`add_custom_command` command gained ``DEPFILE`` support on
|
||||
:ref:`Makefile Generators`.
|
@ -296,6 +296,12 @@ bool cmAddCustomCommandCommand(std::vector<std::string> const& args,
|
||||
status.SetError("given APPEND option with no OUTPUT.");
|
||||
return false;
|
||||
}
|
||||
if (!implicit_depends.empty() && !depfile.empty() &&
|
||||
mf.GetGlobalGenerator()->GetName() != "Ninja") {
|
||||
// Makefiles generators does not support both at the same time
|
||||
status.SetError("IMPLICIT_DEPENDS and DEPFILE can not both be specified.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check for an append request.
|
||||
if (append) {
|
||||
|
@ -19,6 +19,7 @@
|
||||
|
||||
#include "cmFileTime.h"
|
||||
#include "cmGccDepfileReader.h"
|
||||
#include "cmGccDepfileReaderTypes.h"
|
||||
#include "cmGlobalUnixMakefileGenerator3.h"
|
||||
#include "cmLocalUnixMakefileGenerator3.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
@ -86,7 +87,7 @@ bool cmDependsCompiler::CheckDependencies(
|
||||
if (!forceReadDeps) {
|
||||
depFileTime.Load(depFile);
|
||||
}
|
||||
if (forceReadDeps || depFileTime.Newer(internalDepFileTime)) {
|
||||
if (forceReadDeps || depFileTime.Compare(internalDepFileTime) >= 0) {
|
||||
status = false;
|
||||
if (this->Verbose) {
|
||||
cmSystemTools::Stdout(cmStrCat("Dependencies file \"", depFile,
|
||||
@ -95,59 +96,92 @@ bool cmDependsCompiler::CheckDependencies(
|
||||
}
|
||||
|
||||
std::vector<std::string> depends;
|
||||
if (format == "msvc"_s) {
|
||||
cmsys::ifstream fin(depFile.c_str());
|
||||
if (!fin) {
|
||||
continue;
|
||||
if (format == "custom"_s) {
|
||||
std::string prefix;
|
||||
if (this->LocalGenerator->GetCurrentBinaryDirectory() !=
|
||||
this->LocalGenerator->GetBinaryDirectory()) {
|
||||
prefix =
|
||||
cmStrCat(this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetBinaryDirectory(),
|
||||
this->LocalGenerator->GetCurrentBinaryDirectory()),
|
||||
'/');
|
||||
}
|
||||
|
||||
std::string line;
|
||||
if (!isValidPath) {
|
||||
// insert source as first dependency
|
||||
depends.push_back(source);
|
||||
}
|
||||
while (cmSystemTools::GetLineFromStream(fin, line)) {
|
||||
depends.emplace_back(std::move(line));
|
||||
}
|
||||
} else {
|
||||
auto deps = cmReadGccDepfile(depFile.c_str());
|
||||
auto deps = cmReadGccDepfile(depFile.c_str(), prefix);
|
||||
if (!deps) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// dependencies generated by the compiler contains only one target
|
||||
depends = std::move(deps->front().paths);
|
||||
if (depends.empty()) {
|
||||
// unexpectedly empty, ignore it and continue
|
||||
for (auto& entry : *deps) {
|
||||
depends = std::move(entry.paths);
|
||||
if (isValidPath) {
|
||||
cm::erase_if(depends, isValidPath);
|
||||
}
|
||||
// copy depends for each target, except first one, which can be
|
||||
// moved
|
||||
for (auto index = entry.rules.size() - 1; index > 0; --index) {
|
||||
dependencies[entry.rules[index]] = depends;
|
||||
}
|
||||
dependencies[entry.rules.front()] = std::move(depends);
|
||||
}
|
||||
} else {
|
||||
if (format == "msvc"_s) {
|
||||
cmsys::ifstream fin(depFile.c_str());
|
||||
if (!fin) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string line;
|
||||
if (!isValidPath) {
|
||||
// insert source as first dependency
|
||||
depends.push_back(source);
|
||||
}
|
||||
while (cmSystemTools::GetLineFromStream(fin, line)) {
|
||||
depends.emplace_back(std::move(line));
|
||||
}
|
||||
} else if (format == "gcc"_s) {
|
||||
auto deps = cmReadGccDepfile(depFile.c_str());
|
||||
if (!deps) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// dependencies generated by the compiler contains only one target
|
||||
depends = std::move(deps->front().paths);
|
||||
if (depends.empty()) {
|
||||
// unexpectedly empty, ignore it and continue
|
||||
continue;
|
||||
}
|
||||
|
||||
// depending of the effective format of the dependencies file
|
||||
// generated by the compiler, the target can be wrongly identified
|
||||
// as a dependency so remove it from the list
|
||||
if (depends.front() == target) {
|
||||
depends.erase(depends.begin());
|
||||
}
|
||||
|
||||
// ensure source file is the first dependency
|
||||
if (depends.front() != source) {
|
||||
cm::erase(depends, source);
|
||||
if (!isValidPath) {
|
||||
depends.insert(depends.begin(), source);
|
||||
}
|
||||
} else if (isValidPath) {
|
||||
// remove first dependency because it must not be filtered out
|
||||
depends.erase(depends.begin());
|
||||
}
|
||||
} else {
|
||||
// unknown format, ignore it
|
||||
continue;
|
||||
}
|
||||
|
||||
// depending of the effective format of the dependencies file generated
|
||||
// by the compiler, the target can be wrongly identified as a
|
||||
// dependency so remove it from the list
|
||||
if (depends.front() == target) {
|
||||
depends.erase(depends.begin());
|
||||
if (isValidPath) {
|
||||
cm::erase_if(depends, isValidPath);
|
||||
// insert source as first dependency
|
||||
depends.insert(depends.begin(), source);
|
||||
}
|
||||
|
||||
// ensure source file is the first dependency
|
||||
if (depends.front() != source) {
|
||||
cm::erase(depends, source);
|
||||
if (!isValidPath) {
|
||||
depends.insert(depends.begin(), source);
|
||||
}
|
||||
} else if (isValidPath) {
|
||||
// remove first dependency because it must not be filtered out
|
||||
depends.erase(depends.begin());
|
||||
}
|
||||
dependencies[target] = std::move(depends);
|
||||
}
|
||||
|
||||
if (isValidPath) {
|
||||
cm::erase_if(depends, isValidPath);
|
||||
// insert source as first dependency
|
||||
depends.insert(depends.begin(), source);
|
||||
}
|
||||
|
||||
dependencies[target] = std::move(depends);
|
||||
}
|
||||
}
|
||||
|
||||
@ -168,6 +202,8 @@ void cmDependsCompiler::WriteDependencies(
|
||||
|
||||
// external dependencies file
|
||||
for (auto& node : makeDependencies) {
|
||||
auto target = LocalGenerator->ConvertToMakefilePath(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(binDir, node.first));
|
||||
auto& deps = node.second;
|
||||
std::transform(
|
||||
deps.cbegin(), deps.cend(), deps.begin(),
|
||||
@ -176,13 +212,16 @@ void cmDependsCompiler::WriteDependencies(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(binDir, dep));
|
||||
});
|
||||
|
||||
makeDepends << this->LocalGenerator->ConvertToMakefilePath(node.first)
|
||||
<< ": " << deps.front();
|
||||
// first dependency is the source, remove it because should not be declared
|
||||
// as phony target
|
||||
deps.erase(deps.begin());
|
||||
bool first_dep = true;
|
||||
makeDepends << target << ": ";
|
||||
for (const auto& dep : deps) {
|
||||
makeDepends << ' ' << lineContinue << " " << dep;
|
||||
if (first_dep) {
|
||||
first_dep = false;
|
||||
makeDepends << dep;
|
||||
} else {
|
||||
makeDepends << ' ' << lineContinue << " " << dep;
|
||||
}
|
||||
|
||||
phonyTargets.emplace(dep.data(), dep.length());
|
||||
}
|
||||
makeDepends << std::endl << std::endl;
|
||||
|
@ -93,6 +93,12 @@ public:
|
||||
*/
|
||||
static bool SupportsPlatform() { return false; }
|
||||
|
||||
/**
|
||||
* Utilized to determine if this generator
|
||||
* supports DEPFILE option.
|
||||
*/
|
||||
bool SupportsCustomCommandDepfile() const override { return true; }
|
||||
|
||||
/** Get the documentation entry for this generator. */
|
||||
static void GetDocumentation(cmDocumentationEntry& entry);
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <cm/string_view>
|
||||
#include <cm/vector>
|
||||
#include <cmext/algorithm>
|
||||
#include <cmext/string_view>
|
||||
|
||||
#include "cmsys/FStream.hxx"
|
||||
#include "cmsys/Terminal.h"
|
||||
@ -1435,7 +1436,7 @@ bool cmLocalUnixMakefileGenerator3::UpdateDependencies(
|
||||
this->Makefile->GetSafeDefinition("CMAKE_DEPENDS_DEPENDENCY_FILES");
|
||||
if (!depends.empty()) {
|
||||
// dependencies are managed by compiler
|
||||
auto depFiles = cmExpandedList(depends);
|
||||
auto depFiles = cmExpandedList(depends, true);
|
||||
std::string const internalDepFile =
|
||||
targetDir + "/compiler_depend.internal";
|
||||
std::string const depFile = targetDir + "/compiler_depend.make";
|
||||
@ -1998,18 +1999,32 @@ void cmLocalUnixMakefileGenerator3::WriteDependLanguageInfo(
|
||||
cmakefileStream << "\n# The set of dependency files which are needed:\n";
|
||||
cmakefileStream << "set(CMAKE_DEPENDS_DEPENDENCY_FILES\n";
|
||||
for (auto const& compilerLang : compilerLangs) {
|
||||
auto depFormat = this->Makefile->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
|
||||
auto const& compilerPairs = compilerLang.second;
|
||||
for (auto const& compilerPair : compilerPairs) {
|
||||
for (auto const& src : compilerPair.second) {
|
||||
cmakefileStream << " \"" << src << "\" \""
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), compilerPair.first)
|
||||
<< "\" \"" << depFormat << "\" \""
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), compilerPair.first)
|
||||
<< ".d\"\n";
|
||||
if (compilerLang.first == "CUSTOM"_s) {
|
||||
for (auto const& compilerPair : compilerPairs) {
|
||||
for (auto const& src : compilerPair.second) {
|
||||
cmakefileStream << R"( "" ")"
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), compilerPair.first)
|
||||
<< R"(" "custom" ")"
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), src)
|
||||
<< "\"\n";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
auto depFormat = this->Makefile->GetSafeDefinition(
|
||||
cmStrCat("CMAKE_", compilerLang.first, "_DEPFILE_FORMAT"));
|
||||
for (auto const& compilerPair : compilerPairs) {
|
||||
for (auto const& src : compilerPair.second) {
|
||||
cmakefileStream << " \"" << src << "\" \""
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), compilerPair.first)
|
||||
<< "\" \"" << depFormat << "\" \""
|
||||
<< this->MaybeConvertToRelativePath(
|
||||
this->GetBinaryDirectory(), compilerPair.first)
|
||||
<< ".d\"\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1617,6 +1617,16 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
|
||||
std::vector<std::string> depends;
|
||||
this->LocalGenerator->AppendCustomDepend(depends, ccg);
|
||||
|
||||
if (!ccg.GetCC().GetDepfile().empty()) {
|
||||
// Add dependency over timestamp file for dependencies management
|
||||
auto dependTimestamp = cmSystemTools::ConvertToOutputPath(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetBinaryDirectory(),
|
||||
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts")));
|
||||
|
||||
depends.push_back(dependTimestamp);
|
||||
}
|
||||
|
||||
// Write the rule.
|
||||
const std::vector<std::string>& outputs = ccg.GetOutputs();
|
||||
bool symbolic = this->WriteMakeRule(*this->BuildFileStream, nullptr, outputs,
|
||||
@ -1653,6 +1663,15 @@ void cmMakefileTargetGenerator::GenerateCustomRuleFile(
|
||||
objFullPath, srcFullPath);
|
||||
}
|
||||
|
||||
// Setup implicit depend for depfile if any
|
||||
if (!ccg.GetCC().GetDepfile().empty()) {
|
||||
std::string objFullPath = cmSystemTools::CollapseFullPath(
|
||||
outputs[0], this->LocalGenerator->GetCurrentBinaryDirectory());
|
||||
this->LocalGenerator->AddImplicitDepends(
|
||||
this->GeneratorTarget, "CUSTOM", objFullPath, ccg.GetFullDepfile(),
|
||||
cmDependencyScannerKind::Compiler);
|
||||
}
|
||||
|
||||
this->CustomCommandOutputs.insert(outputs.begin(), outputs.end());
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "cmLocalUnixMakefileGenerator3.h"
|
||||
#include "cmMakefile.h"
|
||||
#include "cmOSXBundleGenerator.h"
|
||||
#include "cmStringAlgorithms.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
cmMakefileUtilityTargetGenerator::cmMakefileUtilityTargetGenerator(
|
||||
@ -36,10 +37,42 @@ void cmMakefileUtilityTargetGenerator::WriteRuleFiles()
|
||||
*this->BuildFileStream << "# Utility rule file for "
|
||||
<< this->GeneratorTarget->GetName() << ".\n\n";
|
||||
|
||||
const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")
|
||||
? "$(CMAKE_BINARY_DIR)/"
|
||||
: "");
|
||||
|
||||
// Include the dependencies for the target.
|
||||
std::string dependFile =
|
||||
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.make");
|
||||
*this->BuildFileStream
|
||||
<< "# Include any custom commands dependencies for this target.\n"
|
||||
<< this->GlobalGenerator->IncludeDirective << " " << root
|
||||
<< cmSystemTools::ConvertToOutputPath(
|
||||
this->LocalGenerator->MaybeConvertToRelativePath(
|
||||
this->LocalGenerator->GetBinaryDirectory(), dependFile))
|
||||
<< "\n\n";
|
||||
if (!cmSystemTools::FileExists(dependFile)) {
|
||||
// Write an empty dependency file.
|
||||
cmGeneratedFileStream depFileStream(
|
||||
dependFile, false, this->GlobalGenerator->GetMakefileEncoding());
|
||||
depFileStream << "# Empty custom commands generated dependencies file for "
|
||||
<< this->GeneratorTarget->GetName() << ".\n"
|
||||
<< "# This may be replaced when dependencies are built.\n";
|
||||
}
|
||||
|
||||
std::string dependTimestamp =
|
||||
cmStrCat(this->TargetBuildDirectoryFull, "/compiler_depend.ts");
|
||||
if (!cmSystemTools::FileExists(dependTimestamp)) {
|
||||
// Write a dependency timestamp file.
|
||||
cmGeneratedFileStream depFileStream(
|
||||
dependTimestamp, false, this->GlobalGenerator->GetMakefileEncoding());
|
||||
depFileStream << "# CMAKE generated file: DO NOT EDIT!\n"
|
||||
<< "# Timestamp file for custom commands dependencies "
|
||||
"management for "
|
||||
<< this->GeneratorTarget->GetName() << ".\n";
|
||||
}
|
||||
|
||||
if (!this->NoRuleMessages) {
|
||||
const char* root = (this->Makefile->IsOn("CMAKE_MAKE_INCLUDE_FROM_ROOT")
|
||||
? "$(CMAKE_BINARY_DIR)/"
|
||||
: "");
|
||||
// Include the progress variables for the target.
|
||||
*this->BuildFileStream
|
||||
<< "# Include the progress variables for this target.\n"
|
||||
|
@ -1272,6 +1272,8 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args,
|
||||
cmStateSnapshot snapshot = cm.GetCurrentSnapshot();
|
||||
snapshot.GetDirectory().SetCurrentBinary(startOutDir);
|
||||
snapshot.GetDirectory().SetCurrentSource(startDir);
|
||||
snapshot.GetDirectory().SetRelativePathTopSource(homeDir.c_str());
|
||||
snapshot.GetDirectory().SetRelativePathTopBinary(homeOutDir.c_str());
|
||||
cmMakefile mf(cm.GetGlobalGenerator(), snapshot);
|
||||
auto lgd = cm.GetGlobalGenerator()->CreateLocalGenerator(&mf);
|
||||
|
||||
|
@ -0,0 +1,4 @@
|
||||
CMake Error at CustomCommandDependencies-BadArgs.cmake:[0-9]+ \(add_custom_command\):
|
||||
add_custom_command IMPLICIT_DEPENDS and DEPFILE can not both be specified.
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:[0-9]+ \(include\)
|
@ -0,0 +1,10 @@
|
||||
enable_language(C)
|
||||
|
||||
add_custom_command(OUTPUT main.c
|
||||
DEPFILE main.c.d
|
||||
IMPLICIT_DEPENDS C main.c.in
|
||||
COMMAND "${CMAKE_COMMAND}" -DINFILE=main.c.in -DOUTFILE=main.c -DDEPFILE=main.c.d
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/GenerateDepFile.cmake"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
add_custom_target(mainc ALL DEPENDS main.c)
|
73
Tests/RunCMake/BuildDepends/CustomCommandDependencies.cmake
Normal file
73
Tests/RunCMake/BuildDepends/CustomCommandDependencies.cmake
Normal file
@ -0,0 +1,73 @@
|
||||
enable_language(C)
|
||||
|
||||
add_custom_command(OUTPUT main.c
|
||||
DEPFILE main.c.d
|
||||
COMMAND "${CMAKE_COMMAND}" -DINFILE=main.c.in -DOUTFILE=main.c -DDEPFILE=main.c.d
|
||||
-P "${CMAKE_CURRENT_SOURCE_DIR}/GenerateDepFile.cmake"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
add_custom_target(mainc ALL DEPENDS main.c)
|
||||
|
||||
add_executable(main ${CMAKE_CURRENT_BINARY_DIR}/main.c)
|
||||
|
||||
file(GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/check-$<LOWER_CASE:$<CONFIG>>.cmake CONTENT "
|
||||
cmake_minimum_required(VERSION 3.19)
|
||||
set(check_pairs
|
||||
\"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c.in\"
|
||||
\"$<TARGET_FILE:main>|${CMAKE_CURRENT_BINARY_DIR}/main.c\"
|
||||
)
|
||||
set(check_exes
|
||||
\"$<TARGET_FILE:main>\"
|
||||
)
|
||||
|
||||
if (check_step EQUAL 2)
|
||||
include(\"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/Makefile.cmake\")
|
||||
if (NOT CMAKE_DEPEND_INFO_FILES)
|
||||
set(RunCMake_TEST_FAILED \"Variable CMAKE_DEPEND_INFO_FILES not found.\")
|
||||
else()
|
||||
foreach(DEPEND_INFO_FILE IN LISTS CMAKE_DEPEND_INFO_FILES)
|
||||
include(\"${CMAKE_CURRENT_BINARY_DIR}/\${DEPEND_INFO_FILE}\")
|
||||
if (NOT CMAKE_DEPENDS_DEPENDENCY_FILES)
|
||||
set(RunCMake_TEST_FAILED \"Variable CMAKE_DEPENDS_DEPENDENCY_FILES not found.\")
|
||||
else()
|
||||
list(LENGTH CMAKE_DEPENDS_DEPENDENCY_FILES DEPENDENCY_FILES_SIZE)
|
||||
math(EXPR STOP_INDEX \"\${DEPENDENCY_FILES_SIZE} - 1\")
|
||||
foreach(INDEX RANGE 0 \${STOP_INDEX} 4)
|
||||
math(EXPR OBJECT_INDEX \"\${INDEX} + 1\")
|
||||
math(EXPR FORMAT_INDEX \"\${INDEX} + 2\")
|
||||
math(EXPR DEP_INDEX \"\${INDEX} + 3\")
|
||||
list(GET CMAKE_DEPENDS_DEPENDENCY_FILES \${OBJECT_INDEX} OBJECT_FILE)
|
||||
list(GET CMAKE_DEPENDS_DEPENDENCY_FILES \${FORMAT_INDEX} DEP_FORMAT)
|
||||
list(GET CMAKE_DEPENDS_DEPENDENCY_FILES \${DEP_INDEX} DEP_FILE)
|
||||
if (NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/\${DEP_FILE}\")
|
||||
set(RunCMake_TEST_FAILED \"File \${DEP_FILE} not found.\")
|
||||
else()
|
||||
cmake_path(APPEND TARGET_DEP_FILE \"${CMAKE_CURRENT_BINARY_DIR}\" \"\${DEPEND_INFO_FILE}\")
|
||||
cmake_path(REPLACE_FILENAME TARGET_DEP_FILE \"compiler_depend.make\")
|
||||
file(READ \"\${TARGET_DEP_FILE}\" DEPENDS_CONTENT)
|
||||
if (WIN32)
|
||||
string (REPLACE \"\\\\\" \"/\" DEPENDS_CONTENT \"\${DEPENDS_CONTENT}\")
|
||||
string (TOLOWER \"\${DEPENDS_CONTENT}\" DEPENDS_CONTENT)
|
||||
string (TOLOWER \"\${OBJECT_FILE}\" OBJECT_FILE)
|
||||
else()
|
||||
string(REPLACE \"\\\\ \" \" \" DEPENDS_CONTENT \"\${DEPENDS_CONTENT}\")
|
||||
endif()
|
||||
if(DEPEND_INFO_FILE MATCHES \"main\\\\.dir\")
|
||||
if (DEP_FORMAT STREQUAL \"gcc\" AND NOT DEPENDS_CONTENT MATCHES \"\${OBJECT_FILE} *:.+main.c\")
|
||||
set(RunCMake_TEST_FAILED \"Dependency file '\${TARGET_DEP_FILE}' badly generated:\\n\${DEPENDS_CONTENT}\")
|
||||
endif()
|
||||
if (DEP_FORMAT STREQUAL \"custom\" AND NOT DEPENDS_CONTENT MATCHES \"\${OBJECT_FILE} *:.+main.c.in\")
|
||||
set(RunCMake_TEST_FAILED \"Dependency file '\${TARGET_DEP_FILE}' badly generated:\\n\${DEPENDS_CONTENT}\")
|
||||
endif()
|
||||
else()
|
||||
if (NOT DEPENDS_CONTENT MATCHES \"\${OBJECT_FILE} *:.+main.c.in\")
|
||||
set(RunCMake_TEST_FAILED \"Dependency file '\${TARGET_DEP_FILE}' badly generated:\\n\${DEPENDS_CONTENT}\")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
endif()
|
||||
")
|
@ -0,0 +1,3 @@
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[
|
||||
int main(void) { return 1; }
|
||||
]])
|
@ -0,0 +1,3 @@
|
||||
file(WRITE "${RunCMake_TEST_BINARY_DIR}/main.c.in" [[
|
||||
int main(void) { return 2; }
|
||||
]])
|
6
Tests/RunCMake/BuildDepends/GenerateDepFile.cmake
Normal file
6
Tests/RunCMake/BuildDepends/GenerateDepFile.cmake
Normal file
@ -0,0 +1,6 @@
|
||||
file(READ "${INFILE}" INCONTENT)
|
||||
file(WRITE "${OUTFILE}" "${INCONTENT}")
|
||||
|
||||
string(REPLACE [[ ]] [[\ ]] OUTFILE "${OUTFILE}")
|
||||
string(REPLACE [[ ]] [[\ ]] INFILE "${INFILE}")
|
||||
file(WRITE "${DEPFILE}" "${OUTFILE}: ${INFILE}\n")
|
@ -122,4 +122,9 @@ if ((RunCMake_GENERATOR STREQUAL "Unix Makefiles"
|
||||
AND MSVC_VERSION GREATER 1300
|
||||
AND CMAKE_C_COMPILER_ID STREQUAL "MSVC"))
|
||||
run_BuildDepends(CompilerDependencies)
|
||||
run_BuildDepends(CustomCommandDependencies)
|
||||
endif()
|
||||
|
||||
if (RunCMake_GENERATOR MATCHES "Makefiles")
|
||||
run_cmake(CustomCommandDependencies-BadArgs)
|
||||
endif()
|
||||
|
@ -1,5 +0,0 @@
|
||||
^CMake Error at CustomCommandDepfile-ERROR.cmake:1 \(add_custom_command\):
|
||||
add_custom_command Option DEPFILE not supported by [^
|
||||
]+
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)$
|
@ -1,8 +0,0 @@
|
||||
add_custom_command(
|
||||
OUTPUT hello.copy.c
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/hello.c"
|
||||
hello.copy.c
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
DEPFILE "test.d"
|
||||
)
|
@ -39,7 +39,6 @@ function(run_VerboseBuild)
|
||||
endfunction()
|
||||
run_VerboseBuild()
|
||||
|
||||
run_cmake(CustomCommandDepfile-ERROR)
|
||||
run_cmake(IncludeRegexSubdir)
|
||||
|
||||
function(run_MakefileConflict)
|
||||
|
Loading…
Reference in New Issue
Block a user