欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

cmake跨平臺(tái)構(gòu)建工具的學(xué)習(xí)筆記

 更新時(shí)間:2023年02月06日 14:37:33   作者:謎一樣的男人1  
CMake是一個(gè)跨平臺(tái)的安裝/編譯工具,通過CMake我們可以通過簡單的語句來描述所有平臺(tái)的安裝/編譯過程,下面這篇文章主要給大家介紹了關(guān)于cmake跨平臺(tái)構(gòu)建工具的相關(guān)資料,需要的朋友可以參考下

前言

CMake是一個(gè)跨平臺(tái)的安裝編譯工具,可以用簡單的語句來描述所有平臺(tái)的安裝(編譯過程)。

CMake可以說已經(jīng)成為大部分C++開源項(xiàng)目標(biāo)配

因此,作為一名C C++發(fā)開人員,看到cmake不應(yīng)該一臉茫然…

作為初學(xué)者,通俗的認(rèn)為cmake就是一個(gè)linux下自動(dòng)構(gòu)建makefile等文件的實(shí)用工具!

廣泛使用cmake的原因: 跨平臺(tái)開發(fā)方便共享操作,使寫Makefile更簡便;

跨平臺(tái)開發(fā)

假設(shè)有一個(gè)跨平臺(tái)項(xiàng)目,其中C++代碼可能會(huì)在不同的OS系統(tǒng)/IDE上共享;

Win下的VSLinux下的gccMAC下的Xcode

當(dāng)我們想添加一個(gè)bar.cpp 的源文件,我們就需要將其添加到各種OS使用的每個(gè)工具中:

為了保持運(yùn)行環(huán)境的一致性,則必須多次進(jìn)行類似的更新,還必須手動(dòng)執(zhí)行(在本例中,圖中用紅色標(biāo)記的箭頭)。

這種方法因?yàn)槭謩?dòng)也容易出錯(cuò),而且不靈活。

CMake通過在開發(fā)過程中添加額外的步驟解決這個(gè)設(shè)計(jì)缺陷

您可以在CMakeLists.txt文件中描述您的項(xiàng)目,并使用CMake自動(dòng)生成構(gòu)建項(xiàng)目的工具,使用跨平臺(tái)CMake代碼:

同樣的操作-添加新的bar.cpp文件,現(xiàn)在只需一步即可完成:

跨平臺(tái)的性質(zhì)沒有變,照樣有很多不同的OS在共享代碼,但是只需要一個(gè)cmake可以很好地維護(hù)起來;

CMake語法特性

基本語法格式:指令(參數(shù) 1 參數(shù) 2…)

  • 參數(shù)使用括號括起
  • 參數(shù)之間使用空格分號分開(這里有點(diǎn)違背我們用逗號分隔參數(shù)的習(xí)慣)

指令是大小寫無關(guān)的,參數(shù)和變量是大小寫相關(guān)的

語法指令部分有點(diǎn)像SQL,是大小寫無關(guān)的

set(HELLO hello.cpp) # 設(shè)置變量HELLO的函數(shù),后續(xù)會(huì)介紹
# 下面兩條指令等價(jià)
add_executable(hello main.cpp hello.cpp)
ADD_EXECUTABLE(hello main.cpp ${HELLO})

變量使用${}方式取值,但是在 if 條件控制語句中應(yīng)直接使用變量名

CMake重要指令和常用變量

重要指令

cmake版本,項(xiàng)目工程,變量的設(shè)置:

cmake_minimum_required - 指定CMake的最小版本要求

# 語法:cmake_minimum_required(VERSION versionNumber [FATAL_ERROR])

# CMake最小版本要求為2.8.3
2cmake_minimum_required(VERSION 2.8.3)

linux下 cmake --version查看自己的cmake版本

project - 定義工程名稱,并可指定工程支持的語言

# 語法:project(projectname [CXX] [C] [Java])   -- 方框中的為可選項(xiàng)

# 指定工程名為HELLOWORLD
project(HELLOWORLD)

set - 顯式的定義變量

# 語法:set(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])

# 定義SRC變量,其值為main.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)  #注意參數(shù)之間 空格/;  分隔哦!

頭文件的設(shè)置,庫文件的路徑,庫文件的生成,庫文件的鏈接:

include_directories - 向工程添加多個(gè)特定的 頭 文 件 搜索路徑 —>相當(dāng)于指定g++編譯器的-I(大寫i)參數(shù)

(有了動(dòng)態(tài)庫和靜態(tài)庫,當(dāng)然有對應(yīng)他的頭文件了)

# 語法:include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2 …)

# 將/usr/include/myincludefolder 和 ./include 添加到頭文件搜索路徑中
include_directories(/usr/include/myincludefolder ./include)

