Commit f8241136 authored by Brad King's avatar Brad King Committed by Kitware Robot
Browse files

Merge topic 'INTERFACE_LIBRARY-target-type'

ce0c303d install: Teach EXPORT option to handle INTERFACE_LIBRARY targets
435c9128 export: Add support for INTERFACE_LIBRARY targets
fe732264 Add the INTERFACE_LIBRARY target type.
parents 5c57fded ce0c303d
......@@ -82,6 +82,12 @@ bool cmAddLibraryCommand
++s;
isAlias = true;
}
else if(libType == "INTERFACE")
{
++s;
type = cmTarget::INTERFACE_LIBRARY;
haveSpecifiedType = true;
}
else if(*s == "EXCLUDE_FROM_ALL")
{
++s;
......@@ -151,7 +157,8 @@ bool cmAddLibraryCommand
if(aliasedType != cmTarget::SHARED_LIBRARY
&& aliasedType != cmTarget::STATIC_LIBRARY
&& aliasedType != cmTarget::MODULE_LIBRARY
&& aliasedType != cmTarget::OBJECT_LIBRARY)
&& aliasedType != cmTarget::OBJECT_LIBRARY
&& aliasedType != cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "cannot create ALIAS target \"" << libName
......@@ -213,6 +220,16 @@ bool cmAddLibraryCommand
);
return true;
}
if(type == cmTarget::INTERFACE_LIBRARY)
{
if (!cmGeneratorExpression::IsValidTargetName(libName))
{
cmOStringStream e;
e << "Invalid name for IMPORTED INTERFACE library target: " << libName;
this->SetError(e.str().c_str());
return false;
}
}
// Make sure the target does not already exist.
if(this->Makefile->FindTargetToUse(libName.c_str()))
......@@ -249,6 +266,26 @@ bool cmAddLibraryCommand
}
}
std::vector<std::string> srclists;
if(type == cmTarget::INTERFACE_LIBRARY)
{
if (!cmGeneratorExpression::IsValidTargetName(libName)
|| libName.find("::") != std::string::npos)
{
cmOStringStream e;
e << "Invalid name for INTERFACE library target: " << libName;
this->SetError(e.str().c_str());
return false;
}
this->Makefile->AddLibrary(libName.c_str(),
type,
srclists,
excludeFromAll);
return true;
}
if (s == args.end())
{
std::string msg = "You have called ADD_LIBRARY for library ";
......@@ -258,7 +295,6 @@ bool cmAddLibraryCommand
cmSystemTools::Message(msg.c_str() ,"Warning");
}
std::vector<std::string> srclists;
while (s != args.end())
{
srclists.push_back(*s);
......
......@@ -151,6 +151,16 @@ public:
"properties of <target>, that is, it may not be used as the operand of "
"set_property, set_target_properties, target_link_libraries etc. An "
"ALIAS target may not be installed of exported."
"\n"
"The signature\n"
" add_library(<name> INTERFACE)\n"
"creates an interface target. An interface target does not directly "
"create build output, though it may have properties set on it and it "
"may be installed, exported and imported. Typically the INTERFACE_* "
"properties are populated on the interface target using the "
"set_property(), target_link_libraries(), target_include_directories() "
"and target_compile_defintions() commands, and then it is used as an "
"argument to target_link_libraries() like any other target."
;
}
......
......@@ -355,9 +355,16 @@ void cmComputeLinkDepends::FollowLinkEntry(BFSEntry const& qe)
if(cmTarget::LinkInterface const* iface =
entry.Target->GetLinkInterface(this->Config, this->HeadTarget))
{
const bool isIface =
entry.Target->GetType() == cmTarget::INTERFACE_LIBRARY;
// This target provides its own link interface information.
this->AddLinkEntries(depender_index, iface->Libraries);
if (isIface)
{
return;
}
// Handle dependent shared libraries.
this->FollowSharedDeps(depender_index, iface);
......
......@@ -655,6 +655,11 @@ void cmComputeLinkInformation::AddItem(std::string const& item, cmTarget* tgt)
(this->UseImportLibrary &&
(impexe || tgt->GetType() == cmTarget::SHARED_LIBRARY));
if(tgt->GetType() == cmTarget::INTERFACE_LIBRARY)
{
this->Items.push_back(Item(std::string(), true, tgt));
return;
}
// Pass the full path to the target file.
std::string lib = tgt->GetFullPath(config, implib, true);
if(!this->LinkDependsNoShared ||
......
......@@ -99,6 +99,7 @@ int cmCoreTryCompile::TryCompileCode(std::vector<std::string> const& argv)
{
case cmTarget::SHARED_LIBRARY:
case cmTarget::STATIC_LIBRARY:
case cmTarget::INTERFACE_LIBRARY:
case cmTarget::UNKNOWN_LIBRARY:
break;
case cmTarget::EXECUTABLE:
......
......@@ -47,6 +47,10 @@ bool cmExportBuildFileGenerator::GenerateMainFile(std::ostream& os)
}
return false;
}
if (te->GetType() == cmTarget::INTERFACE_LIBRARY)
{
this->GenerateRequiredCMakeVersion(os, "2.8.12.20131007"); // 2.8.13
}
}
this->GenerateExpectedTargetsCode(os, expectedTargets);
......@@ -118,16 +122,22 @@ cmExportBuildFileGenerator
// Collect import properties for this target.
cmTarget* target = *tei;
ImportPropertyMap properties;
this->SetImportLocationProperty(config, suffix, target, properties);
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
this->SetImportLocationProperty(config, suffix, target, properties);
}
if(!properties.empty())
{
// Get the rest of the target details.
this->SetImportDetailProperties(config, suffix,
target, properties, missingTargets);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::BuildInterface,
target, properties, missingTargets);
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
this->SetImportDetailProperties(config, suffix,
target, properties, missingTargets);
this->SetImportLinkInterface(config, suffix,
cmGeneratorExpression::BuildInterface,
target, properties, missingTargets);
}
// TOOD: PUBLIC_HEADER_LOCATION
// This should wait until the build feature propagation stuff
......
......@@ -130,7 +130,8 @@ bool cmExportCommand
if((target->GetType() == cmTarget::EXECUTABLE) ||
(target->GetType() == cmTarget::STATIC_LIBRARY) ||
(target->GetType() == cmTarget::SHARED_LIBRARY) ||
(target->GetType() == cmTarget::MODULE_LIBRARY))
(target->GetType() == cmTarget::MODULE_LIBRARY) ||
(target->GetType() == cmTarget::INTERFACE_LIBRARY))
{
targets.push_back(target);
}
......
......@@ -378,11 +378,14 @@ void getCompatibleInterfaceProperties(cmTarget *target,
if (!info)
{
cmMakefile* mf = target->GetMakefile();
cmOStringStream e;
e << "Exporting the target \"" << target->GetName() << "\" is not "
"allowed since its linker language cannot be determined";
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
cmMakefile* mf = target->GetMakefile();
cmOStringStream e;
e << "Exporting the target \"" << target->GetName() << "\" is not "
"allowed since its linker language cannot be determined";
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
}
return;
}
......@@ -888,6 +891,9 @@ cmExportFileGenerator
case cmTarget::UNKNOWN_LIBRARY:
os << "add_library(" << targetName << " UNKNOWN IMPORTED)\n";
break;
case cmTarget::INTERFACE_LIBRARY:
os << "add_library(" << targetName << " INTERFACE IMPORTED)\n";
break;
default: // should never happen
break;
}
......
......@@ -114,6 +114,7 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
std::vector<std::string> missingTargets;
bool require2_8_12 = false;
bool require2_8_13 = false;
// Create all the imported targets.
for(std::vector<cmTargetExport*>::const_iterator
tei = allTargets.begin();
......@@ -153,6 +154,10 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
require2_8_12 = true;
}
}
if (te->GetType() == cmTarget::INTERFACE_LIBRARY)
{
require2_8_13 = true;
}
this->PopulateInterfaceProperty("INTERFACE_POSITION_INDEPENDENT_CODE",
te, properties);
this->PopulateCompatibleInterfaceProperties(te, properties);
......@@ -160,7 +165,11 @@ bool cmExportInstallFileGenerator::GenerateMainFile(std::ostream& os)
this->GenerateInterfaceProperties(te, os, properties);
}
if (require2_8_12)
if (require2_8_13)
{
this->GenerateRequiredCMakeVersion(os, "2.8.12.20131007");
}
else if (require2_8_12)
{
this->GenerateRequiredCMakeVersion(os, "2.8.12");
}
......@@ -286,6 +295,14 @@ cmExportInstallFileGenerator
cmTargetExport const* te = *tei;
ImportPropertyMap properties;
std::set<std::string> importedLocations;
if (!properties.empty()
&& te->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
this->GenerateImportPropertyCode(os, config, te->Target, properties);
this->GenerateImportedFileChecksCode(os, te->Target, properties,
importedLocations);
continue;
}
this->SetImportLocationProperty(config, suffix, te->ArchiveGenerator,
properties, importedLocations);
this->SetImportLocationProperty(config, suffix, te->LibraryGenerator,
......
......@@ -2563,6 +2563,10 @@ void cmGlobalGenerator::WriteSummary()
for(std::map<cmStdString,cmTarget *>::const_iterator ti =
this->TotalTargets.begin(); ti != this->TotalTargets.end(); ++ti)
{
if ((ti->second)->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
this->WriteSummary(ti->second);
fout << ti->second->GetSupportDirectory() << "\n";
}
......
......@@ -877,7 +877,12 @@ cmGlobalNinjaGenerator
cmTargetDependSet const& targetDeps =
this->GetTargetDirectDepends(*target);
for (cmTargetDependSet::const_iterator i = targetDeps.begin();
i != targetDeps.end(); ++i) {
i != targetDeps.end(); ++i)
{
if ((*i)->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
this->AppendTargetOutputs(*i, outputs);
}
}
......
......@@ -881,6 +881,10 @@ cmGlobalUnixMakefileGenerator3
for(TargetDependSet::const_iterator di = depends.begin();
di != depends.end(); ++di)
{
if ((*di)->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
count += this->CountProgressMarksInTarget(*di, emitted);
}
}
......@@ -967,6 +971,10 @@ cmGlobalUnixMakefileGenerator3
{
// Create the target-level dependency.
cmTarget const* dep = *i;
if (dep->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
cmLocalUnixMakefileGenerator3* lg3 =
static_cast<cmLocalUnixMakefileGenerator3*>
(dep->GetMakefile()->GetLocalGenerator());
......
......@@ -200,6 +200,10 @@ void cmGlobalVisualStudio6Generator
tt != orderedProjectTargets.end(); ++tt)
{
cmTarget* target = *tt;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
// Write the project into the DSW file
const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
if(expath)
......
......@@ -392,6 +392,10 @@ void cmGlobalVisualStudio7Generator::WriteTargetDepends(
projectTargets.begin(); tt != projectTargets.end(); ++tt)
{
cmTarget* target = *tt;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
cmMakefile* mf = target->GetMakefile();
const char *vcprojName =
target->GetProperty("GENERATOR_FILE_NAME");
......
......@@ -409,6 +409,10 @@ void cmGlobalVisualStudio8Generator::WriteProjectDepends(
for(OrderedTargetDependSet::const_iterator i = depends.begin();
i != depends.end(); ++i)
{
if((*i)->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
std::string guid = this->GetGUID((*i)->GetName());
fout << "\t\t{" << guid << "} = {" << guid << "}\n";
}
......
......@@ -349,6 +349,10 @@ cmGlobalVisualStudioGenerator::GetTargetLinkClosure(cmTarget* target)
void cmGlobalVisualStudioGenerator::FollowLinkDepends(
cmTarget* target, std::set<cmTarget*>& linked)
{
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
return;
}
if(linked.insert(target).second &&
target->GetType() == cmTarget::STATIC_LIBRARY)
{
......
......@@ -976,6 +976,11 @@ cmGlobalXCodeGenerator::CreateXCodeTargets(cmLocalGenerator* gen,
continue;
}
if(cmtarget.GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
if(cmtarget.GetType() == cmTarget::UTILITY ||
cmtarget.GetType() == cmTarget::GLOBAL_TARGET)
{
......@@ -1686,6 +1691,11 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
cmXCodeObject* buildSettings,
const char* configName)
{
if(target.GetType() == cmTarget::INTERFACE_LIBRARY)
{
return;
}
std::string flags;
std::string defFlags;
bool shared = ((target.GetType() == cmTarget::SHARED_LIBRARY) ||
......@@ -2550,6 +2560,10 @@ cmXCodeObject*
cmGlobalXCodeGenerator::CreateXCodeTarget(cmTarget& cmtarget,
cmXCodeObject* buildPhases)
{
if(cmtarget.GetType() == cmTarget::INTERFACE_LIBRARY)
{
return 0;
}
cmXCodeObject* target =
this->CreateObject(cmXCodeObject::PBXNativeTarget);
target->AddAttribute("buildPhases", buildPhases);
......@@ -2756,6 +2770,10 @@ void cmGlobalXCodeGenerator
::AddDependAndLinkInformation(cmXCodeObject* target)
{
cmTarget* cmtarget = target->GetTarget();
if(cmtarget->GetType() == cmTarget::INTERFACE_LIBRARY)
{
return;
}
if(!cmtarget)
{
cmSystemTools::Error("Error no target on xobject\n");
......@@ -2867,7 +2885,8 @@ void cmGlobalXCodeGenerator
{
linkLibs += this->XCodeEscapePath(li->Value.c_str());
}
else
else if (!li->Target
|| li->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
linkLibs += li->Value;
}
......@@ -2909,6 +2928,10 @@ void cmGlobalXCodeGenerator::CreateGroups(cmLocalGenerator* root,
{
continue;
}
if(cmtarget.GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
// add the soon to be generated Info.plist file as a source for a
// MACOSX_BUNDLE file
......
......@@ -379,7 +379,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
target->GetType() != cmTarget::STATIC_LIBRARY &&
target->GetType() != cmTarget::SHARED_LIBRARY &&
target->GetType() != cmTarget::MODULE_LIBRARY &&
target->GetType() != cmTarget::OBJECT_LIBRARY)
target->GetType() != cmTarget::OBJECT_LIBRARY &&
target->GetType() != cmTarget::INTERFACE_LIBRARY)
{
cmOStringStream e;
e << "TARGETS given target \"" << (*targetIt)
......@@ -626,6 +627,11 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
}
}
break;
case cmTarget::INTERFACE_LIBRARY:
// Nothing to do. An INTERFACE_LIBRARY can be installed, but the
// only effect of that is to make it exportable. It installs no
// other files itself.
break;
default:
// This should never happen due to the above type check.
// Ignore the case.
......
......@@ -90,6 +90,11 @@ void cmInstallTargetGenerator::GenerateScriptForConfig(std::ostream& os,
case cmTarget::STATIC_LIBRARY: type = cmInstallType_STATIC_LIBRARY; break;
case cmTarget::SHARED_LIBRARY: type = cmInstallType_SHARED_LIBRARY; break;
case cmTarget::MODULE_LIBRARY: type = cmInstallType_MODULE_LIBRARY; break;
case cmTarget::INTERFACE_LIBRARY:
// Not reachable. We never create a cmInstallTargetGenerator for
// an INTERFACE_LIBRARY.
assert(!"INTERFACE_LIBRARY targets have no installable outputs.");
break;
case cmTarget::OBJECT_LIBRARY:
case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET:
......
......@@ -1794,6 +1794,10 @@ void cmLocalGenerator::OutputLinkLibraries(std::string& linkLibraries,
ItemVector const& items = cli.GetItems();
for(ItemVector::const_iterator li = items.begin(); li != items.end(); ++li)
{
if(li->Target && li->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
if(li->IsPath)
{
linkLibs += this->ConvertToLinkReference(li->Value);
......@@ -1997,6 +2001,10 @@ bool cmLocalGenerator::GetRealDependency(const char* inName,
// An object library has no single file on which to depend.
// This was listed to get the target-level dependency.
return false;
case cmTarget::INTERFACE_LIBRARY:
// An interface library has no file on which to depend.
// This was listed to get the target-level dependency.
return false;
case cmTarget::UTILITY:
case cmTarget::GLOBAL_TARGET:
// A utility target has no file on which to depend. This was listed
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment