summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobias Hunger <tobias.hunger@qt.io>2018-11-28 15:00:50 (GMT)
committerBrad King <brad.king@kitware.com>2019-01-10 13:03:24 (GMT)
commitcd32886b2f5c8f6bdcc9185274a934102c821a20 (patch)
treec9126c0e11fb091ce504039a13d32bded1fc6466
parent9045f6a30fc8ce21d2b2298c27ba1da41c23bbf3 (diff)
downloadCMake-cd32886b2f5c8f6bdcc9185274a934102c821a20.zip
CMake-cd32886b2f5c8f6bdcc9185274a934102c821a20.tar.gz
CMake-cd32886b2f5c8f6bdcc9185274a934102c821a20.tar.bz2
Autogen: Add AUTO(MOC|RCC|UIC)_EXECUTABLE target properties
Allow to force moc/rcc/uic compiler used for AUTO(MOC|RCC|UIC). Setting these properties is only necessary if you are going to do strange things like build these tools as part of your own build system. Setting these properties will also prevent cmake from testing the binary: It is user-provided and assumed to be valid.
-rw-r--r--Help/manual/cmake-properties.7.rst3
-rw-r--r--Help/prop_tgt/AUTOMOC.rst3
-rw-r--r--Help/prop_tgt/AUTOMOC_EXECUTABLE.rst15
-rw-r--r--Help/prop_tgt/AUTORCC.rst3
-rw-r--r--Help/prop_tgt/AUTORCC_EXECUTABLE.rst15
-rw-r--r--Help/prop_tgt/AUTOUIC.rst3
-rw-r--r--Help/prop_tgt/AUTOUIC_EXECUTABLE.rst15
-rw-r--r--Help/release/dev/autogen_executables.rst9
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx22
-rw-r--r--Source/cmQtAutoGenInitializer.cxx61
10 files changed, 131 insertions, 18 deletions
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 047859d..df8f12c 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -129,13 +129,16 @@ Properties on Targets
/prop_tgt/AUTOGEN_TARGET_DEPENDS
/prop_tgt/AUTOMOC_COMPILER_PREDEFINES
/prop_tgt/AUTOMOC_DEPEND_FILTERS
+ /prop_tgt/AUTOMOC_EXECUTABLE
/prop_tgt/AUTOMOC_MACRO_NAMES
/prop_tgt/AUTOMOC_MOC_OPTIONS
/prop_tgt/AUTOMOC
/prop_tgt/AUTOUIC
+ /prop_tgt/AUTOUIC_EXECUTABLE
/prop_tgt/AUTOUIC_OPTIONS
/prop_tgt/AUTOUIC_SEARCH_PATHS
/prop_tgt/AUTORCC
+ /prop_tgt/AUTORCC_EXECUTABLE
/prop_tgt/AUTORCC_OPTIONS
/prop_tgt/BINARY_DIR
/prop_tgt/BUILD_RPATH
diff --git a/Help/prop_tgt/AUTOMOC.rst b/Help/prop_tgt/AUTOMOC.rst
index 7a3fd48..3e6d560 100644
--- a/Help/prop_tgt/AUTOMOC.rst
+++ b/Help/prop_tgt/AUTOMOC.rst
@@ -58,6 +58,9 @@ source files at build time and invoke moc accordingly.
This property is initialized by the value of the :variable:`CMAKE_AUTOMOC`
variable if it is set when a target is created.
+The ``moc`` executable will be detected automatically, but can be forced to
+a certain binary using the :prop_tgt:`AUTOMOC_EXECUTABLE` property.
+
Additional command line options for ``moc`` can be set via the
:prop_tgt:`AUTOMOC_MOC_OPTIONS` property.
diff --git a/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
new file mode 100644
index 0000000..6b66ce8
--- /dev/null
+++ b/Help/prop_tgt/AUTOMOC_EXECUTABLE.rst
@@ -0,0 +1,15 @@
+AUTOMOC_EXECUTABLE
+------------------
+
+:prop_tgt:`AUTOMOC_EXECUTABLE` is file path pointing to the ``moc``
+executable to use for :prop_tgt:`AUTOMOC` enabled files. Setting
+this property will make CMake skip the automatic detection of the
+``moc`` binary as well as the sanity-tests normally run to ensure
+that the binary is available and working as expected.
+
+Usually this property does not need to be set. Only consider this
+property if auto-detection of ``moc`` can not work -- e.g. because
+you are building the ``moc`` binary as part of your project.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTORCC.rst b/Help/prop_tgt/AUTORCC.rst
index 27fb149..5db6ed0 100644
--- a/Help/prop_tgt/AUTORCC.rst
+++ b/Help/prop_tgt/AUTORCC.rst
@@ -21,6 +21,9 @@ If the ``.qrc`` file is :prop_sf:`GENERATED` though, a
Additional command line options for rcc can be set via the
:prop_sf:`AUTORCC_OPTIONS` source file property on the ``.qrc`` file.
+The ``rcc`` executable will be detected automatically, but can be forced to
+a certain binary using the :prop_tgt:`AUTORCC_EXECUTABLE` property.
+
The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group
the autorcc targets together in an IDE, e.g. in MSVS.
diff --git a/Help/prop_tgt/AUTORCC_EXECUTABLE.rst b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
new file mode 100644
index 0000000..ca0fbd7
--- /dev/null
+++ b/Help/prop_tgt/AUTORCC_EXECUTABLE.rst
@@ -0,0 +1,15 @@
+AUTORCC_EXECUTABLE
+------------------
+
+:prop_tgt:`AUTORCC_EXECUTABLE` is file path pointing to the ``rcc``
+executable to use for :prop_tgt:`AUTORCC` enabled files. Setting
+this property will make CMake skip the automatic detection of the
+``rcc`` binary as well as the sanity-tests normally run to ensure
+that the binary is available and working as expected.
+
+Usually this property does not need to be set. Only consider this
+property if auto-detection of ``rcc`` can not work -- e.g. because
+you are building the ``rcc`` binary as part of your project.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/prop_tgt/AUTOUIC.rst b/Help/prop_tgt/AUTOUIC.rst
index 4f58b35..85226c1 100644
--- a/Help/prop_tgt/AUTOUIC.rst
+++ b/Help/prop_tgt/AUTOUIC.rst
@@ -30,6 +30,9 @@ Additional command line options for ``uic`` can be set via the
The global property :prop_gbl:`AUTOGEN_TARGETS_FOLDER` can be used to group the
autouic targets together in an IDE, e.g. in MSVS.
+The ``uic`` executable will be detected automatically, but can be forced to
+a certain binary using the :prop_tgt:`AUTOUIC_EXECUTABLE` property.
+
Source files can be excluded from :prop_tgt:`AUTOUIC` processing by
enabling :prop_sf:`SKIP_AUTOUIC` or the broader :prop_sf:`SKIP_AUTOGEN`.
diff --git a/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
new file mode 100644
index 0000000..03bd554
--- /dev/null
+++ b/Help/prop_tgt/AUTOUIC_EXECUTABLE.rst
@@ -0,0 +1,15 @@
+AUTOUIC_EXECUTABLE
+------------------
+
+:prop_tgt:`AUTOUIC_EXECUTABLE` is file path pointing to the ``uic``
+executable to use for :prop_tgt:`AUTOUIC` enabled files. Setting
+this property will make CMake skip the automatic detection of the
+``uic`` binary as well as the sanity-tests normally run to ensure
+that the binary is available and working as expected.
+
+Usually this property does not need to be set. Only consider this
+property if auto-detection of ``uic`` can not work -- e.g. because
+you are building the ``uic`` binary as part of your project.
+
+See the :manual:`cmake-qt(7)` manual for more information on using CMake
+with Qt.
diff --git a/Help/release/dev/autogen_executables.rst b/Help/release/dev/autogen_executables.rst
new file mode 100644
index 0000000..5e967ea
--- /dev/null
+++ b/Help/release/dev/autogen_executables.rst
@@ -0,0 +1,9 @@
+AUTO*_EXECUTABLE
+----------------
+
+* The :prop_tgt:`AUTOMOC_EXECUTABLE`, :prop_tgt:`AUTORCC_EXECUTABLE` and
+ :prop_tgt:`AUTOUIC_EXECUTABLE` target properties all take a path to an
+ executable and force automoc/autorcc/autouic to use this executable.
+
+ Setting these will also prevent the configure time testing for these
+ executables. This is mainly useful when you build these tools yourself.
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index 0ed8af4..678ff14 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -75,14 +75,26 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
bool const uic = target->GetPropertyAsBool("AUTOUIC");
bool const rcc = target->GetPropertyAsBool("AUTORCC");
if (moc || uic || rcc) {
- // We support Qt4 and Qt5
+ std::string const mocExec =
+ target->GetSafeProperty("AUTOMOC_EXECUTABLE");
+ std::string const uicExec =
+ target->GetSafeProperty("AUTOUIC_EXECUTABLE");
+ std::string const rccExec =
+ target->GetSafeProperty("AUTORCC_EXECUTABLE");
+
+ // We support Qt4, Qt5 and Qt6
auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target);
- if ((qtVersion.Major == 4) || (qtVersion.Major == 5) ||
- (qtVersion.Major == 6)) {
+ bool const validQt = (qtVersion.Major == 4) ||
+ (qtVersion.Major == 5) || (qtVersion.Major == 6);
+ bool const mocIsValid = moc && (validQt || !mocExec.empty());
+ bool const uicIsValid = uic && (validQt || !uicExec.empty());
+ bool const rccIsValid = rcc && (validQt || !rccExec.empty());
+
+ if (mocIsValid || uicIsValid || rccIsValid) {
// Create autogen target initializer
Initializers_.emplace_back(cm::make_unique<cmQtAutoGenInitializer>(
- this, target, qtVersion, moc, uic, rcc, globalAutoGenTarget,
- globalAutoRccTarget));
+ this, target, qtVersion, mocIsValid, uicIsValid, rccIsValid,
+ globalAutoGenTarget, globalAutoRccTarget));
}
}
}
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index ffa6a35..e4d2c82 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -9,6 +9,7 @@
#include "cmCustomCommandLines.h"
#include "cmDuration.h"
#include "cmFilePathChecksum.h"
+#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLinkItem.h"
@@ -398,8 +399,16 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
}
// Init uic specific settings
- if (this->Uic.Enabled && !InitUic()) {
- return false;
+ if (this->Uic.Enabled) {
+ if (InitUic()) {
+ auto* uicTarget = makefile->FindTargetToUse(
+ GetQtExecutableTargetName(this->QtVersion, "uic"));
+ if (uicTarget != nullptr) {
+ this->AutogenTarget.DependTargets.insert(uicTarget);
+ }
+ } else {
+ return false;
+ }
}
// Autogen target name
@@ -440,6 +449,12 @@ bool cmQtAutoGenInitializer::InitCustomTargets()
this->AutogenTarget.DependOrigin =
this->Target->GetPropertyAsBool("AUTOGEN_ORIGIN_DEPENDS");
+ auto* mocTarget = makefile->FindTargetToUse(
+ GetQtExecutableTargetName(this->QtVersion, "moc"));
+ if (mocTarget != nullptr) {
+ this->AutogenTarget.DependTargets.insert(mocTarget);
+ }
+
std::string const deps =
this->Target->GetSafeProperty("AUTOGEN_TARGET_DEPENDS");
if (!deps.empty()) {
@@ -1095,6 +1110,7 @@ bool cmQtAutoGenInitializer::InitRccTargets()
{
cmMakefile* makefile = this->Target->Target->GetMakefile();
cmLocalGenerator* localGen = this->Target->GetLocalGenerator();
+ auto rccTargetName = GetQtExecutableTargetName(this->QtVersion, "rcc");
for (Qrc const& qrc : this->Rcc.Qrcs) {
// Register info file as generated by CMake
@@ -1105,6 +1121,11 @@ bool cmQtAutoGenInitializer::InitRccTargets()
std::vector<std::string> ccOutput;
ccOutput.push_back(qrc.RccFile);
+ std::vector<std::string> ccDepends;
+ // Add the .qrc and info file to the custom command dependencies
+ ccDepends.push_back(qrc.QrcFile);
+ ccDepends.push_back(qrc.InfoFile);
+
cmCustomCommandLines commandLines;
if (this->MultiConfig) {
// Build for all configurations
@@ -1140,15 +1161,12 @@ bool cmQtAutoGenInitializer::InitRccTargets()
ccName += "_";
ccName += qrc.PathChecksum;
}
- std::vector<std::string> ccDepends;
- // Add the .qrc and info file to the custom target dependencies
- ccDepends.push_back(qrc.QrcFile);
- ccDepends.push_back(qrc.InfoFile);
cmTarget* autoRccTarget = makefile->AddUtilityCommand(
ccName, cmMakefile::TargetOrigin::Generator, true,
this->Dir.Work.c_str(), ccOutput, ccDepends, commandLines, false,
ccComment.c_str());
+
// Create autogen generator target
localGen->AddGeneratorTarget(
new cmGeneratorTarget(autoRccTarget, localGen));
@@ -1157,6 +1175,9 @@ bool cmQtAutoGenInitializer::InitRccTargets()
if (!this->TargetsFolder.empty()) {
autoRccTarget->SetProperty("FOLDER", this->TargetsFolder.c_str());
}
+ if (!rccTargetName.empty()) {
+ autoRccTarget->AddUtility(rccTargetName, makefile);
+ }
}
// Add autogen target to the origin target dependencies
this->Target->Target->AddUtility(ccName, makefile);
@@ -1169,16 +1190,15 @@ bool cmQtAutoGenInitializer::InitRccTargets()
// Create custom rcc command
{
std::vector<std::string> ccByproducts;
- std::vector<std::string> ccDepends;
- // Add the .qrc and info file to the custom command dependencies
- ccDepends.push_back(qrc.QrcFile);
- ccDepends.push_back(qrc.InfoFile);
// Add the resource files to the dependencies
for (std::string const& fileName : qrc.Resources) {
// Add resource file to the custom command dependencies
ccDepends.push_back(fileName);
}
+ if (!rccTargetName.empty()) {
+ ccDepends.push_back(rccTargetName);
+ }
makefile->AddCustomCommandToOutput(ccOutput, ccByproducts, ccDepends,
/*main_dependency*/ std::string(),
commandLines, ccComment.c_str(),
@@ -1421,21 +1441,36 @@ std::pair<bool, std::string> GetQtExecutable(
const cmQtAutoGen::IntegerVersion& qtVersion, cmGeneratorTarget* target,
const std::string& executable, bool ignoreMissingTarget, std::string* output)
{
+ const std::string upperExecutable = cmSystemTools::UpperCase(executable);
+ std::string result =
+ target->Target->GetSafeProperty("AUTO" + upperExecutable + "_EXECUTABLE");
+ if (!result.empty()) {
+ cmListFileBacktrace lfbt = target->Target->GetMakefile()->GetBacktrace();
+ cmGeneratorExpression ge(lfbt);
+ std::unique_ptr<cmCompiledGeneratorExpression> cge = ge.Parse(result);
+ result = cge->Evaluate(target->GetLocalGenerator(), "");
+
+ return std::make_pair(true, result);
+ }
+
std::string err;
- std::string result;
// Find executable
{
const std::string targetName =
GetQtExecutableTargetName(qtVersion, executable);
if (targetName.empty()) {
- err = "The AUTOMOC, AUTOUIC and AUTORCC feature ";
+ err = "The AUTO" + upperExecutable + " feature ";
err += "supports only Qt 4, Qt 5 and Qt 6.";
} else {
cmLocalGenerator* localGen = target->GetLocalGenerator();
cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse(targetName);
if (tgt != nullptr) {
- result = tgt->ImportedGetLocation("");
+ if (tgt->IsImported()) {
+ result = tgt->ImportedGetLocation("");
+ } else {
+ result = tgt->GetLocation("");
+ }
} else {
if (ignoreMissingTarget) {
return std::make_pair(true, "");