mirror of
https://github.com/Kitware/CMake.git
synced 2025-10-16 22:37:30 +08:00
cmake -E: Add cmake_transform_depfile internal command
This commit is contained in:
@@ -439,6 +439,8 @@ set(SRCS
|
|||||||
cmTest.h
|
cmTest.h
|
||||||
cmTestGenerator.cxx
|
cmTestGenerator.cxx
|
||||||
cmTestGenerator.h
|
cmTestGenerator.h
|
||||||
|
cmTransformDepfile.cxx
|
||||||
|
cmTransformDepfile.h
|
||||||
cmUuid.cxx
|
cmUuid.cxx
|
||||||
cmUVHandlePtr.cxx
|
cmUVHandlePtr.cxx
|
||||||
cmUVHandlePtr.h
|
cmUVHandlePtr.h
|
||||||
|
114
Source/cmTransformDepfile.cxx
Normal file
114
Source/cmTransformDepfile.cxx
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
|
#include "cmTransformDepfile.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <cm/optional>
|
||||||
|
|
||||||
|
#include "cmsys/FStream.hxx"
|
||||||
|
|
||||||
|
#include "cmGccDepfileReader.h"
|
||||||
|
#include "cmGccDepfileReaderTypes.h"
|
||||||
|
#include "cmStringAlgorithms.h"
|
||||||
|
#include "cmSystemTools.h"
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void WriteFilenameGcc(cmsys::ofstream& fout, const std::string& filename)
|
||||||
|
{
|
||||||
|
for (auto c : filename) {
|
||||||
|
switch (c) {
|
||||||
|
case ' ':
|
||||||
|
fout << "\\ ";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
fout << "\\\\";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
fout << c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteGccDepfile(cmsys::ofstream& fout, const cmGccDepfileContent& content)
|
||||||
|
{
|
||||||
|
for (auto const& dep : content) {
|
||||||
|
bool first = true;
|
||||||
|
for (auto const& rule : dep.rules) {
|
||||||
|
if (!first) {
|
||||||
|
fout << " \\\n ";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
WriteFilenameGcc(fout, rule);
|
||||||
|
}
|
||||||
|
fout << ':';
|
||||||
|
for (auto const& path : dep.paths) {
|
||||||
|
fout << " \\\n " << path;
|
||||||
|
}
|
||||||
|
fout << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteVsTlog(cmsys::ofstream& fout, const cmGccDepfileContent& content)
|
||||||
|
{
|
||||||
|
for (auto const& dep : content) {
|
||||||
|
fout << '^';
|
||||||
|
bool first = true;
|
||||||
|
for (auto const& rule : dep.rules) {
|
||||||
|
if (!first) {
|
||||||
|
fout << '|';
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
fout << cmSystemTools::ConvertToOutputPath(rule);
|
||||||
|
}
|
||||||
|
fout << "\r\n";
|
||||||
|
for (auto const& path : dep.paths) {
|
||||||
|
fout << cmSystemTools::ConvertToOutputPath(path) << "\r\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix,
|
||||||
|
const std::string& infile, const std::string& outfile)
|
||||||
|
{
|
||||||
|
cmGccDepfileContent content;
|
||||||
|
if (cmSystemTools::FileExists(infile)) {
|
||||||
|
auto result = cmReadGccDepfile(infile.c_str());
|
||||||
|
if (!result) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
content = *std::move(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto& dep : content) {
|
||||||
|
for (auto& rule : dep.rules) {
|
||||||
|
if (!cmSystemTools::FileIsFullPath(rule)) {
|
||||||
|
rule = cmStrCat(prefix, rule);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (auto& path : dep.paths) {
|
||||||
|
if (!cmSystemTools::FileIsFullPath(path)) {
|
||||||
|
path = cmStrCat(prefix, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmsys::ofstream fout(outfile.c_str());
|
||||||
|
if (!fout) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
switch (format) {
|
||||||
|
case cmDepfileFormat::GccDepfile:
|
||||||
|
WriteGccDepfile(fout, content);
|
||||||
|
break;
|
||||||
|
case cmDepfileFormat::VsTlog:
|
||||||
|
WriteVsTlog(fout, content);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
14
Source/cmTransformDepfile.h
Normal file
14
Source/cmTransformDepfile.h
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
file Copyright.txt or https://cmake.org/licensing for details. */
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
enum class cmDepfileFormat
|
||||||
|
{
|
||||||
|
GccDepfile,
|
||||||
|
VsTlog,
|
||||||
|
};
|
||||||
|
|
||||||
|
bool cmTransformDepfile(cmDepfileFormat format, const std::string& prefix,
|
||||||
|
const std::string& infile, const std::string& outfile);
|
@@ -19,6 +19,7 @@
|
|||||||
#include "cmStateSnapshot.h"
|
#include "cmStateSnapshot.h"
|
||||||
#include "cmStringAlgorithms.h"
|
#include "cmStringAlgorithms.h"
|
||||||
#include "cmSystemTools.h"
|
#include "cmSystemTools.h"
|
||||||
|
#include "cmTransformDepfile.h"
|
||||||
#include "cmUVProcessChain.h"
|
#include "cmUVProcessChain.h"
|
||||||
#include "cmUtils.hxx"
|
#include "cmUtils.hxx"
|
||||||
#include "cmVersion.h"
|
#include "cmVersion.h"
|
||||||
@@ -1426,6 +1427,23 @@ int cmcmd::ExecuteCMakeCommand(std::vector<std::string> const& args)
|
|||||||
return cmcmd::WindowsCEEnvironment("9.0", args[2]);
|
return cmcmd::WindowsCEEnvironment("9.0", args[2]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Internal depfile transformation
|
||||||
|
if (args[1] == "cmake_transform_depfile" && args.size() == 6) {
|
||||||
|
auto format = cmDepfileFormat::GccDepfile;
|
||||||
|
if (args[2] == "gccdepfile") {
|
||||||
|
format = cmDepfileFormat::GccDepfile;
|
||||||
|
} else if (args[2] == "vstlog") {
|
||||||
|
format = cmDepfileFormat::VsTlog;
|
||||||
|
} else {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
std::string prefix = args[3];
|
||||||
|
if (prefix == "./") {
|
||||||
|
prefix.clear();
|
||||||
|
}
|
||||||
|
return cmTransformDepfile(format, prefix, args[4], args[5]) ? 0 : 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
::CMakeCommandUsage(args[0].c_str());
|
::CMakeCommandUsage(args[0].c_str());
|
||||||
|
@@ -771,6 +771,7 @@ add_RunCMake_test(PrecompileHeaders -DCMAKE_C_COMPILER_ID=${CMAKE_C_COMPILER_ID}
|
|||||||
|
|
||||||
add_RunCMake_test("UnityBuild")
|
add_RunCMake_test("UnityBuild")
|
||||||
add_RunCMake_test(CMakePresets)
|
add_RunCMake_test(CMakePresets)
|
||||||
|
add_RunCMake_test(TransformDepfile)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_RunCMake_test(Win32GenEx)
|
add_RunCMake_test(Win32GenEx)
|
||||||
|
21
Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake
Normal file
21
Tests/RunCMake/TransformDepfile/RunCMakeTest.cmake
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
function(run_transform_depfile name)
|
||||||
|
set(RunCMake-check-file gccdepfile.cmake)
|
||||||
|
run_cmake_command(${name}-gcc
|
||||||
|
${CMAKE_COMMAND} -E cmake_transform_depfile gccdepfile ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.d
|
||||||
|
)
|
||||||
|
set(RunCMake-check-file vstlog.cmake)
|
||||||
|
run_cmake_command(${name}-tlog
|
||||||
|
${CMAKE_COMMAND} -E cmake_transform_depfile vstlog ../ ${CMAKE_CURRENT_LIST_DIR}/${name}.d out.tlog
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
run_transform_depfile(deps-windows)
|
||||||
|
else()
|
||||||
|
run_transform_depfile(deps-unix)
|
||||||
|
endif()
|
||||||
|
run_transform_depfile(noexist)
|
||||||
|
run_transform_depfile(empty)
|
||||||
|
run_transform_depfile(invalid)
|
6
Tests/RunCMake/TransformDepfile/deps-unix.d
Normal file
6
Tests/RunCMake/TransformDepfile/deps-unix.d
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
out1 /home/build/out2: in1 /home/build/in2
|
||||||
|
|
||||||
|
out3 \
|
||||||
|
/home/build/out4: \
|
||||||
|
in3 \
|
||||||
|
/home/build/in4
|
8
Tests/RunCMake/TransformDepfile/deps-unix.d.txt
Normal file
8
Tests/RunCMake/TransformDepfile/deps-unix.d.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
../out1 \
|
||||||
|
/home/build/out2: \
|
||||||
|
../in1 \
|
||||||
|
/home/build/in2
|
||||||
|
../out3 \
|
||||||
|
/home/build/out4: \
|
||||||
|
../in3 \
|
||||||
|
/home/build/in4
|
6
Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt
Normal file
6
Tests/RunCMake/TransformDepfile/deps-unix.tlog.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
^../out1|/home/build/out2
|
||||||
|
../in1
|
||||||
|
/home/build/in2
|
||||||
|
^../out3|/home/build/out4
|
||||||
|
../in3
|
||||||
|
/home/build/in4
|
6
Tests/RunCMake/TransformDepfile/deps-windows.d
Normal file
6
Tests/RunCMake/TransformDepfile/deps-windows.d
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
out1 C:/build/out2: in1 C:/build/in2
|
||||||
|
|
||||||
|
out3 \
|
||||||
|
C:/build/out4: \
|
||||||
|
in3 \
|
||||||
|
C:/build/in4
|
8
Tests/RunCMake/TransformDepfile/deps-windows.d.txt
Normal file
8
Tests/RunCMake/TransformDepfile/deps-windows.d.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
../out1 \
|
||||||
|
C:/build/out2: \
|
||||||
|
../in1 \
|
||||||
|
C:/build/in2
|
||||||
|
../out3 \
|
||||||
|
C:/build/out4: \
|
||||||
|
../in3 \
|
||||||
|
C:/build/in4
|
6
Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt
Normal file
6
Tests/RunCMake/TransformDepfile/deps-windows.tlog.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
^..\out1|C:\build\out2
|
||||||
|
..\in1
|
||||||
|
C:\build\in2
|
||||||
|
^..\out3|C:\build\out4
|
||||||
|
..\in3
|
||||||
|
C:\build\in4
|
0
Tests/RunCMake/TransformDepfile/empty.d
Normal file
0
Tests/RunCMake/TransformDepfile/empty.d
Normal file
0
Tests/RunCMake/TransformDepfile/empty.d.txt
Normal file
0
Tests/RunCMake/TransformDepfile/empty.d.txt
Normal file
0
Tests/RunCMake/TransformDepfile/empty.tlog.txt
Normal file
0
Tests/RunCMake/TransformDepfile/empty.tlog.txt
Normal file
16
Tests/RunCMake/TransformDepfile/gccdepfile.cmake
Normal file
16
Tests/RunCMake/TransformDepfile/gccdepfile.cmake
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
if(EXISTS "${RunCMake_SOURCE_DIR}/${name}.d.txt")
|
||||||
|
file(READ "${RunCMake_SOURCE_DIR}/${name}.d.txt" expected_contents)
|
||||||
|
|
||||||
|
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.d")
|
||||||
|
file(READ "${RunCMake_TEST_BINARY_DIR}/out.d" actual_contents)
|
||||||
|
if(NOT actual_contents STREQUAL expected_contents)
|
||||||
|
string(REPLACE "\n" "\n " p_expected_contents "${expected_contents}")
|
||||||
|
string(REPLACE "\n" "\n " p_actual_contents "${actual_contents}")
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "Expected contents of ${RunCMake_TEST_BINARY_DIR}/out.d:\n ${p_expected_contents}\nActual contents:\n ${p_actual_contents}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.d should exist\n")
|
||||||
|
endif()
|
||||||
|
elseif(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.d")
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.d should not exist\n")
|
||||||
|
endif()
|
1
Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt
Normal file
1
Tests/RunCMake/TransformDepfile/invalid-gcc-result.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
1
Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt
Normal file
1
Tests/RunCMake/TransformDepfile/invalid-tlog-result.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
1
|
1
Tests/RunCMake/TransformDepfile/invalid.d
Normal file
1
Tests/RunCMake/TransformDepfile/invalid.d
Normal file
@@ -0,0 +1 @@
|
|||||||
|
invalid
|
0
Tests/RunCMake/TransformDepfile/noexist.d.txt
Normal file
0
Tests/RunCMake/TransformDepfile/noexist.d.txt
Normal file
0
Tests/RunCMake/TransformDepfile/noexist.tlog.txt
Normal file
0
Tests/RunCMake/TransformDepfile/noexist.tlog.txt
Normal file
16
Tests/RunCMake/TransformDepfile/vstlog.cmake
Normal file
16
Tests/RunCMake/TransformDepfile/vstlog.cmake
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
if(EXISTS "${RunCMake_SOURCE_DIR}/${name}.tlog.txt")
|
||||||
|
file(READ "${RunCMake_SOURCE_DIR}/${name}.tlog.txt" expected_contents)
|
||||||
|
|
||||||
|
if(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.tlog")
|
||||||
|
file(READ "${RunCMake_TEST_BINARY_DIR}/out.tlog" actual_contents)
|
||||||
|
if(NOT actual_contents STREQUAL expected_contents)
|
||||||
|
string(REPLACE "\n" "\n " p_expected_contents "${expected_contents}")
|
||||||
|
string(REPLACE "\n" "\n " p_actual_contents "${actual_contents}")
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "Expected contents of ${RunCMake_TEST_BINARY_DIR}/out.tlog:\n ${p_expected_contents}\nActual contents:\n ${p_actual_contents}")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.tlog should exist\n")
|
||||||
|
endif()
|
||||||
|
elseif(EXISTS "${RunCMake_TEST_BINARY_DIR}/out.tlog")
|
||||||
|
string(APPEND RunCMake_TEST_FAILED "${RunCMake_TEST_BINARY_DIR}/out.tlog should not exist\n")
|
||||||
|
endif()
|
@@ -412,6 +412,8 @@ CMAKE_CXX_SOURCES="\
|
|||||||
cmProjectCommand \
|
cmProjectCommand \
|
||||||
cmPropertyDefinition \
|
cmPropertyDefinition \
|
||||||
cmPropertyMap \
|
cmPropertyMap \
|
||||||
|
cmGccDepfileLexerHelper \
|
||||||
|
cmGccDepfileReader \
|
||||||
cmReturnCommand \
|
cmReturnCommand \
|
||||||
cmRulePlaceholderExpander \
|
cmRulePlaceholderExpander \
|
||||||
cmRuntimeDependencyArchive \
|
cmRuntimeDependencyArchive \
|
||||||
@@ -452,6 +454,7 @@ CMAKE_CXX_SOURCES="\
|
|||||||
cmTest \
|
cmTest \
|
||||||
cmTestGenerator \
|
cmTestGenerator \
|
||||||
cmTimestamp \
|
cmTimestamp \
|
||||||
|
cmTransformDepfile \
|
||||||
cmTryCompileCommand \
|
cmTryCompileCommand \
|
||||||
cmTryRunCommand \
|
cmTryRunCommand \
|
||||||
cmUnsetCommand \
|
cmUnsetCommand \
|
||||||
@@ -491,6 +494,7 @@ LexerParser_CXX_SOURCES="\
|
|||||||
cmCommandArgumentParser \
|
cmCommandArgumentParser \
|
||||||
cmExprLexer \
|
cmExprLexer \
|
||||||
cmExprParser \
|
cmExprParser \
|
||||||
|
cmGccDepfileLexer \
|
||||||
"
|
"
|
||||||
|
|
||||||
LexerParser_C_SOURCES="\
|
LexerParser_C_SOURCES="\
|
||||||
|
Reference in New Issue
Block a user