I am trying to compile some Qt project, including the QCustomPlot library. As a minimum example, i set up a project consisting of:
qcustomplot.h
qcustomplot.cpp
CMakeLists.txt
../cmake/QCustomPlot.cmake
The original project is bigger, but the problem is already reproducible with only those files.
The CMakeLists.txt
contains this code:
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)
If either all lines marked (1)
or all lines marked (3)
are commented out, that means calling find_package()
or qt5_use_modules()
at file scope, i get a project containing the two qcustomplot files and an additional Plots_automoc.cpp
. The additional file is autogenerated and contains the necessary #include "moc_qcustomplot.cpp"
and the project compiles and links properly.
However as soon as i move all qt related commands into functions, the automoc.cpp
file is no longer generated and no longer part of the project, which leads to quite a few unresolved external symbol
during linking.
Calling only a single find_package()
on files scope (like line (2)
) resolves the issue and generates the automoc file again.
Why does simply moving the calls into a function change the automoc behaviour like this and how can i achieve to still move them into functions?
A little bit background: I already have quite a few targets in my project, expect the number to grow rapidly and want to avoid code redundancy. Also people not really trained with CMake are supposed to use it. Thats why i'm trying to move all those Qt related commands into functions and provide a command like this:
add_my_target(
targetName
SOURCES qcustomplot.h qcustomplot.cpp
QT Core Gui Widgets PrintSupport
BOOST filesystem
)
With the exception of Qt, i already achieved this...
I also tried using
target_link_libraries(${projectName} ${Qt5_Core_LIBRARIES} ...
//or
target_link_libraries(${projectName} Qt5::Core ...
it leads to the same result, as long as not at least one find_package()
call is directly on files scope, no automoc is generated.
I am using CMake 3.6.2, Qt 5.7, Visual Studio 2015 and Win 10.
Additional example oLen got most of my underlying confusion sorted out with his answer, but one case remains:
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)
Using the lines marked with (4)
to put all the generation of the target into a function allows CMake to run properly, i.e. qt5_use_modules()
is defined, able to find all the modules and link them (e.g. include directories are set properly). Nowhere outside the function do i rely on variables set by any of the Qt functions. But still automoc does not generate the needed .cpp file. Commenting the marked lines out runs automoc again.