diff --git a/CHANGELOG.md b/CHANGELOG.md index aded34425..550e84d58 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -44,6 +44,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Dependencies are now automatically detected and configured by cxx-qt-build - Libraries can pass build information to cxx-qt-build in the form of a `cxx_qt_build::Interface` - Add CMake wrappers around corrosion to simplify importing crates and qml modules that were built with cxx-qt-build + - CMake code has been extracted into a separate repository for faster downloads (kdab/cxx-qt-cmake) ### Removed diff --git a/CMakeLists.txt b/CMakeLists.txt index 791cdd68d..10449a26f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -107,7 +107,6 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) include(CompilerCaching) -include(CxxQt) # Enable extra Qt definitions for all projects add_compile_definitions( diff --git a/book/src/getting-started/5-cmake-integration.md b/book/src/getting-started/5-cmake-integration.md index 253dc4d42..6e47a9c97 100644 --- a/book/src/getting-started/5-cmake-integration.md +++ b/book/src/getting-started/5-cmake-integration.md @@ -135,7 +135,9 @@ For this example, we are [supporting both Qt5 and Qt6 with CMake](https://doc.qt Download CXX-Qts CMake code with FetchContent: ```cmake,ignore -{{#include ../../../examples/qml_minimal/CMakeLists.txt:book_cmake_find_cxx_qt}} +{{#include ../../../examples/qml_minimal/CMakeLists.txt:book_cmake_find_cxx_qt_start}} + GIT_TAG v0.7.0 +{{#include ../../../examples/qml_minimal/CMakeLists.txt:book_cmake_find_cxx_qt_end}} ``` This provides you with a few wrappers around [Corrosion](https://github.com/corrosion-rs/corrosion), a tool for integrating Rust libraries into CMake: diff --git a/cmake/CxxQt.cmake b/cmake/CxxQt.cmake deleted file mode 100644 index d49524177..000000000 --- a/cmake/CxxQt.cmake +++ /dev/null @@ -1,123 +0,0 @@ -# SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company -# SPDX-FileContributor: Andrew Hayzen -# SPDX-FileContributor: Leon Matthes -# -# SPDX-License-Identifier: MIT OR Apache-2.0 - -find_package(Corrosion QUIET) -if(NOT Corrosion_FOUND) - include(FetchContent) - FetchContent_Declare( - Corrosion - GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git - GIT_TAG v0.5.0 - ) - - FetchContent_MakeAvailable(Corrosion) -endif() - -function(cxx_qt_import_crate) - cmake_parse_arguments(IMPORT_CRATE "" "CXX_QT_EXPORT_DIR;QMAKE" "" ${ARGN}) - - corrosion_import_crate(IMPORTED_CRATES __cxx_qt_imported_crates ${IMPORT_CRATE_UNPARSED_ARGUMENTS}) - - message(STATUS "CXX-Qt Found crate(s): ${__cxx_qt_imported_crates}") - - if (NOT DEFINED IMPORT_CRATE_CXX_QT_EXPORT_DIR) - set(IMPORT_CRATE_CXX_QT_EXPORT_DIR "${CMAKE_CURRENT_BINARY_DIR}/cxxqt/") - endif() - message(VERBOSE "CXX-Qt EXPORT_DIR: ${IMPORT_CRATE_CXX_QT_EXPORT_DIR}") - - if (NOT DEFINED IMPORT_CRATE_QMAKE) - get_target_property(QMAKE Qt::qmake IMPORTED_LOCATION) - if (NOT QMAKE STREQUAL "QMAKE-NOTFOUND") - set(IMPORT_CRATE_QMAKE "${QMAKE}") - else() - message(FATAL_ERROR "cxx_qt_import_crate: QMAKE is not defined and could not be queried from the Qt::qmake target!\nPlease use the QMAKE argument to specify the path to the qmake executable or use find_package(Qt) before calling cxx_qt_import_crate.") - endif() - endif() - - foreach(CRATE ${__cxx_qt_imported_crates}) - corrosion_set_env_vars(${CRATE} - # Tell cxx-qt-build where to export the data - "CXX_QT_EXPORT_DIR=${IMPORT_CRATE_CXX_QT_EXPORT_DIR}" - # Tell cxx-qt-build which crate to export - "CXX_QT_EXPORT_CRATE_${CRATE}=1" - "QMAKE=${IMPORT_CRATE_QMAKE}" - $<$:RUSTC_WRAPPER=${CMAKE_RUSTC_WRAPPER}>) - - file(MAKE_DIRECTORY "${IMPORT_CRATE_CXX_QT_EXPORT_DIR}/crates/${CRATE}/include/") - target_include_directories(${CRATE} INTERFACE "${IMPORT_CRATE_CXX_QT_EXPORT_DIR}/crates/${CRATE}/include/") - - set_target_properties(${CRATE} - PROPERTIES - CXX_QT_EXPORT_DIR "${IMPORT_CRATE_CXX_QT_EXPORT_DIR}") - - # cxx-qt-build generates object files that need to be linked to the final target. - # These are the static initializers that would be removed as an optimization if they're not referenced. - # So add them to an object library instead. - file(MAKE_DIRECTORY "${IMPORT_CRATE_CXX_QT_EXPORT_DIR}/crates/${CRATE}/") - # When using the Ninja generator, we need to provide **some** way to generate the object file - # Unfortunately I'm not able to tell corrosion that this obj file is indeed a byproduct, so - # create a fake target for it. - # This target doesn't need to do anything, because the file should already exist after building the crate. - add_custom_target(${CRATE}_mock_initializers - COMMAND ${CMAKE_COMMAND} -E true - DEPENDS ${CRATE} - BYPRODUCTS "${IMPORT_CRATE_CXX_QT_EXPORT_DIR}/crates/${CRATE}/initializers.o") - - add_library(${CRATE}_initializers OBJECT IMPORTED) - set_target_properties(${CRATE}_initializers - PROPERTIES - IMPORTED_OBJECTS "${IMPORT_CRATE_CXX_QT_EXPORT_DIR}/crates/${CRATE}/initializers.o") - # Note that we need to link using TARGET_OBJECTS, so that the object files are included **transitively**, otherwise - # Only the linker flags from the object library would be included, but not the actual object files. - # See also the "Linking Object Libraries" and "Linking Object Libraries via $" sections: - # https://cmake.org/cmake/help/latest/command/target_link_libraries.html - target_link_libraries(${CRATE} INTERFACE ${CRATE}_initializers $) - endforeach() - -endfunction() - - -function(cxx_qt_import_qml_module target) - cmake_parse_arguments(QML_MODULE "" "URI;SOURCE_CRATE" "" ${ARGN}) - - if (NOT DEFINED QML_MODULE_URI) - message(FATAL_ERROR "cxx_qt_import_qml_module: URI must be specified!") - endif() - - if (NOT DEFINED QML_MODULE_SOURCE_CRATE) - message(FATAL_ERROR "cxx_qt_import_qml_module: SOURCE_CRATE must be specified!") - endif() - - get_target_property(QML_MODULE_EXPORT_DIR ${QML_MODULE_SOURCE_CRATE} CXX_QT_EXPORT_DIR) - get_target_property(QML_MODULE_CRATE_TYPE ${QML_MODULE_SOURCE_CRATE} TYPE) - - if (${QML_MODULE_EXPORT_DIR} STREQUAL "QML_MODULE_EXPORT_DIR-NOTFOUND") - message(FATAL_ERROR "cxx_qt_import_qml_module: SOURCE_CRATE must be a valid target that has been imported with cxx_qt_import_crate!") - endif() - - # Note: This needs to match the URI conversion in cxx-qt-build - string(REPLACE "." "_" module_name ${QML_MODULE_URI}) - set(QML_MODULE_DIR "${QML_MODULE_EXPORT_DIR}/qml_modules/${module_name}") - file(MAKE_DIRECTORY ${QML_MODULE_DIR}) - - # QML plugin - init target - # When using the Ninja generator, we need to provide **some** way to generate the object file - # Unfortunately I'm not able to tell corrosion that this obj file is indeed a byproduct, so - # create a fake target for it. - # This target doesn't need to do anything, because the file should already exist after building the crate. - add_custom_target(${target}_mock_obj_output - COMMAND ${CMAKE_COMMAND} -E true - DEPENDS ${QML_MODULE_SOURCE_CRATE} - BYPRODUCTS "${QML_MODULE_DIR}/plugin_init.o") - - add_library(${target} OBJECT IMPORTED) - set_target_properties(${target} - PROPERTIES - IMPORTED_OBJECTS "${QML_MODULE_DIR}/plugin_init.o") - target_link_libraries(${target} INTERFACE ${QML_MODULE_SOURCE_CRATE}) - - message(VERBOSE "CXX-Qt Expects QML plugin: ${QML_MODULE_URI} in directory: ${QML_MODULE_DIR}") -endfunction() diff --git a/examples/demo_threading/CMakeLists.txt b/examples/demo_threading/CMakeLists.txt index 210c7223e..5ab8ae15f 100644 --- a/examples/demo_threading/CMakeLists.txt +++ b/examples/demo_threading/CMakeLists.txt @@ -28,6 +28,18 @@ if(NOT Qt6_FOUND) find_package(Qt5 5.15 COMPONENTS Core Gui Qml QuickControls2 QmlImportScanner REQUIRED) endif() +find_package(CxxQt QUIET) +if(NOT CxxQt_FOUND) + include(FetchContent) + FetchContent_Declare( + CxxQt + GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git + GIT_TAG main + ) + + FetchContent_MakeAvailable(CxxQt) +endif() + set(CRATE cxx_qt_demo_threading) cxx_qt_import_crate(MANIFEST_PATH rust/Cargo.toml CRATES ${CRATE}) cxx_qt_import_qml_module(${CRATE}_qml diff --git a/examples/qml_features/CMakeLists.txt b/examples/qml_features/CMakeLists.txt index 4f021de0d..25a980fe1 100644 --- a/examples/qml_features/CMakeLists.txt +++ b/examples/qml_features/CMakeLists.txt @@ -28,6 +28,18 @@ if(NOT Qt6_FOUND) find_package(Qt5 5.15 COMPONENTS Core Gui Qml Quick QuickControls2 QmlImportScanner QuickTest Test REQUIRED) endif() +find_package(CxxQt QUIET) +if(NOT CxxQt_FOUND) + include(FetchContent) + FetchContent_Declare( + CxxQt + GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git + GIT_TAG main + ) + + FetchContent_MakeAvailable(CxxQt) +endif() + set(CRATE qml_features) cxx_qt_import_crate(MANIFEST_PATH rust/Cargo.toml CRATES ${CRATE}) cxx_qt_import_qml_module(${CRATE}_qml diff --git a/examples/qml_minimal/CMakeLists.txt b/examples/qml_minimal/CMakeLists.txt index 6bc1ad54e..28a36cfbe 100644 --- a/examples/qml_minimal/CMakeLists.txt +++ b/examples/qml_minimal/CMakeLists.txt @@ -29,15 +29,21 @@ if(NOT Qt6_FOUND) endif() # ANCHOR_END: book_cmake_setup -# ANCHOR: book_cmake_find_qmake -# The path to the qmake executable path needs to be passed to the Rust -# library's build script to ensure it uses the same installation of Qt as CMake. -# TODO: This has been removed, document it -# ANCHOR_END: book_cmake_find_qmake - -# ANCHOR: book_cmake_find_cxx_qt -# TODO: Replace with fetch-content co cxx-qt-cmake -# ANCHOR_END: book_cmake_find_cxx_qt +# ANCHOR: book_cmake_find_cxx_qt_start +find_package(CxxQt QUIET) +if(NOT CxxQt_FOUND) + include(FetchContent) + FetchContent_Declare( + CxxQt + GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git + # ANCHOR_END: book_cmake_find_cxx_qt_start + GIT_TAG main + # ANCHOR: book_cmake_find_cxx_qt_end + ) + + FetchContent_MakeAvailable(CxxQt) +endif() +# ANCHOR_END: book_cmake_find_cxx_qt_end # ANCHOR: book_cmake_use_cxx_qt # CXX-Qt (using Corrosion) creates a CMake target with the same name as the crate. diff --git a/scripts/release_crates.sh b/scripts/release_crates.sh index 136d4ee70..356c4aec7 100755 --- a/scripts/release_crates.sh +++ b/scripts/release_crates.sh @@ -46,6 +46,9 @@ function release_crate() { # Remind about cargo login question_yesno "Have you run cargo login before and setup credentials" +# cxx-qt-cmake (no dependencies) +question_yesno "Have you created a new tag in the cxx-qt-cmake repo" + # No other dependencies release_crate "qt-build-utils" diff --git a/tests/basic_cxx_only/CMakeLists.txt b/tests/basic_cxx_only/CMakeLists.txt index 3e9f72cc7..6c5cd367b 100644 --- a/tests/basic_cxx_only/CMakeLists.txt +++ b/tests/basic_cxx_only/CMakeLists.txt @@ -30,6 +30,18 @@ if(NOT Qt6_FOUND) find_package(Qt5 5.15 COMPONENTS Core Gui Qml Test REQUIRED) endif() +find_package(CxxQt QUIET) +if(NOT CxxQt_FOUND) + include(FetchContent) + FetchContent_Declare( + CxxQt + GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git + GIT_TAG main + ) + + FetchContent_MakeAvailable(CxxQt) +endif() + set(CRATE basic_cxx_only) cxx_qt_import_crate(MANIFEST_PATH rust/Cargo.toml CRATES ${CRATE}) diff --git a/tests/basic_cxx_qt/CMakeLists.txt b/tests/basic_cxx_qt/CMakeLists.txt index ab993d4f7..97b8d17ab 100644 --- a/tests/basic_cxx_qt/CMakeLists.txt +++ b/tests/basic_cxx_qt/CMakeLists.txt @@ -30,6 +30,18 @@ if(NOT Qt6_FOUND) find_package(Qt5 5.15 COMPONENTS Core Gui Qml Test REQUIRED) endif() +find_package(CxxQt QUIET) +if(NOT CxxQt_FOUND) + include(FetchContent) + FetchContent_Declare( + CxxQt + GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git + GIT_TAG main + ) + + FetchContent_MakeAvailable(CxxQt) +endif() + set(CRATE basic_cxx_qt) cxx_qt_import_crate(MANIFEST_PATH rust/Cargo.toml CRATES ${CRATE}) diff --git a/tests/qt_types_standalone/CMakeLists.txt b/tests/qt_types_standalone/CMakeLists.txt index 5361d05db..b1cfaef26 100644 --- a/tests/qt_types_standalone/CMakeLists.txt +++ b/tests/qt_types_standalone/CMakeLists.txt @@ -30,6 +30,18 @@ if(NOT Qt6_FOUND) find_package(Qt5 5.15 COMPONENTS Core Gui Qml Test REQUIRED) endif() +find_package(CxxQt QUIET) +if(NOT CxxQt_FOUND) + include(FetchContent) + FetchContent_Declare( + CxxQt + GIT_REPOSITORY https://github.com/kdab/cxx-qt-cmake.git + GIT_TAG main + ) + + FetchContent_MakeAvailable(CxxQt) +endif() + set(CRATE qt_types_standalone) cxx_qt_import_crate(MANIFEST_PATH rust/Cargo.toml CRATES ${CRATE})