cmake引用靜態(tài)或動態(tài)庫(四)

前言

上一篇文章講解了如何構(gòu)建靜態(tài)庫或者動態(tài)庫协饲,本文目標為:
1扫腺、引入外部靜態(tài)庫
2砌创、引入外部動態(tài)庫

準備工作

創(chuàng)建sample7,在里面創(chuàng)建3rdlilb姆打,將上一篇文章構(gòu)建的Math.h頭文件件余、以及將lib文件夾下內(nèi)容全部拷貝進來讥脐,創(chuàng)建src源碼目錄,將sample2的main.cpp拷貝進來啼器,最終目錄如下:

./sample7
    |
    +--- CMakeLists.txt
    |
    +--- build/
    +--- src/
            +--- CMakeLists.txt
            +--- main.cpp
    +--- lib/
          +--- libMath.a
          +--- libmath.1.2.dylib
          +--- libmath.1.dylib
          +--- libmath.dylib
          +--- Math.h

這里要再main.cpp中應用外部math庫旬渠,其內(nèi)容為:

#include <stdio.h>
#include <stdlib.h>
#include "Math.h"

int main(int argc, char *argv[])
{
    if (argc < 3){
        printf("Usage: %s base exponent \n", argv[0]);
        return 1;
    }
    double base = atof(argv[1]);
    int exponent = atoi(argv[2]);
    double result = power(base, exponent);
    printf("%g ^ %d is %g\n", base, exponent, result);
    return 0;
}

工程根目錄下CMakeLists.txt內(nèi)容為:

# CMake 最低版本號要求
cmake_minimum_required (VERSION 2.8)

if(POLICY CMP0042)
  cmake_policy(SET CMP0042 NEW)  # CMake 3.0+ (2.8.12): MacOS "@rpath" in target's install name
endif()

