Merge topic 'INTERFACE_LIBRARY-property-whitelist'

5ee9e6b cmTarget: Add whitelist of properties on INTERFACE_LIBRARY.
0bfcb45 INTERFACE_LIBRARY: Avoid codepaths which set unneeded properties.
This commit is contained in:
Brad King 2013-11-26 09:36:58 -05:00 committed by CMake Topic Stage
commit 779fd10160
19 changed files with 257 additions and 82 deletions

View File

@ -237,7 +237,15 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index)
it != configs.end(); ++it) it != configs.end(); ++it)
{ {
std::vector<std::string> tlibs; std::vector<std::string> tlibs;
depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender); if (depender->GetType() == cmTarget::INTERFACE_LIBRARY)
{
// For INTERFACE_LIBRARY depend on the interface instead.
depender->GetInterfaceLinkLibraries(it->c_str(), tlibs, depender);
}
else
{
depender->GetDirectLinkLibraries(it->c_str(), tlibs, depender);
}
// A target should not depend on itself. // A target should not depend on itself.
emitted.insert(depender->GetName()); emitted.insert(depender->GetName());
for(std::vector<std::string>::const_iterator lib = tlibs.begin(); for(std::vector<std::string>::const_iterator lib = tlibs.begin();

View File

@ -388,14 +388,11 @@ void getCompatibleInterfaceProperties(cmTarget *target,
if (!info) if (!info)
{ {
if (target->GetType() != cmTarget::INTERFACE_LIBRARY) cmMakefile* mf = target->GetMakefile();
{ cmOStringStream e;
cmMakefile* mf = target->GetMakefile(); e << "Exporting the target \"" << target->GetName() << "\" is not "
cmOStringStream e; "allowed since its linker language cannot be determined";
e << "Exporting the target \"" << target->GetName() << "\" is not " mf->IssueMessage(cmake::FATAL_ERROR, e.str());
"allowed since its linker language cannot be determined";
mf->IssueMessage(cmake::FATAL_ERROR, e.str());
}
return; return;
} }
@ -447,15 +444,18 @@ void cmExportFileGenerator::PopulateCompatibleInterfaceProperties(
getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MAX", getPropertyContents(target, "COMPATIBLE_INTERFACE_NUMBER_MAX",
ifaceProperties); ifaceProperties);
getCompatibleInterfaceProperties(target, ifaceProperties, 0); if (target->GetType() != cmTarget::INTERFACE_LIBRARY)
std::vector<std::string> configNames;
target->GetMakefile()->GetConfigurations(configNames);
for (std::vector<std::string>::const_iterator ci = configNames.begin();
ci != configNames.end(); ++ci)
{ {
getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str()); getCompatibleInterfaceProperties(target, ifaceProperties, 0);
std::vector<std::string> configNames;
target->GetMakefile()->GetConfigurations(configNames);
for (std::vector<std::string>::const_iterator ci = configNames.begin();
ci != configNames.end(); ++ci)
{
getCompatibleInterfaceProperties(target, ifaceProperties, ci->c_str());
}
} }
for (std::set<std::string>::const_iterator it = ifaceProperties.begin(); for (std::set<std::string>::const_iterator it = ifaceProperties.begin();

View File

@ -954,7 +954,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
if (!prop) if (!prop)
{ {
if (target->IsImported()) if (target->IsImported()
|| target->GetType() == cmTarget::INTERFACE_LIBRARY)
{ {
return linkedTargetsContent; return linkedTargetsContent;
} }

View File

@ -1309,6 +1309,11 @@ void cmGlobalGenerator::FinalizeTargetCompileInfo()
{ {
cmTarget* t = &ti->second; cmTarget* t = &ti->second;
if (t->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
t->AppendBuildInterfaceIncludes(); t->AppendBuildInterfaceIncludes();
for (std::vector<cmValueWithOrigin>::const_iterator it for (std::vector<cmValueWithOrigin>::const_iterator it
@ -1461,6 +1466,10 @@ void cmGlobalGenerator::CheckLocalGenerators()
for (cmTargets::iterator l = targets.begin(); for (cmTargets::iterator l = targets.begin();
l != targets.end(); l++) l != targets.end(); l++)
{ {
if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
const cmTarget::LinkLibraryVectorType& libs = const cmTarget::LinkLibraryVectorType& libs =
l->second.GetOriginalLinkLibraries(); l->second.GetOriginalLinkLibraries();
for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin(); for(cmTarget::LinkLibraryVectorType::const_iterator lib = libs.begin();

View File

@ -327,6 +327,10 @@ void cmGlobalVisualStudio7Generator::WriteTargetConfigurations(
projectTargets.begin(); tt != projectTargets.end(); ++tt) projectTargets.begin(); tt != projectTargets.end(); ++tt)
{ {
cmTarget* target = *tt; cmTarget* target = *tt;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
const char* expath = target->GetProperty("EXTERNAL_MSPROJECT"); const char* expath = target->GetProperty("EXTERNAL_MSPROJECT");
if(expath) if(expath)
{ {
@ -364,6 +368,10 @@ void cmGlobalVisualStudio7Generator::WriteTargetsToSolution(
projectTargets.begin(); tt != projectTargets.end(); ++tt) projectTargets.begin(); tt != projectTargets.end(); ++tt)
{ {
cmTarget* target = *tt; cmTarget* target = *tt;
if(target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
bool written = false; bool written = false;
// handle external vc project files // handle external vc project files

View File

@ -442,7 +442,8 @@ bool cmGlobalVisualStudio8Generator::NeedLinkLibraryDependencies(
{ {
if(cmTarget* depTarget = this->FindTarget(0, ui->c_str())) if(cmTarget* depTarget = this->FindTarget(0, ui->c_str()))
{ {
if(depTarget->GetProperty("EXTERNAL_MSPROJECT")) if(depTarget->GetType() != cmTarget::INTERFACE_LIBRARY
&& depTarget->GetProperty("EXTERNAL_MSPROJECT"))
{ {
// This utility dependency names an external .vcproj target. // This utility dependency names an external .vcproj target.
// We use LinkLibraryDependencies="true" to link to it without // We use LinkLibraryDependencies="true" to link to it without

View File

@ -645,7 +645,8 @@ bool cmInstallCommand::HandleTargetsMode(std::vector<std::string> const& args)
// generators for them. // generators for them.
bool createInstallGeneratorsForTargetFileSets = true; bool createInstallGeneratorsForTargetFileSets = true;
if(target.IsFrameworkOnApple()) if(target.IsFrameworkOnApple()
|| target.GetType() == cmTarget::INTERFACE_LIBRARY)
{ {
createInstallGeneratorsForTargetFileSets = false; createInstallGeneratorsForTargetFileSets = false;
} }

View File

@ -541,6 +541,10 @@ void cmLocalGenerator::GenerateTargetManifest()
t != targets.end(); ++t) t != targets.end(); ++t)
{ {
cmGeneratorTarget& target = *t->second; cmGeneratorTarget& target = *t->second;
if (target.Target->GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
if(configNames.empty()) if(configNames.empty())
{ {
target.GenerateTargetManifest(0); target.GenerateTargetManifest(0);
@ -2829,6 +2833,11 @@ cmLocalGenerator
cmTargets& tgts = this->Makefile->GetTargets(); cmTargets& tgts = this->Makefile->GetTargets();
for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l) for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); ++l)
{ {
if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
// Include the user-specified pre-install script for this target. // Include the user-specified pre-install script for this target.
if(const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT")) if(const char* preinstall = l->second.GetProperty("PRE_INSTALL_SCRIPT"))
{ {

View File

@ -68,7 +68,8 @@ void cmLocalNinjaGenerator::Generate()
for(cmGeneratorTargetsType::iterator t = targets.begin(); for(cmGeneratorTargetsType::iterator t = targets.begin();
t != targets.end(); ++t) t != targets.end(); ++t)
{ {
if (t->second->Target->IsImported()) if (t->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY
|| t->second->Target->IsImported())
{ {
continue; continue;
} }

View File

@ -151,7 +151,8 @@ void cmLocalUnixMakefileGenerator3::Generate()
for(cmGeneratorTargetsType::iterator t = targets.begin(); for(cmGeneratorTargetsType::iterator t = targets.begin();
t != targets.end(); ++t) t != targets.end(); ++t)
{ {
if (t->second->Target->IsImported()) if (t->second->Target->GetType() == cmTarget::INTERFACE_LIBRARY
|| t->second->Target->IsImported())
{ {
continue; continue;
} }

View File

@ -868,6 +868,10 @@ void cmMakefile::ConfigureFinalPass()
for (cmTargets::iterator l = this->Targets.begin(); for (cmTargets::iterator l = this->Targets.begin();
l != this->Targets.end(); l++) l != this->Targets.end(); l++)
{ {
if (l->second.GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
l->second.FinishConfigure(); l->second.FinishConfigure();
} }
} }
@ -2256,6 +2260,10 @@ void cmMakefile::ExpandVariablesCMP0019()
l != this->Targets.end(); ++l) l != this->Targets.end(); ++l)
{ {
cmTarget &t = l->second; cmTarget &t = l->second;
if (t.GetType() == cmTarget::INTERFACE_LIBRARY)
{
continue;
}
includeDirs = t.GetProperty("INCLUDE_DIRECTORIES"); includeDirs = t.GetProperty("INCLUDE_DIRECTORIES");
if(mightExpandVariablesCMP0019(includeDirs)) if(mightExpandVariablesCMP0019(includeDirs))
{ {

View File

@ -25,9 +25,12 @@ cmMakefileLibraryTargetGenerator
cmMakefileTargetGenerator(target->Target) cmMakefileTargetGenerator(target->Target)
{ {
this->CustomCommandDriver = OnDepends; this->CustomCommandDriver = OnDepends;
this->Target->GetLibraryNames( if (this->Target->GetType() != cmTarget::INTERFACE_LIBRARY)
this->TargetNameOut, this->TargetNameSO, this->TargetNameReal, {
this->TargetNameImport, this->TargetNamePDB, this->ConfigName); this->Target->GetLibraryNames(
this->TargetNameOut, this->TargetNameSO, this->TargetNameReal,
this->TargetNameImport, this->TargetNamePDB, this->ConfigName);
}
this->OSXBundleGenerator = new cmOSXBundleGenerator(target, this->OSXBundleGenerator = new cmOSXBundleGenerator(target,
this->ConfigName); this->ConfigName);

View File

@ -428,6 +428,12 @@ struct cmStrCmp {
return strcmp(input, m_test) == 0; return strcmp(input, m_test) == 0;
} }
// For use with binary_search
bool operator()(const char *str1, const char *str2)
{
return strcmp(str1, str2) < 0;
}
private: private:
const char *m_test; const char *m_test;
}; };

View File

@ -255,32 +255,34 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->IsApple = this->Makefile->IsOn("APPLE"); this->IsApple = this->Makefile->IsOn("APPLE");
// Setup default property values. // Setup default property values.
this->SetPropertyDefault("INSTALL_NAME_DIR", 0); if (this->GetType() != INTERFACE_LIBRARY)
this->SetPropertyDefault("INSTALL_RPATH", ""); {
this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF"); this->SetPropertyDefault("INSTALL_NAME_DIR", 0);
this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF"); this->SetPropertyDefault("INSTALL_RPATH", "");
this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF"); this->SetPropertyDefault("INSTALL_RPATH_USE_LINK_PATH", "OFF");
this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("SKIP_BUILD_RPATH", "OFF");
this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("BUILD_WITH_INSTALL_RPATH", "OFF");
this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("ARCHIVE_OUTPUT_DIRECTORY", 0);
this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("LIBRARY_OUTPUT_DIRECTORY", 0);
this->SetPropertyDefault("Fortran_FORMAT", 0); this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0);
this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("PDB_OUTPUT_DIRECTORY", 0);
this->SetPropertyDefault("GNUtoMS", 0); this->SetPropertyDefault("Fortran_FORMAT", 0);
this->SetPropertyDefault("OSX_ARCHITECTURES", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0);
this->SetPropertyDefault("AUTOMOC", 0); this->SetPropertyDefault("GNUtoMS", 0);
this->SetPropertyDefault("AUTOUIC", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0);
this->SetPropertyDefault("AUTORCC", 0); this->SetPropertyDefault("AUTOMOC", 0);
this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0); this->SetPropertyDefault("AUTOUIC", 0);
this->SetPropertyDefault("AUTOUIC_OPTIONS", 0); this->SetPropertyDefault("AUTORCC", 0);
this->SetPropertyDefault("AUTORCC_OPTIONS", 0); this->SetPropertyDefault("AUTOMOC_MOC_OPTIONS", 0);
this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0); this->SetPropertyDefault("AUTOUIC_OPTIONS", 0);
this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0); this->SetPropertyDefault("AUTORCC_OPTIONS", 0);
this->SetPropertyDefault("WIN32_EXECUTABLE", 0); this->SetPropertyDefault("LINK_DEPENDS_NO_SHARED", 0);
this->SetPropertyDefault("MACOSX_BUNDLE", 0); this->SetPropertyDefault("LINK_INTERFACE_LIBRARIES", 0);
this->SetPropertyDefault("MACOSX_RPATH", 0); this->SetPropertyDefault("WIN32_EXECUTABLE", 0);
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0); this->SetPropertyDefault("MACOSX_BUNDLE", 0);
this->SetPropertyDefault("MACOSX_RPATH", 0);
this->SetPropertyDefault("NO_SYSTEM_FROM_IMPORTED", 0);
}
// Collect the set of configuration types. // Collect the set of configuration types.
std::vector<std::string> configNames; std::vector<std::string> configNames;
@ -300,6 +302,11 @@ void cmTarget::SetMakefile(cmMakefile* mf)
std::string configUpper = cmSystemTools::UpperCase(*ci); std::string configUpper = cmSystemTools::UpperCase(*ci);
for(const char** p = configProps; *p; ++p) for(const char** p = configProps; *p; ++p)
{ {
if (this->TargetTypeValue == INTERFACE_LIBRARY
&& strcmp(*p, "MAP_IMPORTED_CONFIG_") != 0)
{
continue;
}
std::string property = *p; std::string property = *p;
property += configUpper; property += configUpper;
this->SetPropertyDefault(property.c_str(), 0); this->SetPropertyDefault(property.c_str(), 0);
@ -311,7 +318,8 @@ void cmTarget::SetMakefile(cmMakefile* mf)
// did not support this variable. Projects may still specify the // did not support this variable. Projects may still specify the
// property directly. TODO: Make this depend on backwards // property directly. TODO: Make this depend on backwards
// compatibility setting. // compatibility setting.
if(this->TargetTypeValue != cmTarget::EXECUTABLE) if(this->TargetTypeValue != cmTarget::EXECUTABLE
&& this->TargetTypeValue != cmTarget::INTERFACE_LIBRARY)
{ {
std::string property = cmSystemTools::UpperCase(*ci); std::string property = cmSystemTools::UpperCase(*ci);
property += "_POSTFIX"; property += "_POSTFIX";
@ -352,16 +360,22 @@ void cmTarget::SetMakefile(cmMakefile* mf)
this->InsertCompileOption(*it); this->InsertCompileOption(*it);
} }
this->SetPropertyDefault("C_VISIBILITY_PRESET", 0); if (this->GetType() != INTERFACE_LIBRARY)
this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0); {
this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0); this->SetPropertyDefault("C_VISIBILITY_PRESET", 0);
this->SetPropertyDefault("CXX_VISIBILITY_PRESET", 0);
this->SetPropertyDefault("VISIBILITY_INLINES_HIDDEN", 0);
}
if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY if(this->TargetTypeValue == cmTarget::SHARED_LIBRARY
|| this->TargetTypeValue == cmTarget::MODULE_LIBRARY) || this->TargetTypeValue == cmTarget::MODULE_LIBRARY)
{ {
this->SetProperty("POSITION_INDEPENDENT_CODE", "True"); this->SetProperty("POSITION_INDEPENDENT_CODE", "True");
} }
this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0); if (this->GetType() != INTERFACE_LIBRARY)
{
this->SetPropertyDefault("POSITION_INDEPENDENT_CODE", 0);
}
// Record current policies for later use. // Record current policies for later use.
#define CAPTURE_TARGET_POLICY(POLICY) \ #define CAPTURE_TARGET_POLICY(POLICY) \
@ -1369,6 +1383,47 @@ void cmTarget::GatherDependencies( const cmMakefile& mf,
} }
} }
//----------------------------------------------------------------------------
static bool whiteListedInterfaceProperty(const char *prop)
{
if(cmHasLiteralPrefix(prop, "INTERFACE_"))
{
return true;
}
static const char* builtIns[] = {
// ###: This must remain sorted. It is processed with a binary search.
"COMPATIBLE_INTERFACE_BOOL",
"COMPATIBLE_INTERFACE_NUMBER_MAX",
"COMPATIBLE_INTERFACE_NUMBER_MIN",
"COMPATIBLE_INTERFACE_STRING",
"EXCLUDE_FROM_ALL",
"EXCLUDE_FROM_DEFAULT_BUILD",
"EXPORT_NAME",
"IMPORTED_LINK_INTERFACE_LANGUAGES",
"IMPORTED",
"NAME",
"TYPE",
"VERSION"
};
if (std::binary_search(cmArrayBegin(builtIns),
cmArrayEnd(builtIns),
prop,
cmStrCmp(prop)))
{
return true;
}
if (cmHasLiteralPrefix(prop, "EXCLUDE_FROM_DEFAULT_BUILD_")
|| cmHasLiteralPrefix(prop, "IMPORTED_LINK_INTERFACE_LANGUAGES_")
|| cmHasLiteralPrefix(prop, "MAP_IMPORTED_CONFIG_"))
{
return true;
}
return false;
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void cmTarget::SetProperty(const char* prop, const char* value) void cmTarget::SetProperty(const char* prop, const char* value)
{ {
@ -1376,6 +1431,16 @@ void cmTarget::SetProperty(const char* prop, const char* value)
{ {
return; return;
} }
if (this->GetType() == INTERFACE_LIBRARY
&& !whiteListedInterfaceProperty(prop))
{
cmOStringStream e;
e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
"The property \"" << prop << "\" is not allowed.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
return;
}
if (strcmp(prop, "NAME") == 0) if (strcmp(prop, "NAME") == 0)
{ {
cmOStringStream e; cmOStringStream e;
@ -1445,6 +1510,15 @@ void cmTarget::AppendProperty(const char* prop, const char* value,
{ {
return; return;
} }
if (this->GetType() == INTERFACE_LIBRARY
&& !whiteListedInterfaceProperty(prop))
{
cmOStringStream e;
e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
"The property \"" << prop << "\" is not allowed.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
return;
}
if (strcmp(prop, "NAME") == 0) if (strcmp(prop, "NAME") == 0)
{ {
cmOStringStream e; cmOStringStream e;
@ -2560,6 +2634,16 @@ const char *cmTarget::GetProperty(const char* prop,
return 0; return 0;
} }
if (this->GetType() == INTERFACE_LIBRARY
&& !whiteListedInterfaceProperty(prop))
{
cmOStringStream e;
e << "INTERFACE_LIBRARY targets may only have whitelisted properties. "
"The property \"" << prop << "\" is not allowed.";
this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str().c_str());
return 0;
}
if (strcmp(prop, "NAME") == 0) if (strcmp(prop, "NAME") == 0)
{ {
return this->GetName(); return this->GetName();
@ -4433,7 +4517,8 @@ bool isLinkDependentProperty(cmTarget const* tgt, const std::string &p,
bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
const char *config) const const char *config) const
{ {
if (this->TargetTypeValue == OBJECT_LIBRARY) if (this->TargetTypeValue == OBJECT_LIBRARY
|| this->TargetTypeValue == INTERFACE_LIBRARY)
{ {
return false; return false;
} }
@ -4446,7 +4531,8 @@ bool cmTarget::IsLinkInterfaceDependentBoolProperty(const std::string &p,
bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
const char *config) const const char *config) const
{ {
if (this->TargetTypeValue == OBJECT_LIBRARY) if (this->TargetTypeValue == OBJECT_LIBRARY
|| this->TargetTypeValue == INTERFACE_LIBRARY)
{ {
return false; return false;
} }
@ -4458,7 +4544,8 @@ bool cmTarget::IsLinkInterfaceDependentStringProperty(const std::string &p,
bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
const char *config) const const char *config) const
{ {
if (this->TargetTypeValue == OBJECT_LIBRARY) if (this->TargetTypeValue == OBJECT_LIBRARY
|| this->TargetTypeValue == INTERFACE_LIBRARY)
{ {
return false; return false;
} }
@ -4470,7 +4557,8 @@ bool cmTarget::IsLinkInterfaceDependentNumberMinProperty(const std::string &p,
bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p, bool cmTarget::IsLinkInterfaceDependentNumberMaxProperty(const std::string &p,
const char *config) const const char *config) const
{ {
if (this->TargetTypeValue == OBJECT_LIBRARY) if (this->TargetTypeValue == OBJECT_LIBRARY
|| this->TargetTypeValue == INTERFACE_LIBRARY)
{ {
return false; return false;
} }
@ -5105,34 +5193,37 @@ bool cmTarget::ComputeLinkInterface(const char* config, LinkInterface& iface,
{ {
emitted.insert(*li); emitted.insert(*li);
} }
LinkImplementation const* impl = this->GetLinkImplementation(config, if (this->GetType() != cmTarget::INTERFACE_LIBRARY)
headTarget);
for(std::vector<std::string>::const_iterator
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{ {
if(emitted.insert(*li).second) LinkImplementation const* impl = this->GetLinkImplementation(config,
headTarget);
for(std::vector<std::string>::const_iterator
li = impl->Libraries.begin(); li != impl->Libraries.end(); ++li)
{ {
if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str())) if(emitted.insert(*li).second)
{ {
// This is a runtime dependency on another shared library. if(cmTarget* tgt = this->Makefile->FindTargetToUse(li->c_str()))
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
{ {
iface.SharedDeps.push_back(*li); // This is a runtime dependency on another shared library.
if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
{
iface.SharedDeps.push_back(*li);
}
}
else
{
// TODO: Recognize shared library file names. Perhaps this
// should be moved to cmComputeLinkInformation, but that creates
// a chicken-and-egg problem since this list is needed for its
// construction.
} }
} }
else
{
// TODO: Recognize shared library file names. Perhaps this
// should be moved to cmComputeLinkInformation, but that creates
// a chicken-and-egg problem since this list is needed for its
// construction.
}
} }
} if(this->LinkLanguagePropagatesToDependents())
if(this->LinkLanguagePropagatesToDependents()) {
{ // Targets using this archive need its language runtime libraries.
// Targets using this archive need its language runtime libraries. iface.Languages = impl->Languages;
iface.Languages = impl->Languages; }
} }
} }
} }

View File

@ -184,7 +184,8 @@ void cmVisualStudio10TargetGenerator::WriteString(const char* line,
void cmVisualStudio10TargetGenerator::Generate() void cmVisualStudio10TargetGenerator::Generate()
{ {
// do not generate external ms projects // do not generate external ms projects
if(this->Target->GetProperty("EXTERNAL_MSPROJECT")) if(this->Target->GetType() == cmTarget::INTERFACE_LIBRARY
|| this->Target->GetProperty("EXTERNAL_MSPROJECT"))
{ {
return; return;
} }

View File

@ -3,3 +3,4 @@ include(RunCMake)
run_cmake(invalid_name) run_cmake(invalid_name)
run_cmake(target_commands) run_cmake(target_commands)
run_cmake(no_shared_libs) run_cmake(no_shared_libs)
run_cmake(whitelist)

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,19 @@
CMake Error at whitelist.cmake:4 \(set_property\):
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "OUTPUT_NAME" is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at whitelist.cmake:5 \(set_property\):
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "OUTPUT_NAME" is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)
CMake Error at whitelist.cmake:6 \(get_target_property\):
INTERFACE_LIBRARY targets may only have whitelisted properties. The
property "OUTPUT_NAME" is not allowed.
Call Stack \(most recent call first\):
CMakeLists.txt:3 \(include\)

View File

@ -0,0 +1,6 @@
add_library(iface INTERFACE)
set_property(TARGET iface PROPERTY OUTPUT_NAME output)
set_property(TARGET iface APPEND PROPERTY OUTPUT_NAME append)
get_target_property(outname iface OUTPUT_NAME)