是不是覺得Makefile很繁瑣,一個cmake文件就可以解決

2021-01-08 軟體技術分享

linux編譯程序的時候,通常是使用Makefile文件來進行編譯,這個是能夠提高效率的,但是對於大中型的項目,每個文件夾下都需要創建Makefile,並且改變項目目錄結構都需要調整Makefile文件,如果是小型項目的話,那花費的時間還是能夠接受的,但是大中型項目要調整目錄結構,這個工作量還是不小的。所以,我們可以通過使用cmake來解決這樣的問題。

本文首先簡單介紹什麼是cmake,它可以用來幹什麼,接著給出一個簡單的例子,讓初學者對cmake有一個大致的了解,然後拋出cmake文件,並針對該cmake文件進行詳細的解釋,最後再進行總結,並分享個人的學習心得。

一、什麼是cmake

cmake一款跨平臺的編譯工具, 它的全稱是cross platform make,注意這裡的make不是指linux下的make,使用它構建的工程,既可以生成linux下的makefile,也可以生成Mac系統的xcode的工程文件,還能夠生成window的projects等。cmake並不會生成最終的軟體程序,它只是生成標準的建構檔,例如linux的Makefile文件。簡單來說,cmake可以生產不同平臺的建構檔,然後再由建構檔來生成最終的軟體程序。

cmake組織檔的取名都為CMakeLists.txt, 現在許多開源軟體都採用cmake來組織代碼,可見其用處還是很大的,學習了解cmake對於學習開源軟體是有很大的幫助的。

二、入門例子

首先電腦上需要安裝cmake軟體,具體下載安裝方法,可以網絡搜索,這不是本文的主題,所以不進行說明。

linux上安裝成功之後,可以執行命令cmake –version來查看當前的cmake版本

創建一個main.cpp文件,其內容如下所示,列印一句字符信息。

接著在同級目錄下創建cmake文件 CMakeLists.txt

為了代碼乾淨,同級目錄下創建build目錄,進入build目錄,執行「cmake ./」命令來生成Makefile文件,接著執行命令make編譯,最後build目錄下生成二進位文件example_01, 執行程序可以輸出列印信息。

build目錄下生成的文件內容如下,Makefile是生成的建構檔,example_01是生成的可執行二進位程序。

三、cmake代替Makefile

上面只是cmake的一個簡單的入門例子,還不能明顯看出cmake的強大,對於中大型的項目來看,cmake的作用就比較明顯,特別是相同代碼不同平臺的編譯。

下面給出本章節將要詳細解釋說明的cmake文件,可以先熟悉下整體的流程,看不明白沒有關係,後面將針對該文件進行詳細的解釋說明。

接下來就來詳細說明上面的cmake文件的功能含義。

cmake_minimum_required指定cmake最低版本號要求,FATAL_ERROR 表示當發生警告時,用錯誤方式提示

CMAKE_INCLUDE_CURRENT_DIR 自動增加CMAKE_CURRENT_SOURCE_DIR和CMAKE_CURRENT_BINARY_DIR到每個目錄的include路徑。CMAKE_INCLUDE_CURRENT_DIR默認是關閉的。

當前測試工程的目錄結構如下:

message可以列印輸出變量信息, CMAKE_CURRENT_SOURCE_DIR、CMAKE_CURRENT_BINARY_DIR、PROJECT_SOURCE_DIR是cmake內置變量。

運行後輸出列印的信息, CMAKE_CURRENT_SOURCE_DIR表示當前正在處理的原始碼目錄,CMAKE_CURRENT_BINARY_DIR表示當前正在處理的二進位目錄,PROJECT_SOURCE_DIR表示當前工程的頂層原始碼目錄

EXECUTABLE_OUTPUT_PATH表示可執行文件輸出路徑

find_package()命令是用來查找依賴包, Pkg-Config維護它依賴庫路徑、頭文件路徑、編譯選項、連結選項等信息。

關鍵字ENV查看的是當前環境變量,linux上的環境變量可以通過export命令來查看。

message(STATUS 「LANG: $ENV{LANG}」)對應輸出的內容為:

find_program查找可執行程序。一個名為<VAR>的cache條目會被創建用來存儲該命令的結果。如果該程序被找到了,結果會存儲在該變量CCACHE_FOUND。

