Merge topic 'INTERFACE_POSITION_INDEPENDENT_CODE'
3581b96
Process the INTERFACE_PIC property from linked dependencies042ecf0
Add API to calculate link-interface-dependent bool properties or error.bf5ece5
Keep track of properties used to determine linker libraries.
This commit is contained in:
commit
378899ce87
|
@ -94,7 +94,15 @@ const char *cmCompiledGeneratorExpression::Evaluate(
|
||||||
|
|
||||||
for ( ; it != end; ++it)
|
for ( ; it != end; ++it)
|
||||||
{
|
{
|
||||||
this->Output += (*it)->Evaluate(&context, dagChecker);
|
const std::string result = (*it)->Evaluate(&context, dagChecker);
|
||||||
|
this->Output += result;
|
||||||
|
|
||||||
|
for(std::set<cmStdString>::const_iterator
|
||||||
|
p = context.SeenTargetProperties.begin();
|
||||||
|
p != context.SeenTargetProperties.end(); ++p)
|
||||||
|
{
|
||||||
|
this->SeenTargetProperties[*p] += result + ";";
|
||||||
|
}
|
||||||
if (context.HadError)
|
if (context.HadError)
|
||||||
{
|
{
|
||||||
this->Output = "";
|
this->Output = "";
|
||||||
|
|
|
@ -83,6 +83,9 @@ public:
|
||||||
std::set<cmTarget*> const& GetTargets() const
|
std::set<cmTarget*> const& GetTargets() const
|
||||||
{ return this->Targets; }
|
{ return this->Targets; }
|
||||||
|
|
||||||
|
std::map<cmStdString, cmStdString> const& GetSeenTargetProperties() const
|
||||||
|
{ return this->SeenTargetProperties; }
|
||||||
|
|
||||||
~cmCompiledGeneratorExpression();
|
~cmCompiledGeneratorExpression();
|
||||||
|
|
||||||
std::string GetInput() const
|
std::string GetInput() const
|
||||||
|
@ -110,6 +113,7 @@ private:
|
||||||
bool NeedsParsing;
|
bool NeedsParsing;
|
||||||
|
|
||||||
mutable std::set<cmTarget*> Targets;
|
mutable std::set<cmTarget*> Targets;
|
||||||
|
mutable std::map<cmStdString, cmStdString> SeenTargetProperties;
|
||||||
mutable std::string Output;
|
mutable std::string Output;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -380,6 +380,14 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (target == context->HeadTarget)
|
||||||
|
{
|
||||||
|
// Keep track of the properties seen while processing.
|
||||||
|
// The evaluation of the LINK_LIBRARIES generator expressions
|
||||||
|
// will check this to ensure that properties form a DAG.
|
||||||
|
context->SeenTargetProperties.insert(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
if (propertyName.empty())
|
if (propertyName.empty())
|
||||||
{
|
{
|
||||||
reportError(context, content->GetOriginalExpression(),
|
reportError(context, content->GetOriginalExpression(),
|
||||||
|
|
|
@ -24,6 +24,7 @@ struct cmGeneratorExpressionContext
|
||||||
{
|
{
|
||||||
cmListFileBacktrace Backtrace;
|
cmListFileBacktrace Backtrace;
|
||||||
std::set<cmTarget*> Targets;
|
std::set<cmTarget*> Targets;
|
||||||
|
std::set<cmStdString> SeenTargetProperties;
|
||||||
cmMakefile *Makefile;
|
cmMakefile *Makefile;
|
||||||
const char *Config;
|
const char *Config;
|
||||||
cmTarget *HeadTarget; // The target whose property is being evaluated.
|
cmTarget *HeadTarget; // The target whose property is being evaluated.
|
||||||
|
|
|
@ -1639,14 +1639,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target,
|
||||||
if(strcmp(lang, "CXX") == 0)
|
if(strcmp(lang, "CXX") == 0)
|
||||||
{
|
{
|
||||||
this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
|
this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName);
|
||||||
this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, "C");
|
this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target,
|
||||||
|
"C", configName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add language-specific flags.
|
// Add language-specific flags.
|
||||||
this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
|
this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName);
|
||||||
|
|
||||||
// Add shared-library flags if needed.
|
// Add shared-library flags if needed.
|
||||||
this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, lang);
|
this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target,
|
||||||
|
lang, configName);
|
||||||
}
|
}
|
||||||
else if(binary)
|
else if(binary)
|
||||||
{
|
{
|
||||||
|
|
|
@ -1984,7 +1984,8 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags,
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
|
void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
|
||||||
std::string const& lang)
|
std::string const& lang,
|
||||||
|
const char *config)
|
||||||
{
|
{
|
||||||
int targetType = target->GetType();
|
int targetType = target->GetType();
|
||||||
|
|
||||||
|
@ -1997,11 +1998,21 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Add position independendent flags, if needed.
|
if (target->GetType() == cmTarget::OBJECT_LIBRARY)
|
||||||
|
{
|
||||||
if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
|
if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE"))
|
||||||
{
|
{
|
||||||
this->AddPositionIndependentFlags(flags, lang, targetType);
|
this->AddPositionIndependentFlags(flags, lang, targetType);
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target->GetLinkInterfaceDependentBoolProperty(
|
||||||
|
"POSITION_INDEPENDENT_CODE",
|
||||||
|
config))
|
||||||
|
{
|
||||||
|
this->AddPositionIndependentFlags(flags, lang, targetType);
|
||||||
|
}
|
||||||
if (shared)
|
if (shared)
|
||||||
{
|
{
|
||||||
this->AppendFeatureOptions(flags, lang.c_str(), "DLL");
|
this->AppendFeatureOptions(flags, lang.c_str(), "DLL");
|
||||||
|
|
|
@ -142,7 +142,7 @@ public:
|
||||||
void AddLanguageFlags(std::string& flags, const char* lang,
|
void AddLanguageFlags(std::string& flags, const char* lang,
|
||||||
const char* config);
|
const char* config);
|
||||||
void AddCMP0018Flags(std::string &flags, cmTarget* target,
|
void AddCMP0018Flags(std::string &flags, cmTarget* target,
|
||||||
std::string const& lang);
|
std::string const& lang, const char *config);
|
||||||
void AddConfigVariableFlags(std::string& flags, const char* var,
|
void AddConfigVariableFlags(std::string& flags, const char* var,
|
||||||
const char* config);
|
const char* config);
|
||||||
///! Append flags to a string.
|
///! Append flags to a string.
|
||||||
|
|
|
@ -268,7 +268,8 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l)
|
||||||
this->AddFortranFlags(flags);
|
this->AddFortranFlags(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang);
|
this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
|
||||||
|
lang, this->ConfigName);
|
||||||
|
|
||||||
// Add include directory flags.
|
// Add include directory flags.
|
||||||
this->AddIncludeFlags(flags, lang);
|
this->AddIncludeFlags(flags, lang);
|
||||||
|
|
|
@ -147,7 +147,8 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source,
|
||||||
|
|
||||||
// Add shared-library flags if needed.
|
// Add shared-library flags if needed.
|
||||||
this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
|
this->LocalGenerator->AddCMP0018Flags(flags, this->Target,
|
||||||
language.c_str());
|
language.c_str(),
|
||||||
|
this->GetConfigName());
|
||||||
|
|
||||||
// Add include directory flags.
|
// Add include directory flags.
|
||||||
{
|
{
|
||||||
|
|
|
@ -877,6 +877,20 @@ void cmTarget::DefineProperties(cmake *cm)
|
||||||
"CMAKE_POSITION_INDEPENDENT_CODE if it is set when a target is "
|
"CMAKE_POSITION_INDEPENDENT_CODE if it is set when a target is "
|
||||||
"created.");
|
"created.");
|
||||||
|
|
||||||
|
cm->DefineProperty
|
||||||
|
("INTERFACE_POSITION_INDEPENDENT_CODE", cmProperty::TARGET,
|
||||||
|
"Whether consumers need to create a position-independent target",
|
||||||
|
"The INTERFACE_POSITION_INDEPENDENT_CODE property informs consumers of "
|
||||||
|
"this target whether they must set their POSITION_INDEPENDENT_CODE "
|
||||||
|
"property to ON. If this property is set to ON, then the "
|
||||||
|
"POSITION_INDEPENDENT_CODE property on all consumers will be set to "
|
||||||
|
"ON. Similarly, if this property is set to OFF, then the "
|
||||||
|
"POSITION_INDEPENDENT_CODE property on all consumers will be set to "
|
||||||
|
"OFF. If this property is undefined, then consumers will determine "
|
||||||
|
"their POSITION_INDEPENDENT_CODE property by other means. Consumers "
|
||||||
|
"must ensure that the targets that they link to have a consistent "
|
||||||
|
"requirement for their INTERFACE_POSITION_INDEPENDENT_CODE property.");
|
||||||
|
|
||||||
cm->DefineProperty
|
cm->DefineProperty
|
||||||
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
|
("POST_INSTALL_SCRIPT", cmProperty::TARGET,
|
||||||
"Deprecated install support.",
|
"Deprecated install support.",
|
||||||
|
@ -2164,16 +2178,19 @@ void cmTarget::GetDirectLinkLibraries(const char *config,
|
||||||
{
|
{
|
||||||
cmListFileBacktrace lfbt;
|
cmListFileBacktrace lfbt;
|
||||||
cmGeneratorExpression ge(lfbt);
|
cmGeneratorExpression ge(lfbt);
|
||||||
|
const cmsys::auto_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(prop);
|
||||||
|
|
||||||
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
cmGeneratorExpressionDAGChecker dagChecker(lfbt,
|
||||||
this->GetName(),
|
this->GetName(),
|
||||||
"LINK_LIBRARIES", 0, 0);
|
"LINK_LIBRARIES", 0, 0);
|
||||||
cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile,
|
cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile,
|
||||||
config,
|
config,
|
||||||
false,
|
false,
|
||||||
head,
|
head,
|
||||||
&dagChecker),
|
&dagChecker),
|
||||||
libs);
|
libs);
|
||||||
|
|
||||||
|
this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4376,6 +4393,171 @@ const char* cmTarget::GetExportMacro()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p,
|
||||||
|
std::set<std::string> &targets)
|
||||||
|
{
|
||||||
|
const std::map<cmStdString, std::set<std::string> >::const_iterator findIt
|
||||||
|
= this->LinkDependentProperties.find(p);
|
||||||
|
if (findIt != this->LinkDependentProperties.end())
|
||||||
|
{
|
||||||
|
targets = findIt->second;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::IsNullImpliedByLinkLibraries(const std::string &p)
|
||||||
|
{
|
||||||
|
return this->LinkImplicitNullProperties.find(p)
|
||||||
|
!= this->LinkImplicitNullProperties.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
void cmTarget::AddLinkDependentTargetsForProperties(
|
||||||
|
const std::map<cmStdString, cmStdString> &map)
|
||||||
|
{
|
||||||
|
for (std::map<cmStdString, cmStdString>::const_iterator it = map.begin();
|
||||||
|
it != map.end(); ++it)
|
||||||
|
{
|
||||||
|
std::vector<std::string> targets;
|
||||||
|
cmSystemTools::ExpandListArgument(it->second.c_str(), targets);
|
||||||
|
this->LinkDependentProperties[it->first].insert(targets.begin(),
|
||||||
|
targets.end());
|
||||||
|
if (!this->GetProperty(it->first.c_str()))
|
||||||
|
{
|
||||||
|
this->LinkImplicitNullProperties.insert(it->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------
|
||||||
|
bool cmTarget::GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||||
|
const char *config)
|
||||||
|
{
|
||||||
|
bool propContent = this->GetPropertyAsBool(p.c_str());
|
||||||
|
const bool explicitlySet = this->GetProperties()
|
||||||
|
.find(p.c_str())
|
||||||
|
!= this->GetProperties().end();
|
||||||
|
std::set<std::string> dependentTargets;
|
||||||
|
this->GetLinkDependentTargetsForProperty(p,
|
||||||
|
dependentTargets);
|
||||||
|
const bool impliedByUse =
|
||||||
|
this->IsNullImpliedByLinkLibraries(p);
|
||||||
|
assert((impliedByUse ^ explicitlySet)
|
||||||
|
|| (!impliedByUse && !explicitlySet));
|
||||||
|
|
||||||
|
cmComputeLinkInformation *info = this->GetLinkInformation(config);
|
||||||
|
const cmComputeLinkInformation::ItemVector &deps = info->GetItems();
|
||||||
|
bool propInitialized = explicitlySet;
|
||||||
|
|
||||||
|
for(cmComputeLinkInformation::ItemVector::const_iterator li =
|
||||||
|
deps.begin();
|
||||||
|
li != deps.end(); ++li)
|
||||||
|
{
|
||||||
|
// An error should be reported if one dependency
|
||||||
|
// has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
|
||||||
|
// has INTERFACE_POSITION_INDEPENDENT_CODE OFF, or if the
|
||||||
|
// target itself has a POSITION_INDEPENDENT_CODE which disagrees
|
||||||
|
// with a dependency.
|
||||||
|
|
||||||
|
if (!li->Target)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool ifaceIsSet = li->Target->GetProperties()
|
||||||
|
.find("INTERFACE_" + p)
|
||||||
|
!= li->Target->GetProperties().end();
|
||||||
|
const bool ifacePropContent = li->Target->GetPropertyAsBool(
|
||||||
|
("INTERFACE_" + p).c_str());
|
||||||
|
if (explicitlySet)
|
||||||
|
{
|
||||||
|
if (ifaceIsSet)
|
||||||
|
{
|
||||||
|
if (propContent != ifacePropContent)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Property " << p << " on target \""
|
||||||
|
<< this->GetName() << "\" does\nnot match the "
|
||||||
|
"INTERFACE_" << p << " property requirement\nof "
|
||||||
|
"dependency \"" << li->Target->GetName() << "\".\n";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Agree
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Explicitly set on target and not set in iface. Can't disagree.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (impliedByUse)
|
||||||
|
{
|
||||||
|
if (ifaceIsSet)
|
||||||
|
{
|
||||||
|
if (propContent != ifacePropContent)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "Property " << p << " on target \""
|
||||||
|
<< this->GetName() << "\" is\nimplied to be FALSE because it "
|
||||||
|
"was used to determine the link libraries\nalready. The "
|
||||||
|
"INTERFACE_" << p << " property on\ndependency \""
|
||||||
|
<< li->Target->GetName() << "\" is in conflict.\n";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Agree
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Implicitly set on target and not set in iface. Can't disagree.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (ifaceIsSet)
|
||||||
|
{
|
||||||
|
if (propInitialized)
|
||||||
|
{
|
||||||
|
if (propContent != ifacePropContent)
|
||||||
|
{
|
||||||
|
cmOStringStream e;
|
||||||
|
e << "The INTERFACE_" << p << " property of \""
|
||||||
|
<< li->Target->GetName() << "\" does\nnot agree with the value "
|
||||||
|
"of " << p << " already determined\nfor \""
|
||||||
|
<< this->GetName() << "\".\n";
|
||||||
|
cmSystemTools::Error(e.str().c_str());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Agree.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
propContent = ifacePropContent;
|
||||||
|
propInitialized = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Not set. Nothing to agree on.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return propContent;
|
||||||
|
}
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
void cmTarget::GetLanguages(std::set<cmStdString>& languages) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -487,6 +487,16 @@ public:
|
||||||
std::vector<std::string> GetIncludeDirectories(const char *config);
|
std::vector<std::string> GetIncludeDirectories(const char *config);
|
||||||
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry,
|
||||||
bool before = false);
|
bool before = false);
|
||||||
|
|
||||||
|
void GetLinkDependentTargetsForProperty(const std::string &p,
|
||||||
|
std::set<std::string> &targets);
|
||||||
|
bool IsNullImpliedByLinkLibraries(const std::string &p);
|
||||||
|
|
||||||
|
void AddLinkDependentTargetsForProperties(
|
||||||
|
const std::map<cmStdString, cmStdString> &map);
|
||||||
|
|
||||||
|
bool GetLinkInterfaceDependentBoolProperty(const std::string &p,
|
||||||
|
const char *config);
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
* A list of direct dependencies. Use in conjunction with DependencyMap.
|
||||||
|
@ -596,6 +606,9 @@ private:
|
||||||
bool DLLPlatform;
|
bool DLLPlatform;
|
||||||
bool IsApple;
|
bool IsApple;
|
||||||
bool IsImportedTarget;
|
bool IsImportedTarget;
|
||||||
|
mutable std::map<cmStdString, std::set<std::string> >
|
||||||
|
LinkDependentProperties;
|
||||||
|
mutable std::set<std::string> LinkImplicitNullProperties;
|
||||||
|
|
||||||
// Cache target output paths for each configuration.
|
// Cache target output paths for each configuration.
|
||||||
struct OutputInfo;
|
struct OutputInfo;
|
||||||
|
|
|
@ -50,6 +50,9 @@ add_RunCMake_test(GeneratorExpression)
|
||||||
add_RunCMake_test(TargetPropertyGeneratorExpressions)
|
add_RunCMake_test(TargetPropertyGeneratorExpressions)
|
||||||
add_RunCMake_test(Languages)
|
add_RunCMake_test(Languages)
|
||||||
add_RunCMake_test(ObjectLibrary)
|
add_RunCMake_test(ObjectLibrary)
|
||||||
|
if(NOT WIN32)
|
||||||
|
add_RunCMake_test(PositionIndependentCode)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_RunCMake_test(build_command)
|
add_RunCMake_test(build_command)
|
||||||
add_RunCMake_test(find_package)
|
add_RunCMake_test(find_package)
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
project(${RunCMake_TEST} CXX)
|
||||||
|
|
||||||
|
# MSVC creates extra targets which pollute the stderr unless we set this.
|
||||||
|
set(CMAKE_SUPPRESS_REGENERATION TRUE)
|
||||||
|
|
||||||
|
include(${RunCMake_TEST}.cmake)
|
|
@ -0,0 +1 @@
|
||||||
|
1
|
|
@ -0,0 +1,3 @@
|
||||||
|
CMake Error: Property POSITION_INDEPENDENT_CODE on target "conflict" does
|
||||||
|
not match the INTERFACE_POSITION_INDEPENDENT_CODE property requirement
|
||||||
|
of dependency "piciface".
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
add_library(piciface UNKNOWN IMPORTED)
|
||||||
|
set_property(TARGET piciface PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
add_executable(conflict "main.cpp")
|
||||||
|
set_property(TARGET conflict PROPERTY POSITION_INDEPENDENT_CODE OFF)
|
||||||
|
target_link_libraries(conflict 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 UNKNOWN IMPORTED)
|
||||||
|
set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
add_library(picoff UNKNOWN IMPORTED)
|
||||||
|
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,12 @@
|
||||||
|
|
||||||
|
add_library(picoff UNKNOWN IMPORTED)
|
||||||
|
|
||||||
|
add_library(picon UNKNOWN IMPORTED)
|
||||||
|
set_property(TARGET picon PROPERTY INTERFACE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
|
||||||
|
add_executable(conflict "main.cpp")
|
||||||
|
target_link_libraries(conflict picon)
|
||||||
|
set_property(TARGET conflict APPEND PROPERTY
|
||||||
|
LINK_LIBRARIES
|
||||||
|
$<$<NOT:$<BOOL:$<TARGET_PROPERTY:POSITION_INDEPENDENT_CODE>>>:picoff>
|
||||||
|
)
|
|
@ -0,0 +1,5 @@
|
||||||
|
include(RunCMake)
|
||||||
|
|
||||||
|
run_cmake(Conflict1)
|
||||||
|
run_cmake(Conflict2)
|
||||||
|
run_cmake(Conflict3)
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
int main(int,char**)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue