[SWIFT] Ninja-build with smart differential build

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

Ninja-build with smart differential build
Build Doma1 with Ant
Build Growai with Centos7
Build Java with Wercker
Build bazel with alpine
Build GitLab / Mattermost with DockerForWindows
Build softether VPN with Centos7.
Build docker environment with WSL
Build Ubuntu 18.04.5 with dual boot
Build AWS Lambda with Quarkus
[Introduction] Build MVC with Scala
Build DynamoDB local with Docker
Build Couchbase local environment with Docker
Build a Java project with Gradle
Build a Node.js environment with Docker
Build a Tomcat 8.5 environment with Pleiades 4.8
Build PlantUML environment with VSCode + Docker
Build environment with vue.js + rails + docker
Build Rails environment with Docker Compose
Build a web application with Javalin
Java build with mac vs code
Build jooby development environment with Eclipse
Build docker + laravel environment with laradock
Build WebRTC Janus with Docker container
Spring Boot gradle build with Docker