Merge topic 'INTERFACE_LIBRARY-target-type'
ce0c303
install: Teach EXPORT option to handle INTERFACE_LIBRARY targets435c912
export: Add support for INTERFACE_LIBRARY targetsfe73226
Add the INTERFACE_LIBRARY target type.
This commit is contained in:
commit
f8241136b4
|
@ -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
|
||||
|
|
|
@ -76,6 +76,10 @@ void cmLocalVisualStudio10Generator::Generate()
|
|||
cmTargets &tgts = this->Makefile->GetTargets();
|
||||
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
|
||||
{
|
||||
if(l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if(static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
|
||||
->TargetIsFortranOnly(l->second))
|
||||
{
|
||||
|
|
|
@ -91,6 +91,11 @@ void cmLocalVisualStudio6Generator::AddCMakeListsRules()
|
|||
for(cmTargets::iterator l = tgts.begin();
|
||||
l != tgts.end(); l++)
|
||||
{
|
||||
if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Add a rule to regenerate the build system when the target
|
||||
// specification source changes.
|
||||
const char* suppRegenRule =
|
||||
|
@ -146,6 +151,8 @@ void cmLocalVisualStudio6Generator::OutputDSPFile()
|
|||
case cmTarget::GLOBAL_TARGET:
|
||||
this->SetBuildType(UTILITY, l->first.c_str(), l->second);
|
||||
break;
|
||||
case cmTarget::INTERFACE_LIBRARY:
|
||||
continue;
|
||||
default:
|
||||
cmSystemTools::Error("Bad target type: ", l->first.c_str());
|
||||
break;
|
||||
|
@ -1839,7 +1846,8 @@ void cmLocalVisualStudio6Generator
|
|||
options +=
|
||||
this->ConvertToOptionallyRelativeOutputPath(l->Value.c_str());
|
||||
}
|
||||
else
|
||||
else if (!l->Target
|
||||
|| l->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
options += l->Value;
|
||||
}
|
||||
|
|
|
@ -78,6 +78,10 @@ void cmLocalVisualStudio7Generator::AddHelperCommands()
|
|||
static_cast<cmGlobalVisualStudio7Generator *>(this->GlobalGenerator);
|
||||
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++)
|
||||
{
|
||||
if(l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT");
|
||||
if(path)
|
||||
{
|
||||
|
@ -181,6 +185,10 @@ void cmLocalVisualStudio7Generator::WriteProjectFiles()
|
|||
for(cmTargets::iterator l = tgts.begin();
|
||||
l != tgts.end(); l++)
|
||||
{
|
||||
if(l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// INCLUDE_EXTERNAL_MSPROJECT command only affects the workspace
|
||||
// so don't build a projectfile for it
|
||||
if(!l->second.GetProperty("EXTERNAL_MSPROJECT"))
|
||||
|
@ -1258,6 +1266,7 @@ void cmLocalVisualStudio7Generator::OutputBuildTool(std::ostream& fout,
|
|||
}
|
||||
case cmTarget::UTILITY:
|
||||
case cmTarget::GLOBAL_TARGET:
|
||||
case cmTarget::INTERFACE_LIBRARY:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1288,7 +1297,8 @@ cmLocalVisualStudio7GeneratorInternals
|
|||
cmLocalGenerator::UNCHANGED);
|
||||
fout << lg->ConvertToXMLOutputPath(rel.c_str()) << " ";
|
||||
}
|
||||
else
|
||||
else if (!l->Target
|
||||
|| l->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
fout << l->Value << " ";
|
||||
}
|
||||
|
|
|
@ -1463,6 +1463,7 @@ void cmMakefile::AddLinkLibraryForTarget(const char *target,
|
|||
// if it is not a static or shared library then you can not link to it
|
||||
if(!((tgt->GetType() == cmTarget::STATIC_LIBRARY) ||
|
||||
(tgt->GetType() == cmTarget::SHARED_LIBRARY) ||
|
||||
(tgt->GetType() == cmTarget::INTERFACE_LIBRARY) ||
|
||||
tgt->IsExecutableWithExports()))
|
||||
{
|
||||
cmOStringStream e;
|
||||
|
@ -1990,6 +1991,7 @@ void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target)
|
|||
{
|
||||
case cmTarget::UTILITY:
|
||||
case cmTarget::GLOBAL_TARGET:
|
||||
case cmTarget::INTERFACE_LIBRARY:
|
||||
return;
|
||||
default:;
|
||||
}
|
||||
|
@ -2017,7 +2019,8 @@ cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type,
|
|||
if ( (type != cmTarget::STATIC_LIBRARY)
|
||||
&& (type != cmTarget::SHARED_LIBRARY)
|
||||
&& (type != cmTarget::MODULE_LIBRARY)
|
||||
&& (type != cmTarget::OBJECT_LIBRARY))
|
||||
&& (type != cmTarget::OBJECT_LIBRARY)
|
||||
&& (type != cmTarget::INTERFACE_LIBRARY))
|
||||
{
|
||||
this->IssueMessage(cmake::INTERNAL_ERROR,
|
||||
"cmMakefile::AddLibrary given invalid target type.");
|
||||
|
|
|
@ -1004,7 +1004,12 @@ void cmMakefileTargetGenerator::WriteTargetDependRules()
|
|||
i = items.begin(); i != items.end(); ++i)
|
||||
{
|
||||
cmTarget const* linkee = i->Target;
|
||||
if(linkee && !linkee->IsImported() && emitted.insert(linkee).second)
|
||||
if(linkee && !linkee->IsImported()
|
||||
// We can ignore the INTERFACE_LIBRARY items because
|
||||
// Target->GetLinkInformation already processed their
|
||||
// link interface and they don't have any output themselves.
|
||||
&& linkee->GetType() != cmTarget::INTERFACE_LIBRARY
|
||||
&& emitted.insert(linkee).second)
|
||||
{
|
||||
cmMakefile* mf = linkee->GetMakefile();
|
||||
cmLocalGenerator* lg = mf->GetLocalGenerator();
|
||||
|
|
|
@ -47,6 +47,8 @@ const char* cmTarget::GetTargetTypeName(TargetType targetType)
|
|||
return "UTILITY";
|
||||
case cmTarget::GLOBAL_TARGET:
|
||||
return "GLOBAL_TARGET";
|
||||
case cmTarget::INTERFACE_LIBRARY:
|
||||
return "INTERFACE_LIBRARY";
|
||||
case cmTarget::UNKNOWN_LIBRARY:
|
||||
return "UNKNOWN_LIBRARY";
|
||||
}
|
||||
|
@ -1743,6 +1745,14 @@ void cmTarget::SetMakefile(cmMakefile* mf)
|
|||
CM_FOR_EACH_TARGET_POLICY(CAPTURE_TARGET_POLICY)
|
||||
|
||||
#undef CAPTURE_TARGET_POLICY
|
||||
|
||||
if (this->TargetTypeValue == INTERFACE_LIBRARY)
|
||||
{
|
||||
// This policy is checked in a few conditions. The properties relevant
|
||||
// to the policy are always ignored for INTERFACE_LIBRARY targets,
|
||||
// so ensure that the conditions don't lead to nonsense.
|
||||
this->PolicyStatusCMP0022 = cmPolicies::NEW;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -1808,6 +1818,7 @@ bool cmTarget::IsLinkable()
|
|||
this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
this->GetType() == cmTarget::MODULE_LIBRARY ||
|
||||
this->GetType() == cmTarget::UNKNOWN_LIBRARY ||
|
||||
this->GetType() == cmTarget::INTERFACE_LIBRARY ||
|
||||
this->IsExecutableWithExports());
|
||||
}
|
||||
|
||||
|
@ -2579,8 +2590,8 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
|||
return;
|
||||
}
|
||||
|
||||
{
|
||||
cmTarget *tgt = this->Makefile->FindTargetToUse(lib);
|
||||
{
|
||||
const bool isNonImportedTarget = tgt && !tgt->IsImported();
|
||||
|
||||
const std::string libName = (isNonImportedTarget && llt != GENERAL)
|
||||
|
@ -2591,7 +2602,8 @@ void cmTarget::AddLinkLibrary(cmMakefile& mf,
|
|||
llt).c_str());
|
||||
}
|
||||
|
||||
if (cmGeneratorExpression::Find(lib) != std::string::npos)
|
||||
if (cmGeneratorExpression::Find(lib) != std::string::npos
|
||||
|| (tgt && tgt->GetType() == INTERFACE_LIBRARY))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -4137,6 +4149,7 @@ const char *cmTarget::GetProperty(const char* prop,
|
|||
this->GetType() == cmTarget::STATIC_LIBRARY ||
|
||||
this->GetType() == cmTarget::SHARED_LIBRARY ||
|
||||
this->GetType() == cmTarget::MODULE_LIBRARY ||
|
||||
this->GetType() == cmTarget::INTERFACE_LIBRARY ||
|
||||
this->GetType() == cmTarget::UNKNOWN_LIBRARY)
|
||||
{
|
||||
if(strcmp(prop,"LOCATION") == 0)
|
||||
|
@ -6061,6 +6074,10 @@ cmTarget::GetImportInfo(const char* config, cmTarget *headTarget)
|
|||
i = this->Internal->ImportInfoMap.insert(entry).first;
|
||||
}
|
||||
|
||||
if(this->GetType() == INTERFACE_LIBRARY)
|
||||
{
|
||||
return &i->second;
|
||||
}
|
||||
// If the location is empty then the target is not available for
|
||||
// this configuration.
|
||||
if(i->second.Location.empty() && i->second.ImportLibrary.empty())
|
||||
|
@ -6209,7 +6226,51 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
|
|||
const char* loc = 0;
|
||||
const char* imp = 0;
|
||||
std::string suffix;
|
||||
if (!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
|
||||
if (this->GetType() != INTERFACE_LIBRARY &&
|
||||
!this->GetMappedConfig(desired_config, &loc, &imp, suffix))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the link interface.
|
||||
{
|
||||
std::string linkProp = "INTERFACE_LINK_LIBRARIES";
|
||||
const char *propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
|
||||
if (this->GetType() != INTERFACE_LIBRARY)
|
||||
{
|
||||
if(!propertyLibs)
|
||||
{
|
||||
linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
|
||||
linkProp += suffix;
|
||||
propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
}
|
||||
|
||||
if(!propertyLibs)
|
||||
{
|
||||
linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
|
||||
propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
}
|
||||
}
|
||||
if(propertyLibs)
|
||||
{
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
linkProp, 0, 0);
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
|
||||
->Evaluate(this->Makefile,
|
||||
desired_config.c_str(),
|
||||
false,
|
||||
headTarget,
|
||||
this,
|
||||
&dagChecker),
|
||||
info.LinkInterface.Libraries);
|
||||
}
|
||||
}
|
||||
if(this->GetType() == INTERFACE_LIBRARY)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -6286,42 +6347,6 @@ void cmTarget::ComputeImportInfo(std::string const& desired_config,
|
|||
}
|
||||
}
|
||||
|
||||
// Get the link interface.
|
||||
{
|
||||
std::string linkProp = "INTERFACE_LINK_LIBRARIES";
|
||||
const char *propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
|
||||
if (!propertyLibs)
|
||||
{
|
||||
linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
|
||||
linkProp += suffix;
|
||||
propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
}
|
||||
|
||||
if(!propertyLibs)
|
||||
{
|
||||
linkProp = "IMPORTED_LINK_INTERFACE_LIBRARIES";
|
||||
propertyLibs = this->GetProperty(linkProp.c_str());
|
||||
}
|
||||
if(propertyLibs)
|
||||
{
|
||||
cmListFileBacktrace lfbt;
|
||||
cmGeneratorExpression ge(lfbt);
|
||||
|
||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||
this->GetName(),
|
||||
linkProp, 0, 0);
|
||||
cmSystemTools::ExpandListArgument(ge.Parse(propertyLibs)
|
||||
->Evaluate(this->Makefile,
|
||||
desired_config.c_str(),
|
||||
false,
|
||||
headTarget,
|
||||
this,
|
||||
&dagChecker),
|
||||
info.LinkInterface.Libraries);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the link dependencies.
|
||||
{
|
||||
std::string linkProp = "IMPORTED_LINK_DEPENDENT_LIBRARIES";
|
||||
|
@ -6582,6 +6607,11 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (this->GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
explicitLibraries = newExplicitLibraries;
|
||||
linkIfaceProp = "INTERFACE_LINK_LIBRARIES";
|
||||
}
|
||||
|
||||
// There is no implicit link interface for executables or modules
|
||||
// so if none was explicitly set then there is no link interface.
|
||||
|
@ -6609,7 +6639,8 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
|
|||
this, &dagChecker), iface.Libraries);
|
||||
|
||||
if(this->GetType() == cmTarget::SHARED_LIBRARY
|
||||
|| this->GetType() == cmTarget::STATIC_LIBRARY)
|
||||
|| this->GetType() == cmTarget::STATIC_LIBRARY
|
||||
|| this->GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
// Shared libraries may have runtime implementation dependencies
|
||||
// on other shared libraries that are not in the interface.
|
||||
|
|
|
@ -72,6 +72,7 @@ public:
|
|||
enum TargetType { EXECUTABLE, STATIC_LIBRARY,
|
||||
SHARED_LIBRARY, MODULE_LIBRARY,
|
||||
OBJECT_LIBRARY, UTILITY, GLOBAL_TARGET,
|
||||
INTERFACE_LIBRARY,
|
||||
UNKNOWN_LIBRARY};
|
||||
static const char* GetTargetTypeName(TargetType targetType);
|
||||
enum CustomCommandType { PRE_BUILD, PRE_LINK, POST_BUILD };
|
||||
|
|
|
@ -322,6 +322,15 @@ bool
|
|||
cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
||||
cmTarget::LinkLibraryType llt)
|
||||
{
|
||||
if(this->Target->GetType() == cmTarget::INTERFACE_LIBRARY
|
||||
&& this->CurrentProcessingState != ProcessingKeywordLinkInterface)
|
||||
{
|
||||
this->Makefile->IssueMessage(cmake::FATAL_ERROR,
|
||||
"INTERFACE library can only be used with the INTERFACE keyword of "
|
||||
"target_link_libraries");
|
||||
return false;
|
||||
}
|
||||
|
||||
cmTarget::TLLSignature sig =
|
||||
(this->CurrentProcessingState == ProcessingPlainPrivateInterface
|
||||
|| this->CurrentProcessingState == ProcessingPlainPublicInterface
|
||||
|
@ -407,6 +416,11 @@ cmTargetLinkLibrariesCommand::HandleLibrary(const char* lib,
|
|||
return true;
|
||||
}
|
||||
|
||||
if (this->Target->GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Get the list of configurations considered to be DEBUG.
|
||||
std::vector<std::string> const& debugConfigs =
|
||||
this->Makefile->GetCMakeInstance()->GetDebugConfigs();
|
||||
|
|
|
@ -47,6 +47,7 @@ bool cmTargetPropCommandBase
|
|||
&& (this->Target->GetType() != cmTarget::STATIC_LIBRARY)
|
||||
&& (this->Target->GetType() != cmTarget::OBJECT_LIBRARY)
|
||||
&& (this->Target->GetType() != cmTarget::MODULE_LIBRARY)
|
||||
&& (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
|
||||
&& (this->Target->GetType() != cmTarget::EXECUTABLE))
|
||||
{
|
||||
this->SetError("called with non-compilable target type");
|
||||
|
@ -112,6 +113,14 @@ bool cmTargetPropCommandBase
|
|||
return false;
|
||||
}
|
||||
|
||||
if (this->Target->GetType() == cmTarget::INTERFACE_LIBRARY
|
||||
&& scope != "INTERFACE")
|
||||
{
|
||||
this->SetError("may only be set INTERFACE properties on INTERFACE "
|
||||
"targets");
|
||||
return false;
|
||||
}
|
||||
|
||||
++argIndex;
|
||||
|
||||
std::vector<std::string> content;
|
||||
|
|
|
@ -490,6 +490,7 @@ void cmVisualStudio10TargetGenerator::WriteProjectConfigurationValues()
|
|||
break;
|
||||
case cmTarget::GLOBAL_TARGET:
|
||||
case cmTarget::UNKNOWN_LIBRARY:
|
||||
case cmTarget::INTERFACE_LIBRARY:
|
||||
break;
|
||||
}
|
||||
configType += "</ConfigurationType>\n";
|
||||
|
@ -1701,7 +1702,8 @@ void cmVisualStudio10TargetGenerator::AddLibraries(
|
|||
libstring += sep;
|
||||
libstring += path;
|
||||
}
|
||||
else
|
||||
else if (!l->Target
|
||||
|| l->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
libstring += sep;
|
||||
libstring += l->Value;
|
||||
|
@ -1836,6 +1838,10 @@ void cmVisualStudio10TargetGenerator::WriteProjectReferences()
|
|||
i != depends.end(); ++i)
|
||||
{
|
||||
cmTarget* dt = *i;
|
||||
if(dt->GetType() == cmTarget::INTERFACE_LIBRARY)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// skip fortran targets as they can not be processed by MSBuild
|
||||
// the only reference will be in the .sln file
|
||||
if(static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator)
|
||||
|
|
|
@ -45,3 +45,6 @@ get_property(_alt2 TARGET PREFIX::Foo PROPERTY ALIASED_TARGET)
|
|||
if (NOT ${_alt2} STREQUAL foo)
|
||||
message(SEND_ERROR "ALIASED_TARGET is not foo.")
|
||||
endif()
|
||||
|
||||
add_library(iface INTERFACE)
|
||||
add_library(Alias::Iface ALIAS iface)
|
||||
|
|
|
@ -246,6 +246,7 @@ if(BUILD_TESTING)
|
|||
ADD_TEST_MACRO(CompileOptions CompileOptions)
|
||||
ADD_TEST_MACRO(CompatibleInterface CompatibleInterface)
|
||||
ADD_TEST_MACRO(AliasTarget AliasTarget)
|
||||
ADD_TEST_MACRO(InterfaceLibrary InterfaceLibrary)
|
||||
set_tests_properties(EmptyLibrary PROPERTIES
|
||||
PASS_REGULAR_EXPRESSION "CMake Error: CMake can not determine linker language for target: test")
|
||||
ADD_TEST_MACRO(CrossCompile CrossCompile)
|
||||
|
|
|
@ -6,7 +6,7 @@ project(CompatibleInterface)
|
|||
include(GenerateExportHeader)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
add_library(iface1 empty.cpp)
|
||||
add_library(iface1 INTERFACE)
|
||||
set_property(TARGET iface1 APPEND PROPERTY
|
||||
COMPATIBLE_INTERFACE_BOOL
|
||||
BOOL_PROP1
|
||||
|
|
|
@ -436,3 +436,5 @@ export(TARGETS testExe2 testLib4 testLib5 testLib6 testExe3 testExe2lib
|
|||
NAMESPACE bld_
|
||||
APPEND FILE ExportBuildTree.cmake
|
||||
)
|
||||
|
||||
add_subdirectory(Interface)
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
add_library(headeronly INTERFACE)
|
||||
set_property(TARGET headeronly PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/headeronly>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/headeronly>"
|
||||
)
|
||||
set_property(TARGET headeronly PROPERTY INTERFACE_COMPILE_DEFINITIONS "HEADERONLY_DEFINE")
|
||||
|
||||
include(GenerateExportHeader)
|
||||
add_library(sharedlib SHARED sharedlib.cpp)
|
||||
generate_export_header(sharedlib)
|
||||
set_property(TARGET sharedlib PROPERTY INCLUDE_DIRECTORIES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/sharedlib"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
set_property(TARGET sharedlib PROPERTY INTERFACE_INCLUDE_DIRECTORIES
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/sharedlib;${CMAKE_CURRENT_BINARY_DIR}>"
|
||||
"$<INSTALL_INTERFACE:$<INSTALL_PREFIX>/include/sharedlib>"
|
||||
)
|
||||
|
||||
set_property(TARGET sharedlib PROPERTY INTERFACE_COMPILE_DEFINITIONS "SHAREDLIB_DEFINE")
|
||||
|
||||
add_library(sharediface INTERFACE)
|
||||
target_link_libraries(sharediface INTERFACE sharedlib)
|
||||
|
||||
export(TARGETS sharediface sharedlib headeronly
|
||||
NAMESPACE bld_
|
||||
FILE ../ExportInterfaceBuildTree.cmake
|
||||
)
|
||||
|
||||
install(TARGETS headeronly sharediface sharedlib
|
||||
EXPORT expInterface
|
||||
RUNTIME DESTINATION bin
|
||||
LIBRARY DESTINATION lib NAMELINK_SKIP
|
||||
ARCHIVE DESTINATION lib
|
||||
FRAMEWORK DESTINATION Frameworks
|
||||
BUNDLE DESTINATION Applications
|
||||
)
|
||||
install(FILES
|
||||
headeronly/headeronly.h
|
||||
DESTINATION include/headeronly
|
||||
)
|
||||
install(FILES
|
||||
sharedlib/sharedlib.h
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/sharedlib_export.h"
|
||||
DESTINATION include/sharedlib
|
||||
)
|
||||
|
||||
install(EXPORT expInterface NAMESPACE exp_ DESTINATION lib/exp)
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
enum { one };
|
||||
|
||||
struct HeaderOnly
|
||||
{
|
||||
int foo() const { return 0; }
|
||||
};
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "sharedlib.h"
|
||||
|
||||
int SharedLibObject::foo() const
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "sharedlib_export.h"
|
||||
|
||||
struct SHAREDLIB_EXPORT SharedLibObject
|
||||
{
|
||||
int foo() const;
|
||||
};
|
|
@ -19,3 +19,6 @@ add_executable(imp_testTransExe1b imp_testTransExe1.c)
|
|||
target_link_libraries(imp_testTransExe1b imp_lib1b)
|
||||
|
||||
add_subdirectory(try_compile)
|
||||
|
||||
# Test package INTERFACE controls
|
||||
add_subdirectory(Interface)
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
|
||||
# Import targets from the exported build tree.
|
||||
include(${Import_BINARY_DIR}/../Export/ExportInterfaceBuildTree.cmake)
|
||||
|
||||
# Import targets from the exported install tree.
|
||||
include(${CMAKE_INSTALL_PREFIX}/lib/exp/expInterface.cmake)
|
||||
|
||||
add_library(define_iface INTERFACE)
|
||||
set_property(TARGET define_iface PROPERTY
|
||||
INTERFACE_COMPILE_DEFINITIONS DEFINE_IFACE_DEFINE)
|
||||
|
||||
add_executable(headeronlytest_bld headeronlytest.cpp)
|
||||
target_link_libraries(headeronlytest_bld bld_headeronly)
|
||||
|
||||
set_property(TARGET bld_sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
|
||||
|
||||
add_executable(interfacetest_bld interfacetest.cpp)
|
||||
target_link_libraries(interfacetest_bld bld_sharediface)
|
||||
|
||||
include(CheckCXXSourceCompiles)
|
||||
|
||||
macro(do_try_compile prefix)
|
||||
|
||||
set(CMAKE_REQUIRED_LIBRARIES ${prefix}headeronly)
|
||||
check_cxx_source_compiles(
|
||||
"
|
||||
#include \"headeronly.h\"
|
||||
|
||||
#ifndef HEADERONLY_DEFINE
|
||||
#error Expected HEADERONLY_DEFINE
|
||||
#endif
|
||||
|
||||
int main(int,char**)
|
||||
{
|
||||
HeaderOnly ho;
|
||||
return ho.foo();
|
||||
}
|
||||
" ${prefix}IFACE_TRY_COMPILE)
|
||||
|
||||
if(NOT ${prefix}IFACE_TRY_COMPILE)
|
||||
message(SEND_ERROR "${prefix} try_compile with IMPORTED INTERFACE target failed!\n\n${OUTPUT}")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
do_try_compile(bld_)
|
||||
|
||||
add_executable(headeronlytest_exp headeronlytest.cpp)
|
||||
target_link_libraries(headeronlytest_exp exp_headeronly)
|
||||
|
||||
set_property(TARGET exp_sharediface APPEND PROPERTY INTERFACE_LINK_LIBRARIES define_iface)
|
||||
|
||||
add_executable(interfacetest_exp interfacetest.cpp)
|
||||
target_link_libraries(interfacetest_exp exp_sharediface)
|
||||
|
||||
do_try_compile(exp_)
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#include "headeronly.h"
|
||||
|
||||
#ifndef HEADERONLY_DEFINE
|
||||
#error Expected HEADERONLY_DEFINE
|
||||
#endif
|
||||
|
||||
#ifdef SHAREDLIB_DEFINE
|
||||
#error Unexpected SHAREDLIB_DEFINE
|
||||
#endif
|
||||
|
||||
|
||||
int main(int,char**)
|
||||
{
|
||||
HeaderOnly ho;
|
||||
return ho.foo();
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#include "sharedlib.h"
|
||||
|
||||
#ifndef SHAREDLIB_DEFINE
|
||||
#error Expected SHAREDLIB_DEFINE
|
||||
#endif
|
||||
|
||||
#ifdef HEADERONLY_DEFINE
|
||||
#error Unexpected HEADERONLY_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef DEFINE_IFACE_DEFINE
|
||||
#error Expected DEFINE_IFACE_DEFINE
|
||||
#endif
|
||||
|
||||
int main(int,char**)
|
||||
{
|
||||
SharedLibObject slo;
|
||||
return slo.foo();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(InterfaceLibrary)
|
||||
|
||||
add_library(iface_nodepends INTERFACE)
|
||||
target_compile_definitions(iface_nodepends INTERFACE IFACE_DEFINE)
|
||||
|
||||
add_executable(InterfaceLibrary definetestexe.cpp)
|
||||
target_link_libraries(InterfaceLibrary iface_nodepends)
|
||||
|
||||
add_subdirectory(libsdir)
|
||||
|
||||
add_executable(sharedlibtestexe sharedlibtestexe.cpp)
|
||||
target_link_libraries(sharedlibtestexe shared_iface)
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#ifndef IFACE_DEFINE
|
||||
#error Expected IFACE_DEFINE
|
||||
#endif
|
||||
|
||||
int main(int,char**)
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
include(GenerateExportHeader)
|
||||
|
||||
add_library(sharedlib SHARED sharedlib.cpp)
|
||||
generate_export_header(sharedlib)
|
||||
|
||||
add_library(shareddependlib SHARED shareddependlib.cpp)
|
||||
generate_export_header(shareddependlib)
|
||||
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
|
||||
|
||||
target_link_libraries(sharedlib PUBLIC shareddependlib)
|
||||
|
||||
target_include_directories(shareddependlib
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/shareddependlib")
|
||||
target_compile_definitions(shareddependlib
|
||||
INTERFACE $<1:SHAREDDEPENDLIB_DEFINE>)
|
||||
|
||||
target_include_directories(sharedlib
|
||||
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/sharedlib")
|
||||
target_compile_definitions(shareddependlib
|
||||
INTERFACE $<1:SHAREDLIB_DEFINE>)
|
||||
|
||||
add_library(shared_iface INTERFACE)
|
||||
target_link_libraries(shared_iface INTERFACE sharedlib)
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include "shareddependlib.h"
|
||||
|
||||
int SharedDependLibObject::foo() const
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef SHAREDDEPENDLIB_H
|
||||
#define SHAREDDEPENDLIB_H
|
||||
|
||||
#include "shareddependlib_export.h"
|
||||
|
||||
struct SHAREDDEPENDLIB_EXPORT SharedDependLibObject
|
||||
{
|
||||
int foo() const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#include "sharedlib.h"
|
||||
|
||||
SharedDependLibObject SharedLibObject::object() const
|
||||
{
|
||||
SharedDependLibObject sdlo;
|
||||
return sdlo;
|
||||
}
|
||||
int SharedLibObject::foo() const
|
||||
{
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#ifndef SHAREDLIB_H
|
||||
#define SHAREDLIB_H
|
||||
|
||||
#include "sharedlib_export.h"
|
||||
|
||||
#include "shareddependlib.h"
|
||||
|
||||
struct SHAREDLIB_EXPORT SharedLibObject
|
||||
{
|
||||
SharedDependLibObject object() const;
|
||||
int foo() const;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#ifndef SHAREDLIB_DEFINE
|
||||
#error Expected SHAREDLIB_DEFINE
|
||||
#endif
|
||||
|
||||
#ifndef SHAREDDEPENDLIB_DEFINE
|
||||
#error Expected SHAREDDEPENDLIB_DEFINE
|
||||
#endif
|
||||
|
||||
#include "sharedlib.h"
|
||||
#include "shareddependlib.h"
|
||||
|
||||
int main(int,char**)
|
||||
{
|
||||
SharedLibObject sl;
|
||||
SharedDependLibObject sdl = sl.object();
|
||||
|
||||
return sdl.foo() + sl.foo();
|
||||
}
|
|
@ -9,5 +9,6 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}") # For pic_test.h
|
|||
|
||||
add_subdirectory(global)
|
||||
add_subdirectory(targets)
|
||||
add_subdirectory(interface)
|
||||
|
||||
add_executable(PositionIndependentTargets main.cpp)
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
|
||||
add_library(piciface INTERFACE)
|
||||
set_property(TARGET piciface PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_executable(test_empty_iface "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
|
||||
target_link_libraries(test_empty_iface piciface)
|
||||
|
||||
add_library(sharedlib SHARED "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp")
|
||||
target_link_libraries(sharedlib piciface)
|
||||
set_property(TARGET sharedlib PROPERTY DEFINE_SYMBOL PIC_TEST_BUILD_DLL)
|
||||
|
||||
add_executable(test_iface_via_shared "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
|
||||
target_link_libraries(test_iface_via_shared sharedlib)
|
||||
|
||||
add_library(sharedlibpic SHARED "${CMAKE_CURRENT_SOURCE_DIR}/../pic_lib.cpp")
|
||||
set_property(TARGET sharedlibpic PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||
set_property(TARGET sharedlibpic PROPERTY DEFINE_SYMBOL PIC_TEST_BUILD_DLL)
|
||||
|
||||
add_library(shared_iface INTERFACE)
|
||||
target_link_libraries(shared_iface INTERFACE sharedlibpic)
|
||||
|
||||
add_executable(test_shared_via_iface "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
|
||||
target_link_libraries(test_shared_via_iface shared_iface)
|
||||
|
||||
add_executable(test_shared_via_iface_non_conflict "${CMAKE_CURRENT_SOURCE_DIR}/../pic_main.cpp")
|
||||
set_property(TARGET test_shared_via_iface_non_conflict PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
target_link_libraries(test_shared_via_iface_non_conflict shared_iface)
|
|
@ -100,6 +100,7 @@ add_RunCMake_test(variable_watch)
|
|||
add_RunCMake_test(CMP0004)
|
||||
add_RunCMake_test(TargetPolicies)
|
||||
add_RunCMake_test(alias_targets)
|
||||
add_RunCMake_test(interface_library)
|
||||
|
||||
find_package(Qt4 QUIET)
|
||||
find_package(Qt5Core QUIET)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
CMake Error: Property POSITION_INDEPENDENT_CODE on target "conflict" is
|
||||
implied to be FALSE because it was used to determine the link libraries
|
||||
already. The INTERFACE_POSITION_INDEPENDENT_CODE property on
|
||||
dependency "picon" is in conflict.
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
add_library(piciface INTERFACE)
|
||||
|
||||
add_library(picon INTERFACE)
|
||||
set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_executable(conflict "main.cpp")
|
||||
target_link_libraries(conflict picon $<$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>:piciface>)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,3 @@
|
|||
CMake Error: The INTERFACE_POSITION_INDEPENDENT_CODE property of "picoff" does
|
||||
not agree with the value of POSITION_INDEPENDENT_CODE already determined
|
||||
for "conflict".
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
add_library(picon INTERFACE)
|
||||
set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_library(picoff INTERFACE)
|
||||
set_property(TARGET picoff PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE OFF)
|
||||
|
||||
add_executable(conflict "main.cpp")
|
||||
target_link_libraries(conflict picon picoff)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,4 @@
|
|||
Property POSITION_INDEPENDENT_CODE on target "conflict" is
|
||||
implied to be FALSE because it was used to determine the link libraries
|
||||
already. The INTERFACE_POSITION_INDEPENDENT_CODE property on
|
||||
dependency "picon" is in conflict.
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
add_library(picoff INTERFACE)
|
||||
|
||||
add_library(picon INTERFACE)
|
||||
set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
add_executable(conflict "main.cpp")
|
||||
target_link_libraries(conflict picon $<$<NOT:$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>>:picoff>)
|
|
@ -3,3 +3,6 @@ include(RunCMake)
|
|||
run_cmake(Conflict1)
|
||||
run_cmake(Conflict2)
|
||||
run_cmake(Conflict3)
|
||||
run_cmake(Conflict4)
|
||||
run_cmake(Conflict5)
|
||||
run_cmake(Conflict6)
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
cmake_minimum_required(VERSION 2.8.4)
|
||||
project(${RunCMake_TEST} NONE)
|
||||
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1,4 @@
|
|||
include(RunCMake)
|
||||
|
||||
run_cmake(invalid_name)
|
||||
run_cmake(target_commands)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,15 @@
|
|||
CMake Error at invalid_name.cmake:2 \(add_library\):
|
||||
add_library Invalid name for INTERFACE library target: if\$ace
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at invalid_name.cmake:4 \(add_library\):
|
||||
add_library Invalid name for INTERFACE library target: iface::target
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at invalid_name.cmake:6 \(add_library\):
|
||||
add_library Invalid name for IMPORTED INTERFACE library target:
|
||||
if\$target_imported
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
add_library(if$ace INTERFACE)
|
||||
|
||||
add_library(iface::target INTERFACE)
|
||||
|
||||
add_library(if$target_imported INTERFACE IMPORTED)
|
|
@ -0,0 +1 @@
|
|||
1
|
|
@ -0,0 +1,47 @@
|
|||
CMake Error at target_commands.cmake:4 \(target_link_libraries\):
|
||||
INTERFACE library can only be used with the INTERFACE keyword of
|
||||
target_link_libraries
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at target_commands.cmake:5 \(target_link_libraries\):
|
||||
INTERFACE library can only be used with the INTERFACE keyword of
|
||||
target_link_libraries
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at target_commands.cmake:6 \(target_link_libraries\):
|
||||
INTERFACE library can only be used with the INTERFACE keyword of
|
||||
target_link_libraries
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at target_commands.cmake:7 \(target_link_libraries\):
|
||||
INTERFACE library can only be used with the INTERFACE keyword of
|
||||
target_link_libraries
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at target_commands.cmake:9 \(target_include_directories\):
|
||||
target_include_directories may only be set INTERFACE properties on
|
||||
INTERFACE targets
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at target_commands.cmake:10 \(target_include_directories\):
|
||||
target_include_directories may only be set INTERFACE properties on
|
||||
INTERFACE targets
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at target_commands.cmake:12 \(target_compile_definitions\):
|
||||
target_compile_definitions may only be set INTERFACE properties on
|
||||
INTERFACE targets
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
||||
+
|
||||
CMake Error at target_commands.cmake:13 \(target_compile_definitions\):
|
||||
target_compile_definitions may only be set INTERFACE properties on
|
||||
INTERFACE targets
|
||||
Call Stack \(most recent call first\):
|
||||
CMakeLists.txt:3 \(include\)
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
add_library(iface INTERFACE)
|
||||
|
||||
target_link_libraries(iface PRIVATE foo)
|
||||
target_link_libraries(iface PUBLIC foo)
|
||||
target_link_libraries(iface foo)
|
||||
target_link_libraries(iface LINK_INTERFACE_LIBRARIES foo)
|
||||
|
||||
target_include_directories(iface PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_include_directories(iface PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
|
||||
target_compile_definitions(iface PRIVATE SOME_DEFINE)
|
||||
target_compile_definitions(iface PUBLIC SOME_DEFINE)
|
Loading…
Reference in New Issue