Hello. Recently, I joined a project of Android / iOS SDK written in C language, and I am doing various trial and error about automation of build and unit test.
At first I was doing a lot with Makefile, but I tried using a build tool called ninja-build that I wanted to try before, and I will share it because it was unexpectedly convenient. It was also used to build apple / swift, so it may be famous among C and C ++ people. It's open source and seems to be implemented in C ++. https://ninja-build.org https://github.com/ninja-build/ninja
$ brew install ninja
$ ninja --version
1.7.1
For example, the build script written as follows in the Makefile.
obj=clang -c -g
app=clang
add:
$(obj) add.c
addapp: add
$(obj) addapp.c -o addapp.o
main: addapp add
$(app) addapp.o add.o -o main
Even if I rewrite add.c, the main job does not detect the difference. (* Addition: [This was just the wrong way to write the Makefile. You can also make a differential build with the Makefile!](# Comment-78827f4ccd5b44133347))
c $ make main
clang -c -g add.c -o add.o
clang -c -g addapp.c -o addapp.o
clang addapp.o add.o -o main
c $ make main
make: `main' is up to date.
c $ echo "// hello" >> add.c
c $ make main
make: `main' is up to date.
You can easily solve the differential build problem by writing the dependencies in ninja-build.
build.ninja
rule obj
command=clang -c -g $in -o $out
rule app
command=clang $in -o $out
build addapp.o: obj addapp.c
build add.o: obj add.c
build main: app addapp.o add.o
default main
c $ ninja -v
[1/3] clang -c -g add.c -o add.o
[2/3] clang -c -g addapp.c -o addapp.o
[3/3] clang addapp.o add.o -o main
c $ ninja -v
ninja: no work to do.
c $ echo "// hello" >> add.c
c $ ninja -v
[1/2] clang -c -g add.c -o add.o
[2/2] clang addapp.o add.o -o main
I only rewrote add.c, so I left addapp.o as it is. The syntax is simple and the output is easy to understand.
I would like you to refer to the document and reference site for how to write it, but since the directory can be specified as the target of difference detection ($ in), I think that it can be used for large projects.
Since it is not possible to do difficult things like reading environment variables, I think that in actual operation you will have to write a separate script that outputs the build.ninja file and executes the ninja command.
ninja = ninja -v
build-hoge:
./createbuildninja.sh hoge
$(ninja)
build-fuga:
./createbuildninja.sh fuga
$(ninja)
As an aside, Xcode 8 has significantly improved the performance of LLVM and supports complex differential builds. was. I would like to continue to verify various things in the future.
reference: http://bigoyayubi.hatenablog.com/entry/2015/08/02/222909 http://mattn.kaoriya.net/software/ninja/20140121141906.htm
Recommended Posts