編譯工具:CMake(三)| 最簡單的實例升級

編譯工具:CMake(三)| 最簡單的實例升級

  • 前言
  • 過程
    • 語法解釋
      • ADD_SUBDIRECTORY 指令
    • 如何安裝
      • 目標文件的安裝
      • 普通文件的安裝:
      • 非目標文件的可執行程序安裝(比如腳本之類)
      • 目錄的安裝
  • 修改 Helloworld 支持安裝
  • 測試

在這里插入圖片描述

前言

本篇博客的任務是讓前面的 Hello World 更像一個工程,我們需要作的是:

  • 為工程添加一個子目錄 src,用來放置工程源代碼;
  • 添加一個子目錄 doc,用來放置這個工程的文檔 hello.txt
  • 在工程目錄添加文本文件 COPYRIGHT, README;
  • 在工程目錄添加一個 runhello.sh 腳本,用來調用 hello 二進制
  • 將構建后的目標文件放入構建目錄的 bin 子目錄;
  • 最終安裝這些文件:將 hello 二進制與 runhello.sh 安裝至/usr/bin,將 doc 目錄的內容以及 COPYRIGHT/README 安裝到/usr/share/doc/cmake/test2

過程

在/Compilation_tool/cmake/目錄下建立 test2 目錄。
將 test1 工程的 main.c 和 CMakeLists.txt 拷貝到 test2 目錄中。

添加子目錄 src
將main.c文件移動到src文件夾

mkdir src
mv main.c src

現在的工程是這個樣子:
一個子目錄 src,一個 CMakeLists.txt。
在這里插入圖片描述
CMake要求為任何子目錄建立一個CMakeLists.txt

所以進入src子目錄,編寫CMakeLists.txt如下:

ADD_EXECUTABLE(hello main.c)

將test2工程的CMakeLists.txt修改為:

PROJECT(HELLO)
ADD_SUBDIRECTORY(src bin)

然后建立 build 目錄,進入 build 目錄進行外部編譯。

mkdir build
cd build
cmake ..
make

構建完成后,你會發現生成的目標文件 hello 位于 build/bin 目錄中。
在這里插入圖片描述

語法解釋

ADD_SUBDIRECTORY 指令

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

這個指令用于向當前工程添加存放源文件的子目錄,并可以指定中間二進制和目標二進制存放的位置。

EXCLUDE_FROM_ALL 參數的含義是將這個目錄從編譯過程中排除,比如,工程的 example,可能就需要工程構建完成后,再進入 example 目錄單獨進行構建(當然,也可以通過定義依賴來解決此類問題)。

上面的例子定義了將 src 子目錄加入工程,并指定編譯輸出(包含編譯中間結果)路徑為bin 目錄。

如果不進行 bin 目錄的指定,那么編譯結果(包括中間結果)都將存放在build/src 目錄(這個目錄跟原有的 src 目錄對應),

指定 bin 目錄后,相當于在編譯時將 src 重命名為 bin,所有的中間結果和目標二進制都將存放在 bin 目錄。

換個地方保存目標二進制
ADD_SUBDIRECTORY 指令(不論是否指定編譯輸出目錄),可以通過 SET 指令重新定義EXECUTABLE_OUTPUT_PATHLIBRARY_OUTPUT_PATH 變量,來指定最終的目標二進制的位置(指最終生成的 hello 或者最終的共享庫,不包含編譯生成
的中間文件)

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

<projectname>_BINARY_DIR PROJECT_BINARY_DIR 變量,他們指的編譯發生的當前目錄,如果是內部編譯,就相當于 PROJECT_SOURCE_DIR 也就是工程代碼所在目錄,如果是外部編譯,指的是外部編譯所在目錄,也就是本例中的 build
目錄。

所以,上面兩個指令分別定義了:可執行二進制的輸出路徑為 build/bin 和庫的輸出路徑為 build/lib.
應該把這兩條指令寫在工程的 CMakeLists.txt 還是 src 目錄下的CMakeLists.txt,把握一個簡單的原則,在哪里 ADD_EXECUTABLEADD_LIBRARY,如果需要改變目標存放路徑,就在哪里加入上述的定義。
在這個例子里,當然就是指 src 下的 CMakeLists.txt 了。

如何安裝

安裝的需要有兩種,一種是從代碼編譯后直接 make install 安裝,一種是打包時的指定目錄安裝。

HelloWorld 進行安裝需要引入一個新的 cmake 指令INSTALL 和一個非常有用的變量CMAKE_INSTALL_PREFIX

CMAKE_INSTALL_PREFIX變量類似于 configure 腳本的 – prefix

常見的使用方法是這個樣子:

cmake -DCMAKE_INSTALL_PREFIX=/usr 

