一、文檔背景
在Linux系統(tǒng)下開(kāi)發(fā)一個(gè)較大型的項(xiàng)目時(shí),涉及到許多目錄與文件,如果每個(gè)目錄下的Makefile都手動(dòng)去編寫(xiě),效率會(huì)非常低,同時(shí),也容易出錯(cuò)。
自動(dòng)生成 Makefile 文件可以簡(jiǎn)化項(xiàng)目的構(gòu)建過(guò)程,提高開(kāi)發(fā)效率,并增加項(xiàng)目的可維護(hù)性。
二、 解決的問(wèn)題或者進(jìn)行問(wèn)題分析
Makefile 文件的自動(dòng)生成通常是通過(guò)使用構(gòu)建工具或生成工具來(lái)實(shí)現(xiàn)的。有幾個(gè)工具可以幫助自動(dòng)生成 Makefile 文件,其中一些常見(jiàn)的包括:
● CMake: CMake 是一個(gè)跨平臺(tái)的構(gòu)建系統(tǒng)生成工具,它可以自動(dòng)生成針對(duì)不同構(gòu)建系統(tǒng)(包括 Makefile)的配置文件。通過(guò)編寫(xiě) CMakeLists.txt 文件,你可以使用 CMake 生成相應(yīng)的 Makefile,并用于構(gòu)建你的項(xiàng)目。
● Autotools: Autotools 是一套用于自動(dòng)化軟件構(gòu)建、配置和安裝的工具集。它包括 Autoconf、Automake 和 Libtool。Autoconf 可以根據(jù) configure.ac 文件生成 configure 腳本,而 Automake 可以根據(jù) Makefile.am 文件生成 Makefile。
● qmake: qmake 是 Qt 庫(kù)附帶的一個(gè)構(gòu)建系統(tǒng)生成工具。通過(guò)編寫(xiě) .pro 文件,你可以使用 qmake 自動(dòng)生成適用于不同平臺(tái)的 Makefile 文件。
● GNU Automake: GNU Automake 是 Autoconf 的一部分,它用于生成 Makefile.in 文件,從而使 Autoconf 自動(dòng)生成最終的 Makefile。
本文將通過(guò)CMake工具來(lái)實(shí)現(xiàn)Makefile文件的自動(dòng)生成。
三、 如何應(yīng)用CMake來(lái)自動(dòng)生成Makefile文件
實(shí)例工程的目錄與文件情況如圖3-1所示:

圖3-1
1. 在“math”目錄下,創(chuàng)建一個(gè)CMakeLists.txt文件,內(nèi)容如圖3-2所示:

圖3-2
2. 在“mathlib”目錄下,創(chuàng)建一個(gè)CMakeLists.txt文件,內(nèi)容如圖3-3所示:

圖3-3
3. 在“Add”目錄下,創(chuàng)建一個(gè)CMakeLists.txt文件,內(nèi)容如圖3-4所示:

圖3-4
4. 在“Sub、Mul、Div”目錄下,參照“Add”目錄的CMakeLists.txt文件創(chuàng)建類(lèi)似的CMakeLists.txt文件。
5. 在“math”目錄下,運(yùn)行“cmake -S . -B build”,開(kāi)始生成Makefile文件,如圖3-5所示:

圖3-5
6. 進(jìn)入“build”目錄下,可以看到Makefile文件已生成,同時(shí)也創(chuàng)建工程的目錄鏡象,相應(yīng)的目錄下都生成了Makefile文件,如圖3-6所示:

圖3-6
四、驗(yàn)證自動(dòng)生成的Makefile的正確性
進(jìn)入在“build”目錄下,運(yùn)行make,并運(yùn)行執(zhí)行文件:main,如圖4-1所示:

