summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/cmQtAutoGenGlobalInitializer.cxx3
-rw-r--r--Source/cmQtAutoGenInitializer.cxx74
-rw-r--r--Source/cmQtAutoGenInitializer.h6
-rw-r--r--Tests/QtAutogen/Tests.cmake1
-rw-r--r--Tests/QtAutogen/WrappedFindPackage/CMakeLists.txt16
-rw-r--r--Tests/QtAutogen/WrappedFindPackage/main.cpp19
6 files changed, 114 insertions, 5 deletions
diff --git a/Source/cmQtAutoGenGlobalInitializer.cxx b/Source/cmQtAutoGenGlobalInitializer.cxx
index f8d18f2..153cb6d 100644
--- a/Source/cmQtAutoGenGlobalInitializer.cxx
+++ b/Source/cmQtAutoGenGlobalInitializer.cxx
@@ -119,7 +119,8 @@ cmQtAutoGenGlobalInitializer::cmQtAutoGenGlobalInitializer(
target->GetSafeProperty(this->kw().AUTORCC_EXECUTABLE);
// We support Qt4, Qt5 and Qt6
- auto qtVersion = cmQtAutoGenInitializer::GetQtVersion(target.get());
+ auto qtVersion =
+ cmQtAutoGenInitializer::GetQtVersion(target.get(), mocExec);
bool const validQt = (qtVersion.first.Major == 4) ||
(qtVersion.first.Major == 5) || (qtVersion.first.Major == 6);
diff --git a/Source/cmQtAutoGenInitializer.cxx b/Source/cmQtAutoGenInitializer.cxx
index 3adeb1a..148591c 100644
--- a/Source/cmQtAutoGenInitializer.cxx
+++ b/Source/cmQtAutoGenInitializer.cxx
@@ -6,8 +6,8 @@
#include <deque>
#include <initializer_list>
#include <map>
-#include <ostream>
#include <set>
+#include <sstream> // for basic_ios, istringstream
#include <string>
#include <unordered_set>
#include <utility>
@@ -1833,8 +1833,63 @@ void cmQtAutoGenInitializer::ConfigFileClean(ConfigString& configString)
}
}
+static cmQtAutoGen::IntegerVersion parseMocVersion(std::string str)
+{
+ cmQtAutoGen::IntegerVersion result;
+
+ static const std::string prelude = "moc ";
+ size_t pos = str.find(prelude);
+ if (pos == std::string::npos) {
+ return result;
+ }
+
+ str.erase(0, prelude.size() + pos);
+ std::istringstream iss(str);
+ std::string major;
+ std::string minor;
+ if (!std::getline(iss, major, '.') || !std::getline(iss, minor, '.')) {
+ return result;
+ }
+
+ result.Major = static_cast<unsigned int>(std::stoi(major));
+ result.Minor = static_cast<unsigned int>(std::stoi(minor));
+ return result;
+}
+
+static cmQtAutoGen::IntegerVersion GetMocVersion(
+ const std::string& mocExecutablePath)
+{
+ std::string capturedStdOut;
+ int exitCode;
+ if (!cmSystemTools::RunSingleCommand({ mocExecutablePath, "--version" },
+ &capturedStdOut, nullptr, &exitCode,
+ nullptr, cmSystemTools::OUTPUT_NONE)) {
+ return {};
+ }
+
+ if (exitCode != 0) {
+ return {};
+ }
+
+ return parseMocVersion(capturedStdOut);
+}
+
+static std::string FindMocExecutableFromMocTarget(cmMakefile* makefile,
+ unsigned int qtMajorVersion)
+{
+ std::string result;
+ const std::string mocTargetName =
+ "Qt" + std::to_string(qtMajorVersion) + "::moc";
+ cmTarget* mocTarget = makefile->FindTargetToUse(mocTargetName);
+ if (mocTarget) {
+ result = mocTarget->GetSafeProperty("IMPORTED_LOCATION");
+ }
+ return result;
+}
+
std::pair<cmQtAutoGen::IntegerVersion, unsigned int>
-cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
+cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target,
+ std::string mocExecutable)
{
// Converts a char ptr to an unsigned int value
auto toUInt = [](const char* const input) -> unsigned int {
@@ -1909,6 +1964,21 @@ cmQtAutoGenInitializer::GetQtVersion(cmGeneratorTarget const* target)
}
}
}
+
+ if (res.first.Major == 0) {
+ // We could not get the version number from variables or directory
+ // properties. This might happen if the find_package call for Qt is wrapped
+ // in a function. Try to find the moc executable path from the available
+ // targets and call "moc --version" to get the Qt version.
+ if (mocExecutable.empty()) {
+ mocExecutable =
+ FindMocExecutableFromMocTarget(target->Makefile, res.second);
+ }
+ if (!mocExecutable.empty()) {
+ res.first = GetMocVersion(mocExecutable);
+ }
+ }
+
return res;
}
diff --git a/Source/cmQtAutoGenInitializer.h b/Source/cmQtAutoGenInitializer.h
index 8a6d8f9..e76817b 100644
--- a/Source/cmQtAutoGenInitializer.h
+++ b/Source/cmQtAutoGenInitializer.h
@@ -98,9 +98,11 @@ public:
, GenNameUpper(cmQtAutoGen::GeneratorNameUpper(gen)){};
};
- /** @return The detected Qt version and the required Qt major version. */
+ /** @param mocExecutable The file path to the moc executable. Will be used as
+ fallback to query the version
+ @return The detected Qt version and the required Qt major version. */
static std::pair<IntegerVersion, unsigned int> GetQtVersion(
- cmGeneratorTarget const* genTarget);
+ cmGeneratorTarget const* genTarget, std::string mocExecutable);
cmQtAutoGenInitializer(cmQtAutoGenGlobalInitializer* globalInitializer,
cmGeneratorTarget* genTarget,
diff --git a/Tests/QtAutogen/Tests.cmake b/Tests/QtAutogen/Tests.cmake
index ab5686a..a3c57a5 100644
--- a/Tests/QtAutogen/Tests.cmake
+++ b/Tests/QtAutogen/Tests.cmake
@@ -49,6 +49,7 @@ if(QT_TEST_VERSION GREATER 4)
ADD_AUTOGEN_TEST(MocMacroName mocMacroName)
ADD_AUTOGEN_TEST(MocOsMacros)
ADD_AUTOGEN_TEST(RerunMocPlugin)
+ ADD_AUTOGEN_TEST(WrappedFindPackage)
if(APPLE)
ADD_AUTOGEN_TEST(MacOsFW)
endif()
diff --git a/Tests/QtAutogen/WrappedFindPackage/CMakeLists.txt b/Tests/QtAutogen/WrappedFindPackage/CMakeLists.txt
new file mode 100644
index 0000000..e8f50d5
--- /dev/null
+++ b/Tests/QtAutogen/WrappedFindPackage/CMakeLists.txt
@@ -0,0 +1,16 @@
+cmake_minimum_required(VERSION 3.20)
+project(WrappedFindPackage)
+
+# Wrap the find_package call in a function.
+# Test whether AutoMoc can retrieve the Qt version from the moc executable.
+function(find_qt_package)
+ include("../AutogenCoreTest.cmake")
+ set(QT_LIBRARIES "${QT_LIBRARIES}" PARENT_SCOPE)
+endfunction()
+
+find_qt_package()
+
+set(CMAKE_AUTOMOC ON)
+
+add_executable(wrappedFindPackage main.cpp)
+target_link_libraries(wrappedFindPackage PRIVATE ${QT_LIBRARIES})
diff --git a/Tests/QtAutogen/WrappedFindPackage/main.cpp b/Tests/QtAutogen/WrappedFindPackage/main.cpp
new file mode 100644
index 0000000..1e2c63f
--- /dev/null
+++ b/Tests/QtAutogen/WrappedFindPackage/main.cpp
@@ -0,0 +1,19 @@
+#include <qobject.h>
+
+class MyObject : public QObject
+{
+ Q_OBJECT
+public:
+ MyObject(QObject* parent = 0)
+ : QObject(parent)
+ {
+ }
+};
+
+int main()
+{
+ MyObject obj;
+ return 0;
+}
+
+#include "main.moc"