INSTALL 指令用于定義安裝規則,安裝的內容可以包括目標二進制、動態庫、靜態庫以及文件、目錄、腳本等。

INSTALL 指令包含了各種安裝類型,分開解釋如下:

目標文件的安裝

INSTALL(TARGETS targets...[[ARCHIVE|LIBRARY|RUNTIME][DESTINATION <dir>][PERMISSIONS permissions...][CONFIGURATIONS[Debug|Release|...]][COMPONENT <component>][OPTIONAL]] [...])

參數中的 TARGETS 后面跟的就是我們通過 ADD_EXECUTABLE 或者ADD_LIBRARY定義的目標文件,可能是可執行二進制、動態庫、靜態庫。

目標類型也就相對應的有三種,ARCHIVE 特指靜態庫,LIBRARY 特指動態庫,RUNTIME特指可執行目標二進制。

DESTINATION 定義了安裝的路徑,如果路徑以/開頭,那么指的是絕對路徑,這時候CMAKE_INSTALL_PREFIX 其實就無效了。如果你希望使用 CMAKE_INSTALL_PREFIX 來定義安裝路徑,就要寫成相對路徑,即不要以/開頭,那么安裝后的路徑就是

${CMAKE_INSTALL_PREFIX}/<DESTINATION 定義的路徑>

舉個簡單的例子:

INSTALL(TARGETS myrun mylib mystaticlibRUNTIME DESTINATION binLIBRARY DESTINATION libARCHIVE DESTINATION libstatic)

上面的例子會將:
可執行二進制 myrun 安裝到${CMAKE_INSTALL_PREFIX}/bin 目錄
動態庫 libmylib 安裝到${CMAKE_INSTALL_PREFIX}/lib 目錄
靜態庫 libmystaticlib 安裝到${CMAKE_INSTALL_PREFIX}/libstatic 目錄

特別注意的是不需要關心 TARGETS 具體生成的路徑,只需要寫上 TARGETS 名稱就可以了。

普通文件的安裝:

INSTALL(FILES files... DESTINATION <dir>[PERMISSIONS permissions...][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>][RENAME <name>] [OPTIONAL])

可用于安裝一般文件,并可以指定訪問權限,文件名是此指令所在路徑下的相對路徑。如果默認不定義權限 PERMISSIONS,安裝后的權限為:OWNER_WRITE, OWNER_READ,GROUP_READ,和 WORLD_READ,即 644 權限。

非目標文件的可執行程序安裝(比如腳本之類)

INSTALL(PROGRAMS files... DESTINATION <dir>
[PERMISSIONS permissions...]
[CONFIGURATIONS [Debug|Release|...]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL])

跟上面的 FILES 指令使用方法一樣,唯一的不同是安裝后權限為:
OWNER_EXECUTE, GROUP_EXECUTE, 和 WORLD_EXECUTE,即 755 權限

目錄的安裝

INSTALL(DIRECTORY dirs... DESTINATION <dir>[FILE_PERMISSIONS permissions...][DIRECTORY_PERMISSIONS permissions...][USE_SOURCE_PERMISSIONS][CONFIGURATIONS [Debug|Release|...]][COMPONENT <component>][[PATTERN <pattern> | REGEX <regex>][EXCLUDE] [PERMISSIONS permissions...]] [...])

這里主要介紹其中的 DIRECTORYPATTERN 以及PERMISSIONS參數。
DIRECTORY 后面連接的是所在 Source 目錄的相對路徑,但務必注意:
abc 和 abc/有很大的區別。如果目錄名不以/結尾,那么這個目錄將被安裝為目標路徑下的 abc,如果目錄名以/結尾,
代表將這個目錄中的內容安裝到目標路徑,但不包括這個目錄本身。PATTERN用于使用正則表達式進行過濾,PERMISSIONS 用于指定 PATTERN 過濾后的文件權限。

修改 Helloworld 支持安裝

添加 doc 目錄及文件:

cd /Compilation_tool/cmake/test2
mkdir doc
vi doc/hello.txt

隨便填寫一些內容并保存

在工程目錄添加 runhello.sh 腳本,內容為:

hello

添加工程目錄中的 COPYRIGHT 和 README
touch COPYRIGHT
touch README

下面改寫各目錄的 CMakeLists.txt 文件。

1、安裝 COPYRIGHT/README,直接修改主工程文件 CMakelists.txt,加入以下指令:

INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/t2)

2、安裝 runhello.sh,直接修改主工程文件 CMakeLists.txt,加入如下指令:

INSTALL(PROGRAMS runhello.sh DESTINATION bin)

