CMake學習使用(基于vscode)

目錄

  • 語法
  • 一些重要指令
  • CMake常用變量
  • CMake編譯工程
    • 編譯流程
    • 兩種構建方式
  • 實例展示

參考:
基于VSCode和CMake實現C/C++開發 | Linux篇

語法

基本語法格式:指令(arg1 arg2 …)

  • 參數使用括弧括起來
  • 參數之間使用空格或者分號分開
    指令是大小寫無關的,參數和變量是大小寫相關的
set(HELLO hello.cpp) # 將hello.cpp 作為一個名為 HELLO 的變量
add_executable(hello main.cpp hello.cpp)
ADD_EXECUTABLE(hello main.cpp ${HELLO})

變量使用方式取值,但是在IF控制語句里面直接使用變量名,例如:‘IF(HELLO)‘而不是‘IF({}方式取值,但是在IF控制語句里面直接使用變量名,例如:`IF(HELLO)`而不是`IF(IF使IF(HELLO)IF({HELLO})`

一些重要指令

  • cmake_minimum_required : 用來指定CMake的最小版本要求
# CMake最小版本要求為2.8.3
cmake_minimum_required(VERSION 2.8.3)
  • project :用來定義工程名稱,并可指定工程支持的語言
project(HELLOWORLD C)
  • set :顯示的定義變量
# 定義SRC變量,其值為sayhello.cpp hello.cpp
set(SRC sayhello.cpp hello.cpp)
  • include_directories :向工程添加多個特定的頭文件搜索路徑->相當于指定g++編譯器的-I參數
# 將usr/include/myincludefolder 和 ./include 添加到頭文件搜索路徑
include_directories(usr/include/myincludefolder ./include)
  • link_directories:向工程添加多個特定的庫文件搜索路徑->相當于指定g++編譯器的-L參數
# 將usr/lib/mylibfolder 和 ./lib 添加到庫文件搜索路徑
link_directories(usr/lib/mylibfolder ./lib)
  • add_library :生成庫文件
# 通過變量 SRC 生成 libhello.so 共享庫
add_library(hello SHARED ${SRC})
  • add_compile_options :添加編譯參數
# 添加編譯參數 -Wall -std=c++11 -O2
add_compile_options(-Wall -std=c++11 -O2)
  • add_executable:生成可執行文件
# 編譯main.cpp生成可執行文件main
add_executable(main main.cpp)
  • target_link_libraries:為target添加需要鏈接的共享庫->相當于指定g++編譯器的-l 參數
# 將hello動態庫鏈接到可執行文件main上
target_link_libraries(main hello)
  • add_subdirectory:向當前工程添加存放源文件的子目錄,并可以指定中間二進制和目標二進制存放的位置
# 添加src子目錄,src中需要有一個CMakeLists.txt
add_subdirectory(src)
  • aux_source_directory :發現一個目錄下所有的源代碼文件并將列表存儲在一個變量中,這個指令被用來臨時自動構建源文件列表
# 定義SRC變量,其值為當前目錄下所有的源代碼文件
aux_source_directory(. SRC)
# 編譯SRC變量所代表的源代碼文件,生成main可執行文件
add_executable(main ${SRC})

CMake常用變量

  • CMAKE_C_FLAGS :gcc編譯選項
  • CMAKE_CXX_FLAGS:g++編譯選項
# 在編譯選項后追加-std=c++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
  • CMAKE_BUILD_TYPE:編譯類型(Debug,Release)
# 設定編譯類型為debug,調試時需要選擇debug
set(CMAKE_BUILD_TYPE Debug)
# 設定編譯類型為release,發布時需要選擇release
set(CMAKE_BUILD_TYPE Release)
  • CMAKE_BINARY_DIRPROJECT_BINARY_DIR_BINARY_DIR

這三個變量指代的內容是一致的
如果是 in source build,指的是工程頂層目錄
如果是out-of-source編譯,指的是工程編譯發生的目錄

  • CMAKE_SOURCE_DIRPROJECT_SOURCE_DIR_SOURCE_DIR

這三個變量指代內容一致,不管采用何種編譯方式,都是工程頂層目錄
in source build時,與CMAKE_BINARY_DIR等變量一致

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

CMake編譯工程

CMake目錄結構:項目主目錄存在一個CMakeLists.txt文件
一般有兩種方式設置編譯規則
1、包含源文件的子文件夾包含CMakeLists.txt文件,主目錄的CMakeList.txt通過add_subdirectory添加子目錄即可
2、包含源文件的子文件夾未包含CMakeLists.txt文件,子目錄編譯規則體現在主目錄的CMakeLists.txt中

編譯流程

在linux下使用CMake構建C/C++工程的流程如下:

  • 手寫CMakeLists.txt文件
  • 執行命令cmake PATH生成Makefile(PATH是頂層CMakeLists.txt所在的目錄)
  • 執行命令make進行編譯

兩種構建方式

1、內部構建(in-source build):這種方式不推薦使用
內部構建會在同級目錄下產生一大堆中間文件,和工程源文件放在一起會顯得雜亂無章

# 內部構建
# 在當前目錄下,編譯本目錄的CMakeLists.txt,生成Makefile文件和其他文件
cmake .
# 執行make命令,生成target
make

2、外部構建(out-of-source build) :這種方式推薦使用
該方式將編譯輸出文件和源文件放在不同目錄中

# 外部構建
# 1、在當前目錄下,創建build文件夾
mkdir build
# 2、進入build文件夾
cd build
# 3、編譯上級目錄的CMakeList.txt ,生成Makefile和其他文件
cmake ..
# 4、執行make,生成目標文件
make

實例展示

實例一

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/hello$   tree
.
├── hello
└── hello.cpp

hello.cpp內容為:

#include<iostream>
using namespace std;
int main()
{cout << "hello world!" << endl;return 0;
}      

我們進入目錄,然后輸入:
code . 這樣就能打開vscode了
我們要給這個最簡單的cpp程序寫一個CMakeLists.txt
CMakeLists.txt一般處于項目的頂層目錄,此處就在文件夾下了
一般來說,在vscode中寫cmakelists的話會有只能提示的,如果你裝了插件的話

# 指定最低版本要求
cmake_minimum_required(VERSION 3.0)
# 指定項目名稱
project(HELLO)
# 指定生成的可執行文件的名字 源文件
add_executable(hello_cmake hello.cpp)
## 此時等價于 g++ hello.cpp -o hello_cmake

接下來我們在vscode的終端里面進行外部構建并編譯
在這里插入圖片描述我們在終端下使用tree命令看看文件結構:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/hello$ tree
.
├── build
│   ├── CMakeCache.txt
│   ├── CMakeFiles
│   │   ├── 3.16.3
│   │   │   ├── CMakeCCompiler.cmake
│   │   │   ├── CMakeCXXCompiler.cmake
│   │   │   ├── CMakeDetermineCompilerABI_C.bin
│   │   │   ├── CMakeDetermineCompilerABI_CXX.bin
│   │   │   ├── CMakeSystem.cmake
│   │   │   ├── CompilerIdC
│   │   │   │   ├── a.out
│   │   │   │   ├── CMakeCCompilerId.c
│   │   │   │   └── tmp
│   │   │   └── CompilerIdCXX
│   │   │       ├── a.out
│   │   │       ├── CMakeCXXCompilerId.cpp
│   │   │       └── tmp
│   │   ├── cmake.check_cache
│   │   ├── CMakeDirectoryInformation.cmake
│   │   ├── CMakeOutput.log
│   │   ├── CMakeTmp
│   │   ├── hello_cmake.dir
│   │   │   ├── build.make
│   │   │   ├── cmake_clean.cmake
│   │   │   ├── CXX.includecache
│   │   │   ├── DependInfo.cmake
│   │   │   ├── depend.internal
│   │   │   ├── depend.make
│   │   │   ├── flags.make
│   │   │   ├── hello.cpp.o
│   │   │   ├── link.txt
│   │   │   └── progress.make
│   │   ├── Makefile2
│   │   ├── Makefile.cmake
│   │   ├── progress.marks
│   │   └── TargetDirectories.txt
│   ├── cmake_install.cmake
│   ├── hello_cmake
│   └── Makefile
├── CMakeLists.txt
├── hello
└── hello.cpp

此時發現可執行文件是在build文件夾下的
實例二
此處用到的實例請參考:
gcc 編譯器使用指南
此時工程結構如下:

.
├── include
│   └── swap.h
├── main.cpp
├── sharemain
├── src
│   ├── libswap.a
│   ├── libswap.so
│   ├── swap.cpp
│   └── swap.o
└── staticmain

然后寫cmakelists.txt

cmake_minimum_required(VERSION 3.0)project(SWAP)
# 與 -Iinclude 命令對應
include_directories(include)# 此命令相當于 g++ main.cpp src/swap.cpp -Iinclude -o main_cmake
add_executable(main_cmake main.cpp src/swap.cpp)

然后執行cmake、make:

dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ mkdir build
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST$ cd build/
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ cmake ..
-- The C compiler identification is GNU 9.3.0
-- The CXX compiler identification is GNU 9.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dyy/Desktop/GCCTEST/build
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ make
Scanning dependencies of target main_cmake
[ 33%] Building CXX object CMakeFiles/main_cmake.dir/main.cpp.o
[ 66%] Building CXX object CMakeFiles/main_cmake.dir/src/swap.cpp.o
[100%] Linking CXX executable main_cmake
[100%] Built target main_cmake
dyy@dyy-Lenovo-ThinkBook-14-IIL:~/Desktop/GCCTEST/build$ ./main_cmake 
before
10 20
after
20 10

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

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

相關文章

idhttp.post方式 調用datasnap rest 遠程方法

idhttp.get方式調用&#xff0c;這種比較簡單&#xff0c;大家都會。post方式網上卻沒有任何成功的代碼&#xff0c;本人也是摸索了一個上午才搞定。 分享給大家。 &#xff08;1&#xff09;post方式調用的遠程方法&#xff0c;方法名必須加“update”前綴&#xff0c;不加行不…

[轉]連接excel數據源時,首行包含列名稱選項在連接字符串中的設置。

關于Excel導入的HDRYES; IMEX1詳解 ProviderMicrosoft.Jet.OLEDB.4.0;Data Source111.xls;Extended Properties"Excel 8.0;HDRNO"; 其中HDRNO或YES即首行包含列名稱選項 (參數HDR的值&#xff1a;HDRYes&#xff0c;這代表第一行是標題&#xff0c;不做為數據使用&am…

C++多線程快速入門(一):基本常用操作

目錄case1&#xff1a;創建線程1 join、detachcase2&#xff1a;創建線程2 線程傳參 傳值或者傳引用case3&#xff1a;創建線程 線程傳參 functional object作為參數case4&#xff1a;觀察多線程程序加速計算case5&#xff1a;future get 獲取并發結果case6&#xff1a;互斥鎖…

android:configChanges屬性總結

原文地址&#xff1a;http://blog.csdn.net/zhaokaiqiang1992/article/details/19921703 android中的組件Activity在manifest.xml文件中可以指定參數android&#xff1a;ConfigChanges&#xff0c;用于捕獲手機狀態的改變。 在Activity中添加了android:configChanges屬性&#…

eclipse 中修改 M2_REPO的值

從eclipse中增加了maven2的插件之后&#xff0c;maven默認的本地庫的路徑是${user}/.m2/repository/下&#xff0c;一般windows用戶的操作系統都安裝在C盤&#xff0c;所以這個目錄 下的jar包比較危險。我嘗試從myeclipse->preferences->java->build path->classpa…

C++多線程快速入門(二)共享數據同步以及數據競爭

目錄std::unique_lock類模板僅調用一次線程局部存儲原子變量往期內容回顧std::unique_lock類模板 互斥鎖保證了線程間的同步&#xff0c;卻將并行操作變成了串行操作&#xff0c;對性能有較大影響&#xff0c;所以我們要盡可能減小鎖的區間粒度。 lock_guard只能保證在析構的時…

DNS安全淺議、域名A記錄(ANAME),MX記錄,CNAME記錄

相關學習資料 http://baike.baidu.com/link?url77B3BYIuVsB3MpK1nOQXI-JbS-AP5MvREzSnnedU7F9_G8l_Kvbkt_O2gKqFw7vm http://www.rfc-editor.org/rfc/rfc1035.txt http://www.rfc-editor.org/rfc/rfc3596.txt http://www.rfc-editor.org/rfc/rfc2782.txt http://www.rfc-edito…

ThinkInJava4讀書筆記之第一章對象入門

那句話怎么說來著&#xff0c;原句記不住了好像是出來混的遲早要還的。話說當初學校剛開Java課程&#xff0c;自己沒有好好學啊&#xff0c;后來直接做了jsp和servlet&#xff0c;然后學了SSH框架和Extjs、jQuery&#xff0c;接著是mybatis&#xff08;ibatis&#xff09;、fre…

C++多線程快速入門(三):生產者消費者模型與條件變量使用

互斥鎖完成 #include <iostream> #include <deque> #include <thread> #include <mutex>std::deque<int> q; std::mutex mtx;static void produce(int val) {while(val--) {std::unique_lock<std::mutex> guard(mtx);q.push_front(val);m…

【blade利刃出鞘】一起進入移動端webapp開發吧

前言 在移動浪潮襲來的時候&#xff0c;小釵有幸進入框架組做webapp框架開發&#xff0c;過程中遇到了移動端的各種坑&#xff0c;也產生了各種激情&#xff0c;就我們公司的發展歷程來說 第一階段&#xff1a;使用傳統方式開發移動站點&#xff0c;少量引入HTML5元素 第二階段…

題目理解。。

有時候一道大水題&#xff0c;因為英文描述可能有點復雜或者其它云云&#xff0c; 就比如那道PRO。。 別先被一道題嚇一跳&#xff0c;&#xff0c;&#xff0c; 英文描述看深入一點總歸會能解決的&#xff0c;盡可能多的考慮情況。大膽嘗試。轉載于:https://www.cnblogs.com/c…

C++多線程快速入門(四)shared_mutex以及讀寫鎖應用

在前面的三講中我們使用的mutex都是普通的std::mutex&#xff0c;這里介紹一下shared_mutex&#xff0c;版本為C17 std::shared_mutex的底層實現時操作系統提供的讀寫鎖&#xff0c;在讀多寫少的情況下&#xff0c;該shared_mutex比mutex更加高效。 它提供了常用的四種方法&am…

Tornado/Python 學習筆記(一)

1.源代碼下載及安裝&#xff1a;http://www.tornadoweb.org/en/stable/ 2.python中xmlrpc庫官方文檔&#xff1a;https://docs.python.org/3/library/xmlrpc.html?highlightxmlrpc 3.xml介紹與學習&#xff1a;http://www.w3school.com.cn/xml/xml_intro.asp XML 被設計為傳輸…

spring-aop-annotation

1。假設你已經配好依賴注入那一塊。此時的bean.xml為 <?xml version"1.0" encoding"UTF-8"?><beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:cont…

c++實現簡單線程池代碼

目錄完整代碼TaskPool.cppTaskPool.hmain.cpp完整代碼 TaskPool.cpp // // Created by LENOVO on 2021/10/25. //#include "TaskPool.h" #include <functional>std::mutex printMutex;TaskPool::TaskPool() : m_bRunning(false) {}TaskPool::~TaskPool() {re…

Android靜態圖片人臉識別的完整demo(附完整源碼)

Demo功能&#xff1a;利用android自帶的人臉識別進行識別&#xff0c;標記出眼睛和人臉位置。點擊按鍵后進行人臉識別&#xff0c;完畢后顯示到imageview上。 第一部分&#xff1a;布局文件activity_main.xml [html] view plaincopyprint?<RelativeLayout xmlns:android&qu…

圖論:最短路徑搜索--Dijkstra算法(c代碼實現)

最近因為辭職&#xff0c;有不少閑功夫&#xff0c;重溫下數據結構&#xff0c;順便練練手。今天說說最短路徑搜索算法中的Dijkstra原理和實現。 一&#xff1a;簡介 這個算法用于解決圖中單源最短路徑問題。所謂單源節點是指給定源節點&#xff0c;求圖中其它節點到此源節點的…

C++多線程快速入門(五)簡單線程池設計

目錄設計思路主線程運行邏輯task以及taskpool設計詳細流程講解完整代碼打印結果往期回顧設計思路 線程池實際上就是一組線程&#xff0c;當我們需要異步執行一些任務時&#xff0c;經常要通過OS頻繁創建和銷毀線程&#xff0c;不如直接創建一組在程序生命周期內不會退出的線程…

C--函數

函數:具有特定功能的代碼段,分為庫函數,自定義函數. 函數定義: 函數返回值類型 函數名(形式參數列表) { 代碼段; return 返回值; } 注意:每個函數返回值最多只有一個.return是一個函數結束的標志. 形式參數(形參):函數定義時使用的虛擬參數名,用以接收函數調用是傳遞過來的實際…

公式系統 - TradeBlazer公式基礎 - Bar數據

Bar數據 在介紹Bar數據之前&#xff0c;首先&#xff0c;我們需要討論一下TradeBlazer公式的計算方法&#xff0c;針對上面介紹的各種公式類型&#xff0c;包含公式應用&#xff0c;在公式進行計算時&#xff0c;都是建立在基本數據源(Bar數據)之上&#xff0c;我們這里所謂的B…