set_property給定範圍內設置一個命名屬性,GLOBAL域是唯一的,PROPERTY後面緊跟著要設置的屬性的名字。

function,定義函數name, 並且參數為<arg1> … , 函數只有在調用的時候才起作用。

include_directories包含頭文件的搜索路徑。

link_directories指定查找庫的目錄。

target_link_libraries標示連結的庫。<target>必須時 add_executable() or add_library() 命令創建。<item>則是連結的庫

file產生一個匹配 <globbing-expressions> 的文件列表並將它存儲到變量 <variable> 中,果 RELATIVE 標誌位被設定,將返回指定路徑的相對路徑。file的第一個參數設置為GLOB_RECURSE,則表示遍歷匹配目錄的所有子目錄並匹配文件。

add_custom_command,定義一個跟指定目標target關聯的新的命令,命令何時執行取決於PRE_BUILD | PRE_LINK | POST_BUILD這三個參數。

四、總結

創建cmake文件的過程,首先當然是先創建CMakeLists.txt文件,接著聲明cmake的版本要求,然後設置項目信息,再根據具體場景設置相關屬性以及生成的可執行目標。

上面講解的例子中,主要涉及到cmake的幾個知識點。具體如下:

cmake的變量:內置變量、環境變量以及自定義變量。查找命令:find_package、find_program定義函數:function查找文件:file搜索路徑:include_directories、link_directories、target_link_libraries自定義命令:add_custom_command設置目標: add_executable五、學習心得

學習cmake也有一段時間,網絡上也搜索了很多信息,但是總感覺說的不夠明白和全面。最後發現要想全面的了解cmake, 最有效的方法就是直接查看cmake的官方文檔。雖然是英文,但是只要耐心認真閱讀,就會發現裡面講的很全面。然後再結合具體的例子進行消化理解就可以。而對於cmake的變量的含義,除了查看cmake官方文檔之後,還可以通過message直接列印出變量信息來加深理解其含義。