link_directories - 向工程添加多個(gè)特定的 庫 文 件 搜索路徑 —>相當(dāng)于指定g++編譯器的-L參數(shù)

# 語法:link_directories(dir1 dir2 …)  

# 將/usr/lib/mylibfolder 和 ./lib 添加到庫文件搜索路徑中
link_directories(/usr/lib/mylibfolder ./lib)

add_library - 生成共享庫文件

# 語法:add_library(libname [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 … sourceN)

# 通過變量 SRC 生成 libhello.so 共 享 動(dòng)態(tài)庫hello,通過 (SHARED | STATIC)來選擇
add_library(hello SHARED ${SRC})

# 通過src/Swap.cpp 生成 libswap_library.a 共 享 靜態(tài)庫swap_library,通過 (SHARED | STATIC)來選擇
add_library( swap_library STATIC src/Swap.cpp )

target_link_libraries - 為 target 添加需要鏈接的共享庫 —>相同于指定g++編譯器-l(小L)參數(shù)

# 語法:target_link_libraries(target library1library2…)

# 將hello動(dòng)態(tài)庫文件鏈接到可執(zhí)行文件main
target_link_libraries(main hello)

編譯參數(shù)選擇,編譯生成exe:

add_compile_options - 添加編譯參數(shù) -->相當(dāng)于g++編譯器 -std=c++11 -O2…

# 語法:add_compile_options(xxxx);

# 添加編譯參數(shù)  -std=c++11 -O2
add_compile_options(-std=c++11 -O2)

add_executable - 生成可執(zhí)行文件(最重要的一步,如果沒可執(zhí)行程序怎么運(yùn)行?)

# 語法:**add_library(exename source1 source2 … sourceN)**

# 編譯main.cpp生成可執(zhí)行文件main
add_executable(main main.cpp)

其他工程源文件管理等雜項(xiàng):

add_subdirectory - 向當(dāng)前工程 添加 存放源文件的子目錄,并可以指定中間二進(jìn)制和目標(biāo)二進(jìn)制存放的位置 – 多目錄工程

# 語法:add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

# 添加src子目錄,src中需有一個(gè)CMakeLists.txt
add_subdirectory(src)

aux_source_directory - 發(fā)現(xiàn)一個(gè)目錄下 所有的源代碼文件 并將列表 存儲(chǔ)在 一個(gè) 變量中,這個(gè)指令臨時(shí)被用來自動(dòng)構(gòu)建源文件列表

# 語法:aux_source_directory(dir VARIABLE)

# 定義SRC變量,其值為當(dāng)前目錄下所有的源代碼文件
aux_source_directory(. SRC)
#配合src, 編譯SRC變量所代表的源代碼文件,生成main可執(zhí)行文件
add_executable(main ${SRC})

常用變量

CMAKE_C_FLAGS gcc編譯選項(xiàng)

CMAKE_CXX_FLAGS g++編譯選項(xiàng)

# 利用set(), 在CMAKE_CXX_FLAGS編譯選項(xiàng)后追加-std=c++11
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

CMAKE_BUILD_TYPE 編譯類型(Debug, Release)

#利用set(), 設(shè)定編譯類型為debug,調(diào)試時(shí)需要選擇debug
set(CMAKE_BUILD_TYPE Debug) 

# 設(shè)定編譯類型為release,發(fā)布時(shí)需要選擇release
set(CMAKE_BUILD_TYPE Release) 

下面幾個(gè)自己玩:

  • CMAKE_C_COMPILER:指定C編譯器
  • CMAKE_CXX_COMPILER:指定C++編譯器
  • EXECUTABLE_OUTPUT_PATH:可執(zhí)行文件輸出的存放路徑
  • LIBRARY_OUTPUT_PATH:庫文件輸出的存放路徑

下面幾個(gè)了解一下:

  • CMAKE_BINARY_DIR
  • PROJECT_BINARY_DIR
  • <projectname>__BINARY_DIR

這三個(gè)變量指代的內(nèi)容是一致的。

如果是 in source build(內(nèi)部構(gòu)建),指的就是工程頂層目錄。

如果是 out-of-source(外部構(gòu)建 --推薦使用), 指的是工程編譯發(fā)生的目錄

PROJECT_BINARY_DIR 跟其他指令稍有區(qū)別,不過現(xiàn)在,你可以理解為他們是一致的。

CMAKE_SOURCE_DIR

PROJECT_SOURCE_DIR

<projectname>__SOURCE_DIR

這三個(gè)變量指代的內(nèi)容是一致的,不論采用何種編譯方式,都是工程頂層目錄

也就是在 in source build時(shí),他跟 CMAKE_BINARY_DIR 等變量一致。

