CMake: More fixes for QT_CMAKE_EXPORT_NAMESPACE not being available
The _qt_internal_write_qmldir_part function is deferred to be called in the root CMAKE_BINARY_DIR, where QT_CMAKE_EXPORT_NAMESPACE is not defined if find_package(Qt6) is not called in the root of the project. Make sure to pass the value of QT_CMAKE_EXPORT_NAMESPACE to the function explicitly, from a scope where it is available. This avoids errors like: CMake Error at Qt6QmlMacros.cmake:155 (add_custom_command): Error evaluating generator expression: $<TARGET_FILE:::qmltyperegistrar> No target "::qmltyperegistrar" As a drive by, do the same for _qt_internal_deferred_aotstats_setup and use that variable, instead of the hardcoded Qt6:: prefix. Add test. Amendsb47555feff
Amendsf2889262c8
Pick-to: 6.8 6.9 6.10 Fixes: QTBUG-138559 Change-Id: I9ecf2149737f3522fa61b7188403c8470b5a15d3 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
This commit is contained in:
parent
e365250e9d
commit
afe28ca1cb
|
@ -96,7 +96,14 @@ function(_qt_internal_parse_qml_module_dependency dependency was_marked_as_targe
|
|||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_write_qmldir_part target)
|
||||
function(_qt_internal_write_qmldir_part target qt_cmake_export_namespace)
|
||||
# _qt_internal_write_qmldir_part is deferred to be called in the root
|
||||
# CMAKE_BINARY_DIR. If find_package(Qt6) is not called in the root of the project (like in the
|
||||
# Qt Creator super repo), QT_CMAKE_EXPORT_NAMESPACE will not be defined.
|
||||
# Manually define it here, based on the value passed to the function, from a scope where it
|
||||
# is available.
|
||||
set(QT_CMAKE_EXPORT_NAMESPACE "${qt_cmake_export_namespace}")
|
||||
|
||||
set(effective_outdir $<TARGET_FILE_DIR:${target}>)
|
||||
set(qtconf_file "${effective_outdir}/${target}_qt.part.conf")
|
||||
get_target_property(dependency_targets "${target}" QT_QML_DEPENDENT_QML_MODULE_TARGETS)
|
||||
|
@ -1124,7 +1131,8 @@ Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html for policy details."
|
|||
)
|
||||
cmake_language(EVAL CODE "
|
||||
cmake_language(DEFER DIRECTORY [[${PROJECT_SOURCE_DIR}]]
|
||||
CALL _qt_internal_write_qmldir_part ${target})
|
||||
CALL _qt_internal_write_qmldir_part \"${target}\"
|
||||
\"${QT_CMAKE_EXPORT_NAMESPACE}\")
|
||||
")
|
||||
else()
|
||||
# Before CMake 3.19, we don't have DEFER, so we immediately write out the qt.conf
|
||||
|
@ -1168,12 +1176,20 @@ Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0001.html for policy details."
|
|||
if(NOT aotstats_setup_called)
|
||||
set_property(GLOBAL PROPERTY _qt_internal_deferred_aotstats_setup TRUE)
|
||||
cmake_language(EVAL CODE "cmake_language(DEFER DIRECTORY \"${CMAKE_BINARY_DIR}\" "
|
||||
"CALL _qt_internal_deferred_aotstats_setup)")
|
||||
"CALL _qt_internal_deferred_aotstats_setup \"${QT_CMAKE_EXPORT_NAMESPACE}\"
|
||||
)")
|
||||
endif()
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function(_qt_internal_deferred_aotstats_setup)
|
||||
function(_qt_internal_deferred_aotstats_setup qt_cmake_export_namespace)
|
||||
# _qt_internal_deferred_aotstats_setup is deferred to be called in the root
|
||||
# CMAKE_BINARY_DIR. If find_package(Qt6) is not called in the root of the project (like in the
|
||||
# Qt Creator super repo), QT_CMAKE_EXPORT_NAMESPACE will not be defined.
|
||||
# Manually define it here, based on the value passed to the function, from a scope where it
|
||||
# is available.
|
||||
set(QT_CMAKE_EXPORT_NAMESPACE "${qt_cmake_export_namespace}")
|
||||
|
||||
get_property(module_targets GLOBAL PROPERTY _qt_qml_aotstats_module_targets)
|
||||
|
||||
set(onlybytecode_modules "")
|
||||
|
@ -1206,7 +1222,7 @@ function(_qt_internal_deferred_aotstats_setup)
|
|||
DEPENDS ${aotstats_files} ${module_aotstats_list_file}
|
||||
COMMAND
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:Qt6::qmlaotstats>
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmlaotstats>
|
||||
aggregate
|
||||
${module_aotstats_list_file}
|
||||
${output}
|
||||
|
@ -1259,13 +1275,13 @@ function(_qt_internal_deferred_aotstats_setup)
|
|||
DEPENDS ${module_aotstats_targets} ${module_aotstats_files}
|
||||
COMMAND
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:Qt6::qmlaotstats>
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmlaotstats>
|
||||
aggregate
|
||||
"${aotstats_list_file}"
|
||||
"${all_aotstats_file}"
|
||||
COMMAND
|
||||
${tool_wrapper}
|
||||
$<TARGET_FILE:Qt6::qmlaotstats>
|
||||
$<TARGET_FILE:${QT_CMAKE_EXPORT_NAMESPACE}::qmlaotstats>
|
||||
format
|
||||
"${all_aotstats_file}"
|
||||
"${formatted_stats_file}"
|
||||
|
|
|
@ -5,6 +5,7 @@ _qt_internal_get_cmake_test_configure_options(config_flags)
|
|||
if(NOT CMAKE_CROSSCOMPILING)
|
||||
add_RunCMake_test(qt_target_qml_sources ${config_flags} "-D_Qt6CTestMacros=${_Qt6CTestMacros}")
|
||||
endif()
|
||||
add_RunCMake_test(export_namespace_in_root ${config_flags})
|
||||
|
||||
_qt_internal_get_cmake_test_configure_options(option_list)
|
||||
add_RunCMake_test(generate_qmlls_ini ${option_list})
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
cmake_minimum_required(VERSION 3.16)
|
||||
project(${RunCMake_TEST} LANGUAGES CXX)
|
||||
|
||||
add_subdirectory(Foo/Bar)
|
||||
add_subdirectory(app)
|
|
@ -0,0 +1,21 @@
|
|||
find_package(Qt6 6.8 REQUIRED COMPONENTS Gui Quick REQUIRED)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.8)
|
||||
|
||||
qt_add_qml_module(FooBar
|
||||
URI Foo.Bar
|
||||
VERSION 1.0
|
||||
STATIC
|
||||
SOURCES
|
||||
foobar.h foobar.cpp
|
||||
QML_FILES
|
||||
FoobarQML.qml
|
||||
IMPORTS
|
||||
QtQuick
|
||||
)
|
||||
|
||||
target_link_libraries(FooBar
|
||||
PRIVATE
|
||||
Qt6::Quick
|
||||
Qt6::Gui
|
||||
)
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (C) 2025 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
import QtQuick
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: root
|
||||
color: "green"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2025 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include "foobar.h"
|
||||
|
||||
#include <QPainter>
|
||||
|
||||
void Foobar::paint(QPainter *painter)
|
||||
{
|
||||
QPen pen(QColorConstants::Red, 2);
|
||||
QBrush brush(QColorConstants::Red);
|
||||
|
||||
painter->setPen(pen);
|
||||
painter->setBrush(brush);
|
||||
painter->drawRect(0, 0, 100, 100);
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (C) 2025 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtQuick/QQuickPaintedItem>
|
||||
|
||||
class Foobar : public QQuickPaintedItem
|
||||
{
|
||||
Q_OBJECT
|
||||
QML_ELEMENT
|
||||
public:
|
||||
using QQuickPaintedItem::QQuickPaintedItem;
|
||||
|
||||
void paint(QPainter *painter) override;
|
||||
};
|
|
@ -0,0 +1,24 @@
|
|||
include(RunCMake)
|
||||
|
||||
include(${_Qt6CTestMacros})
|
||||
# Stub function to make `_qt_internal_get_cmake_test_configure_options` work
|
||||
function(_qt_internal_get_build_vars_for_external_projects)
|
||||
endfunction()
|
||||
|
||||
_qt_internal_get_cmake_test_configure_options(config_flags)
|
||||
list(APPEND config_flags "-DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}")
|
||||
|
||||
function(run_cmake_and_build case)
|
||||
# Set common build directory for configure and build
|
||||
set(RunCMake_TEST_BINARY_DIR ${RunCMake_BINARY_DIR}/${case}-build)
|
||||
run_cmake_with_options(${case} ${config_flags})
|
||||
# Do not remove the current RunCMake_TEST_BINARY_DIR
|
||||
set(RunCMake_TEST_NO_CLEAN 1)
|
||||
run_cmake_command(${case}-build ${CMAKE_COMMAND} --build .)
|
||||
endfunction()
|
||||
|
||||
if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.19"
|
||||
AND RunCMake_GENERATOR MATCHES "^Ninja"
|
||||
)
|
||||
run_cmake_and_build(export_namespace_in_root)
|
||||
endif()
|
|
@ -0,0 +1,18 @@
|
|||
find_package(Qt6 6.8 COMPONENTS Quick REQUIRED)
|
||||
|
||||
qt_standard_project_setup(REQUIRES 6.8)
|
||||
|
||||
qt_add_executable(app app.cpp)
|
||||
qt_add_qml_module(app
|
||||
URI ExampleProjectApp
|
||||
VERSION 1.0
|
||||
QML_FILES Main.qml
|
||||
DEPENDENCIES
|
||||
TARGET FooBar
|
||||
)
|
||||
|
||||
target_link_libraries(app
|
||||
PRIVATE
|
||||
Qt6::Quick
|
||||
FooBarplugin
|
||||
)
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright (C) 2025 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
import QtQuick
|
||||
import Foo.Bar
|
||||
|
||||
Window {
|
||||
width: 640
|
||||
height: 400
|
||||
visible: true
|
||||
title: qsTr("Example Project")
|
||||
|
||||
Foobar {
|
||||
id: controls
|
||||
anchors.left: parent.left
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 20
|
||||
width: 100
|
||||
height: 100
|
||||
}
|
||||
FoobarQML {
|
||||
id: rect
|
||||
anchors.left: controls.right
|
||||
anchors.top: parent.top
|
||||
anchors.margins: 20
|
||||
width: 100
|
||||
height: 100
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (C) 2025 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QDebug>
|
||||
#include <QDirIterator>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
|
||||
QDirIterator dirIterator(":/", QDirIterator::Subdirectories);
|
||||
while (dirIterator.hasNext()) {
|
||||
qDebug() << dirIterator.next();
|
||||
}
|
||||
QQmlApplicationEngine engine;
|
||||
engine.loadFromModule("ExampleProjectApp", "Main");
|
||||
|
||||
return app.exec();
|
||||
}
|
Loading…
Reference in New Issue