Ich versuche, einige Qt-Projekt zu kompilieren, einschließlich der QCustomPlot-Bibliothek. Als Minimum Beispiel setzte i ein Projekt, bestehend aus:Warum schlägt AUTOMOC fehl, wenn find_package() und qt5_use_modules() aus Funktionen aufgerufen werden?
qcustomplot.h
qcustomplot.cpp
CMakeLists.txt
../cmake/QCustomPlot.cmake
Das ursprüngliche Projekt ist größer, aber das Problem ist bereits reproduzierbar nur mit den Dateien.
Der CMakeLists.txt
enthält diesen 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)
Wenn entweder alle Linien (1)
markiert oder alle Linien markiert (3)
sind auf Kommentar, die find_package()
oder qt5_use_modules()
in Dateigültigkeitsbereich bedeutet Aufruf, ich ein Projekt bekommen die zwei qcustomplot enthalten Dateien und eine zusätzliche Plots_automoc.cpp
. Die zusätzliche Datei wird automatisch generiert und enthält die erforderlichen und das Projekt kompiliert und verknüpft ordnungsgemäß.
Sobald ich jedoch alle qt-bezogenen Befehle in Funktionen verschiebe, wird die Datei automoc.cpp
nicht mehr erzeugt und ist nicht mehr Teil des Projekts, was beim Verknüpfen zu einigen wenigen unresolved external symbol
führt.
Der Aufruf eines einzigen find_package()
on files-Bereichs (wie Zeile) behebt das Problem und generiert die Automoc-Datei erneut.
Warum ändert das Verschieben der Aufrufe in eine Funktion das Automoc-Verhalten so und wie kann ich erreichen, dass sie immer noch in Funktionen verschoben werden?
Ein wenig Hintergrund: Ich habe bereits einige Ziele in meinem Projekt, erwarte, dass die Zahl schnell wächst und Code-Redundanz vermeiden will. Auch Leute, die nicht wirklich mit CMake trainiert sind, sollen es benutzen. Das ist, warum versuche ich all die Qt bezogene Befehle in Funktionen zu bewegen und einen Befehl wie diesen bieten:
add_my_target(
targetName
SOURCES qcustomplot.h qcustomplot.cpp
QT Core Gui Widgets PrintSupport
BOOST filesystem
)
Mit Ausnahme von Qt, ich dies bereits erreicht ...
Ich habe auch versucht mit
target_link_libraries(${projectName} ${Qt5_Core_LIBRARIES} ...
//or
target_link_libraries(${projectName} Qt5::Core ...
es führt zum gleichen Ergebnis, solange nicht mindestens ein find_package()
Anruf direkt auf Dateien Umfang, wird keine automoc erzeugt.
Ich bin mit CMake 3.6.2, Qt 5.7, Visual Studio 2015 und Win 10.
Weiteres Beispiel Olen bekam die meisten meiner zugrunde liegenden Verwirrung mit seiner Antwort aussortiert, aber ein Fall bleibt:
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)
Unter Verwendung der mit (4)
markierten Linien in eine Funktion all die Erzeugung des Ziels setzen ermöglicht CMake ordnungsgemäß ausgeführt wird, dh qt5_use_modules()
definiert ist, in der Lage, alle Module zu finden und verknüpfen sie (zB include, die gesetzt sind richtig ly). Nirgendwo außerhalb der Funktion verlasse ich mich auf Variablen, die von einer der Qt-Funktionen festgelegt wurden. Automoc generiert jedoch nicht die erforderliche CPP-Datei. Durch Kommentieren der markierten Zeilen wird autoc erneut ausgeführt.
Für dieses minimale Beispiel könnte Ihre Lösung geeignet sein, aber für das größere Projekt dahinter ist es nicht geeignet. Außerdem kann ich alle 'find_package()' tief in den verschachtelten Funktionen aufrufen und die definierten Variablen wie Qt5_Core_LIBRARIES irgendwo völlig anders benutzen. Nur der AUTOMOC generiert diese einzelne Datei nicht. – Anedar
@Anedar Können Sie in Ihrer Frage angeben, warum ein 'Makro' nicht geeignet ist? – oLen
@Anedar wie für 'Qt5Core_LIBRARIES' noch definiert, habe ich es gerade getestet und die Variablen bleiben nicht definiert, wenn ich eine' Funktion' verwende, was bedeutet, dass meine Antwort in dieser Hinsicht korrekt ist. In Ihrem Fall könnte es wegen des Caches noch da sein oder weil es von woanders kommt. – oLen