objlib: Allow other libraries to link to OBJECT libraries.

Note: This only allows `OBJECT` libraries to be on the right-hand side
of `target_link_libraries` but still does not link its object-files to
the target on the left-hand side.

Issue: #14778
This commit is contained in:
Deniz Bahadir
2017-11-24 17:20:18 +01:00
committed by Brad King
parent 51249e69ea
commit dfb6e84082
20 changed files with 94 additions and 66 deletions
+3
View File
@@ -611,6 +611,9 @@ void cmComputeLinkInformation::AddItem(std::string const& item,
if (!libName.empty()) {
this->AddItem(libName, nullptr);
}
} else if (tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) {
// Ignore object library!
// Its object-files should already have been extracted for linking.
} else {
// Decide whether to use an import library.
bool implib =
+3 -3
View File
@@ -211,11 +211,11 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
if (depender->GetType() != cmStateEnums::EXECUTABLE &&
depender->GetType() != cmStateEnums::STATIC_LIBRARY &&
depender->GetType() != cmStateEnums::SHARED_LIBRARY &&
depender->GetType() != cmStateEnums::MODULE_LIBRARY) {
depender->GetType() != cmStateEnums::MODULE_LIBRARY &&
depender->GetType() != cmStateEnums::OBJECT_LIBRARY) {
this->GlobalGenerator->GetCMakeInstance()->IssueMessage(
cmake::FATAL_ERROR,
"Only executables and non-OBJECT libraries may "
"reference target objects.",
"Only executables and libraries may reference target objects.",
depender->GetBacktrace());
return;
}
+3 -1
View File
@@ -159,7 +159,9 @@ cmStateEnums::TargetType cmExportBuildFileGenerator::GetExportTargetType(
{
cmStateEnums::TargetType targetType = target->GetType();
// An object library exports as an interface library if we cannot
// tell clients where to find the objects.
// tell clients where to find the objects. This is sufficient
// to support transitive usage requirements on other targets that
// use the object library.
if (targetType == cmStateEnums::OBJECT_LIBRARY &&
!this->LG->GetGlobalGenerator()->HasKnownObjectFileLocation(nullptr)) {
targetType = cmStateEnums::INTERFACE_LIBRARY;
+7 -16
View File
@@ -240,13 +240,16 @@ const char* cmGeneratorTarget::GetOutputTargetType(
case cmStateEnums::MODULE_LIBRARY:
switch (artifact) {
case cmStateEnums::RuntimeBinaryArtifact:
// Module import libraries are treated as archive targets.
// Module libraries are always treated as library targets.
return "LIBRARY";
case cmStateEnums::ImportLibraryArtifact:
// Module libraries are always treated as library targets.
// Module import libraries are treated as archive targets.
return "ARCHIVE";
}
break;
case cmStateEnums::OBJECT_LIBRARY:
// Object libraries are always treated as object targets.
return "OBJECT";
case cmStateEnums::EXECUTABLE:
switch (artifact) {
case cmStateEnums::RuntimeBinaryArtifact:
@@ -1671,6 +1674,7 @@ bool cmGeneratorTarget::HaveWellDefinedOutputFiles() const
return this->GetType() == cmStateEnums::STATIC_LIBRARY ||
this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::MODULE_LIBRARY ||
this->GetType() == cmStateEnums::OBJECT_LIBRARY ||
this->GetType() == cmStateEnums::EXECUTABLE;
}
@@ -5323,20 +5327,6 @@ cmGeneratorTarget* cmGeneratorTarget::FindTargetToLink(
tgt = nullptr;
}
if (tgt && tgt->GetType() == cmStateEnums::OBJECT_LIBRARY) {
std::ostringstream e;
e << "Target \"" << this->GetName() << "\" links to "
"OBJECT library \""
<< tgt->GetName()
<< "\" but this is not "
"allowed. "
"One may link only to STATIC or SHARED libraries, or to executables "
"with the ENABLE_EXPORTS property set.";
cmake* cm = this->LocalGenerator->GetCMakeInstance();
cm->IssueMessage(cmake::FATAL_ERROR, e.str(), this->GetBacktrace());
tgt = nullptr;
}
return tgt;
}
@@ -5400,6 +5390,7 @@ bool cmGeneratorTarget::IsLinkable() const
this->GetType() == cmStateEnums::SHARED_LIBRARY ||
this->GetType() == cmStateEnums::MODULE_LIBRARY ||
this->GetType() == cmStateEnums::UNKNOWN_LIBRARY ||
this->GetType() == cmStateEnums::OBJECT_LIBRARY ||
this->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
this->IsExecutableWithExports());
}
+8 -10
View File
@@ -114,15 +114,12 @@ const char* cmTargetPropertyComputer::GetSources<cmTarget>(
}
if (!noMessage) {
e << "Target \"" << tgt->GetName()
<< "\" contains "
"$<TARGET_OBJECTS> generator expression in its sources "
"list. "
"This content was not previously part of the SOURCES "
"property "
"when that property was read at configure time. Code "
"reading "
"that property needs to be adapted to ignore the generator "
"expression using the string(GENEX_STRIP) command.";
<< "\" contains $<TARGET_OBJECTS> generator expression in its "
"sources list. This content was not previously part of the "
"SOURCES property when that property was read at configure "
"time. Code reading that property needs to be adapted to "
"ignore the generator expression using the string(GENEX_STRIP) "
"command.";
messenger->IssueMessage(messageType, e.str(), context);
}
if (addContent) {
@@ -742,7 +739,8 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf, const std::string& lib,
}
if (cmGeneratorExpression::Find(lib) != std::string::npos ||
(tgt && tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY) ||
(tgt && (tgt->GetType() == cmStateEnums::INTERFACE_LIBRARY ||
tgt->GetType() == cmStateEnums::OBJECT_LIBRARY)) ||
(this->Name == lib)) {
return;
}
+3 -2
View File
@@ -391,14 +391,15 @@ bool cmTargetLinkLibrariesCommand::HandleLibrary(const std::string& lib,
if (tgt && (tgt->GetType() != cmStateEnums::STATIC_LIBRARY) &&
(tgt->GetType() != cmStateEnums::SHARED_LIBRARY) &&
(tgt->GetType() != cmStateEnums::UNKNOWN_LIBRARY) &&
(tgt->GetType() != cmStateEnums::OBJECT_LIBRARY) &&
(tgt->GetType() != cmStateEnums::INTERFACE_LIBRARY) &&
!tgt->IsExecutableWithExports()) {
std::ostringstream e;
e << "Target \"" << lib << "\" of type "
<< cmState::GetTargetTypeName(tgt->GetType())
<< " may not be linked into another target. One may link only to "
"INTERFACE, STATIC or SHARED libraries, or to executables with the "
"ENABLE_EXPORTS property set.";
"INTERFACE, OBJECT, STATIC or SHARED libraries, or to executables "
"with the ENABLE_EXPORTS property set.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
}