簡體   English   中英

CMake 用於 C++/Qt 項目中的外部庫

[英]CMake for external library in C++/Qt project

我正在嘗試構建一個小型 C++/Qt 測試程序來讀取各種編碼的文件,我正在嘗試使用 Google 的緊湊編碼檢測 (CED) 庫: https://github.com/google/compact_enc_det有很多類似的問題,但它們似乎都不起作用或反映我的問題。

CED 作為一個獨立項目構建得很好,但我正在努力將它作為一個外部庫合並到我的項目中。 我習慣了 QMake,在 QtCreator 中工作,但這只適用於 CMake 所以我開始環顧四周,但我有點迷路(QMake 在這方面似乎更簡單)。

我設法讓我的 C++/Qt 項目在 QtCreator 下與 CMake 一起工作,並且還設法構建和測試 CED(CMake 然后生成一個庫:libced.a)。

這是我的小(工作)CMakeLists 文件:

cmake_minimum_required(VERSION 3.1.0)

project(FileTestCMakeCED)

set(CMAKE_AUTOMOC ON)

find_package(Qt5 COMPONENTS Core Widgets REQUIRED)

set(FileTest_src
    ${CMAKE_CURRENT_LIST_DIR}/src/mainwindow.cpp
    ${CMAKE_CURRENT_LIST_DIR}/src/main.cpp
)

add_executable(${PROJECT_NAME} ${FileTest_src})

# Use the Widgets module from Qt 5
target_link_libraries(${PROJECT_NAME} Qt5::Widgets)

我沒有粘貼CED的CMakeLists,它有點長,它在GitHub頁面上: https://github.com/google/compact_enc_det/blob/master/CMakeLists.txt

我想要么將 CED 用作 static 庫(但我嘗試了很多方法,但都沒有用),要么合並源代碼,以便在需要時將它們與我的項目一起編譯(我嘗試將 CED 作為外部項目鏈接到我的源代碼樹,但如果更容易的話,我可以將它移動到同一源代碼樹中)。

我嘗試過的一件有前途的事情是:

include_directories(../compact_enc_det)
add_library(ced STATIC IMPORTED)
set_target_properties(ced PROPERTIES IMPORTED_LOCATION ../compact_enc_det/lib/libced.a)
...
target_link_libraries(${PROJECT_NAME} Qt5::Widgets ced)

但是我得到一個“ no rule to make target.../libced.a ”錯誤,即使我只想使用預編譯庫。

我唯一設法開始工作的是從谷歌制作的 CED 項目開始並將我的源代碼粘貼到那里,並讓 CED 的 CMakeLists 為我的程序生成一個額外的可執行文件,但這與我想要的相反代碼和項目結構。 如果我嘗試相反的方法(將 CED 包括到我的項目中),我總是會遇到 CED 的源和包含的路徑問題。

有人可以啟發我解決此類問題的最佳做法嗎? 另外,正如我所說,我是 CMake 的新手,因此我們將不勝感激。 如果重要的話,我正在撥打 Debian Stretch。

非常感謝,

一種快速的解決方案是提供libced.a庫的完整路徑:

target_link_libraries(${PROJECT_NAME} Qt5::Widgets /path/to/libced.a)

這種方法的缺點是您的CMakeLists.txt變得特定於您正在使用的計算機。 如果分發代碼,其他人將無法在不更改源代碼CMakeLists.txt情況下配置其構建。

通常,外部庫使用find_package()位於CMake中。 為了使此功能起作用,您嘗試鏈接的包必須在CMake可以找到它的位置提供<package>Config.cmakeFind<package>.cmake文件。 這些文件已經存在於CMake安裝中的許多流行軟件包中(例如,在/ usr / lib / cmake下查找)。 但是,如果只是從CMake開始,編寫自己的腳本可能不是一個簡單的解決方案,因為在這些文件中,您嘗試編寫一個腳本,該腳本執行許多與系統有關的檢查以定位包並設置可以在構建中進一步使用的適當變量處理。 您可以在鏈接的文檔頁面上了解更多信息。

另一種解決方案是使用find_library() ,您可以在其中為所需庫的位置提供提示或環境變量。 如果找不到該庫,則可以打印一條消息或錯誤,要求用戶設置特定的提示變量,您的CMakeLists.txt可用於查找該庫。 例如,在您的CMakeLists.txt您可以執行

find_library(CED_LIBRARY ced HINTS ${CED_ROOT})
if( ${CED_LIBRARY} STREQUAL "CED_LIBRARY-NOTFOUND")
    message("Please set CED_LIBRARY variable to location of libced")
endif()

[使用兩個小補丁編輯的代碼]

上面的代碼片段指示CMake查找ced庫的文件路徑,並將該路徑存儲在CED_LIBRARY變量中。 如果找不到文件,它將在該變量中存儲CED_LIBRARY-NOTFOUND 如果找到該庫,則可以使用進行鏈接

target_link_libraries(${PROJECT_NAME} Qt5::Widgets ${CED_LIBRARY})

find_library()非常聰明,可以自己嘗試各種前綴和后綴,因此您無需編寫libced 例如,在Windows上,它可能會嘗試找到libced.dll ;對於Unix上的共享庫,它將搜索libced.so等。

自問題發布以來已經有很長時間了,但我將這個問題留作參考。 我有一篇博客文章逐步描述了您(或其他任何人)正在嘗試做的事情。 請在此處查看: https://michae9.wordpress.com/2022/09/01/shared-lib-to-be-used-by-client-programs-with-cmake/

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM