交叉编译中的CMake CMAKE_AUTOMOC

Mag*_*nar 6 c++ qt cmake cross-compiling

我有以下问题。我尝试使用 CMake 中构建的本机机制进行交叉编译。我准备了以下 toolchain.cmake 文件:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_SYSROOT /tmp/filesystem)

set(tools /opt/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux/bin/arm-linux-gnueabihf)
set(CMAKE_C_COMPILER ${tools}-gcc)
set(CMAKE_CXX_COMPILER ${tools}-g++)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
Run Code Online (Sandbox Code Playgroud)

并在目标中CMakeList.txt使用:

set(CMAKE_AUTOMOC ON)
Run Code Online (Sandbox Code Playgroud)

我希望当我使用CMAKE_FIND_ROOT_PATH_MODE_PROGRAMset 到NEVERCMake 时,根据文档,将使用 moc from HOST

如果设置为 NEVER,则 CMAKE_FIND_ROOT_PATH 中的根将被忽略,仅使用主机系统根。

然而它仍然尝试使用来自TARGETarm镜像rootfs的moc。

我尝试重新查找 moc 可执行文件,就像这篇文章的第一个答案中一样:How to include a certain Qt Installation using CMake? 但没有运气。

我还尝试将QT_MOC_EXECUTABLE变量设置为HOSTrootfs 的正确路径,而不是TARGET一个,但也没有运气。我认为当CMAKE_AUTOMOC设置为时,CMake 不会使用此变量ON,因为在强制更改此缓存变量后,cmake 仍然使用TARGETrootfs 中的 moc。

有什么想法如何解决这个问题吗?

# 编辑1

我发现 automoc 在 build 文件夹中生成这样的文件:

CMakeFiles/*target_name*_automoc.dir/AutogenInfo.cmake

在我的例子中,此类变量设置为错误的路径:

set(AM_QT_MOC_EXECUTABLE "/tmp/filesystem/usr/lib/arm-linux-gnueabihf/qt5/bin/moc")

应该:

set(AM_QT_MOC_EXECUTABLE "/usr/bin/moc")

AM_QT_MOC_EXECUTABLE在 main 中设置了正确的值CMakeList.txt,但仍然在使用 rootfs 的错误路径生成了上述文件之后TARGET

Mag*_*nar 2

感谢这篇文章,我终于找到了解决方案:How can I use CMake's AUTOMOC feature with a custom Qt package? 。正如我假设的那样,QT_MOC_EXECUTABLE不直接使用AUTOMOC, .

在第一个 qt 之前find_package必须添加以下行:

set(QT_MOC_EXECUTABLE /usr/bin/moc)
add_executable(Qt5::moc IMPORTED)
set_property(TARGET Qt5::moc PROPERTY IMPORTED_LOCATION ${QT_MOC_EXECUTABLE})
Run Code Online (Sandbox Code Playgroud)

这里的问题是,不仅变量QT_MOC_EXECUTABLE必须设置为正确的值,而且最终 automoc 仅使用Qt5:moc目标,该目标必须在任何 qt 包包含在其中之前声明CMakeList.txt文件中之前声明。

其他 qt 工具也存在同样的问题,因此更通用的选项是:

file(GLOB Qt_bin /usr/bin)
find_program(QT_MOC_EXECUTABLE qt_moc moc PATHS ${Qt_bin})
add_executable(Qt5::moc IMPORTED)
set_property(TARGET Qt5::moc PROPERTY IMPORTED_LOCATION ${QT_MOC_EXECUTABLE})
Run Code Online (Sandbox Code Playgroud)