ninja:一個簡單的構(gòu)建方式
大家好!每隔一段時間,我就會發(fā)現(xiàn)一款我非常喜歡的新軟件,今天我想說說我最近喜歡的一款軟件:ninja!
增量構(gòu)建很有用
我做了很多小項(xiàng)目,在這些項(xiàng)目中,我想設(shè)置增量構(gòu)建。例如,現(xiàn)在我正在寫一本關(guān)于 bash 的雜志,雜志的每一頁都有一個 .svg文件。我需要將 SVG 轉(zhuǎn)換為 PDF,我的做法是這樣的:
for i in *.svgdosvg2pdf $i $i.pdf # or ${i/.svg/.pdf} if you want to get really fancydone
這很好用,但是我的 svg2pdf 腳本有點(diǎn)慢(它使用 Inkscape),而且當(dāng)我剛剛只更新了一頁的時候,必須等待 90 秒或者其他什么時間來重建所有的 PDF 文件,這很煩人。
構(gòu)建系統(tǒng)是讓人困惑的
在過去,我對使用 make 或 bazel 這樣的構(gòu)建系統(tǒng)來做我的小項(xiàng)目一直很反感,因?yàn)?nbsp;bazel 是個大而復(fù)雜的東西,而 make 對我來說感覺有點(diǎn)神秘。我真的不想使用它們中的任何一個。
所以很長時間以來,我只是寫了一個 bash 腳本或者其他的東西來進(jìn)行構(gòu)建,然后就認(rèn)命了,有時候只能等一分鐘。
ninja 是一個極其簡單的構(gòu)建系統(tǒng)
但 ninja 并不復(fù)雜!以下是我所知道的關(guān)于 ninja 構(gòu)建文件的語法:創(chuàng)建一個 rule 和一個 build:
rule 有一個命令(command)和描述(description)參數(shù)(描述只是給人看的,所以你可以知道它在構(gòu)建你的代碼時在做什么)。
rule svg2pdfcommand = inkscape $in --export-text-to-path --export-pdf=$outdescription = svg2pdf $in $out
build 的語法是 build output_file: rule_name input_files。下面是一個使用 svg2pdf 規(guī)則的例子。輸出在規(guī)則中的 $out 里,輸入在 $in 里。
build pdfs/variables.pdf: svg2pdf variables.svg
這就完成了!如果你把這兩個東西放在一個叫 build.ninja 的文件里,然后運(yùn)行 ninja,ninja 會運(yùn)行 inkscape variables.svg --export-text-to-path --export-pdf=pdfs/variables.pdf。然后如果你再次運(yùn)行它,它不會運(yùn)行任何東西(因?yàn)樗梢愿嬖V你已經(jīng)構(gòu)建了 pdfs/variables.pdf,而且是最新的)。
Ninja 還有一些更多的功能(見手冊),但我還沒有用過。它最初是為 Chromium 構(gòu)建的,所以即使只有一個小的功能集,它也能支持大型構(gòu)建。
ninja 文件通常是自動生成的
ninja 的神奇之處在于,你不必使用一些混亂的構(gòu)建語言,它們很難記住,因?yàn)槟悴唤?jīng)常使用它(比如 make),相反,ninja 語言超級簡單,如果你想做一些復(fù)雜的事情,那么你只需使用任意編程語言生成你想要的構(gòu)建文件。
我喜歡寫一個 build.py 文件,或者像這樣的文件,創(chuàng)建 ninja 的構(gòu)建文件,然后運(yùn)行 ninja:
with open('build.ninja', 'w') as ninja_file:# write some rulesninja_file.write("""rule svg2pdfcommand = inkscape $in --export-text-to-path --export-pdf=$outdescription = svg2pdf $in $out""")# some for loop with every file I need to buildfor filename in things_to_convert:ninja_file.write(f"""build {filename.replace('svg', 'pdf')}: svg2pdf {filename}""")# run ninjaimport subprocesssubprocess.check_call(['ninja'])
我相信有一堆 ninja 的最佳實(shí)踐,但我不知道。對于我的小項(xiàng)目而言,我發(fā)現(xiàn)它很好用。
meson 是一個生成 ninja 文件的構(gòu)建系統(tǒng)
我對 Meson 還不太了解,但最近我在構(gòu)建一個 C 程序 (plocate,一個比 locate 更快的替代方案)時,我注意到它有不同的構(gòu)建說明,而不是通常的 ./configure; make; make install:
meson builddircd builddirninja
看起來 Meson 是一個可以用 ninja 作為后端的 C/C++/Java/Rust/Fortran 構(gòu)建系統(tǒng)。
就是這些!
我使用 ninja 已經(jīng)有幾個月了。我真的很喜歡它,而且它幾乎沒有給我?guī)碜屓祟^疼的構(gòu)建問題,這讓我感覺非常神奇。

























