国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

現(xiàn)代CMake高級教程 - 第 3 章:鏈接庫文件

這篇具有很好參考價值的文章主要介紹了現(xiàn)代CMake高級教程 - 第 3 章:鏈接庫文件。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

雙笙子佯謬老師的【公開課】現(xiàn)代CMake高級教程課程筆記

第 3 章:鏈接庫文件

main.cpp 調(diào)用 mylib.cpp 里的 say_hello 函數(shù)

$tree
.
├── CMakeLists.txt
├── main.cpp
├── mylib.cpp
└── mylib.h	
// main.cpp
#include "mylib.h"

int main() {
	say_hello();
}
// mylib.h
#pragma once

void say_hello();
// mylib.cpp
#include "mylib.h"
#include <cstdio>

void say_hello() 
{
	printf("hello, mylib!\n");
}	

1. 直接鏈接到一起編譯

# CMakeLists.txt
add_executable(main main.cpp mylib.cpp)	

2. mylib 作為一個靜態(tài)庫

add_library(mylib STATIC mylib.cpp)

add_executable(main main.cpp)

target_link_libraries(main PUBLIC mylib)

編譯:

$cmake --build build
[build] [1/3  33% :: 0.194] Building CXX object CMakeFiles/mylib.dir/mylib.cpp.o
[build] [2/3  66% :: 0.420] Linking CXX static library libmylib.a
[build] [3/3 100% :: 0.741] Linking CXX executable main
[build] Build finished with exit code 0	

生成了 libmylib.a:

$ls build
CMakeCache.txt  CMakeFiles  build.ninja  cmake_install.cmake  compile_commands.json  libmylib.a  main  mylib

3. mylib 作為一個動態(tài)庫

add_library(mylib SHARED mylib.cpp)

add_executable(main main.cpp)

target_link_libraries(main PUBLIC mylib)

編譯:

[main] Building folder: CMakeLession 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /mnt/h/Code/lessonCode/CMakeLession/build --config Debug --target all --
[build] [1/3  33% :: 0.485] Building CXX object CMakeFiles/mylib.dir/mylib.cpp.o
[build] [2/3  66% :: 0.786] Linking CXX shared library libmylib.so
[build] [3/3 100% :: 1.071] Linking CXX executable main
[build] Build finished with exit code 0
[main] Building folder: CMakeLession 
[build] Starting build
[proc] Executing command: /usr/bin/cmake --build /mnt/h/Code/lessonCode/CMakeLession/build --config Debug --target all --
[build] [1/3  33% :: 0.485] Building CXX object CMakeFiles/mylib.dir/mylib.cpp.o
[build] [2/3  66% :: 0.786] Linking CXX shared library libmylib.so
[build] [3/3 100% :: 1.071] Linking CXX executable main
[build] Build finished with exit code 0	

4. mylib 作為一個對象庫

對象庫類似于靜態(tài)庫,但不生成 .a 文件,只由 CMake 記住該庫生成了哪些對象文件

add_library(mylib OBJECT mylib.cpp)

add_executable(main main.cpp)

target_link_libraries(main PUBLIC mylib) 	

編譯:

cmake --build build
[ 33%] Building CXX object CMakeFiles/mylib.dir/mylib.cpp.o
[ 33%] Built target mylib
[ 66%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable main
[100%] Built target main	

對象庫類似于靜態(tài)庫,但不生成 .a 文件,只由 CMake 記住該庫生成了哪些對象文件,對象庫是 CMake 自創(chuàng)的,繞開了編譯器和操作系統(tǒng)的各種繁瑣規(guī)則,保證了跨平臺統(tǒng)一性。在自己的項目中,我推薦全部用對象庫(OBJECT)替代靜態(tài)庫(STATIC)避免跨平臺的麻煩。

對象庫僅僅作為組織代碼的方式,而實際生成的可執(zhí)行文件只有一個,減輕了部署的困難。

? ls build/CMakeFiles/mylib.dir
DependInfo.cmake  build.make  cmake_clean.cmake  compiler_depend.make  compiler_depend.ts  depend.make  flags.make  mylib.cpp.o  mylib.cpp.o.d  progress.make

靜態(tài)庫的麻煩:GCC 編譯器自作聰明,會自動剔除沒有引用符號的那些對象
例:
CMakeLists.txt

add_library(mylib STATIC mylib.cpp)	

mylib.cpp

#include <cstdio>

// 此處進行靜態(tài)初始化
static int unused = printf("mylib initialized!");

main.cpp

#include <cstdio>

int main()
{
	printf("main function\n");
}

編譯:

? cmake --build build
[ 50%] Built target mylib
Consolidate compiler generated dependencies of target main
[ 75%] Building CXX object CMakeFiles/main.dir/main.cpp.o
[100%] Linking CXX executable main
[100%] Built target main	

查看符號:

.init_array:0000000000003DB8 _init_array     segment qword public 'DATA' use64
.init_array:0000000000003DB8                 assume cs:_init_array
.init_array:0000000000003DB8                 ;org 3DB8h
.init_array:0000000000003DB8 __frame_dummy_init_array_entry dq offset frame_dummy
.init_array:0000000000003DB8                                         ; DATA XREF: LOAD:0000000000000168↑o
.init_array:0000000000003DB8                                         ; LOAD:00000000000002F0↑o
.init_array:0000000000003DB8 _init_array     ends

這里可以看到?jīng)]有 mylib 的初始化

