我想编译一些Qt项目,包括QCustomPlot库。作为最小的例子,我设置了包括项目:如果从函数调用find_package()和qt5_use_modules(),为什么AUTOMOC会失败?
qcustomplot.h
qcustomplot.cpp
CMakeLists.txt
../cmake/QCustomPlot.cmake
原始项目比较大,但问题是已经重现的,只有这些文件。
的CMakeLists.txt
包含此代码:
cmake_minimum_required(VERSION 3.6)
set(CMAKE_AUTOMOC ON)
include(../cmake/QCustomPlot.cmake)
function(findqt) #(1)
find_package(Qt5Core)
find_package(Qt5Gui)
find_package(Qt5Widgets)
find_package(Qt5PrintSupport)
endfunction() #(1)
findqt() #(1)
#find_package(Qt5Core) #(2)
add_library(
Plots
src/qcustomplot.h
src/qcustomplot.cpp
)
function(linkqt) #(3)
qt5_use_modules(Plots Core Gui Widgets PrintSupport)
endfunction() #(3)
linkqt() #(3)
如果任所有行标(1)
或全部行标(3)
被注释掉,这意味着在文件范围内调用find_package()
或qt5_use_modules()
,我得到含有两种qcustomplot项目文件和一个额外的Plots_automoc.cpp
。附加文件是自动生成的,包含必要的#include "moc_qcustomplot.cpp"
,并且项目编译和链接正确。
但是只要我把所有的QT的相关命令进入功能,不再产生automoc.cpp
文件和项目,连接期间导致不少unresolved external symbol
不再一部分。
在文件范围(如行(2)
)上只调用一个find_package()
可解决此问题并再次生成automoc文件。
为什么简单地将调用转换为函数会改变像这样的自动行为,我如何才能将它们移动到函数中呢?有点背景:我的项目中已经有了很多目标,希望这个数字能够快速增长,并且希望避免代码冗余。也没有真正受过CMake培训的人应该使用它。这就是为什么我试图所有这些Qt的相关命令进入功能,并提供这样的命令:
add_my_target(
targetName
SOURCES qcustomplot.h qcustomplot.cpp
QT Core Gui Widgets PrintSupport
BOOST filesystem
)
有了Qt的例外,我已经达到了这个...
我也尝试使用
target_link_libraries(${projectName} ${Qt5_Core_LIBRARIES} ...
//or
target_link_libraries(${projectName} Qt5::Core ...
它会导致同样的结果,只要在不至少一个find_package()
电话是直接在文件范围内,不产生automoc。
我使用的CMake 3.6.2,Qt的5.7,Visual Studio的2015年和Win 10
其他例子 OLEN得到了最底层的我困惑的整理出来,他的答案,但一个情况下仍然是:
cmake_minimum_required(VERSION 3.6)
set(CMAKE_AUTOMOC ON)
function(doit) #(4)
find_package(Qt5Core)
add_library(
Plots
qcustomplot.h
qcustomplot.cpp
)
qt5_use_modules(Plots Core Gui Widgets PrintSupport)
endfunction() #(4)
doit() #(4)
使用标有(4)
行把目标的所有代入函数允许CMake的正常运行,即qt5_use_modules()
定义,能够找到的所有模块并将其链接(如包括目录都设置适当的LY)。函数之外的任何地方都不依赖于由任何Qt函数设置的变量。但仍然automoc不会生成所需的.cpp文件。再次注释已标记的线路将自动运行。
对于这个最小的例子,你的解决方案可能是合适的,但对于它后面的更大的项目它不是。除此之外,我可以在嵌套函数内调用所有'find_package()',并可以使用定义的变量,如Qt5_Core_LIBRARIES,这些变量完全不同。只有AUTOMOC无法生成该单个文件。 – Anedar
@Anedar你可以在你的问题中指定为什么“宏”不适合? – oLen
@Anarar对于'Qt5Core_LIBRARIES'仍然被定义,我只是测试它,当我使用'function'时变量不会被定义,这意味着我的答案在这方面是正确的。在你的情况下,它可能仍然存在,因为缓存或因为它来自其他地方。 – oLen