mirror of
https://github.com/Kitware/CMake.git
synced 2026-01-08 23:00:07 -06:00
VS,Xcode: Add CMakeLists.txt sources without mutating targets
Rather than injecting `CMakeLists.txt` files into each target's `SOURCES`, teach the generators to add them during generation using dedicated code. This avoids mutating the original targets, and avoids polluting `$<TARGET_PROPERTY:foo,SOURCES>` with generator-specific content. This also avoids listing the `CMakeLists.txt` sources in the results of `CMAKE_DEBUG_TARGET_PROPERTIES==SOURCES` so the `RunCMake.TargetSources` test no longer needs a separate case for IDEs.
This commit is contained in:
@@ -106,15 +106,6 @@ void cmGlobalVisualStudioGenerator::AddExtraIDETargets()
|
||||
// Configure CMake Visual Studio macros, for this user on this version
|
||||
// of Visual Studio.
|
||||
this->ConfigureCMakeVisualStudioMacros();
|
||||
|
||||
// Add CMakeLists.txt with custom command to rerun CMake.
|
||||
for (std::vector<cmLocalGenerator*>::const_iterator lgi =
|
||||
this->LocalGenerators.begin();
|
||||
lgi != this->LocalGenerators.end(); ++lgi) {
|
||||
cmLocalVisualStudioGenerator* lg =
|
||||
static_cast<cmLocalVisualStudioGenerator*>(*lgi);
|
||||
lg->AddCMakeListsRules();
|
||||
}
|
||||
}
|
||||
|
||||
void cmGlobalVisualStudioGenerator::ComputeTargetObjectDirectory(
|
||||
|
||||
@@ -438,12 +438,6 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
|
||||
cmGeneratorTarget* allBuildGt = new cmGeneratorTarget(allbuild, root);
|
||||
root->AddGeneratorTarget(allBuildGt);
|
||||
|
||||
// Refer to the main build configuration file for easy editing.
|
||||
std::string listfile = root->GetCurrentSourceDirectory();
|
||||
listfile += "/";
|
||||
listfile += "CMakeLists.txt";
|
||||
allBuildGt->AddSource(listfile);
|
||||
|
||||
// Add XCODE depend helper
|
||||
std::string dir = root->GetCurrentBinaryDirectory();
|
||||
cmCustomCommandLine makeHelper;
|
||||
@@ -513,12 +507,6 @@ void cmGlobalXCodeGenerator::AddExtraTargets(
|
||||
!target->GetPropertyAsBool("EXCLUDE_FROM_ALL")) {
|
||||
allbuild->AddUtility(target->GetName());
|
||||
}
|
||||
|
||||
// Refer to the build configuration file for easy editing.
|
||||
listfile = gen->GetCurrentSourceDirectory();
|
||||
listfile += "/";
|
||||
listfile += "CMakeLists.txt";
|
||||
target->AddSource(listfile);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -996,6 +984,13 @@ bool cmGlobalXCodeGenerator::CreateXCodeTargets(
|
||||
if (!gtgt->GetConfigCommonSourceFiles(classes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Add CMakeLists.txt file for user convenience.
|
||||
std::string listfile =
|
||||
gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
|
||||
listfile += "/CMakeLists.txt";
|
||||
classes.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
|
||||
|
||||
std::sort(classes.begin(), classes.end(), cmSourceFilePathCompare());
|
||||
|
||||
gtgt->ComputeObjectMapping();
|
||||
@@ -2299,6 +2294,12 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add CMakeLists.txt file for user convenience.
|
||||
std::string listfile =
|
||||
gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
|
||||
listfile += "/CMakeLists.txt";
|
||||
sources.push_back(gtgt->Makefile->GetOrCreateSource(listfile));
|
||||
|
||||
for (std::vector<cmSourceFile*>::const_iterator i = sources.begin();
|
||||
i != sources.end(); ++i) {
|
||||
if (!(*i)->GetPropertyAsBool("GENERATED")) {
|
||||
@@ -2740,6 +2741,20 @@ bool cmGlobalXCodeGenerator::CreateGroups(
|
||||
std::string key = GetGroupMapKeyFromPath(gtgt, source);
|
||||
this->GroupMap[key] = pbxgroup;
|
||||
}
|
||||
|
||||
// Add CMakeLists.txt file for user convenience.
|
||||
{
|
||||
std::string listfile =
|
||||
gtgt->GetLocalGenerator()->GetCurrentSourceDirectory();
|
||||
listfile += "/CMakeLists.txt";
|
||||
cmSourceFile* sf = gtgt->Makefile->GetOrCreateSource(listfile);
|
||||
std::string const& source = sf->GetFullPath();
|
||||
cmSourceGroup* sourceGroup =
|
||||
mf->FindSourceGroup(source.c_str(), sourceGroups);
|
||||
cmXCodeObject* pbxgroup = this->CreateOrGetPBXGroup(gtgt, sourceGroup);
|
||||
std::string key = GetGroupMapKeyFromPath(gtgt, source);
|
||||
this->GroupMap[key] = pbxgroup;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -36,6 +36,13 @@ private:
|
||||
cmLocalVisualStudio7Generator* LocalGenerator;
|
||||
};
|
||||
|
||||
class cmLocalVisualStudio7Generator::AllConfigSources
|
||||
{
|
||||
public:
|
||||
std::vector<cmGeneratorTarget::AllConfigSource> Sources;
|
||||
std::map<cmSourceFile const*, size_t> Index;
|
||||
};
|
||||
|
||||
extern cmVS7FlagTable cmLocalVisualStudio7GeneratorFlagTable[];
|
||||
|
||||
static void cmConvertToWindowsSlash(std::string& s)
|
||||
@@ -83,29 +90,6 @@ void cmLocalVisualStudio7Generator::Generate()
|
||||
this->WriteStampFiles();
|
||||
}
|
||||
|
||||
void cmLocalVisualStudio7Generator::AddCMakeListsRules()
|
||||
{
|
||||
// Create the regeneration custom rule.
|
||||
if (!this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION")) {
|
||||
// Create a rule to regenerate the build system when the target
|
||||
// specification source changes.
|
||||
if (cmSourceFile* sf = this->CreateVCProjBuildRule()) {
|
||||
// Add the rule to targets that need it.
|
||||
const std::vector<cmGeneratorTarget*>& tgts =
|
||||
this->GetGeneratorTargets();
|
||||
for (std::vector<cmGeneratorTarget*>::const_iterator l = tgts.begin();
|
||||
l != tgts.end(); ++l) {
|
||||
if ((*l)->GetType() == cmStateEnums::GLOBAL_TARGET) {
|
||||
continue;
|
||||
}
|
||||
if ((*l)->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
|
||||
(*l)->AddSource(sf->GetFullPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmLocalVisualStudio7Generator::FixGlobalTargets()
|
||||
{
|
||||
// Visual Studio .NET 2003 Service Pack 1 will not run post-build
|
||||
@@ -239,19 +223,29 @@ void cmLocalVisualStudio7Generator::CreateSingleVCProj(
|
||||
|
||||
cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
|
||||
{
|
||||
if (this->Makefile->IsOn("CMAKE_SUPPRESS_REGENERATION")) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string makefileIn = this->GetCurrentSourceDirectory();
|
||||
makefileIn += "/";
|
||||
makefileIn += "CMakeLists.txt";
|
||||
makefileIn = cmSystemTools::CollapseFullPath(makefileIn);
|
||||
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn)) {
|
||||
if (file->GetCustomCommand()) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
if (!cmSystemTools::FileExists(makefileIn)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string stampName = this->GetCurrentBinaryDirectory();
|
||||
stampName += "/";
|
||||
stampName += cmake::GetCMakeFilesDirectoryPostSlash();
|
||||
stampName += "generate.stamp";
|
||||
cmCustomCommandLine commandLine;
|
||||
commandLine.push_back(cmSystemTools::GetCMakeCommand());
|
||||
std::string makefileIn = this->GetCurrentSourceDirectory();
|
||||
makefileIn += "/";
|
||||
makefileIn += "CMakeLists.txt";
|
||||
makefileIn = cmSystemTools::CollapseFullPath(makefileIn.c_str());
|
||||
if (!cmSystemTools::FileExists(makefileIn.c_str())) {
|
||||
return 0;
|
||||
}
|
||||
std::string comment = "Building Custom Rule ";
|
||||
comment += makefileIn;
|
||||
std::string args;
|
||||
@@ -275,10 +269,13 @@ cmSourceFile* cmLocalVisualStudio7Generator::CreateVCProjBuildRule()
|
||||
fullpathStampName.c_str(), listFiles, makefileIn.c_str(), commandLines,
|
||||
comment.c_str(), no_working_directory, true, false);
|
||||
if (cmSourceFile* file = this->Makefile->GetSource(makefileIn.c_str())) {
|
||||
// Finalize the source file path now since we're adding this after
|
||||
// the generator validated all project-named sources.
|
||||
file->GetFullPath();
|
||||
return file;
|
||||
} else {
|
||||
cmSystemTools::Error("Error adding rule for ", makefileIn.c_str());
|
||||
return 0;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1368,13 +1365,26 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||
// We may be modifying the source groups temporarily, so make a copy.
|
||||
std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();
|
||||
|
||||
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
|
||||
target->GetAllConfigSources();
|
||||
std::map<cmSourceFile const*, size_t> sourcesIndex;
|
||||
AllConfigSources sources;
|
||||
sources.Sources = target->GetAllConfigSources();
|
||||
|
||||
for (size_t si = 0; si < sources.size(); ++si) {
|
||||
cmSourceFile const* sf = sources[si].Source;
|
||||
sourcesIndex[sf] = si;
|
||||
// Add CMakeLists.txt file with rule to re-run CMake for user convenience.
|
||||
if (target->GetType() != cmStateEnums::GLOBAL_TARGET &&
|
||||
target->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
|
||||
if (cmSourceFile const* sf = this->CreateVCProjBuildRule()) {
|
||||
cmGeneratorTarget::AllConfigSource acs;
|
||||
acs.Source = sf;
|
||||
acs.Kind = cmGeneratorTarget::SourceKindCustomCommand;
|
||||
for (size_t ci = 0; ci < configs.size(); ++ci) {
|
||||
acs.Configs.push_back(ci);
|
||||
}
|
||||
sources.Sources.emplace_back(std::move(acs));
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t si = 0; si < sources.Sources.size(); ++si) {
|
||||
cmSourceFile const* sf = sources.Sources[si].Source;
|
||||
sources.Index[sf] = si;
|
||||
if (!sf->GetObjectLibrary().empty()) {
|
||||
if (this->FortranProject) {
|
||||
// Intel Fortran does not support per-config source locations
|
||||
@@ -1400,7 +1410,7 @@ void cmLocalVisualStudio7Generator::WriteVCProjFile(std::ostream& fout,
|
||||
// Loop through every source group.
|
||||
for (unsigned int i = 0; i < sourceGroups.size(); ++i) {
|
||||
cmSourceGroup sg = sourceGroups[i];
|
||||
this->WriteGroup(&sg, target, fout, libName, configs, sourcesIndex);
|
||||
this->WriteGroup(&sg, target, fout, libName, configs, sources);
|
||||
}
|
||||
|
||||
fout << "\t</Files>\n";
|
||||
@@ -1567,7 +1577,7 @@ std::string cmLocalVisualStudio7Generator::ComputeLongestObjectDirectory(
|
||||
bool cmLocalVisualStudio7Generator::WriteGroup(
|
||||
const cmSourceGroup* sg, cmGeneratorTarget* target, std::ostream& fout,
|
||||
const std::string& libName, std::vector<std::string> const& configs,
|
||||
std::map<cmSourceFile const*, size_t> const& sourcesIndex)
|
||||
AllConfigSources const& sources)
|
||||
{
|
||||
cmGlobalVisualStudio7Generator* gg =
|
||||
static_cast<cmGlobalVisualStudio7Generator*>(this->GlobalGenerator);
|
||||
@@ -1579,7 +1589,7 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
|
||||
std::ostringstream tmpOut;
|
||||
for (unsigned int i = 0; i < children.size(); ++i) {
|
||||
if (this->WriteGroup(&children[i], target, tmpOut, libName, configs,
|
||||
sourcesIndex)) {
|
||||
sources)) {
|
||||
hasChildrenWithSources = true;
|
||||
}
|
||||
}
|
||||
@@ -1595,9 +1605,6 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
|
||||
this->WriteVCProjBeginGroup(fout, name.c_str(), "");
|
||||
}
|
||||
|
||||
std::vector<cmGeneratorTarget::AllConfigSource> const& sources =
|
||||
target->GetAllConfigSources();
|
||||
|
||||
// Loop through each source in the source group.
|
||||
for (std::vector<const cmSourceFile*>::const_iterator sf =
|
||||
sourceFiles.begin();
|
||||
@@ -1608,10 +1615,11 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
|
||||
target->GetType() == cmStateEnums::GLOBAL_TARGET) {
|
||||
// Look up the source kind and configs.
|
||||
std::map<cmSourceFile const*, size_t>::const_iterator map_it =
|
||||
sourcesIndex.find(*sf);
|
||||
sources.Index.find(*sf);
|
||||
// The map entry must exist because we populated it earlier.
|
||||
assert(map_it != sourcesIndex.end());
|
||||
cmGeneratorTarget::AllConfigSource const& acs = sources[map_it->second];
|
||||
assert(map_it != sources.Index.end());
|
||||
cmGeneratorTarget::AllConfigSource const& acs =
|
||||
sources.Sources[map_it->second];
|
||||
|
||||
FCInfo fcinfo(this, target, acs, configs);
|
||||
|
||||
|
||||
@@ -65,7 +65,6 @@ public:
|
||||
|
||||
virtual void ReadAndStoreExternalGUID(const std::string& name,
|
||||
const char* path);
|
||||
virtual void AddCMakeListsRules();
|
||||
|
||||
protected:
|
||||
void CreateSingleVCProj(const std::string& lname, cmGeneratorTarget* tgt);
|
||||
@@ -117,10 +116,11 @@ private:
|
||||
FCInfo& fcinfo);
|
||||
void WriteTargetVersionAttribute(std::ostream& fout, cmGeneratorTarget* gt);
|
||||
|
||||
class AllConfigSources;
|
||||
bool WriteGroup(const cmSourceGroup* sg, cmGeneratorTarget* target,
|
||||
std::ostream& fout, const std::string& libName,
|
||||
std::vector<std::string> const& configs,
|
||||
std::map<cmSourceFile const*, size_t> const& sourcesIndex);
|
||||
AllConfigSources const& sources);
|
||||
|
||||
friend class cmLocalVisualStudio7GeneratorFCInfo;
|
||||
friend class cmLocalVisualStudio7GeneratorInternals;
|
||||
|
||||
@@ -44,8 +44,6 @@ public:
|
||||
virtual std::string ComputeLongestObjectDirectory(
|
||||
cmGeneratorTarget const*) const = 0;
|
||||
|
||||
virtual void AddCMakeListsRules() = 0;
|
||||
|
||||
virtual void ComputeObjectFilenames(
|
||||
std::map<cmSourceFile const*, std::string>& mapping,
|
||||
cmGeneratorTarget const* = 0);
|
||||
|
||||
@@ -1174,6 +1174,15 @@ void cmVisualStudio10TargetGenerator::WriteCustomCommands()
|
||||
si != customCommands.end(); ++si) {
|
||||
this->WriteCustomCommand(*si);
|
||||
}
|
||||
|
||||
// Add CMakeLists.txt file with rule to re-run CMake for user convenience.
|
||||
if (this->GeneratorTarget->GetType() != cmStateEnums::GLOBAL_TARGET &&
|
||||
this->GeneratorTarget->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
|
||||
if (cmSourceFile const* sf =
|
||||
this->LocalGenerator->CreateVCProjBuildRule()) {
|
||||
this->WriteCustomCommand(sf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void cmVisualStudio10TargetGenerator::WriteCustomCommand(
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
file(READ ${RunCMake_TEST_BINARY_DIR}/foo.txt foo_sources)
|
||||
|
||||
# VS generators inject CMakeLists.txt as a source. Remove it.
|
||||
string(REGEX REPLACE ";[^;]*CMakeLists.txt$" "" foo_sources "${foo_sources}")
|
||||
|
||||
set(foo_expected "empty.c;empty2.c;empty3.c")
|
||||
if(NOT foo_sources STREQUAL foo_expected)
|
||||
set(RunCMake_TEST_FAILED "foo SOURCES was:\n [[${foo_sources}]]\nbut expected:\n [[${foo_expected}]]")
|
||||
|
||||
@@ -6,9 +6,7 @@ CMake Error in CMakeLists.txt:
|
||||
|
||||
.*/Tests/RunCMake/TargetSources/empty_1.cpp
|
||||
.*/Tests/RunCMake/TargetSources/empty_2.cpp
|
||||
.*/Tests/RunCMake/TargetSources/CMakeLists.txt
|
||||
|
||||
Config "Release":
|
||||
|
||||
.*/Tests/RunCMake/TargetSources/empty_1.cpp
|
||||
.*/Tests/RunCMake/TargetSources/CMakeLists.txt
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
0
|
||||
@@ -1,40 +0,0 @@
|
||||
CMake Debug Log at OriginDebug.cmake:13 \(add_library\):
|
||||
Used sources for target OriginDebug:
|
||||
|
||||
\* .*Tests/RunCMake/TargetSources/empty_2.cpp
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
OriginDebugIDE.cmake:4 \(include\)
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Debug Log at OriginDebug.cmake:16 \(set_property\):
|
||||
Used sources for target OriginDebug:
|
||||
|
||||
\* .*Tests/RunCMake/TargetSources/empty_3.cpp
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
OriginDebugIDE.cmake:4 \(include\)
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Debug Log at OriginDebug.cmake:20 \(target_sources\):
|
||||
Used sources for target OriginDebug:
|
||||
|
||||
\* .*Tests/RunCMake/TargetSources/empty_4.cpp
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
OriginDebugIDE.cmake:4 \(include\)
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Debug Log in CMakeLists.txt:
|
||||
Used sources for target OriginDebug:
|
||||
|
||||
* .*CMakeLists.txt
|
||||
+
|
||||
CMake Debug Log at OriginDebug.cmake:14 \(target_link_libraries\):
|
||||
Used sources for target OriginDebug:
|
||||
|
||||
\* .*Tests/RunCMake/TargetSources/empty_1.cpp
|
||||
|
||||
Call Stack \(most recent call first\):
|
||||
OriginDebugIDE.cmake:4 \(include\)
|
||||
CMakeLists.txt:3 \(include\)
|
||||
@@ -1,4 +0,0 @@
|
||||
|
||||
# Separate test for the IDEs, because they show the CMakeLists.txt file
|
||||
# as a source file.
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/OriginDebug.cmake)
|
||||
@@ -2,11 +2,9 @@ include(RunCMake)
|
||||
|
||||
if(RunCMake_GENERATOR MATCHES "Visual Studio|Xcode")
|
||||
run_cmake(ConfigNotAllowed)
|
||||
run_cmake(OriginDebugIDE)
|
||||
else()
|
||||
run_cmake(OriginDebug)
|
||||
endif()
|
||||
|
||||
run_cmake(OriginDebug)
|
||||
run_cmake(CMP0026-LOCATION)
|
||||
run_cmake(RelativePathInInterface)
|
||||
run_cmake(ExportBuild)
|
||||
|
||||
Reference in New Issue
Block a user