2017-08-21 59 views
2

我想編譯一些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文件。再次註釋已標記的線路將自動運行。

回答

2

問題是CMake函數引入了一個作用域,因此find_package中定義的變量在函數外部不可用。

解決您的問題的一個簡單方法是使用CMake宏 - 您可以將它們視爲CMake的C宏等價物。此處聲明的變量在宏觀範圍之外也可用。

在你的情況下,這意味着用macroendfunctionendmacro代替function

+0

對於這個最小的例子,你的解決方案可能是合適的,但對於它後面的更大的項目它不是。除此之外,我可以在嵌套函數內調用所有'find_package()',並可以使用定義的變量,如Qt5_Core_LIBRARIES,這些變量完全不同。只有AUTOMOC無法生成該單個文件。 – Anedar

+0

@Anedar你可以在你的問題中指定爲什麼「宏」不適合? – oLen

+0

@Anarar對於'Qt5Core_LIBRARIES'仍然被定義,我只是測試它,當我使用'function'時變量不會被定義,這意味着我的答案在這方面是正確的。在你的情況下,它可能仍然存在,因爲緩存或因爲它來自其他地方。 – oLen

相關問題