Commit e69a3287 authored by Brad King's avatar Brad King Committed by Kitware Robot
Browse files

Merge topic 'autogen-moc-version'

5b0ea587

 AutoGen: Retrieve Qt version from moc as fallback
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !6027
parents 6aabf279 5b0ea587
......@@ -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);
......
......@@ -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;
}
......
......@@ -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,
......
......@@ -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()
......
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})
#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"
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment