Thin wrapper to build Linux kernels
pip install tuxmake==1.29.3
TuxMake is a thin python+docker wrapper for building Linux kernels.
Python is used to provide a common command-line interface for building across architectures, targets, and toolchains.
Docker is used to provide isolated build environments, and allows builds to be reproducible.
Requirements: python 3.6+, docker
[[TOC]]
Building Linux is easy, right? You just run "make defconfig; make"!
It gets complicated when you want to support the following combinations:
Each of those items requires specific configuration, and supporting all combinations becomes difficult. TuxMake seeks to simplify Linux kernel building by supporting dockerized build environments and providing a consistent command line interface to each of those combinations listed above.
For example, wouldn't it be great if a user could install docker and then check out a Linux source tree and run:
tuxmake --kconfig defconfig --target-arch arm64 --toolchain clang-9
While bit-for-bit reproducible builds are out of scope for the initial version of this project, the above command should be portable such that if there is a problem with the build, any other user should be able to use the same command to produce the same build problem.
Such an interface provides portability and simplicity, making arbitrary Linux kernel build combinations easier for developers.
TuxMake should provide strong defaults, making the easy cases easy. By default, tuxmake will build a config, a kernel, and modules and dtbs if applicable. Additional targets can be specified with command line flags.
Every step of the build should be clearly shown so that there is no mystery or obfuscation during the build.
It should not 'fix' any problems in Linux - rather it should provide a thin veneer over the top of the existing Linux source tree to make building Linux easier. e.g. if a build combination fails in Linux, it should fail the same way when building with TuxMake.
The resulting build artifacts and meta-data should be automatically saved in a single local per-build directory.
Finally, TuxMake must be well tested and reliable so that developers can rely on it to save time and make it worth the additional complexity that another layer of abstraction introduces.
For each use-case shown, an example tuxmake invocation is shown, followed by the example set of docker commands that would need to be run to complete the build request.
Note that artifact handling is not dealt with here.
By default tuxmake will do a defconfig build with the latest gcc for the native architecture.
tuxmake
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux -it tuxbuild/build-gcc-9_x86 make defconfig
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux -it tuxbuild/build-gcc-9_x86 make -j8
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux -it tuxbuild/build-gcc-9_x86 make -j8 modules
tuxmake --kconfig defconfig --target-arch x86_64 --toolchain gcc-9
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux -it tuxbuild/build-gcc-9_x86 make defconfig
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux -it tuxbuild/build-gcc-9_x86 make -j8
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux -it tuxbuild/build-gcc-9_x86 make -j8 modules
tuxmake --kconfig defconfig --target-arch arm64 --toolchain gcc-9
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm64 --env CROSS_COMPILE=aarch64-linux-gnu- -it tuxbuild/build-gcc-9_arm64 make -j8 defconfig
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm64 --env CROSS_COMPILE=aarch64-linux-gnu- -it tuxbuild/build-gcc-9_arm64 make -j8 Image
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm64 --env CROSS_COMPILE=aarch64-linux-gnu- -it tuxbuild/build-gcc-9_arm64 make -j8 modules
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm64 --env CROSS_COMPILE=aarch64-linux-gnu- -it tuxbuild/build-gcc-9_arm64 make -j8 dtbs
tuxmake --kconfig defconfig --target-arch x86_64 --toolchain clang-9
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env CC=clang --env HOSTCC=clang -it tuxbuild/build-clang-9 make defconfig
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env CC=clang --env HOSTCC=clang -it tuxbuild/build-clang-9 make -j8
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env CC=clang --env HOSTCC=clang -it tuxbuild/build-clang-9 make -j8 modules
tuxmake --kconfig multi_v7_defconfig --target-arch arm --toolchain clang-9
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm --env CC=clang --env HOSTCC=clang --env CROSS_COMPILE=arm-linux-gnueabihf- -it tuxbuild/build-clang-9_arm64 make -j8 multi_v7_defconfig
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm --env CC=clang --env HOSTCC=clang --env CROSS_COMPILE=arm-linux-gnueabihf- -it tuxbuild/build-clang-9_arm64 make -j8 zImage
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm --env CC=clang --env HOSTCC=clang --env CROSS_COMPILE=arm-linux-gnueabihf- -it tuxbuild/build-clang-9_arm64 make -j8 modules
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux --env ARCH=arm --env CC=clang --env HOSTCC=clang --env CROSS_COMPILE=arm-linux-gnueabihf- -it tuxbuild/build-clang-9_arm64 make -j8 dtbs
tuxmake --targets htmldocs
docker run --rm -u $(id -u):$(id -g) -v $(pwd):/linux -w /linux -it tuxbuild/build-htmldocs make htmldocs
tuxmake --targets kernel,selftests,htmldocs
import tuxmake
build = tuxmake.build("/path/to/linux")
for artifact in build.artifacts:
print(artifact)
doc_build = tuxmake.build("/path/to/linux", targets=[tuxmake.targets.htmldocs])
full_build = tuxmake.build("/path/to/linux", targets=tuxmake.targets.all)
Required.
Every build must have a .config
. If a .config
is provided, it must be
updated with make olddefconfig
. If a config is not provided, a config can be
built from the source tree using defconfig files, special make targets, and/or
config fragments.
IN: Config arguments
OUT: config file
Required.
Building the actual kernel has different make targets depending on architecture as well as different output kernel types/filenames.
In addition to the kernel binary, other artifacts might include a debug kernel image and kernel header files.
IN: config file
OUT: kernel image file
Optional.
When a .config file requests "MODULES", modules might be built.
IN:
OUT: modules.tgz
Optional.
Some architectures allow DTBs to be built.
IN:
OUT: Directory tree of .dtb
files
Optional.
The tools/perf
directory might be built.
IN:
OUT: perf binaries
Optional.
The tools/testing/selftests
directory might be built.
IN:
OUT: kselftest artifacts
Optional.
The Documentation
directory might be built.
IN:
OUT: documentation artifacts
Each build stage will produce artifacts. Some artifacts (like .config
) need
to be passed to subsequent build stages. All artifacts should be preserved in a
local per-build directory.
Build artifacts will be saved to a path defined by KBUILD_OUTPUT
, if set.
Things like modules need to be installed with make modules_install
into the
build directory.
KBUILD_BUILD_USER
, KBUILD_BUILD_HOST
, and KBUILD_BUILD_TIMESTAMP
may be
set to define information about the build environment. These values are built
into the kernel, so to have truly reproducible builds, they should be set
consistently/statically.
Passing -s
to make will make the build quieter by eliminating output except
for error output.
Passing -k
to make will the build keep going after failure, which is often
desirable.
Kernel config needs to handle a user supplied config, config fragments, and configs that are in tree.
tuxmake will make clean
by default, and provide a flag to disable it if needed.
ccache and sccache should be supported, but the details are to be determined.
Initially the following targets will be supported:
tuxmake needs to provide default containerized environments, but also have the ability to specify alternative container environments.
The following features are desirable and should be possible to do with TuxMake.