對象庫可以繞開編譯器的不統(tǒng)一:保證不會自動剔除沒引用到的對象文件。我們改成 OBJECT:
CMakeLists.txt

add_library(mylib STATIC mylib.cpp)

使用 ida 可以看到 mylib 初始化:

.init_array:0000000000003DA8 _init_array     segment qword public 'DATA' use64
.init_array:0000000000003DA8                 assume cs:_init_array
.init_array:0000000000003DA8                 ;org 3DA8h
.init_array:0000000000003DA8 __frame_dummy_init_array_entry dq offset frame_dummy
.init_array:0000000000003DA8                                         ; DATA XREF: LOAD:0000000000000168↑o
.init_array:0000000000003DA8                                         ; LOAD:00000000000002F0↑o
.init_array:0000000000003DB0                 dq offset _GLOBAL__sub_I_mylib_cpp
.init_array:0000000000003DB0 _init_array     ends	

雖然動態(tài)庫也可以避免剔除沒引用的對象文件,但引入了運行時鏈接的麻煩

小技巧

add_library 無參數(shù)

add_library 無參數(shù)時,是靜態(tài)庫還是動態(tài)庫?

會根據(jù) BUILD_SHARED_LIBS 這個變量的值決定是動態(tài)庫還是靜態(tài)庫。ON 則相當(dāng)于 SHARED,OFF 則相當(dāng)于 STATIC。如果未指定 BUILD_SHARED_LIBS 變量,則默認為 STATIC。

因此,如果發(fā)現(xiàn)一個項目里的 add_library 都是無參數(shù)的,意味著你可以用:cmake -B build -DBUILD_SHARED_LIBS:BOOL=ON 來讓他全部生成為動態(tài)庫。稍后會詳解命令行傳遞變量的規(guī)則。

設(shè)定一個變量的默認值

要讓 BUILD_SHARED_LIBS 默認為 ON,可以用下圖這個方法:
如果該變量沒有定義,則設(shè)為 ON,否則保持用戶指定的值不變。
這樣當(dāng)用戶沒有指定 BUILD_SHARED_LIBS 這個變量時,會默認變成 ON。
也就是說除非用戶指定了 -DBUILD_SHARED_LIBS:BOOL=OFF 才會生成靜態(tài)庫,否則默認是生成動態(tài)庫。

if (NOT DEFINED BUILD_SHARED_LIBS)
	set(BUILD_SHARED_LIBS ON)
endif()

常見坑點

動態(tài)庫無法鏈接靜態(tài)庫(3.22.1 可以正常鏈接)

add_library(otherlib STATIC otherlib.cpp)

add_library(mylib SHARED mylib.cpp)

target_link_libraries(mylib PUBLIC otherlib)

add_executable(main main.cpp)
target_link_libraries(main PUBLIC mylib)

讓靜態(tài)庫編譯時也生成位置無關(guān)的代碼(PIC),這樣才能裝在動態(tài)庫里

也可以只針對一個庫,只對他啟用位置無關(guān)的代碼(PIC)文章來源地址http://www.zghlxwxcb.cn/news/detail-434369.html

add_library(otherlib STATIC otherlib.cpp)
set_property(TARGET otherlib PROPERTY POSITION_INDEPENDENT_CODE ON)

add_library(mylib SHARED mylib.cpp)

target_link_libraries(mylib PUBLIC otherlib)

add_executable(main main.cpp)
target_link_libraries(main PUBLIC mylib)