# 項目工程名
project (sample7)
message(STATUS "root This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "root This is SOURCE dir " ${PROJECT_SOURCE_DIR})

# 添加子目錄
ADD_SUBDIRECTORY(src)

1、引入外部靜態(tài)庫

src目錄下的CMakeLists.txt文件內(nèi)容為:

# 打印信息
message(STATUS "src This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "src This is SOURCE dir " ${PROJECT_SOURCE_DIR})

# 定義工程根目錄; CMAKE_SOURCE_DIR為內(nèi)建變量端壳,表示工程根目錄的CMakeLists.txt文件路徑
SET(ROOT_DIR ${CMAKE_SOURCE_DIR})

# 指定頭文件搜索路徑
INCLUDE_DIRECTORIES(${ROOT_DIR}/3rdlib)

# 指定引用的外部庫的搜索路徑
LINK_DIRECTORIES(${ROOT_DIR}/3rdlib)

# 指定可執(zhí)行文件存放目錄
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# 構(gòu)建可執(zhí)行程序
ADD_EXECUTABLE(sample7 main.cpp)
TARGET_LINK_LIBRARIES(sample7 libmath.a)
  • INCLUDE_DIRECTORIES(${ROOT_DIR}/3rdlib)
    用于指定頭文件的搜索路徑告丢,因為Math.h與main.cpp不在同一目錄,所以如果不配置這個搜索路徑损谦,肯定會報錯
  • LINK_DIRECTORIES(${ROOT_DIR}/3rdlib)
    指定靜態(tài)庫或者動態(tài)庫的搜索路徑
  • TARGET_LINK_LIBRARIES(sample7 libmath.a)
    指定要連接的靜態(tài)庫岖免,必須要有岳颇,第二個參數(shù)也可以換成math,那么將自動去搜索libmath.a或者libmath.so或者libmath.dyld動態(tài)庫

還有另外一種寫法颅湘,如下:

# 打印信息
message(STATUS "src This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "src This is SOURCE dir " ${PROJECT_SOURCE_DIR})

# 定義工程根目錄; CMAKE_SOURCE_DIR為內(nèi)建變量话侧,表示工程根目錄的CMakeLists.txt文件路徑
SET(ROOT_DIR ${CMAKE_SOURCE_DIR})

# 指定頭文件搜索路徑
INCLUDE_DIRECTORIES(${ROOT_DIR}/3rdlib)

# 以導入外部庫的方式(不會重新編譯)重新構(gòu)建一個靜態(tài)庫libMath
add_library(libMath STATIC IMPORTED)
# 設置要導入的外部靜態(tài)庫的路徑
set_target_properties(libMath PROPERTIES IMPORTED_LOCATION ${ROOT_DIR}/3rdlib/libmath.a)

# 指定可執(zhí)行文件存放目錄
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# 構(gòu)建可執(zhí)行程序
ADD_EXECUTABLE(sample7 main.cpp)
# 注意這里連接的庫名為新構(gòu)建的庫名libMath而外部庫libmath
TARGET_LINK_LIBRARIES(sample7 libMath)

這里解釋下,這里是先根據(jù)外部靜態(tài)庫重新構(gòu)建一個libMath靜態(tài)庫闯参,然后可執(zhí)行程序連接到該庫

  • add_library(libMath STATIC IMPORTED)
    以導入外部庫的方式重新構(gòu)建一個靜態(tài)庫libMath,不會重新編譯
  • set_target_properties(libMath PROPERTIES IMPORTED_LOCATION ${ROOT_DIR}/3rdlib/libmath.a)

設置要導入的外部靜態(tài)庫的路徑

tips:
建議用方式一導入外部庫

2瞻鹏、引入外部動態(tài)庫

修改src下CMakeLists.txt文件內(nèi)容:

# 打印信息
message(STATUS "src This is BINARY dir " ${PROJECT_BINARY_DIR})
message(STATUS "src This is SOURCE dir " ${PROJECT_SOURCE_DIR})

# 定義工程根目錄; CMAKE_SOURCE_DIR為內(nèi)建變量,表示工程根目錄的CMakeLists.txt文件路徑
SET(ROOT_DIR ${CMAKE_SOURCE_DIR})

# 指定頭文件搜索路徑
INCLUDE_DIRECTORIES(${ROOT_DIR}/3rdlib)

# 指定引用的外部庫的搜索路徑
LINK_DIRECTORIES(${ROOT_DIR}/3rdlib)

# 指定可執(zhí)行文件存放目錄
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

# 構(gòu)建可執(zhí)行程序
ADD_EXECUTABLE(sample7 main.cpp)
TARGET_LINK_LIBRARIES(sample7 libmath.dylib)

tips:
因為sample7 在構(gòu)建的時候引入了動態(tài)庫赢赊,所以當./sample7 在執(zhí)行的時候?qū)⑷ブ付ǖ哪夸浖虞d這個動態(tài)庫(這個路徑非編譯時指定的動態(tài)庫路徑乙漓,發(fā)現(xiàn)會報錯"dyld: Library not loaded: @rpath/libmath.1.dylib") ,如果將他們拷貝到/usr/local/lib/目錄下释移,發(fā)現(xiàn)就不報錯了叭披。對于mac 系統(tǒng),它默認按照如下順序搜索動態(tài)庫:

1.編譯目標代碼時指定的動態(tài)庫搜索路徑(通過 -Wl,-rpath參數(shù)指定的)
2.環(huán)境變量LD_LIBRARY_PATH指定的動態(tài)庫搜索路徑玩讳;
3.配置文件/etc/ld.so.conf中指定的動態(tài)庫搜索路徑涩蜘;
4.默認的動態(tài)庫搜索路徑/usr/lib
5.默認的動態(tài)庫搜索路徑/usr/local/lib

其它系統(tǒng)可能有些區(qū)別,但大體都差不多

引入靜態(tài)庫和動態(tài)庫的區(qū)別

1熏纯、引入靜態(tài)庫時同诫,靜態(tài)庫在連接階段會被連接到最終目標中(比如可執(zhí)行執(zhí)行程序中),缺點就是同一份靜態(tài)庫如果被不同的程序引用樟澜,那么內(nèi)存中會存在這個靜態(tài)庫函數(shù)的多份拷貝
2误窖、引入動態(tài)庫時,連接階段不會被拷貝最終目標中秩贰,程序運行時將按照指定的規(guī)則(上一步提到的規(guī)則霹俺,并非編譯時的動態(tài)庫路徑)去搜索這個動態(tài)庫,搜索到了之后才加載到內(nèi)存中毒费。所以多個程序就算引用了同一個動態(tài)庫丙唧,內(nèi)存中也只是存在一份動態(tài)庫函數(shù)的拷貝

CMake 環(huán)境變量關鍵字

1、CMAKE_INCLUDE_PATH
2觅玻、CMAKE_LIBRARY_PATH
這兩個變量在cmake語法中顯示調(diào)用并沒有效果想际,它的作用給CMake的FIND__XXX()系列函數(shù)提供查找路徑,比如如下代碼

# 在環(huán)境變量CMAKE_LIBRARY_PATH指定的目錄中查找libmath.dylib
# 的路徑溪厘,并賦值給mypath變量
message(STATUS "ddd This is SOURCE dir " ${CMAKE_INCLUDE_PATH})
FIND_PATH(myHeader hello.h)
FIND_LIBRARY(mypath libmath.dylib)
message(STATUS "ee This is SOURCE dir " ${myHeader})
message(STATUS "ttt This is SOURCE dir " ${mypath})

將libmath.dyld,Math.h分別拷貝到/usr/local/lib胡本,/usr/local/include目錄中,執(zhí)行

export PATH=$PATH:/usr/local/lib:/usr/local/include
cmake ..

發(fā)現(xiàn)${myHeader}和${mypath}都是有值的

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末畸悬,一起剝皮案震驚了整個濱河市打瘪,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖闺骚,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彩扔,死亡現(xiàn)場離奇詭異,居然都是意外死亡僻爽,警方通過查閱死者的電腦和手機虫碉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胸梆,“玉大人敦捧,你說我怎么就攤上這事∨鼍担” “怎么了兢卵?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長绪颖。 經(jīng)常有香客問我秽荤,道長,這世上最難降的妖魔是什么柠横? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任窃款,我火速辦了婚禮,結(jié)果婚禮上牍氛,老公的妹妹穿的比我還像新娘晨继。我一直安慰自己,他們只是感情好搬俊,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布紊扬。 她就那樣靜靜地躺著,像睡著了一般唉擂。 火紅的嫁衣襯著肌膚如雪珠月。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天楔敌,我揣著相機與錄音,去河邊找鬼驻谆。 笑死卵凑,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的胜臊。 我是一名探鬼主播勺卢,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼象对!你這毒婦竟也來了黑忱?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎甫煞,沒想到半個月后菇曲,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡抚吠,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年常潮,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片楷力。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡喊式,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萧朝,到底是詐尸還是另有隱情岔留,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布检柬,位于F島的核電站献联,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏厕吉。R本人自食惡果不足惜酱固,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望头朱。 院中可真熱鬧运悲,春花似錦、人聲如沸项钮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烁巫。三九已至署隘,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間亚隙,已是汗流浹背磁餐。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留阿弃,地道東北人诊霹。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像渣淳,于是被迫代替她去往敵國和親脾还。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 前言 前文的的最終目標都是構(gòu)建一個可執(zhí)行文件入愧,本文目標是如何構(gòu)建靜態(tài)庫或者動態(tài)庫目標如下:1鄙漏、創(chuàng)建一個靜態(tài)庫lib...
    仙人掌__閱讀 2,971評論 0 3
  • CMake學習 本篇分享一下有關CMake的一些學習心得以及相關使用嗤谚。 本文目錄如下: [1、CMake介紹] [...
    AlphaGL閱讀 12,226評論 11 79
  • 搬運自本人 CSDN 博客:https://blog.csdn.net/ajianyingxiaoqinghan/...
    琦小蝦閱讀 15,341評論 0 11
  • 在Android Studio 2.2開始怔蚌,正式支持cmake編譯巩步,在與android studio結(jié)合之前,cm...
    蛋西閱讀 5,605評論 0 3
  • CMake 全稱“cross platform make”媚创,是開源渗钉、跨平臺的自動化構(gòu)建系統(tǒng)。CMake 由 Kit...
    神齊閱讀 4,094評論 0 6