3、安裝 doc 中的 hello.txt
因為 hello.txt 要安裝到//share/doc/cmake/t2,所以我們不能直接安裝整個 doc 目錄,這里采用的方式是安裝 doc 目錄中的內容,也就是使用 ” doc/” 在工程文件中添加

INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/t2)

測試

現在進入 build 目錄進行外部編譯,注意使用 CMAKE_INSTALL_PREFIX 參數,這里我們將它安裝到了/tmp/t2 目錄:

cmake -DCMAKE_INSTALL_PREFIX=/tmp/t2/usr ..

然后運行

make
make install

這時候在計算機的 tmp路徑下就多了 t2 文件夾
t2的目錄為
在這里插入圖片描述

如果你要直接安裝到系統,可以使用如下指令:

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

如果沒有定義CMAKE_INSTALL_PREFIX會安裝到什么地方?
CMAKE_INSTALL_PREFIX 的默認定義是/usr/local

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39098.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39098.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39098.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

utf-8和utf-8 mb4區別

UTF-8&#xff08;Unicode Transformation Format-8&#xff09;和UTF-8MB4&#xff08;UTF-8 Multibyte 4-byte&#xff09;是字符編碼方案&#xff0c;用于表示 Unicode 字符集中的字符。它們之間的主要區別在于編碼范圍。 UTF-8&#xff1a;UTF-8 是一種變長編碼方式&#x…

可視化繪圖技巧100篇進階篇(七)-三維堆積柱形圖(3D Stacked Bar Chart)

目錄 前言 適用場景 圖例 繪圖工具及代碼實現 HighCharts echarts MATLAB

學習Vue:安裝Vue.js和設置開發環境

當您決定進入現代前端開發的世界&#xff0c;Vue.js 無疑是一個令人激動的選擇。它以其簡潔、靈活和高效的特點在開發者社區中備受贊譽。本文將為您詳細介紹如何安裝 Vue.js 并設置開發環境&#xff0c;讓您能夠迅速開始編寫 Vue 應用程序。 步驟1&#xff1a;安裝 Node.js 和 …

解決右鍵打印html只能識別1頁的問題

hello,大家好久不見,昨天在開發中遇到了一個問題,就是在自己開發的網頁中右鍵-->打印&#xff0c;由于頁面內容過多&#xff0c;打印出來的內容只被識別到一頁。 針對這一問題&#xff0c;查閱了好多資料最終解決啦。 1.問題重現 大家可以看到這個是我們開發的頁面,公司需要…

CentOS系統環境搭建(六)——使用docker-compose安裝redis

centos系統環境搭建專欄&#x1f517;點擊跳轉 關于Docker-compose安裝請看CentOS系統環境搭建&#xff08;三&#xff09;——Centos7安裝Docker&Docker Compose&#xff0c;該文章同樣收錄于centos系統環境搭建專欄。 Docker-compose安裝redis 文章目錄 Docker-compose安…

2023最新最全最細版本~ESP8266/ESP01S燒錄AT固件

硬件準備 圖上有兩種型號的模塊均可刷寫AT固件 ① ESP01S ② ESP8266NODEMCU 軟件準備(私聊免費分享) ESP01S1燒錄方式 如圖使用模塊燒錄座的方式~ 模塊插入燒錄座后直接連接電腦的USB接口即可~ ESP8266NODEMCU燒錄方式 如圖usb直接連接的方式~ 一端接模塊的USB口&…

數據暴漲時代,該如何數據治理?_光點科技

隨著信息技術的迅猛發展&#xff0c;數據已經成為現代社會的核心資源。在這個被稱為"數據暴漲時代"的時代里&#xff0c;大量的數據源源不斷地被產生和積累&#xff0c;但如何有效地管理、分析和利用這些數據成為了一個迫切需要解決的問題。數據治理&#xff0c;作為…

【Spring源碼】Spring擴展點及順序

Spring擴展點及順序 01-調用BeanFactoryPostProcessor的構造器 02-調用了BeanFactoryPostProcessor的postProcessBeanFactory 03-調用了BeanPostProcessor構造器 04-調用InstantiationAwareBeanPostProcessor構造方法 05-調用了InstantiationAwareBeanPostProcessor接口的Befo…

Memory Analyzer(MAT)分析內存

關于作者&#xff1a;CSDN內容合伙人、技術專家&#xff0c; 從零開始做日活千萬級APP。 專注于分享各領域原創系列文章 &#xff0c;擅長java后端、移動開發、人工智能等&#xff0c;希望大家多多支持。 目錄 一、導讀二、概覽三、 使用3.1 hprof 文件準備3.1.1 Android sutdi…

【SpringBoot學習筆記】04. Thymeleaf模板引擎

