Skip to content

Commit 0d3ae2a

Browse files
committed
linux: support building Python and dependencies with musl
I believe this works! We had to use --disable-shared in various places because we can't build shared libraries with musl. In theory this should be possible. I suspect the musl-clang wrapper is passing conflicting compiler/linker flags or something. C++ compilation doesn't work with musl. So we disabled C++ compilation in some components. This would be a reasonable change otherwise as we should never use the C++ bits. Some hacks were required here and there. For example, OpenSSL insists on looking for kernel headers, which we don't have. So we had to disable some OpenSSL functionality to get things to build. Disabling secure memory is sounds a bit scary. I left a TODO to track investigating that.
1 parent f36b5e6 commit 0d3ae2a

18 files changed

+169
-75
lines changed

build-linux.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
def bootstrap():
2626
parser = argparse.ArgumentParser()
27+
parser.add_argument('--musl', action='store_true')
2728
parser.add_argument('--optimized', action='store_true')
2829

2930
args = parser.parse_args()
@@ -40,6 +41,8 @@ def bootstrap():
4041
os.environ['PATH'] = '%s:%s' % (str(VENV / 'bin'), os.environ['PATH'])
4142
os.environ['PYTHONPATH'] = str(ROOT)
4243

44+
if args.musl:
45+
os.environ['PYBUILD_MUSL'] = '1'
4346
if args.optimized:
4447
os.environ['PYBUILD_OPTIMIZED'] = '1'
4548

@@ -58,6 +61,9 @@ def run():
5861
basename = 'cpython-linux64'
5962
extra = ''
6063

64+
if 'PYBUILD_MUSL' in os.environ:
65+
basename += '-musl'
66+
extra = '-musl'
6167
if 'PYBUILD_OPTIMIZED' in os.environ:
6268
basename += '-pgo'
6369
extra = '-pgo'

cpython-linux/Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ COMMON_DEPENDS := \
1111

1212
PLATFORM := linux64
1313

14+
ifdef PYBUILD_MUSL
15+
PLATFORM := $(PLATFORM)-musl
16+
endif
17+
1418
BASE_TOOLCHAIN_DEPENDS := \
1519
$(OUTDIR)/binutils-linux64.tar \
1620
$(OUTDIR)/gcc-linux64.tar \
@@ -22,7 +26,7 @@ TOOLCHAIN_DEPENDS := \
2226
$(OUTDIR)/musl-linux64.tar \
2327
$(NULL)
2428

25-
default: $(OUTDIR)/cpython-linux64$(if $(PYBUILD_OPTIMIZED),-pgo,).tar
29+
default: $(OUTDIR)/cpython-$(PLATFORM)$(if $(PYBUILD_OPTIMIZED),-pgo,).tar
2630

2731
$(OUTDIR)/image-%.tar: $(HERE)/%.Dockerfile $(COMMON_DEPENDS)
2832
$(BUILD) image-$*

cpython-linux/build-bdb.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf db-${BDB_VERSION}.tar.gz
1513

@@ -19,7 +17,8 @@ CLFAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" ..
1917
--build=x86_64-unknown-linux-gnu \
2018
--target=${TARGET} \
2119
--prefix=/tools/deps \
22-
--enable-dbm
20+
--enable-dbm \
21+
--disable-shared
2322

2423
make -j `nproc`
2524
make -j `nproc` install DESTDIR=/build/out

cpython-linux/build-bzip2.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pushd bzip2-${BZIP2_VERSION}
1515

1616
make -j `nproc` install \
1717
AR=/tools/host/bin/${TOOLCHAIN_PREFIX}ar \
18-
CC=clang \
18+
CC="${CC}" \
1919
CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" \
2020
LDFLAGS="${EXTRA_TARGET_LDFLAGS}" \
2121
PREFIX=/build/out/tools/deps

cpython-linux/build-cpython.sh

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/clang-linux64/bin:/tools/host/bin:/tools/deps/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
# configure somehow has problems locating llvm-profdata even though it is in
1513
# PATH. The macro it is using allows us to specify its path via an
@@ -26,6 +24,8 @@ tar -xf Python-${PYTHON_VERSION}.tar.xz
2624
cat Setup.local
2725
mv Setup.local Python-${PYTHON_VERSION}/Modules/Setup.local
2826

27+
cat Makefile.extra
28+
2929
pushd Python-${PYTHON_VERSION}
3030

3131
cp Modules/readline.c Modules/readline-libedit.c
@@ -44,6 +44,12 @@ CFLAGS="-fPIC -I/tools/deps/include -I/tools/deps/include/ncurses"
4444
CPPFLAGS=$CFLAGS
4545
LDFLAGS="-L/tools/deps/lib"
4646

47+
if [ "${CC}" = "musl-clang" ]; then
48+
CFLAGS="${CFLAGS} -static"
49+
CPPFLAGS="${CPPFLAGS} -static"
50+
LDFLAGS="${LDFLAGS} -static"
51+
fi
52+
4753
CONFIGURE_FLAGS="--prefix=/install --with-openssl=/tools/deps --without-ensurepip"
4854

4955
# TODO support --with-lto

cpython-linux/build-gdbm.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf gdbm-${GDBM_VERSION}.tar.gz
1513

@@ -21,6 +19,7 @@ CLFAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" ./
2119
--build=x86_64-unknown-linux-gnu \
2220
--target=${TARGET} \
2321
--prefix=/tools/deps \
22+
--disable-shared \
2423
--enable-libgdbm-compat
2524

