Skip to content

Commit 13e62c7

Browse files
committed
cmake: pass QT_MODULES from CMake to Rust and set link libs
We need to set the link libs onto the static target and not the resultant crate target otherwise the order of the linking can be incorrect which then fails with ld.bfd
1 parent 555f45b commit 13e62c7

File tree

1 file changed

+24
-1
lines changed

1 file changed

+24
-1
lines changed

cmake/CxxQt.cmake

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ if(NOT Corrosion_FOUND)
1717
endif()
1818

1919
function(cxx_qt_import_crate)
20-
cmake_parse_arguments(IMPORT_CRATE "" "CXX_QT_EXPORT_DIR;QMAKE" "" ${ARGN})
20+
cmake_parse_arguments(IMPORT_CRATE "" "CXX_QT_EXPORT_DIR;QMAKE" "QT_MODULES" ${ARGN})
2121

2222
corrosion_import_crate(IMPORTED_CRATES __cxx_qt_imported_crates ${IMPORT_CRATE_UNPARSED_ARGUMENTS})
2323

@@ -37,12 +37,27 @@ function(cxx_qt_import_crate)
3737
endif()
3838
endif()
3939

40+
if (NOT DEFINED IMPORT_CRATE_QT_MODULES)
41+
message(FATAL_ERROR "Missing QT_MODULES argument! You must specify at least one Qt module to link to.")
42+
else()
43+
message(VERBOSE "CXX_QT_QT_MODULES: ${IMPORT_CRATE_QT_MODULES}")
44+
endif()
45+
4046
foreach(CRATE ${__cxx_qt_imported_crates})
47+
# Join modules by a comma so that we can pass easily via an env variable
48+
#
49+
# TODO: can we instead read the module from _qt_config_module_name or
50+
# _qt_public_module_interface_name of the target, but need to consider
51+
# private modules too
52+
list(JOIN IMPORT_CRATE_QT_MODULES "," IMPORT_CRATE_QT_MODULES_STR)
53+
4154
corrosion_set_env_vars(${CRATE}
4255
# Tell cxx-qt-build where to export the data
4356
"CXX_QT_EXPORT_DIR=${IMPORT_CRATE_CXX_QT_EXPORT_DIR}"
4457
# Tell cxx-qt-build which crate to export
4558
"CXX_QT_EXPORT_CRATE_${CRATE}=1"
59+
# Tell cxx-qt-build which Qt modules we are using
60+
"CXX_QT_QT_MODULES=${IMPORT_CRATE_QT_MODULES_STR}"
4661
"QMAKE=${IMPORT_CRATE_QMAKE}"
4762
$<$<BOOL:${CMAKE_RUSTC_WRAPPER}>:RUSTC_WRAPPER=${CMAKE_RUSTC_WRAPPER}>)
4863

@@ -75,6 +90,14 @@ function(cxx_qt_import_crate)
7590
# See also the "Linking Object Libraries" and "Linking Object Libraries via $<TARGET_OBJECTS>" sections:
7691
# https://cmake.org/cmake/help/latest/command/target_link_libraries.html
7792
target_link_libraries(${CRATE} INTERFACE ${CRATE}_initializers $<TARGET_OBJECTS:${CRATE}_initializers>)
93+
94+
# Link the static library to Qt
95+
# Note that we cannot do this on the final CRATE target as this is an interface
96+
# which depends on the static library. If we do target_link_libraries on the ${CRATE} target,
97+
# the static library will not actually depend on the Qt modules, but be a kind of "sibling dependency", which CMake may reorder.
98+
# This can cause CMake to emit the wrong link order, with Qt before the static library, which then fails to build with ld.bfd
99+
# https://stackoverflow.com/questions/51333069/how-do-the-library-selection-rules-differ-between-gold-and-the-standard-bfd-li
100+
target_link_libraries(${CRATE}-static INTERFACE ${IMPORT_CRATE_QT_MODULES})
78101
endforeach()
79102

80103
endfunction()

0 commit comments

Comments
 (0)