summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/CMakeLists.txt2
-rw-r--r--Source/CMakeVersion.cmake2
-rw-r--r--Source/CPack/cpack.cxx18
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.cxx12
-rw-r--r--Source/cmGeneratorExpressionDAGChecker.h1
-rw-r--r--Source/cmGeneratorExpressionNode.cxx3
-rw-r--r--Source/cmGeneratorTarget.cxx171
-rw-r--r--Source/cmGeneratorTarget.h5
-rw-r--r--Source/cmGlobalGenerator.cxx64
-rw-r--r--Source/cmGlobalXCodeGenerator.cxx23
-rw-r--r--Source/cmGlobalXCodeGenerator.h3
-rw-r--r--Source/cmLocalGenerator.cxx32
-rw-r--r--Source/cmLocalGenerator.h4
-rw-r--r--Source/cmMakefileTargetGenerator.cxx3
-rw-r--r--Source/cmPolicies.h7
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx185
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.h47
-rw-r--r--Source/cmQtAutoGenInitializer.cxx32
-rw-r--r--Source/cmQtAutoGenInitializer.h10
19 files changed, 529 insertions, 95 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt
index ded21bc..9aebfa7 100644
--- a/Source/CMakeLists.txt
+++ b/Source/CMakeLists.txt
@@ -320,6 +320,8 @@ set(SRCS
cmQtAutoGen.h
cmQtAutoGenerator.cxx
cmQtAutoGenerator.h
+ cmQtAutoGenGlobalInitializer.cxx
+ cmQtAutoGenGlobalInitializer.h
cmQtAutoGenInitializer.cxx
cmQtAutoGenInitializer.h
cmQtAutoGeneratorMocUic.cxx
diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake
index 3671d53..19e2da7 100644
--- a/Source/CMakeVersion.cmake
+++ b/Source/CMakeVersion.cmake
@@ -1,5 +1,5 @@
# CMake version number components.
set(CMake_VERSION_MAJOR 3)
set(CMake_VERSION_MINOR 13)
-set(CMake_VERSION_PATCH 20181109)
+set(CMake_VERSION_PATCH 20181113)
#set(CMake_VERSION_RC 1)
diff --git a/Source/CPack/cpack.cxx b/Source/CPack/cpack.cxx
index c083945..7cf69fc 100644
--- a/Source/CPack/cpack.cxx
+++ b/Source/CPack/cpack.cxx
@@ -21,6 +21,7 @@
#include "cmCPackLog.h"
#include "cmDocumentation.h"
#include "cmDocumentationEntry.h"
+#include "cmDocumentationFormatter.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmStateSnapshot.h"
@@ -358,8 +359,21 @@ int main(int argc, char const* const* argv)
cpackGenerator->SetTraceExpand(traceExpand);
} else {
cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
- "Cannot initialize CPack generator: " << gen
- << std::endl);
+ "Could not create CPack generator: " << gen
+ << std::endl);
+ // Print out all the valid generators
+ cmDocumentation generatorDocs;
+ std::vector<cmDocumentationEntry> v;
+ for (auto const& g : generators.GetGeneratorsList()) {
+ cmDocumentationEntry e;
+ e.Name = g.first;
+ e.Brief = g.second;
+ v.push_back(std::move(e));
+ }
+ generatorDocs.SetSection("Generators", v);
+ std::cerr << "\n";
+ generatorDocs.PrintDocumentation(cmDocumentation::ListGenerators,
+ std::cerr);
parsed = 0;
}
diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx
index 8d57441..56eb2bf 100644
--- a/Source/cmGeneratorExpressionDAGChecker.cxx
+++ b/Source/cmGeneratorExpressionDAGChecker.cxx
@@ -166,6 +166,18 @@ bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression()
return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL";
}
+bool cmGeneratorExpressionDAGChecker::EvaluatingPICExpression()
+{
+ const cmGeneratorExpressionDAGChecker* top = this;
+ const cmGeneratorExpressionDAGChecker* parent = this->Parent;
+ while (parent) {
+ top = parent;
+ parent = parent->Parent;
+ }
+
+ return top->Property == "INTERFACE_POSITION_INDEPENDENT_CODE";
+}
+
bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(
cmGeneratorTarget const* tgt)
{
diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h
index a5134c3..1525c39 100644
--- a/Source/cmGeneratorExpressionDAGChecker.h
+++ b/Source/cmGeneratorExpressionDAGChecker.h
@@ -66,6 +66,7 @@ struct cmGeneratorExpressionDAGChecker
const std::string& expr);
bool EvaluatingGenexExpression();
+ bool EvaluatingPICExpression();
bool EvaluatingLinkLibraries(cmGeneratorTarget const* tgt = nullptr);
#define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const;
diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx
index f901215..49b97fb 100644
--- a/Source/cmGeneratorExpressionNode.cxx
+++ b/Source/cmGeneratorExpressionNode.cxx
@@ -1225,7 +1225,8 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
const char* prop = target->GetProperty(propertyName);
if (dagCheckerParent) {
- if (dagCheckerParent->EvaluatingGenexExpression()) {
+ if (dagCheckerParent->EvaluatingGenexExpression() ||
+ dagCheckerParent->EvaluatingPICExpression()) {
// No check required.
} else if (dagCheckerParent->EvaluatingLinkLibraries()) {
#define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \
diff --git a/Source/cmGeneratorTarget.cxx b/Source/cmGeneratorTarget.cxx
index 1663400..0b28d1e 100644
--- a/Source/cmGeneratorTarget.cxx
+++ b/Source/cmGeneratorTarget.cxx
@@ -495,6 +495,36 @@ const char* cmGeneratorTarget::GetFeature(const std::string& feature,
return this->LocalGenerator->GetFeature(feature, config);
}
+const char* cmGeneratorTarget::GetLinkPIEProperty(
+ const std::string& config) const
+{
+ static std::string PICValue;
+
+ PICValue = this->GetLinkInterfaceDependentStringAsBoolProperty(
+ "POSITION_INDEPENDENT_CODE", config);
+
+ if (PICValue == "(unset)") {
+ // POSITION_INDEPENDENT_CODE is not set
+ return nullptr;
+ }
+
+ switch (this->GetPolicyStatusCMP0083()) {
+ case cmPolicies::WARN: {
+ std::ostringstream e;
+ e << cmPolicies::GetPolicyWarning(cmPolicies::CMP0083);
+ this->LocalGenerator->IssueMessage(cmake::AUTHOR_WARNING, e.str());
+ CM_FALLTHROUGH;
+ }
+ case cmPolicies::OLD:
+ return nullptr;
+ default:
+ // nothing to do
+ break;
+ }
+
+ return PICValue.c_str();
+}
+
bool cmGeneratorTarget::IsIPOEnabled(std::string const& lang,
std::string const& config) const
{
@@ -4237,6 +4267,29 @@ void cmGeneratorTarget::CheckPropertyCompatibility(
}
}
+template <typename PropertyType>
+std::string valueAsString(PropertyType);
+template <>
+std::string valueAsString<bool>(bool value)
+{
+ return value ? "TRUE" : "FALSE";
+}
+template <>
+std::string valueAsString<const char*>(const char* value)
+{
+ return value ? value : "(unset)";
+}
+template <>
+std::string valueAsString<std::string>(std::string value)
+{
+ return value;
+}
+template <>
+std::string valueAsString<std::nullptr_t>(std::nullptr_t /*unused*/)
+{
+ return "(unset)";
+}
+
std::string compatibilityType(CompatibleType t)
{
switch (t) {
@@ -4268,34 +4321,49 @@ std::string compatibilityAgree(CompatibleType t, bool dominant)
}
template <typename PropertyType>
-PropertyType getTypedProperty(cmGeneratorTarget const* tgt,
- const std::string& prop);
+PropertyType getTypedProperty(
+ cmGeneratorTarget const* tgt, const std::string& prop,
+ cmGeneratorExpressionInterpreter* genexInterpreter = nullptr);
template <>
bool getTypedProperty<bool>(cmGeneratorTarget const* tgt,
- const std::string& prop)
+ const std::string& prop,
+ cmGeneratorExpressionInterpreter* genexInterpreter)
{
- return tgt->GetPropertyAsBool(prop);
-}
+ if (genexInterpreter == nullptr) {
+ return tgt->GetPropertyAsBool(prop);
+ }
-template <>
-const char* getTypedProperty<const char*>(cmGeneratorTarget const* tgt,
- const std::string& prop)
-{
- return tgt->GetProperty(prop);
+ const char* value = tgt->GetProperty(prop);
+ return cmSystemTools::IsOn(genexInterpreter->Evaluate(value, prop));
}
-template <typename PropertyType>
-std::string valueAsString(PropertyType);
template <>
-std::string valueAsString<bool>(bool value)
+const char* getTypedProperty<const char*>(
+ cmGeneratorTarget const* tgt, const std::string& prop,
+ cmGeneratorExpressionInterpreter* genexInterpreter)
{
- return value ? "TRUE" : "FALSE";
+ const char* value = tgt->GetProperty(prop);
+
+ if (genexInterpreter == nullptr) {
+ return value;
+ }
+
+ return genexInterpreter->Evaluate(value, prop).c_str();
}
+
template <>
-std::string valueAsString<const char*>(const char* value)
+std::string getTypedProperty<std::string>(
+ cmGeneratorTarget const* tgt, const std::string& prop,
+ cmGeneratorExpressionInterpreter* genexInterpreter)
{
- return value ? value : "(unset)";
+ const char* value = tgt->GetProperty(prop);
+
+ if (genexInterpreter == nullptr) {
+ return valueAsString(value);
+ }
+
+ return genexInterpreter->Evaluate(value, prop);
}
template <typename PropertyType>
@@ -4310,6 +4378,12 @@ const char* impliedValue<const char*>(const char* /*unused*/)
{
return "";
}
+template <>
+std::string impliedValue<std::string>(
+ std::string /*unused*/) // NOLINT(clang-tidy)
+{
+ return std::string();
+}
template <typename PropertyType>
std::pair<bool, PropertyType> consistentProperty(PropertyType lhs,
@@ -4330,6 +4404,13 @@ std::pair<bool, const char*> consistentStringProperty(const char* lhs,
return std::make_pair(b, b ? lhs : nullptr);
}
+std::pair<bool, std::string> consistentStringProperty(const std::string& lhs,
+ const std::string& rhs)
+{
+ const bool b = lhs == rhs;
+ return std::make_pair(b, b ? lhs : valueAsString(nullptr));
+}
+
std::pair<bool, const char*> consistentNumberProperty(const char* lhs,
const char* rhs,
CompatibleType t)
@@ -4372,9 +4453,10 @@ std::pair<bool, const char*> consistentProperty(const char* lhs,
const char* const null_ptr = nullptr;
switch (t) {
- case BoolType:
- assert(false && "consistentProperty for strings called with BoolType");
- return std::pair<bool, const char*>(false, null_ptr);
+ case BoolType: {
+ bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs);
+ return std::make_pair(same, same ? lhs : nullptr);
+ }
case StringType:
return consistentStringProperty(lhs, rhs);
case NumberMinType:
@@ -4385,6 +4467,40 @@ std::pair<bool, const char*> consistentProperty(const char* lhs,
return std::pair<bool, const char*>(false, null_ptr);
}
+std::pair<bool, std::string> consistentProperty(const std::string& lhs,
+ const std::string& rhs,
+ CompatibleType t)
+{
+ const std::string null_ptr = valueAsString(nullptr);
+
+ if (lhs == null_ptr && rhs == null_ptr) {
+ return std::make_pair(true, lhs);
+ }
+ if (lhs == null_ptr) {
+ return std::make_pair(true, rhs);
+ }
+ if (rhs == null_ptr) {
+ return std::make_pair(true, lhs);
+ }
+
+ switch (t) {
+ case BoolType: {
+ bool same = cmSystemTools::IsOn(lhs) == cmSystemTools::IsOn(rhs);
+ return std::make_pair(same, same ? lhs : null_ptr);
+ }
+ case StringType:
+ return consistentStringProperty(lhs, rhs);
+ case NumberMinType:
+ case NumberMaxType: {
+ auto value = consistentNumberProperty(lhs.c_str(), rhs.c_str(), t);
+ return std::make_pair(
+ value.first, value.first ? std::string(value.second) : null_ptr);
+ }
+ }
+ assert(false && "Unreachable!");
+ return std::pair<bool, std::string>(false, null_ptr);
+}
+
template <typename PropertyType>
PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
const std::string& p,
@@ -4394,6 +4510,7 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
PropertyType* /*unused*/)
{
PropertyType propContent = getTypedProperty<PropertyType>(tgt, p);
+
std::vector<std::string> headPropKeys = tgt->GetPropertyKeys();
const bool explicitlySet =
std::find(headPropKeys.begin(), headPropKeys.end(), p) !=
@@ -4423,6 +4540,11 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
}
std::string interfaceProperty = "INTERFACE_" + p;
+ std::unique_ptr<cmGeneratorExpressionInterpreter> genexInterpreter(
+ p == "POSITION_INDEPENDENT_CODE" ? new cmGeneratorExpressionInterpreter(
+ tgt->GetLocalGenerator(), config, tgt)
+ : nullptr);
+
for (cmGeneratorTarget const* theTarget : deps) {
// An error should be reported if one dependency
// has INTERFACE_POSITION_INDEPENDENT_CODE ON and the other
@@ -4434,8 +4556,8 @@ PropertyType checkInterfacePropertyCompatibility(cmGeneratorTarget const* tgt,
const bool ifaceIsSet = std::find(propKeys.begin(), propKeys.end(),
interfaceProperty) != propKeys.end();
- PropertyType ifacePropContent =
- getTypedProperty<PropertyType>(theTarget, interfaceProperty);
+ PropertyType ifacePropContent = getTypedProperty<PropertyType>(
+ theTarget, interfaceProperty, genexInterpreter.get());
std::string reportEntry;
if (ifaceIsSet) {
@@ -4533,6 +4655,13 @@ bool cmGeneratorTarget::GetLinkInterfaceDependentBoolProperty(
BoolType, nullptr);
}
+std::string cmGeneratorTarget::GetLinkInterfaceDependentStringAsBoolProperty(
+ const std::string& p, const std::string& config) const
+{
+ return checkInterfacePropertyCompatibility<std::string>(
+ this, p, config, "FALSE", BoolType, nullptr);
+}
+
const char* cmGeneratorTarget::GetLinkInterfaceDependentStringProperty(
const std::string& p, const std::string& config) const
{
diff --git a/Source/cmGeneratorTarget.h b/Source/cmGeneratorTarget.h
index 5e7cf12..52defee 100644
--- a/Source/cmGeneratorTarget.h
+++ b/Source/cmGeneratorTarget.h
@@ -173,6 +173,8 @@ public:
const char* GetFeature(const std::string& feature,
const std::string& config) const;
+ const char* GetLinkPIEProperty(const std::string& config) const;
+
bool IsIPOEnabled(std::string const& lang, std::string const& config) const;
bool IsLinkInterfaceDependentBoolProperty(const std::string& p,
@@ -789,6 +791,9 @@ private:
cmHeadToLinkInterfaceMap& GetHeadToLinkInterfaceUsageRequirementsMap(
std::string const& config) const;
+ std::string GetLinkInterfaceDependentStringAsBoolProperty(
+ const std::string& p, const std::string& config) const;
+
// Cache import information from properties for each configuration.
struct ImportInfo
{
diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx
index cf85473..2805395 100644
--- a/Source/cmGlobalGenerator.cxx
+++ b/Source/cmGlobalGenerator.cxx
@@ -34,8 +34,6 @@
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmPolicies.h"
-#include "cmQtAutoGen.h"
-#include "cmQtAutoGenInitializer.h"
#include "cmSourceFile.h"
#include "cmState.h"
#include "cmStateDirectory.h"
@@ -46,6 +44,7 @@
#if defined(CMAKE_BUILD_WITH_CMAKE)
# include "cmCryptoHash.h"
+# include "cmQtAutoGenGlobalInitializer.h"
# include "cm_jsoncpp_value.h"
# include "cm_jsoncpp_writer.h"
#endif
@@ -1469,64 +1468,11 @@ bool cmGlobalGenerator::ComputeTargetDepends()
bool cmGlobalGenerator::QtAutoGen()
{
#ifdef CMAKE_BUILD_WITH_CMAKE
- std::vector<std::unique_ptr<cmQtAutoGenInitializer>> autogenInits;
-
- for (cmLocalGenerator* localGen : this->LocalGenerators) {
- const std::vector<cmGeneratorTarget*>& targets =
- localGen->GetGeneratorTargets();
- // Find targets that require AUTOGEN processing
- for (cmGeneratorTarget* target : targets) {
- if (target->GetType() == cmStateEnums::GLOBAL_TARGET) {
- continue;
- }
- if (target->GetType() != cmStateEnums::EXECUTABLE &&
- target->GetType() != cmStateEnums::STATIC_LIBRARY &&
- target->GetType() != cmStateEnums::SHARED_LIBRARY &&
- target->GetType() != cmStateEnums::MODULE_LIBRARY &&
- target->GetType() != cmStateEnums::OBJECT_LIBRARY) {
- continue;
- }
- if (target->IsImported()) {
- continue;
- }
-
- const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC");
- const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC");
- const bool rccEnabled = target->GetPropertyAsBool("AUTORCC");
- if (!mocEnabled && !uicEnabled && !rccEnabled) {
- continue;
- }
-
- auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target);
- // don't do anything if there is no Qt4 or Qt5Core (which contains moc)
- if (qtVersion.Major != 4 && qtVersion.Major != 5) {
- continue;
- }
-
- autogenInits.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
- target, mocEnabled, uicEnabled, rccEnabled, qtVersion));
- }
- }
-
- if (!autogenInits.empty()) {
- // Initialize custom targets
- for (auto& autoGen : autogenInits) {
- if (!autoGen->InitCustomTargets()) {
- return false;
- }
- }
-
- // Setup custom targets
- for (auto& autoGen : autogenInits) {
- if (!autoGen->SetupCustomTargets()) {
- return false;
- }
- autoGen.reset(nullptr);
- }
- }
-#endif
-
+ cmQtAutoGenGlobalInitializer initializer(this->LocalGenerators);
+ return initializer.generate();
+#else
return true;
+#endif
}
cmLinkLineComputer* cmGlobalGenerator::CreateLinkLineComputer(
diff --git a/Source/cmGlobalXCodeGenerator.cxx b/Source/cmGlobalXCodeGenerator.cxx
index b7a361e..8a38f9b 100644
--- a/Source/cmGlobalXCodeGenerator.cxx
+++ b/Source/cmGlobalXCodeGenerator.cxx
@@ -1755,6 +1755,26 @@ void cmGlobalXCodeGenerator::CreateCustomRulesMakefile(
}
}
+void cmGlobalXCodeGenerator::AddPositionIndependentLinkAttribute(
+ cmGeneratorTarget* target, cmXCodeObject* buildSettings,
+ const std::string& configName)
+{
+ // For now, only EXECUTABLE is concerned
+ if (target->GetType() != cmStateEnums::EXECUTABLE) {
+ return;
+ }
+
+ const char* PICValue = target->GetLinkPIEProperty(configName);
+ if (PICValue == nullptr) {
+ // POSITION_INDEPENDENT_CODE is not set
+ return;
+ }
+
+ buildSettings->AddAttribute(
+ "LD_NO_PIE",
+ this->CreateString(cmSystemTools::IsOn(PICValue) ? "NO" : "YES"));
+}
+
void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
cmXCodeObject* buildSettings,
const std::string& configName)
@@ -1806,6 +1826,9 @@ void cmGlobalXCodeGenerator::CreateBuildSettings(cmGeneratorTarget* gtgt,
buildSettings->AddAttribute("LLVM_LTO", this->CreateString(ltoValue));
}
+ // Handle PIE linker configuration
+ this->AddPositionIndependentLinkAttribute(gtgt, buildSettings, configName);
+
// Add define flags
this->CurrentLocalGenerator->AppendFlags(
defFlags, this->CurrentMakefile->GetDefineFlags());
diff --git a/Source/cmGlobalXCodeGenerator.h b/Source/cmGlobalXCodeGenerator.h
index 62f7030..9b0d4fe 100644
--- a/Source/cmGlobalXCodeGenerator.h
+++ b/Source/cmGlobalXCodeGenerator.h
@@ -171,6 +171,9 @@ private:
const std::string& configName);
cmXCodeObject* CreateUtilityTarget(cmGeneratorTarget* gtgt);
void AddDependAndLinkInformation(cmXCodeObject* target);
+ void AddPositionIndependentLinkAttribute(cmGeneratorTarget* target,
+ cmXCodeObject* buildSettings,
+ const std::string& configName);
void CreateBuildSettings(cmGeneratorTarget* gtgt,
cmXCodeObject* buildSettings,
const std::string& buildType);
diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx
index a703f4d..da48950 100644
--- a/Source/cmLocalGenerator.cxx
+++ b/Source/cmLocalGenerator.cxx
@@ -1201,6 +1201,8 @@ void cmLocalGenerator::GetTargetFlags(
break;
}
+ this->AppendPositionIndependentLinkerFlags(linkFlags, target, config,
+ linkLanguage);
this->AppendIPOLinkerFlags(linkFlags, target, config, linkLanguage);
}
@@ -2027,6 +2029,36 @@ void cmLocalGenerator::AppendIPOLinkerFlags(std::string& flags,
}
}
+void cmLocalGenerator::AppendPositionIndependentLinkerFlags(
+ std::string& flags, cmGeneratorTarget* target, const std::string& config,
+ const std::string& lang)
+{
+ // For now, only EXECUTABLE is concerned
+ if (target->GetType() != cmStateEnums::EXECUTABLE) {
+ return;
+ }
+
+ const char* PICValue = target->GetLinkPIEProperty(config);
+ if (PICValue == nullptr) {
+ // POSITION_INDEPENDENT_CODE is not set
+ return;
+ }
+
+ std::string name = "CMAKE_" + lang + "_LINK_OPTIONS_";
+ name += cmSystemTools::IsOn(PICValue) ? "PIE" : "NO_PIE";
+
+ auto pieFlags = this->Makefile->GetSafeDefinition(name);
+ if (pieFlags.empty()) {
+ return;
+ }
+
+ std::vector<std::string> flagsList;
+ cmSystemTools::ExpandListArgument(pieFlags, flagsList);
+ for (const auto& flag : flagsList) {
+ this->AppendFlagEscape(flags, flag);
+ }
+}
+
void cmLocalGenerator::AppendCompileOptions(std::string& options,
const char* options_list,
const char* regex) const
diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h
index 3dd6929..2fa0070 100644
--- a/Source/cmLocalGenerator.h
+++ b/Source/cmLocalGenerator.h
@@ -126,6 +126,10 @@ public:
void AppendIPOLinkerFlags(std::string& flags, cmGeneratorTarget* target,
const std::string& config,
const std::string& lang);
+ void AppendPositionIndependentLinkerFlags(std::string& flags,
+ cmGeneratorTarget* target,
+ const std::string& config,
+ const std::string& lang);
///! Get the include flags for the current makefile and language
std::string GetIncludeFlags(const std::vector<std::string>& includes,
cmGeneratorTarget* target,
diff --git a/Source/cmMakefileTargetGenerator.cxx b/Source/cmMakefileTargetGenerator.cxx
index 3c46784..9acae49 100644
--- a/Source/cmMakefileTargetGenerator.cxx
+++ b/Source/cmMakefileTargetGenerator.cxx
@@ -97,6 +97,9 @@ void cmMakefileTargetGenerator::GetTargetLinkFlags(
this->GeneratorTarget->GetLinkOptions(opts, this->ConfigName, linkLanguage);
// LINK_OPTIONS are escaped.
this->LocalGenerator->AppendCompileOptions(flags, opts);
+
+ this->LocalGenerator->AppendPositionIndependentLinkerFlags(
+ flags, this->GeneratorTarget, this->ConfigName, linkLanguage);
}
void cmMakefileTargetGenerator::CreateRuleFile()
diff --git a/Source/cmPolicies.h b/Source/cmPolicies.h
index 5c27124..52ef470 100644
--- a/Source/cmPolicies.h
+++ b/Source/cmPolicies.h
@@ -244,7 +244,9 @@ class cmMakefile;
SELECT(POLICY, CMP0082, \
"Install rules from add_subdirectory() are interleaved with those " \
"in caller.", \
- 3, 14, 0, cmPolicies::WARN)
+ 3, 14, 0, cmPolicies::WARN) \
+ SELECT(POLICY, CMP0083, "Add PIE options when linking executable.", 3, 14, \
+ 0, cmPolicies::WARN)
#define CM_SELECT_ID(F, A1, A2, A3, A4, A5, A6) F(A1)
#define CM_FOR_EACH_POLICY_ID(POLICY) \
@@ -271,7 +273,8 @@ class cmMakefile;
F(CMP0069) \
F(CMP0073) \
F(CMP0076) \
- F(CMP0081)
+ F(CMP0081) \
+ F(CMP0083)
/** \class cmPolicies
* \brief Handles changes in CMake behavior and policies
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
new file mode 100644
index 0000000..5470ec3
--- /dev/null
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -0,0 +1,185 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#include "cmQtAutoGenGlobalInitializer.h"
+#include "cmQtAutoGen.h"
+#include "cmQtAutoGenInitializer.h"
+
+#include "cmAlgorithms.h"
+#include "cmCustomCommandLines.h"
+#include "cmGeneratorTarget.h"
+#include "cmLocalGenerator.h"
+#include "cmMakefile.h"
+#include "cmState.h"
+#include "cmStateTypes.h"
+#include "cmSystemTools.h"
+#include "cmTarget.h"
+
+#include <memory>
+#include <utility>
+
+cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
+ std::vector<cmLocalGenerator*> const& localGenerators)
+{
+ for (cmLocalGenerator* localGen : localGenerators) {
+ // Detect global autogen and autorcc target names
+ bool globalAutoGenTarget = false;
+ bool globalAutoRccTarget = false;
+ {
+ cmMakefile* makefile = localGen->GetMakefile();
+ // Detect global autogen target name
+ if (cmSystemTools::IsOn(
+ makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET"))) {
+ std::string targetName =
+ makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTOGEN_TARGET_NAME");
+ if (targetName.empty()) {
+ targetName = "autogen";
+ }
+ GlobalAutoGenTargets_.emplace(localGen, std::move(targetName));
+ globalAutoGenTarget = true;
+ }
+
+ // Detect global autorcc target name
+ if (cmSystemTools::IsOn(
+ makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET"))) {
+ std::string targetName =
+ makefile->GetSafeDefinition("CMAKE_GLOBAL_AUTORCC_TARGET_NAME");
+ if (targetName.empty()) {
+ targetName = "autorcc";
+ }
+ GlobalAutoRccTargets_.emplace(localGen, std::move(targetName));
+ globalAutoRccTarget = true;
+ }
+ }
+
+ // Find targets that require AUTOMOC/UIC/RCC processing
+ for (cmGeneratorTarget* target : localGen->GetGeneratorTargets()) {
+ // Process only certain target types
+ switch (target->GetType()) {
+ case cmStateEnums::EXECUTABLE:
+ case cmStateEnums::STATIC_LIBRARY:
+ case cmStateEnums::SHARED_LIBRARY:
+ case cmStateEnums::MODULE_LIBRARY:
+ case cmStateEnums::OBJECT_LIBRARY:
+ // Process target
+ break;
+ default:
+ // Don't process target
+ continue;
+ }
+ if (target->IsImported()) {
+ // Don't process target
+ continue;
+ }
+
+ bool const moc = target->GetPropertyAsBool("AUTOMOC");
+ bool const uic = target->GetPropertyAsBool("AUTOUIC");
+ bool const rcc = target->GetPropertyAsBool("AUTORCC");
+ if (moc || uic || rcc) {
+ // We support Qt4 and Qt5
+ auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target);
+ if ((qtVersion.Major == 4) || (qtVersion.Major == 5)) {
+ // Create autogen target initializer
+ Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
+ this, target, qtVersion, moc, uic, rcc, globalAutoGenTarget,
+ globalAutoRccTarget));
+ }
+ }
+ }
+ }
+}
+
+cmQtAutoGenGlobalInitializer::~cmQtAutoGenGlobalInitializer()
+{
+}
+
+void cmQtAutoGenGlobalInitializer::GetOrCreateGlobalTarget(
+ cmLocalGenerator* localGen, std::string const& name,
+ std::string const& comment)
+{
+ // Test if the target already exists
+ if (localGen->FindGeneratorTargetToUse(name) == nullptr) {
+ cmMakefile* makefile = localGen->GetMakefile();
+
+ // Create utility target
+ cmTarget* target = makefile->AddUtilityCommand(
+ name, cmMakefile::TargetOrigin::Generator, true,
+ makefile->GetHomeOutputDirectory().c_str() /*work dir*/,
+ std::vector<std::string>() /*output*/,
+ std::vector<std::string>() /*depends*/, cmCustomCommandLines(), false,
+ comment.c_str());
+ localGen->AddGeneratorTarget(new cmGeneratorTarget(target, localGen));
+
+ // Set FOLDER property in the target
+ {
+ char const* folder =
+ makefile->GetState()->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
+ if (folder != nullptr) {
+ target->SetProperty("FOLDER", folder);
+ }
+ }
+ }
+}
+
+void cmQtAutoGenGlobalInitializer::AddToGlobalAutoGen(
+ cmLocalGenerator* localGen, std::string const& targetName)
+{
+ auto it = GlobalAutoGenTargets_.find(localGen);
+ if (it != GlobalAutoGenTargets_.end()) {
+ cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
+ if (target != nullptr) {
+ target->Target->AddUtility(targetName, localGen->GetMakefile());
+ }
+ }
+}
+
+void cmQtAutoGenGlobalInitializer::AddToGlobalAutoRcc(
+ cmLocalGenerator* localGen, std::string const& targetName)
+{
+ auto it = GlobalAutoRccTargets_.find(localGen);
+ if (it != GlobalAutoRccTargets_.end()) {
+ cmGeneratorTarget* target = localGen->FindGeneratorTargetToUse(it->second);
+ if (target != nullptr) {
+ target->Target->AddUtility(targetName, localGen->GetMakefile());
+ }
+ }
+}
+
+bool cmQtAutoGenGlobalInitializer::generate()
+{
+ return (InitializeCustomTargets() && SetupCustomTargets());
+}
+
+bool cmQtAutoGenGlobalInitializer::InitializeCustomTargets()
+{
+ // Initialize global autogen targets
+ {
+ std::string const comment = "Global AUTOGEN target";
+ for (auto const& pair : GlobalAutoGenTargets_) {
+ GetOrCreateGlobalTarget(pair.first, pair.second, comment);
+ }
+ }
+ // Initialize global autorcc targets
+ {
+ std::string const comment = "Global AUTORCC target";
+ for (auto const& pair : GlobalAutoRccTargets_) {
+ GetOrCreateGlobalTarget(pair.first, pair.second, comment);
+ }
+ }
+ // Initialize per target autogen targets
+ for (auto& initializer : Initializers_) {
+ if (!initializer->InitCustomTargets()) {
+ return false;
+ }
+ }
+ return true;
+}
+
+bool cmQtAutoGenGlobalInitializer::SetupCustomTargets()
+{
+ for (auto& initializer : Initializers_) {
+ if (!initializer->SetupCustomTargets()) {
+ return false;
+ }
+ }
+ return true;
+}
diff --git a/Source/cmQtAutoGenGlobalInitializer.h b/Source/cmQtAutoGenGlobalInitializer.h
new file mode 100644
index 0000000..9e6bac0
--- /dev/null
+++ b/Source/cmQtAutoGenGlobalInitializer.h
@@ -0,0 +1,47 @@
+/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+ file Copyright.txt or https://cmake.org/licensing for details. */
+#ifndef cmQtAutoGenGlobalInitializer_h
+#define cmQtAutoGenGlobalInitializer_h
+
+#include "cmConfigure.h" // IWYU pragma: keep
+
+#include <map>
+#include <memory> // IWYU pragma: keep
+#include <string>
+#include <vector>
+
+class cmLocalGenerator;
+class cmQtAutoGenInitializer;
+
+/// @brief Initializes the QtAutoGen generators
+class cmQtAutoGenGlobalInitializer
+{
+public:
+ cmQtAutoGenGlobalInitializer(
+ std::vector<cmLocalGenerator*> const& localGenerators);
+ ~cmQtAutoGenGlobalInitializer();
+
+ bool generate();
+
+private:
+ friend class cmQtAutoGenInitializer;
+
+ bool InitializeCustomTargets();
+ bool SetupCustomTargets();
+
+ void GetOrCreateGlobalTarget(cmLocalGenerator* localGen,
+ std::string const& name,
+ std::string const& comment);
+
+ void AddToGlobalAutoGen(cmLocalGenerator* localGen,
+ std::string const& targetName);
+ void AddToGlobalAutoRcc(cmLocalGenerator* localGen,
+ std::string const& targetName);
+
+private:
+ std::vector<std::unique_ptr<cmQtAutoGenInitializer>> Initializers_;
+ std::map<cmLocalGenerator*, std::string> GlobalAutoGenTargets_;
+ std::map<cmLocalGenerator*, std::string> GlobalAutoRccTargets_;
+};
+
+#endif
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index a213c84..793c0b2 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -2,6 +2,7 @@
file Copyright.txt or https://cmake.org/licensing for details. */
#include "cmQtAutoGenInitializer.h"
#include "cmQtAutoGen.h"
+#include "cmQtAutoGenGlobalInitializer.h"
#include "cmAlgorithms.h"
#include "cmCustomCommand.h"
@@ -174,17 +175,19 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin,
return cycle;
}
-cmQtAutoGenInitializer::cmQtAutoGenInitializer(cmGeneratorTarget* target,
- bool mocEnabled,
- bool uicEnabled,
- bool rccEnabled,
- IntegerVersion const& qtVersion)
- : Target(target)
+cmQtAutoGenInitializer::cmQtAutoGenInitializer(
+ cmQtAutoGenGlobalInitializer* globalInitializer, cmGeneratorTarget* target,
+ IntegerVersion const& qtVersion, bool mocEnabled, bool uicEnabled,
+ bool rccEnabled, bool globalAutogenTarget, bool globalAutoRccTarget)
+ : GlobalInitializer(globalInitializer)
+ , Target(target)
, QtVersion(qtVersion)
{
+ AutogenTarget.GlobalTarget = globalAutogenTarget;
Moc.Enabled = mocEnabled;
Uic.Enabled = uicEnabled;
Rcc.Enabled = rccEnabled;
+ Rcc.GlobalTarget = globalAutoRccTarget;
}
bool cmQtAutoGenInitializer::InitCustomTargets()
@@ -882,6 +885,10 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
if (!this->AutogenTarget.DependFiles.empty()) {
usePRE_BUILD = false;
}
+ // Cannot use PRE_BUILD when a global autogen target is in place
+ if (AutogenTarget.GlobalTarget) {
+ usePRE_BUILD = false;
+ }
}
// Create the autogen target/command
if (usePRE_BUILD) {
@@ -961,6 +968,12 @@ bool cmQtAutoGenInitializer::InitAutogenTarget()
// Add autogen target to the origin target dependencies
this->Target->Target->AddUtility(this->AutogenTarget.Name, makefile);
+
+ // Add autogen target to the global autogen target dependencies
+ if (this->AutogenTarget.GlobalTarget) {
+ this->GlobalInitializer->AddToGlobalAutoGen(localGen,
+ this->AutogenTarget.Name);
+ }
}
return true;
@@ -1004,7 +1017,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
std::string ccComment = "Automatic RCC for ";
ccComment += FileProjectRelativePath(makefile, qrc.QrcFile);
- if (qrc.Generated) {
+ if (qrc.Generated || this->Rcc.GlobalTarget) {
// Create custom rcc target
std::string ccName;
{
@@ -1035,6 +1048,11 @@ bool cmQtAutoGenInitializer::InitRccTargets()
}
// Add autogen target to the origin target dependencies
this->Target->Target->AddUtility(ccName, makefile);
+
+ // Add autogen target to the global autogen target dependencies
+ if (this->Rcc.GlobalTarget) {
+ this->GlobalInitializer->AddToGlobalAutoRcc(localGen, ccName);
+ }
} else {
// Create custom rcc command
{
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 1d3947b..53ad571 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -13,6 +13,7 @@
class cmGeneratorTarget;
class cmTarget;
+class cmQtAutoGenGlobalInitializer;
/// @brief Initializes the QtAutoGen generators
class cmQtAutoGenInitializer : public cmQtAutoGen
@@ -46,9 +47,11 @@ public:
public:
static IntegerVersion GetQtVersion(cmGeneratorTarget const* target);
- cmQtAutoGenInitializer(cmGeneratorTarget* target, bool mocEnabled,
+ cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer,
+ cmGeneratorTarget* target,
+ IntegerVersion const& qtVersion, bool mocEnabled,
bool uicEnabled, bool rccEnabled,
- IntegerVersion const& qtVersion);
+ bool globalAutogenTarget, bool globalAutoRccTarget);
bool InitCustomTargets();
bool SetupCustomTargets();
@@ -76,6 +79,7 @@ private:
std::string& errorMessage);
private:
+ cmQtAutoGenGlobalInitializer* GlobalInitializer;
cmGeneratorTarget* Target;
// Configuration
@@ -100,6 +104,7 @@ private:
struct
{
std::string Name;
+ bool GlobalTarget = false;
// Settings
std::string Parallel;
// Configuration files
@@ -148,6 +153,7 @@ private:
struct
{
bool Enabled = false;
+ bool GlobalTarget = false;
std::string Executable;
std::vector<std::string> ListOptions;
std::vector<Qrc> Qrcs;