Skip to content

Commit eb62d39

Browse files
committed
buildroot: Rewrite build script in Python
This is the last shell script in this repository and further improvements to it are needed. Rewrite it in Python to make future modifications easier, as the majority of ClangBuiltLinux repositories use Python as the main scripting language now. Remove the shell linting, as this repository no longer uses it. As part of the rewrite, this prepares for moving to GitHub releases for rootfs uploads by moving the final images to 'buildroot/out' versus 'images' directly. Signed-off-by: Nathan Chancellor <nathan@kernel.org>
1 parent 012c3ac commit eb62d39

4 files changed

Lines changed: 147 additions & 95 deletions

File tree

.github/workflows/main.yml

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Run shellcheck and shfmt on all shell files and several Python linters on all Python files in this repository
1+
# Run several Python linters on all Python files in this repository
22
name: Lint checks
33
on: [push, pull_request]
44
jobs:
@@ -10,7 +10,3 @@ jobs:
1010
uses: ClangBuiltLinux/actions-workflows/.github/workflows/python_lint.yml@main
1111
with:
1212
python_version: ${{ matrix.version }}
13-
shellcheck:
14-
uses: ClangBuiltLinux/actions-workflows/.github/workflows/shellcheck.yml@main
15-
shfmt:
16-
uses: ClangBuiltLinux/actions-workflows/.github/workflows/shfmt.yml@main

buildroot/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
src/
2+
out/

buildroot/rebuild.py

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
#!/usr/bin/env python3
2+
3+
from argparse import ArgumentParser
4+
import os
5+
from pathlib import Path
6+
import shutil
7+
import subprocess
8+
9+
BUILDROOT_VERSION = '2022.02'
10+
SUPPORTED_ARCHES = [
11+
'arm64',
12+
'arm64be',
13+
'arm',
14+
'm68k',
15+
'mips',
16+
'mipsel',
17+
'ppc32',
18+
'ppc64',
19+
'ppc64le',
20+
'riscv',
21+
's390',
22+
'x86',
23+
'x86_64',
24+
]
25+
ROOT_FOLDER = Path(__file__).resolve().parent
26+
OUT_FOLDER = Path(ROOT_FOLDER, 'out')
27+
SRC_FOLDER = Path(ROOT_FOLDER, 'src')
28+
29+
30+
def buildroot_make(make_arg=None, **kwargs):
31+
make_cmd = ['make', f"-j{os.cpu_count()}"]
32+
if make_arg:
33+
make_cmd.append(make_arg)
34+
subprocess.run(make_cmd, **kwargs, check=True, cwd=SRC_FOLDER)
35+
36+
37+
def build_image(architecture, edit_config):
38+
buildroot_make('clean')
39+
40+
config = Path(ROOT_FOLDER, f"{architecture}.config")
41+
# Python documentation notes that when subprocess.Popen()'s env parameter
42+
# is not None, the current process's envirionment is not inherited, which
43+
# causes issues because PATH is not inherited. Add BR2_DEFCONFIG to the
44+
# environment, rather than replacing it (we support Python 3.8, so we
45+
# cannot use 'os.environ | {...}').
46+
buildroot_make('defconfig', env={**os.environ, 'BR2_DEFCONFIG': config})
47+
if edit_config:
48+
buildroot_make('menuconfig')
49+
buildroot_make('savedefconfig')
50+
51+
buildroot_make()
52+
53+
OUT_FOLDER.mkdir(exist_ok=True, parents=True)
54+
55+
images = [Path(SRC_FOLDER, 'output/images/rootfs.cpio')]
56+
# For x86_64, we also build an ext4 image for UML
57+
if architecture == 'x86_64':
58+
images.append(images[0].with_suffix('.ext4'))
59+
60+
for image in images:
61+
if not image.exists():
62+
raise FileNotFoundError(
63+
f"{image} could not be found! Did the build error?")
64+
zstd_cmd = [
65+
'zstd', '-f', '-19', '-o',
66+
Path(OUT_FOLDER, f"{architecture}-{image.name}.zst"), image
67+
]
68+
subprocess.run(zstd_cmd, check=True)
69+
70+
71+
def download_and_extract_buildroot():
72+
SRC_FOLDER.mkdir(parents=True)
73+
74+
tarball = Path(ROOT_FOLDER, f"buildroot-{BUILDROOT_VERSION}.tar.gz")
75+
tarball.unlink(missing_ok=True)
76+
77+
curl_cmd = [
78+
'curl', '-LSs', '-o', tarball,
79+
f"https://buildroot.org/downloads/{tarball.name}"
80+
]
81+
subprocess.run(curl_cmd, check=True)
82+
83+
sha256_cmd = ['sha256sum', '--quiet', '-c', f"{tarball.name}.sha256"]
84+
subprocess.run(sha256_cmd, check=True, cwd=ROOT_FOLDER)
85+
86+
tar_cmd = [
87+
'tar', '-C', SRC_FOLDER, '--strip-components=1', '-axf', tarball
88+
]
89+
subprocess.run(tar_cmd, check=True)
90+
91+
tarball.unlink(missing_ok=True)
92+
93+
94+
def download_buildroot_if_necessary():
95+
if SRC_FOLDER.exists():
96+
# Make support/scripts/setlocalversion do nothing because we are in a
97+
# git repository so it will return information about this repo, not
98+
# Buildroot
99+
setlocalversion = Path(SRC_FOLDER, 'support/scripts/setlocalversion')
100+
setlocalversion.write_text('', encoding='utf-8')
101+
102+
installed_version = subprocess.run(['make', 'print-version'],
103+
capture_output=True,
104+
check=True,
105+
cwd=SRC_FOLDER,
106+
text=True).stdout.strip()
107+
if installed_version != BUILDROOT_VERSION:
108+
shutil.rmtree(SRC_FOLDER)
109+
download_and_extract_buildroot()
110+
else:
111+
download_and_extract_buildroot()
112+
113+
114+
def parse_arguments():
115+
parser = ArgumentParser()
116+
117+
parser.add_argument(
118+
'-a',
119+
'--architectures',
120+
choices=[*SUPPORTED_ARCHES, 'all'],
121+
default=SUPPORTED_ARCHES,
122+
help=
123+
'The architectures to build images for. Defaults to all supported architectures.',
124+
nargs='+')
125+
parser.add_argument(
126+
'-e',
127+
'--edit-config',
128+
action='store_true',
129+
help='Edit configuration file and run savedefconfig on result')
130+
131+
return parser.parse_args()
132+
133+
134+
if __name__ == '__main__':
135+
args = parse_arguments()
136+
137+
if not shutil.which('zstd'):
138+
raise RuntimeError(
139+
'zstd could not be found on your system, please install it!')
140+
141+
architectures = SUPPORTED_ARCHES if 'all' in args.architectures else args.architectures
142+
143+
download_buildroot_if_necessary()
144+
for arch in architectures:
145+
build_image(arch, args.edit_config)

buildroot/rebuild.sh

Lines changed: 0 additions & 90 deletions
This file was deleted.

0 commit comments

Comments
 (0)