PROJECT_SOURCE_DIR 跟其他指令稍有區(qū)別,現(xiàn)在,你可以理解為他們是一致的。

CMake編譯工程

CMake目錄結(jié)構(gòu):項(xiàng)目主目錄(各種.c.h等源碼的項(xiàng)目目錄),存在一個(gè)CMakeLists.txt文件

兩種方式設(shè)置編譯規(guī)則

包含源文件的子文件夾包含CMakeLists.txt文件,主目錄的CMakeLists.txt通過add_subdirectory添加子目錄(這個(gè)子目錄也包含一個(gè)CMakeLists.txt)即可;

-相當(dāng)于 多目錄 的工程,好多目錄有好多.c .h

包含源文件的子文件夾未包含CMakeLists.txt文件,子目錄編譯規(guī)則就只體現(xiàn)在主目錄的CMakeLists.txt中;

相當(dāng)于只有一個(gè)主目錄的CMakeLists.txt文件 – 單目錄工程;

兩種構(gòu)建方式 內(nèi)部構(gòu)建(in-source build):不推薦使用

內(nèi)部構(gòu)建會(huì)在源文件的同級目錄下產(chǎn)生一大堆中間文件,這些中間文件并不是我們最終所需要的,和工程源文件放在一起會(huì)顯得雜亂無章

## 內(nèi)部構(gòu)建
# 在當(dāng)前項(xiàng)目主目錄下,編譯本目錄的CMakeLists.txt,生成Makefile等文件

cmake .    # 在哪個(gè)目錄下調(diào)用cmake,生成的中間文件就會(huì)存在這個(gè)目錄下,和CMakeLists.txt位置無關(guān)

# 執(zhí)行make命令,生成target可執(zhí)行程序
make

外部構(gòu)建(out-of-source build):推薦使用

編譯輸出文件源文件放到不同目錄中,這樣源文件中的代碼結(jié)構(gòu)不會(huì)變化太多,清晰明了;

## 外部構(gòu)建
# 1. 在當(dāng)前目錄下,創(chuàng)建build文件夾
mkdir build 

# 2. 進(jìn)入到build文件夾
cd build
 
# 3. 編譯上級目錄的CMakeLists.txt,生成Makefile和其他文件

cmake ..   # 在哪個(gè)目錄下調(diào)用cmake,生成的中間文件就會(huì)存在這個(gè)目錄下,和CMakeLists.txt位置無關(guān)

# 4. 執(zhí)行make命令,生成target
make

編譯實(shí)戰(zhàn)

hello.hpp

#pragma once
#include<iostream>
using namespace std;
void Print()
{
    cout<<"Hello CMake!"<<endl;
}

test.cpp

#include"hello.hpp"

int main()
{
    Print();
    return 0;
}

可以看到,我們目的是main調(diào)用hello.hpp里的Print()函數(shù),打印Hello CMake;

這里將hello.hpp文件放在 與test.cpp源文件同級目錄的inculde目錄下;

這樣#include"hello.hpp"如果不指定include目錄就會(huì)找不到; (正確寫法:#include"./include/hello.hpp")

CMakeLists.txt

這里也能體現(xiàn)出來cmake簡化了構(gòu)建Makefile的過程(項(xiàng)目越大,越復(fù)雜 cmake的簡化作用越明顯)!

cmake_minimum_required(VERSION 2.8) #指定最小版本
project(HelloCMake) #指定工程名字
include_directories(./include) #添加頭文件路徑 -->等價(jià)于 g++ xxx -Iinclude
add_executable(hello test.cpp) #編譯生成可執(zhí)行程序 -->等價(jià)于g++ -o hello test.cpp

內(nèi)部構(gòu)建

當(dāng)前目錄結(jié)構(gòu):

我們在當(dāng)前目錄下直接運(yùn)行:cmake . 生成 Makefile,并且make,運(yùn)行程序:

運(yùn)行后的源文件主目錄結(jié)構(gòu):

可以看到,內(nèi)部構(gòu)建除了之前的工程源文件之外,多了一些cmake編譯產(chǎn)生的中間文件,工程業(yè)務(wù)龐大可能會(huì)造成混淆,所以我們不建議這種方法;

外部構(gòu)建

當(dāng)前目錄結(jié)構(gòu):

我們在當(dāng)前目錄 下 的build目錄下 運(yùn)行:cmake … 生成 Makefile,并且make,運(yùn)行程序:

運(yùn)行后的build目錄結(jié)構(gòu):

運(yùn)行后的源文件主目錄結(jié)構(gòu):

