之前我們學(xué)到了如何編寫一個(gè)可執(zhí)行程序和Library,在繼續(xù)學(xué)習(xí)之前,需要解釋下target
,在cmake中我們可以給executable
和library
設(shè)置一個(gè)target名字,這樣可以方便我們?cè)诤罄m(xù)對(duì)target進(jìn)行更加詳細(xì)的屬性設(shè)置。
本節(jié)我們將學(xué)習(xí)如何在項(xiàng)目中引用lib,相關(guān)的api有:
makefile
復(fù)制代碼
link_libraries(<item>... ...) # item鏈接到所有目標(biāo)中 target_link_libraries(<target> ... <item>... ...) # 將item鏈接到指定的target中
其中item參數(shù)支持的情況比較多,提前介紹幾種情況:
- lib name:提供庫的名字,讓cmake去查找對(duì)應(yīng)的庫文件絕對(duì)路徑
- lib fullpath:直接一步到位給出庫文件的絕對(duì)路徑
- target name: 根據(jù)target的屬性,讓cmake查找對(duì)應(yīng)庫文件的絕對(duì)路徑
target_xxx
的命令顆粒度更細(xì),是比較高版本的命令。
app調(diào)用有源代碼的lib
這種情況是有l(wèi)ib的源代碼,我們將lib以源代碼的方式鏈接到項(xiàng)目?jī)?nèi)
項(xiàng)目結(jié)構(gòu)為:
- main.cpp
- lib.cpp
- CMakeLists.txt
makefile
復(fù)制代碼
# app cmake_minimum_required(VERSION 3.0.0) set(app "demo") project(${app} VERSION 0.1.0) add_executable(${app} main.cpp) # lib set(lib "my-lib") project(${lib}) add_library(${lib} ./lib.cpp) # 將lib鏈接到app target_link_libraries(${app} ${lib})
需要注意的target_link_libraries
- 第一個(gè)
target
參數(shù)來自add_executable
的第一個(gè)參數(shù) - 后續(xù)
item
參數(shù)來自add_library
的第一個(gè)參數(shù)
app調(diào)用第三方lib、dll
這種情況是我們使用第三方的lib,只有頭文件和庫文件(
.a、.dll、*.so
)
方式1:imported-libraries
bash
復(fù)制代碼
# 設(shè)置target名字為dll,并且是一個(gè)外部導(dǎo)入的lib # GLOBAL選項(xiàng)可以將target的作用域變?yōu)槿?,默認(rèn)是只在目錄內(nèi)可見 add_library(dll SHARED IMPORTED GLOBAL) # 設(shè)置target dll的詳細(xì)屬性,dll/lib 不區(qū)分debug/release的情況 set_target_properties(dll PROPERTIES # 指向lib,windows必須設(shè)置此項(xiàng) IMPORTED_IMPLIB ${CMAKE_CURRENT_LIST_DIR}/dll.lib # 指向dll、so等 IMPORTED_LOCATION ${CMAKE_CURRENT_LIST_DIR}/dll.dll ) # 設(shè)置debug/release set_target_properties(dll PROPERTIES IMPORTED_IMPLIB_DEBUG ${CMAKE_CURRENT_LIST_DIR}/dll_debug.lib IMPORTED_IMPLIB_RELEASE ${CMAKE_CURRENT_LIST_DIR}/dll_release.lib IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_LIST_DIR}/dll_debug.dll IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_LIST_DIR}/dll_release.dll ) target_link_libraries(app dll)
這里我們使用的是set_target_properties
,可以同時(shí)給多個(gè)target設(shè)置多個(gè)不同的屬性:
scss
復(fù)制代碼
set_target_properties( target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ... )
方式2:將指定的庫文件直接鏈接到target的不同配置
bash
復(fù)制代碼
target_link_libraries(${target} debug ${debug_fullpath}) target_link_libraries(${target} optimized ${release_fullpath})
這兩種方式都可以,原因是target_link_libraries的item
參數(shù)既可以是target name
,也可以是lib fullpath
。
在xcode中,對(duì)應(yīng)的工程配置為:
-
當(dāng)為
target name
時(shí),出現(xiàn)在command的args中 -
當(dāng)為
lib fullpath
時(shí),在xcode中的位置在Linking/Others Linker Flags:
無論使用哪種方式,注意dll、lib必須是存在的,底層查找lib時(shí),不會(huì)自動(dòng)補(bǔ)充lib前綴。
include頭文件目錄問題
以上僅僅是告訴編譯器lib文件的位置在哪里,我們需要添加頭文件目錄,編譯器才能識(shí)別到lib api
方式1:直接添加頭文件目錄,缺點(diǎn)是要手動(dòng)把使用到的lib include path一個(gè)一個(gè)加進(jìn)去,比較麻煩
bash
復(fù)制代碼
# 注意:要放在add_executable、add_library前邊才有效 include_directories("a/b/c/")
方式2:給lib target中添加,只要項(xiàng)目依賴了這個(gè)target,就會(huì)自動(dòng)將目錄添加到項(xiàng)目中
makefile
復(fù)制代碼
# 注意:要放在add_library后邊才有效 target_include_directories(lib INTERFACE # 權(quán)限控制,類比:public/private/protected ${CMAKE_CURRENT_SOURCE_DIR}/ )
方式3:和方式2沒啥區(qū)別,寫法不同而已
makefile
復(fù)制代碼
set_property(TARGET lib PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_LIST_DIR} )
推薦使用第2種方式。
lib包含目錄問題
這種情況對(duì)應(yīng)的是我們target_link_libraries
的item參數(shù)是lib name
,為了讓CMake可以通過lib name
找到對(duì)應(yīng)的lib文件 ,所以我們才需要設(shè)置庫包含目錄,如果item參數(shù)是lib path
、target name
,則不需要設(shè)置庫包含目錄。
相關(guān)的命令有link_directories
和target_link_directories
,區(qū)別參考上文。文章來源:http://www.zghlxwxcb.cn/news/detail-656516.html
作者:xu__yanfeng
鏈接:https://juejin.cn/post/7157618014311940126
來源:稀土掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。文章來源地址http://www.zghlxwxcb.cn/news/detail-656516.html
到了這里,關(guān)于CMake教程6:調(diào)用lib、dll的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!