常見構(gòu)建系統(tǒng)學(xué)習(xí)

構(gòu)建系統(tǒng)(build system)是用來從源代碼生成用戶可以使用的目標(biāo)(targets)的自動(dòng)化工具,目標(biāo)可以包括庫、可執(zhí)行文件、或者生成的腳本等等。

當(dāng)前主流的編譯基礎(chǔ)工具是makefile,當(dāng)時(shí)makefile有缺點(diǎn):

  1. 大型工程手寫makefile費(fèi)事費(fèi)力
  2. makefile隱式規(guī)則影響構(gòu)建效率

所以,又出現(xiàn)了很多新的構(gòu)建工具來解決這兩個(gè)問題,如

CMake, XMake, qmake, Scons, Ninja, Meson, Bazel等等。

這些構(gòu)建工具的使用,我們舉例并使用下。
代碼見 https://gitee.com/style7en/build-system。

假設(shè)我們的目錄如下,main.c需要使用hello.c中的函數(shù)hello()

app/
├── hello
│   ├── hello.c
│   └── hello.h
└── main.c

其中,hello.c內(nèi)容為

#include <stdio.h>

int hello(void)
{
    printf("hello, world!\n");
    return 0;
}

hello.h內(nèi)容為

#ifndef HELLO_H_
#define HELLO_H_

int hello(void);

#endif

main.c內(nèi)容為

#include "hello.h"

int main(void)
{
    hello();
    return 0;
}

Shell

如果不用任何構(gòu)建工具,直接使用最原始的構(gòu)建腳本,內(nèi)容如下,執(zhí)行如下腳本,會(huì)在當(dāng)前目錄生成可執(zhí)行程序app

#!/bin/bash
gcc -c main.c -I hello
gcc -c hello/hello.c
gcc main.o hello.o -o app

Makefile

一個(gè)工程中的源文件不計(jì)其數(shù),其按類型、功能、模塊分別放在若干個(gè)目錄中,makefile定義了一系列的規(guī)則來指定哪些文件需要先編譯,哪些文件需要后編譯,哪些文件需要重新編譯,甚至于進(jìn)行更復(fù)雜的功能操作,因?yàn)?makefile就像一個(gè)Shell腳本一樣,也可以執(zhí)行操作系統(tǒng)的命令。

上述工程的makefile文件如下,使用make命令執(zhí)行,會(huì)在當(dāng)前目錄生成可執(zhí)行程序app

app: main.o hello.o
    gcc main.o hello.o -o app 

main.o: main.c
    gcc -c main.c -I hello

hello.o: hello/hello.c
    gcc -c hello/hello.c
    
clean:
    rm -rf main.o hello.o app

或者進(jìn)階版

TARGET = app
SRCS = main.c hello/hello.c
INC = -Ihello
OJBS = $(SRCS:.c=.o)

$(TARGET): $(OJBS)
    echo $(OJBS)
    $(CC) -o $@ $^

%.o: %.c
    $(CC) $(INC) -o $@ -c $<

clean:
    rm -rf $(TARGET) $(OJBS)

CMake

CMake是一個(gè)跨平臺(tái)的安裝(編譯)工具,可以用簡(jiǎn)單的語句來描述所有平臺(tái)的安裝(編譯過程)。他能夠輸出各種各樣的makefile或者project文件,能測(cè)試編譯器所支持的C++特性,類似UNIX下的automake。 CMake 的組態(tài)檔取名為 CMakeLists.txt,Cmake 并不直接建構(gòu)出最終的軟件,而是產(chǎn)生標(biāo)準(zhǔn)的建構(gòu)檔(如 Unix 的 Makefile 或 Windows Visual C++ 的 projects/workspaces),然后再依一般的建構(gòu)方式使用。

如下為當(dāng)前目錄下CMakeLists.txt文件內(nèi)容

cmake_minimum_required(VERSION 2.8)
project(app)

set(hello hello/hello.c hello/hello.h)
include_directories(hello)

add_executable(app main.c ${hello})

執(zhí)行命令

mkdir build && cd build
cmake ..  # 在build目錄下生成makefile
make  # 在build目錄生成可執(zhí)行程序app