到了這里,關(guān)于現(xiàn)代CMake高級教程 - 第 3 章:鏈接庫文件的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • ESP32工程中CMake使用及加入第三方SDK庫文件

    ESP32工程中CMake使用及加入第三方SDK庫文件

    ? ? ? ? 本文中使用的是樂鑫官方推出的 ESP-IDF v5.1 對 ESP32S3 設(shè)備開發(fā),并非是Arduino、Micro-python等第三方工具開發(fā)。在ESP-IDF框架中,樂鑫官方已經(jīng)將 CMake 和 Ninja 編譯構(gòu)建工具 集成到了ESP-IDF中。 ????????ESP-IDF 即樂鑫物聯(lián)網(wǎng)開發(fā)框架,可為在 Windows、Linux 和 macOS 系統(tǒng)平臺

    2024年02月20日
    瀏覽(99)
  • 現(xiàn)代CMake高級教程 - 第 5 章:鏈接第三方庫

    雙笙子佯謬老師的【公開課】現(xiàn)代CMake高級教程課程筆記 案例 使用 tbb 庫 main.cpp 直接鏈接 tbb CMakeLists.txt 直接鏈接 tbb 的缺點: 如果這樣直接指定 tbb,CMake 會讓鏈接器在系統(tǒng)的庫目錄里查找 tbb,他會找到 /usr/lib/libtbb.so 這個系統(tǒng)自帶的,但這對于沒有一個固定庫安裝位置的

    2024年02月02日
    瀏覽(88)
  • windows執(zhí)行完LoadLibrary()后,可以刪除源動態(tài)庫文件,函數(shù)不會鎖庫文件

    windows執(zhí)行完LoadLibrary()后,可以刪除源動態(tài)庫文件,函數(shù)不會鎖庫文件。 運行結(jié)果:

    2024年02月13日
    瀏覽(26)
  • 【Linux基礎(chǔ)】庫文件

    (??? ),hello我是 祐言 博客主頁:C語言基礎(chǔ),Linux基礎(chǔ),軟件配置領(lǐng)域博主?? 快上??,一起學(xué)習(xí)! 送給讀者的一句雞湯??: 集中起來的意志可以擊穿頑石! 作者水平很有限,如果發(fā)現(xiàn)錯誤,可在評論區(qū)指正,感謝?? ?? ????????在Linux系統(tǒng)中,庫文件(Library files)是一

    2024年02月16日
    瀏覽(25)
  • 【實用技巧】更改ArduinoIDE默認庫文件位置,解放系統(tǒng)盤,將Arduino15中的庫文件移動到其他磁盤

    【實用技巧】更改ArduinoIDE默認庫文件位置,解放系統(tǒng)盤,將Arduino15中的庫文件移動到其他磁盤

    本文主要介紹更改Arduino IDE (含2.0以上版本)默認庫文件位置的方法。 ?原創(chuàng)文章,轉(zhuǎn)載請注明出處: 【實用技巧】更改ArduinoIDE默認庫文件位置,解放C盤,將Arduino15中的庫文件移動到其他磁盤-CSDN博客 文章瀏覽閱讀185次。本文主要介紹更改Arduino IDE (含2.0以上版本)默認庫

    2024年02月03日
    瀏覽(21)
  • linux下頭文件及庫文件搜索路徑知識匯總

    跟gcc相關(guān)的搜索目錄: 安裝gcc時,如果有指定prefix的話,那么系統(tǒng)的默認搜索路徑為: C_INCLUDE_PATH:編譯 C 程序的時候使用的環(huán)境變量 CPLUS_INCLUDE_PATH:編譯 C++ 程序的時候使用的環(huán)境變量 CPATH:編譯 C、 C++及Objective-C 程序時使用的環(huán)境變量 OBJC_INCLUDE_PATH:編譯 Objective-C 程序

    2023年04月27日
    瀏覽(57)
  • C標準庫文件&常用函數(shù)

    編號 頭文件 C標準版本 介紹 1 assert.h C89/C90 條件編譯宏,將參數(shù)與零比較 2 ctype.h C89/C90 用來確定包含于字符數(shù)據(jù)中的類型的函數(shù) 3 errno.h C89/C90 報告錯誤條件的宏 4 float.h C89/C90 浮點數(shù)類型的極限 5 limits.h C89/C90 基本類型的大小 6 locale.h C89/C90 本地化工具 7 math.h C89/C90 常用數(shù)據(jù)函

    2024年02月12日
    瀏覽(18)
  • C++有哪些常用的庫文件

    常用庫文件: iostream: ?輸入輸出流庫,包含cin、cout、cerr等標準輸入輸出對象。 string : 字符串庫,包含字符串類型std::string及相關(guān)操作函數(shù)。 vector : 動態(tài)數(shù)組庫,包含vector類型及相關(guān)操作函數(shù)。 map: ?字典庫,包含map、multimap、set、multiset等關(guān)聯(lián)容器類型及相關(guān)操作函數(shù)。 algorithm

    2024年02月02日
    瀏覽(25)
  • 現(xiàn)代CMake高級教程 - 第 7 章:變量與緩存

    現(xiàn)代CMake高級教程 - 第 7 章:變量與緩存

    雙笙子佯謬老師的【公開課】現(xiàn)代CMake高級教程課程筆記 重復(fù)執(zhí)行 cmake -B build 會有什么區(qū)別? 可以看到第二次的輸出少了很多,這是因為 CMake 第一遍需要檢測編譯器和 C++ 特性等比較耗時,檢測完會把結(jié)果存儲到緩存中,這樣第二遍運行 cmake -B build 時就可以直接用緩存的值

    2024年02月02日
    瀏覽(23)
  • 7-LINUX--庫文件的生成與使用

    7-LINUX--庫文件的生成與使用

    庫是一組預(yù)先編譯好的方法的集合。Linux系統(tǒng)存儲的庫的位置一般在:/lib 和 /usr/lib。 在 64 位的系統(tǒng)上有些庫也可能被存儲在/usr/lib64 下。庫的頭文件一般會被存儲在 /usr/include 下或其子目錄下。 庫有兩種,一種是靜態(tài)庫,其命令規(guī)則為 libxxx.a,一種是共享庫,其命令規(guī)則為

    2024年03月16日
    瀏覽(31)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包