可以看到,外部構(gòu)建之前的源文件主目錄沒有新的cmake中間文件結(jié)合進(jìn)來,那些文件去了我們可以設(shè)置的build目錄中,與源文件區(qū)分開了,所以我們建議這種方法;

當(dāng)然,可以通過其他的cmake操作或者bash指令,將生成的Makefile或者可執(zhí)行程序進(jìn)行output從build目錄中移動(dòng)到別的指定目錄,而且別忘了還有.sh shell腳本;

小結(jié)

cmake的好處:

  1. 跨平臺(tái)開發(fā)的時(shí)候,cmake相當(dāng)于對編譯過程進(jìn)行了二次封裝,提高了該工程的跨平臺(tái)性,各種OS的上策被cmake統(tǒng)一管理,方便了類似添加源文件等一系列改動(dòng);
  2. 簡化了生成Makefile等構(gòu)建工程文件的復(fù)雜度!

(我們借助這種好的工具,便于管理構(gòu)建項(xiàng)目,讓我們更多專注于業(yè)務(wù)的開發(fā),只能說大老牛,真香~)

到此這篇關(guān)于cmake跨平臺(tái)構(gòu)建工具的文章就介紹到這了,更多相關(guān)cmake跨平臺(tái)構(gòu)建工具內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++ SOCKET多線程實(shí)現(xiàn)聊天小程序

    C++ SOCKET多線程實(shí)現(xiàn)聊天小程序

    這篇文章主要為大家詳細(xì)介紹了C++ SOCKET多線程實(shí)現(xiàn)聊天小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • 詳解設(shè)計(jì)模式中的Command命令模式及相關(guān)C++實(shí)現(xiàn)

    詳解設(shè)計(jì)模式中的Command命令模式及相關(guān)C++實(shí)現(xiàn)

    這篇文章主要介紹了詳解設(shè)計(jì)模式中的Command命令模式及相關(guān)C++實(shí)現(xiàn),命令模式強(qiáng)調(diào)調(diào)用操作的對象和操作的具體實(shí)現(xiàn)者之間的解耦,需要的朋友可以參考下
    2016-03-03
  • 深入解析C++編程中的運(yùn)算符重載

    深入解析C++編程中的運(yùn)算符重載

    這篇文章主要介紹了C++編程中的運(yùn)算符重載,運(yùn)算符重載是C++入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2016-04-04
  • c++中引用作為形參的使用方法以及作用

    c++中引用作為形參的使用方法以及作用

    這篇文章主要給大家介紹了關(guān)于c++中引用作為形參的使用方法以及作用的相關(guān)資料,引用是地址傳值,作為引用的形參數(shù)值被修改的同時(shí),也修改了對應(yīng)實(shí)參的值,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-11-11
  • C++11中互斥鎖的使用

    C++11中互斥鎖的使用

    本文主要介紹了C++11中互斥鎖的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • memset函數(shù)的使用分析

    memset函數(shù)的使用分析

    本篇文章是對memset函數(shù)的使用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • c++非變易算法-stl算法

    c++非變易算法-stl算法

    本文主要介紹了C++ STL算法庫中的非變易算法,是一些原則上不會(huì)變更操作數(shù)據(jù)的算法,包括:逐個(gè)查找算法、元素搜索算法、元素統(tǒng)計(jì)算法、序列匹配算法、子序列搜索算法、這些函數(shù)均包含于<algorithm>頭文件,本文給出的所有代碼在VS2010中編譯運(yùn)行通過
    2014-03-03
  • c++中l(wèi)og4cplus日志庫使用的基本步驟和示例代碼

    c++中l(wèi)og4cplus日志庫使用的基本步驟和示例代碼

    這篇文章主要給大家介紹了關(guān)于c++中l(wèi)og4cplus日志庫使用的相關(guān)資料,log4cplus是一款開源的c++日志庫,具有線程安全,靈活,以及多粒度控制的特點(diǎn),log4cplus可以將日志按照優(yōu)先級進(jìn)行劃分,使其可以面向程序的調(diào)試,運(yùn)行,測試,后期維護(hù)等軟件全生命周期,需要的朋友可以參考下
    2024-06-06
  • VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件

    VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件

    這篇文章主要為大家詳細(xì)介紹了VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-08-08
  • 詳解基于C++實(shí)現(xiàn)約瑟夫環(huán)問題的三種解法

    詳解基于C++實(shí)現(xiàn)約瑟夫環(huán)問題的三種解法

    約瑟夫環(huán)問題是算法中相當(dāng)經(jīng)典的一個(gè)問題,其問題理解是相當(dāng)容易的,并且問題描述有非常多的版本,并且約瑟夫環(huán)問題還有很多變形,通過這篇約瑟夫問題的講解,一定可以帶你理解透徹
    2021-06-06

最新評論