模板引擎 所有的html元素都可以被thymeleaf替換接管 th:元素名 templates下的只能通過Controller來跳轉&#xff0c;templates前后端分離&#xff0c;需要模板引擎thymeleaf支持 模板引擎的作用就是我們來寫一個頁面模板&#xff0c;比如有些值呢&#xff0c;是動態的&#x…

cuda+anaconda+pytorch按照教程

首先安裝顯卡對應的CUDA版本&#xff0c;關鍵點在于區別顯卡支持的CUDA最高版本和運行版本 1、查看當前顯卡支持的最高版本&#xff0c;有兩種方式&#xff1a; 1&#xff09;NVIDIA控制面板—>幫助—>系統信息—>組件—>NVCUDA.dll對應版本 請注意&#xff0c;12…

2023年國賽數學建模思路 - 案例:ID3-決策樹分類算法

文章目錄 0 賽題思路1 算法介紹2 FP樹表示法3 構建FP樹4 實現代碼 建模資料 0 賽題思路 &#xff08;賽題出來以后第一時間在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 算法介紹 FP-Tree算法全稱是FrequentPattern Tree算法&#xff0c;就是頻繁模…

項目:基于UDP的TFTP文件傳輸

1&#xff09;tftp協議概述 簡單文件傳輸協議&#xff0c;適用于在網絡上進行文件傳輸的一套標準協議&#xff0c;使用UDP傳輸特點&#xff1a; 是應用層協議 基于UDP協議實現 數據傳輸模式 octet&#xff1a;二進制模式&#xff08;常用&#xff09; mail&#xff1a;已經不再…

分布式 - 服務器Nginx:一小時入門系列之代理緩沖與緩存

官方文檔&#xff1a;https://nginx.org/en/docs/http/ngx_http_proxy_module.html 1. 代理緩沖 proxy_buffer 代理緩沖用于臨時存儲從后端服務器返回的響應數據。通過使用代理緩沖&#xff0c;Nginx可以在接收完整的響應后再將其發送給客戶端&#xff0c;從而提高性能和效率…

docker版jxTMS使用指南:使用jxTMS采集數據之三

本文是如何用jxTMS進行數據采集的第三部分&#xff0c;整個系列的文章請查看&#xff1a;docker版jxTMS使用指南&#xff1a;4.4版升級內容 docker版本的使用&#xff0c;請查看&#xff1a;docker版jxTMS使用指南 4.0版jxTMS的說明&#xff0c;請查看&#xff1a;4.0版升級內…

LeetCode 2682. 找出轉圈游戲輸家

【LetMeFly】2682.找出轉圈游戲輸家 力扣題目鏈接&#xff1a;https://leetcode.cn/problems/find-the-losers-of-the-circular-game/ n 個朋友在玩游戲。這些朋友坐成一個圈&#xff0c;按 順時針方向 從 1 到 n 編號。從第 i 個朋友的位置開始順時針移動 1 步會到達第 (i …

照耀國產的星火,再度上新!

國產之光&#xff0c;星火閃耀 ? 新時代的星火? 多模態能力? 圖像生成與虛擬人視頻生成? 音頻生成與OCR筆記收藏? 助手模式更新? 插件能力? 代碼能力? 寫在最后 ? 新時代的星火 在這個快速變革的時代&#xff0c;人工智能正迅猛地催生著前所未有的革命。從醫療到金融…

使用老北鼻AI免費GPT對話解決gun make安裝和解析iso9660的問題

在學習解析ISO9660鏡像文件時&#xff0c;使用了GPT來了解相關的庫和gun make編譯器的相關知識。這個過程可真是一言難盡&#xff0c;每個問題的回答都模棱兩可都需要去證實&#xff0c;不能直接復制粘貼&#xff0c;也不能說GPT的回答一點用也沒有&#xff0c;至少GPT給出了一…

自然語言處理從入門到應用——LangChain:記憶(Memory)-[聊天消息記錄]

分類目錄&#xff1a;《自然語言處理從入門到應用》總目錄 Cassandra聊天消息記錄 Cassandra是一種分布式數據庫&#xff0c;非常適合存儲大量數據&#xff0c;是存儲聊天消息歷史的良好選擇&#xff0c;因為它易于擴展&#xff0c;能夠處理大量寫入操作。 # List of contact…

Android 學習筆記:SharedPreferences實現數據的保存和讀取

一、概述 1.鍵值對方式存儲 SharedPreferences 是使用鍵值對的方式來存儲數據的。也就是說&#xff0c;當保存一條數據的時候&#xff0c;需要給這條數據提供一個對應的鍵&#xff0c;這樣在讀取數據的時候就可以通過這個鍵把相應的值取出來。 2.支持多種不同的數據類型存儲…