From bf5ece51c3827dc05018128fefe8270da88cfefb Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 5 Nov 2012 14:48:42 +0100 Subject: Keep track of properties used to determine linker libraries. Those properties can't later be implicitly defined by the interface of those link libraries. --- Source/cmGeneratorExpression.cxx | 10 +++++++- Source/cmGeneratorExpression.h | 4 +++ Source/cmGeneratorExpressionEvaluator.cxx | 8 ++++++ Source/cmGeneratorExpressionEvaluator.h | 1 + Source/cmTarget.cxx | 42 ++++++++++++++++++++++++++++++- Source/cmTarget.h | 10 ++++++++ 6 files changed, 73 insertions(+), 2 deletions(-) diff --git a/Source/cmGeneratorExpression.cxx b/Source/cmGeneratorExpression.cxx index 6d003e1..4063697 100644 --- a/Source/cmGeneratorExpression.cxx +++ b/Source/cmGeneratorExpression.cxx @@ -94,7 +94,15 @@ const char *cmCompiledGeneratorExpression::Evaluate( for ( ; it != end; ++it) { - this->Output += (*it)->Evaluate(&context, dagChecker); + const std::string result = (*it)->Evaluate(&context, dagChecker); + this->Output += result; + + for(std::set::const_iterator + p = context.SeenTargetProperties.begin(); + p != context.SeenTargetProperties.end(); ++p) + { + this->SeenTargetProperties[*p] += result + ";"; + } if (context.HadError) { this->Output = ""; diff --git a/Source/cmGeneratorExpression.h b/Source/cmGeneratorExpression.h index dcdfefb..b58dde5 100644 --- a/Source/cmGeneratorExpression.h +++ b/Source/cmGeneratorExpression.h @@ -83,6 +83,9 @@ public: std::set const& GetTargets() const { return this->Targets; } + std::map const& GetSeenTargetProperties() const + { return this->SeenTargetProperties; } + ~cmCompiledGeneratorExpression(); std::string GetInput() const @@ -110,6 +113,7 @@ private: bool NeedsParsing; mutable std::set Targets; + mutable std::map SeenTargetProperties; mutable std::string Output; }; diff --git a/Source/cmGeneratorExpressionEvaluator.cxx b/Source/cmGeneratorExpressionEvaluator.cxx index 82becaf..f4e4131 100644 --- a/Source/cmGeneratorExpressionEvaluator.cxx +++ b/Source/cmGeneratorExpressionEvaluator.cxx @@ -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()) { reportError(context, content->GetOriginalExpression(), diff --git a/Source/cmGeneratorExpressionEvaluator.h b/Source/cmGeneratorExpressionEvaluator.h index 59804ff..fb6c7ee 100644 --- a/Source/cmGeneratorExpressionEvaluator.h +++ b/Source/cmGeneratorExpressionEvaluator.h @@ -24,6 +24,7 @@ struct cmGeneratorExpressionContext { cmListFileBacktrace Backtrace; std::set Targets; + std::set SeenTargetProperties; cmMakefile *Makefile; const char *Config; cmTarget *HeadTarget; // The target whose property is being evaluated. diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 25054c5..e4adb09 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -2164,16 +2164,19 @@ void cmTarget::GetDirectLinkLibraries(const char *config, { cmListFileBacktrace lfbt; cmGeneratorExpression ge(lfbt); + const cmsys::auto_ptr cge = ge.Parse(prop); cmGeneratorExpressionDAGChecker dagChecker(lfbt, this->GetName(), "LINK_LIBRARIES", 0, 0); - cmSystemTools::ExpandListArgument(ge.Parse(prop)->Evaluate(this->Makefile, + cmSystemTools::ExpandListArgument(cge->Evaluate(this->Makefile, config, false, head, &dagChecker), libs); + + this->AddLinkDependentTargetsForProperties(cge->GetSeenTargetProperties()); } } @@ -4377,6 +4380,43 @@ const char* cmTarget::GetExportMacro() } //---------------------------------------------------------------------------- +void cmTarget::GetLinkDependentTargetsForProperty(const std::string &p, + std::set &targets) +{ + const std::map >::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 &map) +{ + for (std::map::const_iterator it = map.begin(); + it != map.end(); ++it) + { + std::vector 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); + } + } +} + +//---------------------------------------------------------------------------- void cmTarget::GetLanguages(std::set& languages) const { for(std::vector::const_iterator diff --git a/Source/cmTarget.h b/Source/cmTarget.h index d4069fa..5ce7d53 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -487,6 +487,13 @@ public: std::vector GetIncludeDirectories(const char *config); void InsertInclude(const cmMakefileIncludeDirectoriesEntry &entry, bool before = false); + + void GetLinkDependentTargetsForProperty(const std::string &p, + std::set &targets); + bool IsNullImpliedByLinkLibraries(const std::string &p); + + void AddLinkDependentTargetsForProperties( + const std::map &map); private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. @@ -596,6 +603,9 @@ private: bool DLLPlatform; bool IsApple; bool IsImportedTarget; + mutable std::map > + LinkDependentProperties; + mutable std::set LinkImplicitNullProperties; // Cache target output paths for each configuration. struct OutputInfo; -- cgit v0.12 From 042ecf0471be84ce6c3e6c32dae526fdbd9a3a14 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Sun, 6 Jan 2013 13:49:05 +0100 Subject: Add API to calculate link-interface-dependent bool properties or error. This new method checks that the property FOO on a target is consistent with the INTERFACE_FOO properties of its dependees. If they are not the consistent, an error is reported. 'Consistent' means that iff the property is set, it must have the same boolean value as all other related properties. --- Source/cmTarget.cxx | 128 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Source/cmTarget.h | 3 ++ 2 files changed, 131 insertions(+) diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index e4adb09..c8f9c1d 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -4417,6 +4417,134 @@ void cmTarget::AddLinkDependentTargetsForProperties( } //---------------------------------------------------------------------------- +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 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& languages) const { for(std::vector::const_iterator diff --git a/Source/cmTarget.h b/Source/cmTarget.h index 5ce7d53..1188a6a 100644 --- a/Source/cmTarget.h +++ b/Source/cmTarget.h @@ -494,6 +494,9 @@ public: void AddLinkDependentTargetsForProperties( const std::map &map); + + bool GetLinkInterfaceDependentBoolProperty(const std::string &p, + const char *config); private: /** * A list of direct dependencies. Use in conjunction with DependencyMap. -- cgit v0.12 From 3581b96caa1d7bd6c02e85baf72ce28b5128e5e7 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Mon, 5 Nov 2012 12:46:26 +0100 Subject: Process the INTERFACE_PIC property from linked dependencies This allows a dependee to inform a target that it should have its POSITION_INDEPENDENT_CODE property set to ON, or OFF. The value of the POSITION_INDEPENDENT_CODE property, if set, must be consistent with any INTERFACE_POSITION_INDEPENDENT_CODE properties on dependees. Add a test covering the consistency checks on platforms where they run. --- Source/cmGlobalXCodeGenerator.cxx | 6 ++++-- Source/cmLocalGenerator.cxx | 17 ++++++++++++++--- Source/cmLocalGenerator.h | 2 +- Source/cmMakefileTargetGenerator.cxx | 3 ++- Source/cmNinjaTargetGenerator.cxx | 3 ++- Source/cmTarget.cxx | 14 ++++++++++++++ Tests/RunCMake/CMakeLists.txt | 3 +++ Tests/RunCMake/PositionIndependentCode/CMakeLists.txt | 8 ++++++++ .../PositionIndependentCode/Conflict1-result.txt | 1 + .../PositionIndependentCode/Conflict1-stderr.txt | 3 +++ Tests/RunCMake/PositionIndependentCode/Conflict1.cmake | 7 +++++++ .../PositionIndependentCode/Conflict2-result.txt | 1 + .../PositionIndependentCode/Conflict2-stderr.txt | 3 +++ Tests/RunCMake/PositionIndependentCode/Conflict2.cmake | 9 +++++++++ .../PositionIndependentCode/Conflict3-result.txt | 1 + .../PositionIndependentCode/Conflict3-stderr.txt | 4 ++++ Tests/RunCMake/PositionIndependentCode/Conflict3.cmake | 12 ++++++++++++ .../RunCMake/PositionIndependentCode/RunCMakeTest.cmake | 5 +++++ Tests/RunCMake/PositionIndependentCode/main.cpp | 5 +++++ 19 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 Tests/RunCMake/PositionIndependentCode/CMakeLists.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict1.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict2.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt create mode 100644 Tests/RunCMake/PositionIndependentCode/Conflict3.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake create mode 100644 Tests/RunCMake/PositionIndependentCode/main.cpp diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx index 4c26b82..2cfe4da 100644 --- a/Source/cmGlobalXCodeGenerator.cxx +++ b/Source/cmGlobalXCodeGenerator.cxx @@ -1639,14 +1639,16 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmTarget& target, if(strcmp(lang, "CXX") == 0) { this->CurrentLocalGenerator->AddLanguageFlags(cflags, "C", configName); - this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, "C"); + this->CurrentLocalGenerator->AddCMP0018Flags(cflags, &target, + "C", configName); } // Add language-specific flags. this->CurrentLocalGenerator->AddLanguageFlags(flags, lang, configName); // Add shared-library flags if needed. - this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, lang); + this->CurrentLocalGenerator->AddCMP0018Flags(flags, &target, + lang, configName); } else if(binary) { diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index b557ca1..ecf6b41 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -1984,7 +1984,8 @@ void cmLocalGenerator::AddSharedFlags(std::string& flags, //---------------------------------------------------------------------------- void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target, - std::string const& lang) + std::string const& lang, + const char *config) { int targetType = target->GetType(); @@ -1997,8 +1998,18 @@ void cmLocalGenerator::AddCMP0018Flags(std::string &flags, cmTarget* target, } else { - // Add position independendent flags, if needed. - if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE")) + if (target->GetType() == cmTarget::OBJECT_LIBRARY) + { + if (target->GetPropertyAsBool("POSITION_INDEPENDENT_CODE")) + { + this->AddPositionIndependentFlags(flags, lang, targetType); + } + return; + } + + if (target->GetLinkInterfaceDependentBoolProperty( + "POSITION_INDEPENDENT_CODE", + config)) { this->AddPositionIndependentFlags(flags, lang, targetType); } diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 63559d7..b2ff0c4 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -142,7 +142,7 @@ public: void AddLanguageFlags(std::string& flags, const char* lang, const char* config); 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, const char* config); ///! Append flags to a string. diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx index 9bf6b7d..64fcfce 100644 --- a/Source/cmMakefileTargetGenerator.cxx +++ b/Source/cmMakefileTargetGenerator.cxx @@ -268,7 +268,8 @@ std::string cmMakefileTargetGenerator::GetFlags(const std::string &l) this->AddFortranFlags(flags); } - this->LocalGenerator->AddCMP0018Flags(flags, this->Target, lang); + this->LocalGenerator->AddCMP0018Flags(flags, this->Target, + lang, this->ConfigName); // Add include directory flags. this->AddIncludeFlags(flags, lang); diff --git a/Source/cmNinjaTargetGenerator.cxx b/Source/cmNinjaTargetGenerator.cxx index 15842e4..0f484da 100644 --- a/Source/cmNinjaTargetGenerator.cxx +++ b/Source/cmNinjaTargetGenerator.cxx @@ -147,7 +147,8 @@ cmNinjaTargetGenerator::ComputeFlagsForObject(cmSourceFile *source, // Add shared-library flags if needed. this->LocalGenerator->AddCMP0018Flags(flags, this->Target, - language.c_str()); + language.c_str(), + this->GetConfigName()); // Add include directory flags. { diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index c8f9c1d..2cfb1bf 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -878,6 +878,20 @@ void cmTarget::DefineProperties(cmake *cm) "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 ("POST_INSTALL_SCRIPT", cmProperty::TARGET, "Deprecated install support.", "The PRE_INSTALL_SCRIPT and POST_INSTALL_SCRIPT properties are the " diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index fec64b5..9b133b2 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -50,6 +50,9 @@ add_RunCMake_test(GeneratorExpression) add_RunCMake_test(TargetPropertyGeneratorExpressions) add_RunCMake_test(Languages) add_RunCMake_test(ObjectLibrary) +if(NOT WIN32) + add_RunCMake_test(PositionIndependentCode) +endif() add_RunCMake_test(build_command) add_RunCMake_test(find_package) diff --git a/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt new file mode 100644 index 0000000..22577da --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/CMakeLists.txt @@ -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) diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt new file mode 100644 index 0000000..cb07109 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict1-stderr.txt @@ -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". diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake new file mode 100644 index 0000000..242bec3 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict1.cmake @@ -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) diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt new file mode 100644 index 0000000..ecd0492 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict2-stderr.txt @@ -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". diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake new file mode 100644 index 0000000..215d08d --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict2.cmake @@ -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) diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt b/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict3-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt b/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt new file mode 100644 index 0000000..0254e55 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict3-stderr.txt @@ -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. diff --git a/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake b/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake new file mode 100644 index 0000000..bf669bf --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/Conflict3.cmake @@ -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 + $<$>>:picoff> +) diff --git a/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake new file mode 100644 index 0000000..64a340c --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/RunCMakeTest.cmake @@ -0,0 +1,5 @@ +include(RunCMake) + +run_cmake(Conflict1) +run_cmake(Conflict2) +run_cmake(Conflict3) diff --git a/Tests/RunCMake/PositionIndependentCode/main.cpp b/Tests/RunCMake/PositionIndependentCode/main.cpp new file mode 100644 index 0000000..31ba482 --- /dev/null +++ b/Tests/RunCMake/PositionIndependentCode/main.cpp @@ -0,0 +1,5 @@ + +int main(int,char**) +{ + return 0; +} -- cgit v0.12