2625
make -j `nproc`

cpython-linux/build-libedit.sh

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,25 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf libedit-${LIBEDIT_VERSION}.tar.gz
1513

1614
pushd libedit-${LIBEDIT_VERSION}
1715

1816
cflags="${EXTRA_TARGET_CFLAGS} -fPIC -I/tools/deps/include -I/tools/deps/include/ncurses"
1917

18+
# musl doesn't define __STDC_ISO_10646__, so work around that.
19+
if [ "${CC}" = "musl-clang" ]; then
20+
cflags="${cflags} -D__STDC_ISO_10646__=201103L"
21+
fi
22+
2023
# Install to /tools/deps/libedit so it doesn't conflict with readline's files.
2124
CLFAGS="${cflags}" CPPFLAGS="${cflags}" LDFLAGS="-L/tools/deps/lib" \
2225
./configure \
2326
--build=x86_64-unknown-linux-gnu \
2427
--host=${TARGET} \
2528
--prefix=/tools/deps/libedit \
29+
--disable-shared
2630

2731
make -j `nproc`
2832
make -j `nproc` install DESTDIR=/build/out

cpython-linux/build-libffi.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf libffi-${LIBFFI_VERSION}.tar.gz
1513

@@ -18,7 +16,8 @@ pushd libffi-${LIBFFI_VERSION}
1816
CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" ./configure \
1917
--build=x86_64-unknown-linux-gnu \
2018
--host=${TARGET} \
21-
--prefix=/tools/deps
19+
--prefix=/tools/deps \
20+
--disable-shared
2221

2322
make -j `nproc`
2423
make -j `nproc` install DESTDIR=/build/out

cpython-linux/build-ncurses.sh

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf ncurses-${NCURSES_VERSION}.tar.gz
1513

@@ -18,6 +16,7 @@ pushd ncurses-${NCURSES_VERSION}
1816
CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" ./configure \
1917
--build=x86_64-unknown-linux-gnu \
2018
--host=${TARGET} \
21-
--prefix=/tools/deps
19+
--prefix=/tools/deps \
20+
--without-cxx
2221
make -j `nproc`
2322
make -j `nproc` install DESTDIR=/build/out

cpython-linux/build-openssl.sh

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,19 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf openssl-${OPENSSL_VERSION}.tar.gz
1513

1614
pushd openssl-${OPENSSL_VERSION}
1715

18-
/usr/bin/perl ./Configure --prefix=/tools/deps linux-x86_64
16+
# musl is missing support for various primitives.
17+
# TODO disable secure memory is a bit scary. We should look into a proper
18+
# workaround.
19+
if [ "${CC}" = "musl-clang" ]; then
20+
EXTRA_FLAGS="no-async -DOPENSSL_NO_ASYNC -D__STDC_NO_ATOMICS__=1 no-engine -DOPENSSL_NO_SECURE_MEMORY "
21+
fi
22+
23+
/usr/bin/perl ./Configure --prefix=/tools/deps linux-x86_64 no-shared ${EXTRA_FLAGS}
1924

2025
make -j `nproc`
2126
make -j `nproc` install DESTDIR=/build/out

cpython-linux/build-readline.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf readline-${READLINE_VERSION}.tar.gz
1513

@@ -20,6 +18,7 @@ CLFAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LD
2018
--build=x86_64-unknown-linux-gnu \
2119
--host=${TARGET} \
2220
--prefix=/tools/deps \
21+
--disable-shared \
2322
--with-curses
2423

2524
make -j `nproc`

cpython-linux/build-sqlite.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf sqlite-autoconf-3280000.tar.gz
1513
pushd sqlite-autoconf-3280000
1614

17-
CFLAGS="-fPIC" CPPFLAGS="-fPIC" ./configure --prefix /tools/deps
15+
CFLAGS="-fPIC" CPPFLAGS="-fPIC" ./configure \
16+
--prefix /tools/deps \
17+
--disable-shared
1818

1919
make -j `nproc`
2020
make -j `nproc` install DESTDIR=/build/out

cpython-linux/build-tcltk.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf tcl8.6.9-src.tar.gz
1513

cpython-linux/build-uuid.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf libuuid-${UUID_VERSION}.tar.gz
1513
pushd libuuid-${UUID_VERSION}
1614

17-
CFLAGS="-fPIC" CPPFLAGS="-fPIC" ./configure --prefix=/tools/deps
15+
CFLAGS="-fPIC" CPPFLAGS="-fPIC" ./configure \
16+
--prefix=/tools/deps \
17+
--disable-shared
1818

1919
make -j `nproc`
2020
make -j `nproc` install DESTDIR=/build/out

cpython-linux/build-xz.sh

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,14 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf xz-${XZ_VERSION}.tar.gz
1513

1614
pushd xz-${XZ_VERSION}
1715

1816
CFLAGS="-fPIC" CPPFLAGS="-fPIC" CCASFLAGS="-fPIC" ./configure \
1917
--prefix=/tools/deps \
18+
--disable-shared \
2019
--disable-xz \
2120
--disable-xzdec \
2221
--disable-lzmadec \

cpython-linux/build-zlib.sh

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@ set -ex
88
cd /build
99

1010
export PATH=/tools/${TOOLCHAIN}/bin:/tools/host/bin:$PATH
11-
export CC=clang
12-
export CXX=clang++
1311

1412
tar -xf zlib-${ZLIB_VERSION}.tar.gz
1513

0 commit comments

Comments
 (0)