以上是老版本CMake的寫法,CMake 3.xx版本增加了模塊化target的寫法,推薦使用。

XMake

XMake 是一個(gè)基于 Lua 的輕量級(jí)跨平臺(tái)構(gòu)建工具,使用 xmake.lua 維護(hù)項(xiàng)目構(gòu)建,相比 makefile/cmake,配置語法更加簡(jiǎn)潔直觀,對(duì)新手非常友好,短時(shí)間內(nèi)就能快速入門,能夠讓用戶把更多的精力集中在實(shí)際的項(xiàng)目開發(fā)上。

xmake.lua可通過xmake命令生成,更加靈活的配置修要手動(dòng)修改,內(nèi)容如下

target("app")
    set_kind("binary")
    add_files("main.c")
    add_files("hello/hello.c")
    add_includedirs("hello")

有了xmake.lua后,執(zhí)行命令

xmake  # 編譯
xmake run app  # 運(yùn)行
xmake run -d app  # gdb調(diào)試

Scons

Scons是一個(gè)開放源碼、以Python語言編碼的自動(dòng)化構(gòu)建工具,可用來替代make編寫復(fù)雜的makefile。并且scons是跨平臺(tái)的,只要

Scons腳本寫的好,可以在Linux和Windows下隨意編譯。

SCons 的設(shè)計(jì)目標(biāo)就是讓開發(fā)人員更容易、更可靠和更快速的建造軟件。

上述工程,需要在工程目錄創(chuàng)建一個(gè)SConstruct文件,內(nèi)容如下

Program(
    target = "app", 
    source = ["main.c", "hello/hello.c"], 
    CPPPATH = ["hello"]
)

然后在命令行執(zhí)行

scons  # 編譯
scons -c  # 清除編譯結(jié)果

Ninja

Ninja 是Google的一名程序員推出的注重速度的構(gòu)建工具,一般在Unix/Linux上的程序通過make/makefile來構(gòu)建編譯,而Ninja通過將編譯任務(wù)并行組織,大大提高了構(gòu)建速度,Ninja的定位非常清晰,就是達(dá)到更快的構(gòu)建速度。

如上工程,ninja編譯需要build.ninja文件。如果有CMakeLists.txt,可通過 cmake -G Ninja 生成,沒有的話,可以手寫一個(gè),內(nèi)容如下

ninja_required_version = 1.5

# 編譯
rule cc
  command = gcc -c -Ihello $in -o $out
  description = compiling $in to $out ...

build main.o: cc main.c
build hello.o: cc hello/hello.c

# 鏈接
rule link
  command = gcc $in -o $out
  description = linking $in to $out ...

build app: link main.o hello.o

然后在命令行執(zhí)行

ninja  # 編譯
ninja -t clean  # 清除編譯結(jié)果

Meson

Meson(The Meson Build System)是個(gè)項(xiàng)目構(gòu)建系統(tǒng),如Makefile,automake,CMake等等。Meson是一個(gè)Python實(shí)現(xiàn)的開源項(xiàng)目,編譯需要Ninja命令, 其思想是,開發(fā)人員花費(fèi)在構(gòu)建調(diào)試上的每一秒都是浪費(fèi),同樣等待構(gòu)建過程直到真正開始編譯都是不值得的。

Meson需要meson.build文件,手動(dòng)編輯,內(nèi)容如下

project('app', 'c')
src = ['main.c', 'hello/hello.c']
inc = 'hello'
executable('app', src, include_directories: inc)

然后在命令行執(zhí)行

meson _build  # 生成_build(這里加下劃線是為了與cmake的build區(qū)分下)目錄,下面有build.ninja
ninja -C _build  # 編譯

當(dāng)前很多開源軟件構(gòu)建工具已經(jīng)轉(zhuǎn)meson了,以前的開源軟件按照老套路./configure && make && sudo make install 要換成meson build && ninja -C build && sudo ninja -C build install了。

其他

當(dāng)然,還有Bazel,Buck,qmakeAutotools等構(gòu)建系統(tǒng),就不一一示范了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容