Skip to content

Commit ee034f3

Browse files
committed
build: Install musl-based toolchains in the docker.
1 parent e622133 commit ee034f3

File tree

3 files changed

+95
-4
lines changed

3 files changed

+95
-4
lines changed

Dockerfile

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
FROM ubuntu:24.04
22

3-
# Install dependencies
4-
RUN apt update && apt install -y \
3+
RUN apt update
4+
5+
RUN apt install -y \
56
bison \
67
file \
78
flex \
@@ -18,16 +19,26 @@ RUN apt update && apt install -y \
1819
gcc-mipsel-linux-gnu \
1920
gcc-powerpc-linux-gnu \
2021
git \
21-
libncurses-dev \
2222
libtool \
2323
m4 \
2424
make \
2525
patch \
2626
pkg-config \
2727
python3.12 \
28+
python3-pip \
2829
libpython3-dev \
2930
texinfo \
3031
wget \
3132
xz-utils
3233

34+
# Remove externally-managed constrainsts since we run inside a docker...
35+
RUN rm -f /usr/lib/python3.*/EXTERNALLY-MANAGED
36+
RUN python3.12 -m pip install requests
37+
38+
COPY src/docker_utils/download_musl_toolchains.py .
39+
RUN python3.12 -u download_musl_toolchains.py
40+
3341
WORKDIR /app/gdb
42+
43+
ENTRYPOINT ["/entrypoint.sh"]
44+
CMD ["bash"]

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ help:
2727
@echo ""
2828
@echo " make clean"
2929

30-
build/build-docker-image.stamp: Dockerfile
30+
build/build-docker-image.stamp: Dockerfile src/docker_utils/download_musl_toolchains.py
3131
mkdir -p build
3232
docker buildx build --tag gdb-static .
3333
touch build/build-docker-image.stamp
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#!/usr/bin/env python3.12
2+
3+
import requests
4+
import tarfile
5+
import os
6+
import shutil
7+
8+
from pathlib import Path
9+
10+
ARCHS = {
11+
"x86_64" : "https://musl.cc/x86_64-linux-musl-cross.tgz",
12+
"arm" : "https://musl.cc/arm-linux-musleabi-cross.tgz",
13+
"aarch64" : "https://musl.cc/aarch64-linux-musl-cross.tgz",
14+
"powerpc" : "https://musl.cc/powerpc-linux-musl-cross.tgz",
15+
"mips" : "https://musl.cc/mips-linux-musl-cross.tgz",
16+
"mipsel" : "https://musl.cc/mipsel-linux-musl-cross.tgz",
17+
}
18+
CHUNK_SIZE = 65536
19+
MUSL_TOOLCHAINS_DIR = Path("/musl-toolchains")
20+
ENTRYPOINT = "/entrypoint.sh"
21+
22+
def download_file(url: str, filename: str):
23+
print(f"Downloading {filename}")
24+
with requests.get(url, stream=True) as r:
25+
r.raise_for_status()
26+
with open(filename, "wb") as f:
27+
for chunk in r.iter_content(chunk_size=CHUNK_SIZE):
28+
f.write(chunk)
29+
print(f"{filename} downloaded.")
30+
31+
def extract_tarball(filename: str, dst: Path):
32+
print(f"Extracting {filename}")
33+
with tarfile.open(filename, "r:gz") as tar:
34+
tar.extractall(path=dst)
35+
print(f"{filename} extracted")
36+
37+
def add_to_path(curr_path: str, package_path: Path):
38+
return curr_path + ":" + str((package_path / "bin").resolve())
39+
40+
41+
def main():
42+
os.mkdir(MUSL_TOOLCHAINS_DIR)
43+
44+
updated_path = "$PATH"
45+
for arch, url in ARCHS.items():
46+
filename = url.split("/")[-1]
47+
download_file(url, filename)
48+
extract_tarball(filename, MUSL_TOOLCHAINS_DIR)
49+
updated_path = add_to_path(updated_path, MUSL_TOOLCHAINS_DIR / filename.removesuffix(".tgz"))
50+
51+
# Fix the x86_64 dynamic loader if needed:
52+
# Unfortunately, the internal gdb build scripts builds some binaries (that generate documentation)
53+
# in a dynamic manner.
54+
#
55+
# Because we may use a musl-based toolchain, this means that we need to set-up the dynamic loader.
56+
# The fix may seem a little hacky, but it is simple, and is the best we can do.
57+
if "x86_64" in ARCHS:
58+
x86_toolchain_name = ARCHS["x86_64"].split("/")[-1].removesuffix(".tgz")
59+
x86_toolchain_path = MUSL_TOOLCHAINS_DIR / x86_toolchain_name
60+
x86_loader_path = x86_toolchain_path / "x86_64-linux-musl" / "lib" / "libc.so"
61+
shutil.copy2(x86_loader_path, "/lib/ld-musl-x86_64.so.1")
62+
63+
# Create the entrypoint with the updated path.
64+
with open(ENTRYPOINT, mode="w") as f:
65+
f.write(
66+
f"""#!/usr/bin/env bash
67+
export PATH="{updated_path}"
68+
exec "$@"
69+
""")
70+
71+
# Make sure we can execute the entrypoint.
72+
os.chmod(ENTRYPOINT, 0o755)
73+
74+
# Append the path to bash.bashrc so that other users will have these paths.
75+
with open("/etc/bash.bashrc", mode="a") as f:
76+
f.write(f"\nexport PATH=\"{updated_path}\"")
77+
78+
79+
if __name__ == "__main__":
80+
main()

0 commit comments

Comments
 (0)