summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-07-20 17:19:26 (GMT)
committerBrad King <brad.king@kitware.com>2020-08-07 12:46:32 (GMT)
commit439191313363caea225a508634495c50d4cc60dd (patch)
treeeb1156c1fbf93b4a9ea23ec812ba49ef7a195846 /Source
parentafb998704e67d3d3ce5b24c112cb06e770fca78d (diff)
downloadCMake-439191313363caea225a508634495c50d4cc60dd.zip
CMake-439191313363caea225a508634495c50d4cc60dd.tar.gz
CMake-439191313363caea225a508634495c50d4cc60dd.tar.bz2
Add INTERFACE libraries to generated buildsystem if they have SOURCES
INTERFACE libraries were created with the intention of collecting usage requirements for use by other targets via `target_link_libraries`. Therefore they were not allowed to have SOURCES and were not included in the generated buildsystem. In practice, this has become limiting: * Header-only libraries do have sources, they just do not compile. Developers should be able to edit those sources (the header files) in their IDE. * Header-only libraries may need to generate some of their header files via custom commands. Some projects work around these limitations by pairing each interface library with an `add_custom_target` that makes the header files and custom commands appear in the generated buildsystem and in IDEs. Lift such limitations by allowing INTERFACE libraries to have SOURCES. For those with sources, add a corresponding build target to the generated buildsystem. Fixes: #19145
Diffstat (limited to 'Source')
-rw-r--r--Source/cmAddLibraryCommand.cxx26
-rw-r--r--Source/cmGeneratorTarget.cxx13
-rw-r--r--Source/cmGlobalNinjaGenerator.cxx2
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx3
-rw-r--r--Source/cmLocalVisualStudio7Generator.cxx10
-rw-r--r--Source/cmMakefileTargetGenerator.cxx1
-rw-r--r--Source/cmNinjaTargetGenerator.cxx1
-rw-r--r--Source/cmTarget.cxx41
-rw-r--r--Source/cmTargetPropCommandBase.cxx2
-rw-r--r--Source/cmVisualStudio10TargetGenerator.cxx11
10 files changed, 47 insertions, 63 deletions
diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx
index 3e5d764..f262fac 100644
--- a/Source/cmAddLibraryCommand.cxx
+++ b/Source/cmAddLibraryCommand.cxx
@@ -2,8 +2,6 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmAddLibraryCommand.h"
-#include <cmext/algorithm>
-
#include "cmExecutionStatus.h"
#include "cmGeneratorExpression.h"
#include "cmGlobalGenerator.h"
@@ -111,20 +109,10 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
"INTERFACE library specified with conflicting ALIAS type.");
return false;
}
- if (excludeFromAll) {
- status.SetError(
- "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
- return false;
- }
++s;
type = cmStateEnums::INTERFACE_LIBRARY;
haveSpecifiedType = true;
} else if (*s == "EXCLUDE_FROM_ALL") {
- if (type == cmStateEnums::INTERFACE_LIBRARY) {
- status.SetError(
- "INTERFACE library may not be used with EXCLUDE_FROM_ALL.");
- return false;
- }
++s;
excludeFromAll = true;
} else if (*s == "IMPORTED") {
@@ -143,10 +131,6 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
}
if (type == cmStateEnums::INTERFACE_LIBRARY) {
- if (s != args.end()) {
- status.SetError("INTERFACE library requires no source arguments.");
- return false;
- }
if (importGlobal && !importTarget) {
status.SetError(
"INTERFACE library specified as GLOBAL, but not as IMPORTED.");
@@ -302,8 +286,6 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
}
}
- std::vector<std::string> srclists;
-
if (type == cmStateEnums::INTERFACE_LIBRARY) {
if (!cmGeneratorExpression::IsValidTargetName(libName) ||
libName.find("::") != std::string::npos) {
@@ -311,14 +293,10 @@ bool cmAddLibraryCommand(std::vector<std::string> const& args,
cmStrCat("Invalid name for INTERFACE library target: ", libName));
return false;
}
-
- mf.AddLibrary(libName, type, srclists, excludeFromAll);
- return true;
}
- cm::append(srclists, s, args.end());
-
- mf.AddLibrary(libName, type, srclists, excludeFromAll);
+ std::vector<std::string> srcs(s, args.end());
+ mf.AddLibrary(libName, type, srcs, excludeFromAll);
return true;
}
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index d39c493..06c32fe 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -1099,6 +1099,10 @@ bool cmGeneratorTarget::IsInBuildSystem() const
case cmStateEnums::GLOBAL_TARGET:
return true;
case cmStateEnums::INTERFACE_LIBRARY:
+ // An INTERFACE library is in the build system if it has SOURCES.
+ if (!this->SourceEntries.empty()) {
+ return true;
+ }
case cmStateEnums::UNKNOWN_LIBRARY:
break;
}
@@ -1543,7 +1547,6 @@ std::vector<BT<std::string>> cmGeneratorTarget::GetSourceFilePaths(
std::string const& config) const
{
std::vector<BT<std::string>> files;
- assert(this->GetType() != cmStateEnums::INTERFACE_LIBRARY);
if (!this->LocalGenerator->GetGlobalGenerator()->GetConfigureDoneCMP0026()) {
// At configure-time, this method can be called as part of getting the
@@ -1735,9 +1738,11 @@ void cmGeneratorTarget::ComputeKindedSources(KindedSources& files,
std::string ext = cmSystemTools::LowerCase(sf->GetExtension());
if (sf->GetCustomCommand()) {
kind = SourceKindCustomCommand;
- // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
- // NOLINTNEXTLINE(bugprone-branch-clone)
- } else if (this->Target->GetType() == cmStateEnums::UTILITY) {
+ } else if (this->Target->GetType() == cmStateEnums::UTILITY ||
+ this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY
+ // XXX(clang-tidy): https://bugs.llvm.org/show_bug.cgi?id=44165
+ // NOLINTNEXTLINE(bugprone-branch-clone)
+ ) {
kind = SourceKindExtra;
} else if (this->IsSourceFilePartOfUnityBatch(sf->ResolveFullPath())) {
kind = SourceKindUnityBatched;
diff --git a/Source/cmGlobalNinjaGenerator.cxx b/Source/cmGlobalNinjaGenerator.cxx
index 2ef202d..f0fa1f4 100644
--- a/Source/cmGlobalNinjaGenerator.cxx
+++ b/Source/cmGlobalNinjaGenerator.cxx
@@ -1093,6 +1093,7 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
}
// FALLTHROUGH
case cmStateEnums::GLOBAL_TARGET:
+ case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::UTILITY: {
std::string path =
cmStrCat(target->GetLocalGenerator()->GetCurrentBinaryDirectory(), '/',
@@ -1105,7 +1106,6 @@ void cmGlobalNinjaGenerator::AppendTargetOutputs(
break;
}
- case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::UNKNOWN_LIBRARY:
break;
}
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index 574e0f5..793f6f7 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1204,6 +1204,7 @@ bool cmGlobalXCodeGenerator::CreateXCodeTarget(
}
if (gtgt->GetType() == cmStateEnums::UTILITY ||
+ gtgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
gtgt->GetType() == cmStateEnums::GLOBAL_TARGET) {
cmXCodeObject* t = this->CreateUtilityTarget(gtgt);
if (!t) {
@@ -2536,7 +2537,7 @@ cmXCodeObject* cmGlobalXCodeGenerator::CreateUtilityTarget(
this->XCodeObjectMap[gtgt] = target;
// Add source files without build rules for editing convenience.
- if (gtgt->GetType() == cmStateEnums::UTILITY &&
+ if (gtgt->GetType() != cmStateEnums::GLOBAL_TARGET &&
gtgt->GetName() != CMAKE_CHECK_BUILD_SYSTEM_TARGET) {
std::vector<cmSourceFile*> sources;
if (!gtgt->GetConfigCommonSourceFiles(sources)) {
diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx
index fec6a9d..50ffe8d 100644
--- a/Source/cmLocalVisualStudio7Generator.cxx
+++ b/Source/cmLocalVisualStudio7Generator.cxx
@@ -629,9 +629,10 @@ void cmLocalVisualStudio7Generator::WriteConfiguration(
break;
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
+ case cmStateEnums::INTERFACE_LIBRARY:
configType = "10";
CM_FALLTHROUGH;
- default:
+ case cmStateEnums::UNKNOWN_LIBRARY:
targetBuilds = false;
break;
}
@@ -1638,7 +1639,8 @@ bool cmLocalVisualStudio7Generator::WriteGroup(
std::string source = sf->GetFullPath();
if (source != libName || target->GetType() == cmStateEnums::UTILITY ||
- target->GetType() == cmStateEnums::GLOBAL_TARGET) {
+ target->GetType() == cmStateEnums::GLOBAL_TARGET ||
+ target->GetType() == cmStateEnums::INTERFACE_LIBRARY) {
// Look up the source kind and configs.
std::map<cmSourceFile const*, size_t>::const_iterator map_it =
sources.Index.find(sf);
@@ -1937,6 +1939,7 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
const char* keyword = p ? p->c_str() : "Console Application";
const char* projectType = 0;
switch (target->GetType()) {
+ case cmStateEnums::OBJECT_LIBRARY:
case cmStateEnums::STATIC_LIBRARY:
projectType = "typeStaticLibrary";
if (keyword) {
@@ -1958,7 +1961,8 @@ void cmLocalVisualStudio7Generator::WriteProjectStartFortran(
break;
case cmStateEnums::UTILITY:
case cmStateEnums::GLOBAL_TARGET:
- default:
+ case cmStateEnums::INTERFACE_LIBRARY:
+ case cmStateEnums::UNKNOWN_LIBRARY:
break;
}
if (projectType) {
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 13c2fe9..fae1d76 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -71,6 +71,7 @@ std::unique_ptr<cmMakefileTargetGenerator> cmMakefileTargetGenerator::New(
case cmStateEnums::OBJECT_LIBRARY:
result = cm::make_unique<cmMakefileLibraryTargetGenerator>(tgt);
break;
+ case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::UTILITY:
result = cm::make_unique<cmMakefileUtilityTargetGenerator>(tgt);
break;
diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx
index 048dbb6..57f526e 100644
--- a/Source/cmNinjaTargetGenerator.cxx
+++ b/Source/cmNinjaTargetGenerator.cxx
@@ -51,6 +51,7 @@ std::unique_ptr<cmNinjaTargetGenerator> cmNinjaTargetGenerator::New(
return cm::make_unique<cmNinjaNormalTargetGenerator>(target);
case cmStateEnums::UTILITY:
+ case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::GLOBAL_TARGET:
return cm::make_unique<cmNinjaUtilityTargetGenerator>(target);
diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx
index 67d7451..51b4e9e 100644
--- a/Source/cmTarget.cxx
+++ b/Source/cmTarget.cxx
@@ -401,12 +401,10 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
#endif
}
- if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
- initProp("FOLDER");
+ initProp("FOLDER");
- if (this->GetGlobalGenerator()->IsXcode()) {
- initProp("XCODE_GENERATE_SCHEME");
- }
+ if (this->GetGlobalGenerator()->IsXcode()) {
+ initProp("XCODE_GENERATE_SCHEME");
}
// Setup per-configuration property default values.
@@ -521,24 +519,21 @@ cmTarget::cmTarget(std::string const& name, cmStateEnums::TargetType type,
initProp("DOTNET_TARGET_FRAMEWORK_VERSION");
}
- if (this->GetType() != cmStateEnums::INTERFACE_LIBRARY) {
-
- // check for "CMAKE_VS_GLOBALS" variable and set up target properties
- // if any
- const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
- if (globals) {
- const std::string genName = mf->GetGlobalGenerator()->GetName();
- if (cmHasLiteralPrefix(genName, "Visual Studio")) {
- std::vector<std::string> props = cmExpandedList(globals);
- const std::string vsGlobal = "VS_GLOBAL_";
- for (const std::string& i : props) {
- // split NAME=VALUE
- const std::string::size_type assignment = i.find('=');
- if (assignment != std::string::npos) {
- const std::string propName = vsGlobal + i.substr(0, assignment);
- const std::string propValue = i.substr(assignment + 1);
- initPropValue(propName, propValue.c_str());
- }
+ // check for "CMAKE_VS_GLOBALS" variable and set up target properties
+ // if any
+ const char* globals = mf->GetDefinition("CMAKE_VS_GLOBALS");
+ if (globals) {
+ const std::string genName = mf->GetGlobalGenerator()->GetName();
+ if (cmHasLiteralPrefix(genName, "Visual Studio")) {
+ std::vector<std::string> props = cmExpandedList(globals);
+ const std::string vsGlobal = "VS_GLOBAL_";
+ for (const std::string& i : props) {
+ // split NAME=VALUE
+ const std::string::size_type assignment = i.find('=');
+ if (assignment != std::string::npos) {
+ const std::string propName = vsGlobal + i.substr(0, assignment);
+ const std::string propValue = i.substr(assignment + 1);
+ initPropValue(propName, propValue.c_str());
}
}
}
diff --git a/Source/cmTargetPropCommandBase.cxx b/Source/cmTargetPropCommandBase.cxx
index e714720..9e30136 100644
--- a/Source/cmTargetPropCommandBase.cxx
+++ b/Source/cmTargetPropCommandBase.cxx
@@ -123,7 +123,7 @@ bool cmTargetPropCommandBase::ProcessContentArgs(
}
if (!content.empty()) {
if (this->Target->GetType() == cmStateEnums::INTERFACE_LIBRARY &&
- scope != "INTERFACE") {
+ scope != "INTERFACE" && this->Property != "SOURCES") {
this->SetError("may only set INTERFACE properties on INTERFACE targets");
return false;
}
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 6369c1f..db9dc53 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -315,8 +315,7 @@ std::ostream& cmVisualStudio10TargetGenerator::Elem::WriteString(
void cmVisualStudio10TargetGenerator::Generate()
{
// do not generate external ms projects
- if (this->GeneratorTarget->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
- this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
+ if (this->GeneratorTarget->GetProperty("EXTERNAL_MSPROJECT")) {
return;
}
const std::string ProjectFileExtension =
@@ -437,7 +436,7 @@ void cmVisualStudio10TargetGenerator::Generate()
e1.Element("ProjectGuid", "{" + this->GUID + "}");
if ((this->MSTools || this->Android) &&
- this->GeneratorTarget->GetType() <= cmStateEnums::GLOBAL_TARGET) {
+ this->GeneratorTarget->IsInBuildSystem()) {
this->WriteApplicationTypeSettings(e1);
this->VerifyNecessaryFiles();
}
@@ -605,11 +604,11 @@ void cmVisualStudio10TargetGenerator::Generate()
}
break;
case cmStateEnums::UTILITY:
+ case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::GLOBAL_TARGET:
outputType = "Utility";
break;
case cmStateEnums::UNKNOWN_LIBRARY:
- case cmStateEnums::INTERFACE_LIBRARY:
break;
}
e1.Element("OutputType", outputType);
@@ -1157,6 +1156,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
}
break;
case cmStateEnums::UTILITY:
+ case cmStateEnums::INTERFACE_LIBRARY:
case cmStateEnums::GLOBAL_TARGET:
if (this->NsightTegra) {
// Tegra-Android platform does not understand "Utility".
@@ -1166,7 +1166,6 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues(Elem& e0)
}
break;
case cmStateEnums::UNKNOWN_LIBRARY:
- case cmStateEnums::INTERFACE_LIBRARY:
break;
}
}
@@ -2152,7 +2151,7 @@ void cmVisualStudio10TargetGenerator::WriteSource(Elem& e2,
void cmVisualStudio10TargetGenerator::WriteAllSources(Elem& e0)
{
- if (this->GeneratorTarget->GetType() > cmStateEnums::UTILITY) {
+ if (this->GeneratorTarget->GetType() == cmStateEnums::GLOBAL_TARGET) {
return;
}