相關焦點

  • g++,CMake和Makefile了解一下
    顯示規則:通常在寫makefile時使用的都是顯式規則,這需要指明target和prerequisite文件。一條規則可以包含多個target,這意味著其中每個target的prerequisite都是相同的。當其中的一個target被修改後,整個規則中的其他target文件都會被重新編譯或執行。 2.
  • Linux CMake 快速使用(一)
    小結剛安裝的ubuntu 16.04沒有cmake, 使用sudo apt install cmake命令可完成安裝。二、改善文件結構通過以上幾個步驟,我們掌握了基本cmake命令使用、makefile文件編寫等技能。
  • Visual Studio 現已支持 CMake
    CMake 是一個跨平臺的開源工具,通過抽象本地構建環境和編譯器以管理建立跨多平臺程序。CMake解析一個CMake腳本,作者在一個選擇好的構建環境中創造並生成一個構建計劃。(例如在Visual studio 項目, make 腳本, Xcode 項目中等等)CMake是一個跨平臺的makefile生成工具,主要用於C和C++編程。
  • Linux CMake 快速使用之共享庫庫創建與連結
    一、 處理多文件情況文件結構moreFile文件夾下分別是build、src文件夾以及主CMakeLists.txt文件src文件夾是main.cpp、子CMakeLists.txt文件以及其他源文件和頭文件2.
  • linux中的makefile
    在linux中gcc一次只能編譯一個目標。對於大型項目,效率太低。因此引入linux中一個重要的編譯工具makefile,相當於在一個文本文件中,指定程序的編譯方式。makefile關係到整個工程的編譯規則。小項目無所謂,對於一個大的項目來說,其必不可少。
  • 程式設計師的術與道:術——makefile基本操作
    這其中其實涉及到了每一個源文件,這些源文件基本都要經歷這樣一個過程:每一個文件都需要被gcc編譯一遍,當你的項目足夠大時,這份工作是相當龐大的。而且你把源碼換到其他地方,還需要繼續重複來一遍。這個時候makefile出場了,makefile為你解決了這些重複性的勞動。讓你一次編寫,處處運行。
  • 解鎖新技能,python與cmake結合,實現自動生成工廠類
    工作過程中,當需要創建很多同一類對象的時候,為了方便管理和維護,通常通過創建一個工廠類,由該工廠類根據不同的參數來創建返回對象,但是在C++中,存在這樣的問題,每當新建新的對象的時候,都需要修改工廠類來支持新的對象的創建。從這個過程中,我們可以看出,操作相當繁瑣和重複。
  • 解鎖新技能,python與cmake結合,實現自動生成工廠類
    工作過程中,當需要創建很多同一類對象的時候,為了方便管理和維護,通常通過創建一個工廠類,由該工廠類根據不同的參數來創建返回對象,但是在C++中,存在這樣的問題,每當新建新的對象的時候,都需要修改工廠類來支持新的對象的創建。從這個過程中,我們可以看出,操作相當繁瑣和重複。
  • 1.2 CMake基礎:hello-headers
    本節demo地址:https://github.com/ttroy50/cmake-examples/tree/master/01-basic/B-hello-headers1 簡介還是一個hello cmake示例,將頭文件和源文件放在不同的文件夾來組織工程文件目錄。
  • 一次cmake編譯查錯,cmake重裝
    Centos7上面默認cmake版本為2.8.11版本,但是編譯包的時候會報各種奇怪的錯誤。這裡通過編譯json-c-0.14進行定位,錯誤如下圖所示。tar xzf json-c-0.14.tar.gzcmake .
  • CMake 入門學習2 使用VSCode cmake插件
    新建一個目錄mkdir -p d:/documents/cmake新建一個main.cpp文件:#include選擇創建可執行文件CMake Select a kit按提示選擇後,在界面最下方工具欄可以看到:
  • makefile的全自動化編譯和批量編譯
    對於大型項目來說,邊寫邊修改makefile中的.c文件是不效率的makefile實現自動添加.c文件(全自動化編譯)。$(wildcard 模式)在當前目錄下匹配所有的相應模式的文件。src = $(wildcard *.c) ,用於獲取所有.c文件。$(src :%.c=%.o), 把src的.c全部替換為.o (這裡的%是通配符)obj = $(src:%.c=%.o)這裡的 %.o:%.c 意思是所有的.o文件的生成,都依賴於.c文件。替代了下邊用#注釋的那幾句指令。
  • CMake 入門學習1 Hello World
    建立一個main.cpp文件#include <iostream>int main(int argc, char *argv[]){ std::cout << "Hello CMake!
  • Cmake學習總結(二) - OFweek電子工程網
    大家好,上次給大家分享了第一篇 cmake 文章:cmake學習總結(一),今天繼續給大家分享cmake。那麼廢話就不多說,開始內容分享。用好 Cmake,高興一整天(甚至……):1、多個源文件,使用命令 aux_source_directory(dir var):在上一篇文章最後結尾的時候,有一個問題,就是在同一目錄下面,有多個源文件的時候,這個時候你不能都往下面第三條命令裡面一直手動添加源文件,那工作效率多低啊:cmake_minimum_required
  • vs2017下使用Cmake生成源碼編譯錯誤以及解決方法
    錯誤碼提示內容編寫了一個比較大的項目工程,需要使用cmake,但是安裝的v2017進行編譯的時候,卻報了一堆的錯誤:The CXX compiler identification is unknownThe C compiler identification
  • CMake for Mac(編譯工具)
    CMake是用於控制軟體使用簡單的平臺和編譯器編譯過程獨立配置文件。CMake生成本機makefile和工作區,可以使用您所選擇的編譯器環境。它用於使用簡單的平臺和編譯器獨立配置文件來控制軟體編譯過程。CMake生成可以在您選擇的編譯環境中使用的本機makefile和工作區。它是由Kitware創建的,以響應對開源項目(如ITK和VTK)的強大的跨平臺構建環境的需求。
  • Linux系統下多線程程序編譯makefile文件
    在Linux下,編譯一個多線程的程序命令為:本文引用地址:http://www.eepw.com.cn/article/201609/305140.htmgcc -lpthread -o file file.c在Linux下,用交叉編譯器編譯一個在
  • 使用mac系統,基於cmake搭建OpenGL環境
    工作中越來越多的需求是要將數據以3D的形式展示給用戶,但是在實現3D特效之前,都需要有一個準備階段。OpenGL規範描述了繪製2D和3D圖形的抽象API,正所謂「工欲善其事必先利其器」,所以,學習OpenGL之前,當然是需要搭建好運行的環境。