圖4-1
五、討論分析
1. CMakeLists.txt的基本結(jié)構(gòu)是什么?
# Set the minimum required version of CMake
cmake_minimum_required(VERSION 3.10)
# Define the project name
project(MyProject)
# Add build rules for an executable or library
add_executable(my_executable main.cpp)
# Set the source file directory
add_subdirectory(src)
# Set the library file directory
add_subdirectory(lib)
# Add linking libraries
target_link_libraries(my_executable my_library)
# Add include directories
target_include_directories(my_executable PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
上述代碼包含了以下主要元素:
● cmake_minimum_required: 設(shè)置 CMake 的最低版本要求。
● project: 定義項(xiàng)目名稱(chēng)。
● add_executable 或 add_library: 添加可執(zhí)行文件或庫(kù)的構(gòu)建規(guī)則。
● add_subdirectory: 設(shè)置源文件目錄或子項(xiàng)目的構(gòu)建規(guī)則。
● target_link_libraries: 添加鏈接庫(kù)的規(guī)則。
● target_include_directories: 添加包含目錄的規(guī)則。
2. cmake,Bazel及buck等構(gòu)建工具的差異?
CMake:
特點(diǎn):
● 語(yǔ)言支持: CMake 是一種構(gòu)建工具和構(gòu)建系統(tǒng)生成工具,支持多種編程語(yǔ)言,包括 C++、C、Java、Python 等。
● 平臺(tái)支持: CMake 是跨平臺(tái)的,可以生成針對(duì)不同平臺(tái)(Windows、Linux、macOS 等)的構(gòu)建系統(tǒng)。
● 生成器: CMake 支持生成多種構(gòu)建系統(tǒng),如 Makefile、Ninja、Visual Studio 等。
● 易學(xué)易用: CMake 的語(yǔ)法相對(duì)簡(jiǎn)單,易于學(xué)習(xí)和使用。
● 社區(qū)支持: 有廣泛的社區(qū)支持和文檔資源。
Bazel:(google)
特點(diǎn):
● 多語(yǔ)言支持: Bazel 支持多種編程語(yǔ)言,包括 C++, Java, Python, Go, JavaScript。
● 高度可重現(xiàn): 通過(guò)準(zhǔn)確的依賴(lài)分析和緩存機(jī)制,Bazel 確保構(gòu)建是可重現(xiàn)的,即使在分布式環(huán)境中也能保持一致。
● 多平臺(tái)支持: 能夠構(gòu)建適用于多個(gè)平臺(tái)的軟件,包括 Linux、macOS、Windows 等。
● 分布式構(gòu)建: 支持將構(gòu)建任務(wù)分發(fā)到多臺(tái)計(jì)算機(jī)上,以加速構(gòu)建過(guò)程。
● 增量構(gòu)建: 只重新構(gòu)建發(fā)生變化的部分,提高構(gòu)建效率。
● 支持多倉(cāng)庫(kù): 能夠處理大規(guī)模代碼庫(kù),支持多倉(cāng)庫(kù)構(gòu)建。
Buck:
特點(diǎn):
● Android/iOS 構(gòu)建: Buck 最初是為 Facebook 的 Android 和 iOS 項(xiàng)目開(kāi)發(fā)的,因此在處理移動(dòng)應(yīng)用構(gòu)建方面非常強(qiáng)大。
● 增量構(gòu)建: 與 Bazel 一樣,Buck 也支持增量構(gòu)建,只重新構(gòu)建發(fā)生變化的部分。
● 可配置性: 提供靈活的配置選項(xiàng),允許開(kāi)發(fā)者根據(jù)項(xiàng)目需求進(jìn)行定制。
● 并行構(gòu)建: 能夠并行構(gòu)建項(xiàng)目,提高構(gòu)建效率。
● 緩存機(jī)制: 使用緩存來(lái)存儲(chǔ)中間和最終構(gòu)建產(chǎn)物,以減少不必要的重新構(gòu)建。
共同點(diǎn):
● 都支持分布式構(gòu)建,可以將構(gòu)建任務(wù)分發(fā)到多個(gè)機(jī)器上。
● 都注重構(gòu)建速度和可重現(xiàn)性。
● 都采用聲明式的構(gòu)建規(guī)則,使用 BUILD 文件來(lái)描述構(gòu)建過(guò)程。
六、結(jié)論
應(yīng)用CMake工具自動(dòng)生成 Makefile 文件可以簡(jiǎn)化項(xiàng)目的構(gòu)建過(guò)程,大大提高了項(xiàng)目的開(kāi)發(fā)效率。