Skip to content

Commit 7d3476d

Browse files
committed
Build libtcl, libtk, and _tkinter as shared objects
1 parent 8a85bae commit 7d3476d

File tree

6 files changed

+59
-39
lines changed

6 files changed

+59
-39
lines changed

cpython-unix/build-cpython.sh

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ sed "${sed_args[@]}" "s|/tools/host|${TOOLS_PATH}/host|g" ${TOOLS_PATH}/host/sha
4444
# We force linking of external static libraries by removing the shared
4545
# libraries. This is hacky. But we're building in a temporary container
4646
# and it gets the job done.
47-
find ${TOOLS_PATH}/deps -name '*.so*' -exec rm {} \;
47+
find ${TOOLS_PATH}/deps -name '*.so*' -a \! \( -name 'libtcl*.so*' -or -name 'libtk*.so*' \) -exec rm {} \;
4848

4949
tar -xf Python-${PYTHON_VERSION}.tar.xz
5050

@@ -705,6 +705,8 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then
705705
${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}
706706

707707
# Python's build system doesn't make this file writable.
708+
# TODO(geofft): @executable_path/ is a weird choice here, who is
709+
# relying on it? Should probably be @loader_path.
708710
chmod 755 ${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}
709711
install_name_tool \
710712
-change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \
@@ -723,6 +725,13 @@ if [ "${PYBUILD_SHARED}" = "1" ]; then
723725
-change /install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} @executable_path/../lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME} \
724726
${ROOT}/out/python/install/bin/python${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}
725727
fi
728+
729+
# At the moment, python3 and libpython don't have shared-library
730+
# dependencies, but at some point we will want to run this for
731+
# them too.
732+
for module in ${ROOT}/out/python/install/lib/python*/lib-dynload/*.so; do
733+
install_name_tool -add_rpath @loader_path/../.. "$module"
734+
done
726735
else # (not macos)
727736
LIBPYTHON_SHARED_LIBRARY_BASENAME=libpython${PYTHON_MAJMIN_VERSION}${PYTHON_BINARY_SUFFIX}.so.1.0
728737
LIBPYTHON_SHARED_LIBRARY=${ROOT}/out/python/install/lib/${LIBPYTHON_SHARED_LIBRARY_BASENAME}
@@ -1250,6 +1259,14 @@ if [ -d "${TOOLS_PATH}/deps/lib/tcl8" ]; then
12501259
for source in ${TOOLS_PATH}/deps/lib/{itcl4.2.4,tcl8,tcl8.6,thread2.8.9,tk8.6}; do
12511260
cp -av $source ${ROOT}/out/python/install/lib/
12521261
done
1262+
1263+
(
1264+
shopt -s nullglob
1265+
dylibs=(${TOOLS_PATH}/deps/lib/lib*.dylib ${TOOLS_PATH}/deps/lib/lib*.so)
1266+
if [ "${#dylibs[@]}" -gt 0 ]; then
1267+
cp -av "${dylibs[@]}" ${ROOT}/out/python/install/lib/
1268+
fi
1269+
)
12531270
fi
12541271

12551272
# Copy the terminfo database if present.

cpython-unix/build-tcl.sh

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ if [ -n "${STATIC}" ]; then
2020
# `checking whether musl-clang accepts -g...` fails with a duplicate definition error
2121
TARGET_TRIPLE="$(echo "${TARGET_TRIPLE}" | sed -e 's/-unknown-linux-musl/-unknown-linux-gnu/g')"
2222
fi
23-
fi
2423

25-
patch -p1 << 'EOF'
24+
patch -p1 << 'EOF'
2625
diff --git a/unix/Makefile.in b/unix/Makefile.in
2726
--- a/unix/Makefile.in
2827
+++ b/unix/Makefile.in
@@ -36,6 +35,7 @@ diff --git a/unix/Makefile.in b/unix/Makefile.in
3635
fi; \
3736
fi; \
3837
EOF
38+
fi
3939

4040
# Remove packages we don't care about and can pull in unwanted symbols.
4141
rm -rf pkgs/sqlite* pkgs/tdbc*
@@ -48,12 +48,14 @@ CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./conf
4848
--build=${BUILD_TRIPLE} \
4949
--host=${TARGET_TRIPLE} \
5050
--prefix=/tools/deps \
51-
--enable-shared=no \
51+
--enable-shared"${STATIC:+=no}" \
5252
--enable-threads
5353

54-
make -j ${NUM_CPUS}
55-
make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out
54+
make -j ${NUM_CPUS} DYLIB_INSTALL_DIR=@rpath
55+
make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out DYLIB_INSTALL_DIR=@rpath
5656
make -j ${NUM_CPUS} install-private-headers DESTDIR=${ROOT}/out
5757

58-
# For some reason libtcl*.a have weird permissions. Fix that.
59-
chmod 644 ${ROOT}/out/tools/deps/lib/libtcl*.a
58+
if [ -n "${STATIC}" ]; then
59+
# For some reason libtcl*.a have weird permissions. Fix that.
60+
chmod 644 ${ROOT}/out/tools/deps/lib/libtcl*.a
61+
fi

cpython-unix/build-tk.sh

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ CFLAGS="${CFLAGS}" CPPFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}" ./configure \
3131
--host=${TARGET_TRIPLE} \
3232
--prefix=/tools/deps \
3333
--with-tcl=${TOOLS_PATH}/deps/lib \
34-
--enable-shared=no \
34+
--enable-shared"${STATIC:+=no}" \
3535
--enable-threads \
3636
${EXTRA_CONFIGURE_FLAGS}
3737

@@ -41,19 +41,25 @@ if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then
4141
sed -i 's/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE) ${WISH_EXE}/install-binaries: $(TK_STUB_LIB_FILE) $(TK_LIB_FILE)/' Makefile
4242
fi
4343

44-
# For some reason musl isn't link libXau and libxcb. So we hack the Makefile
45-
# to do what we want.
46-
if [ "${CC}" = "musl-clang" ]; then
47-
sed -i 's/-ldl -lpthread /-ldl -lpthread -lXau -lxcb/' tkConfig.sh
48-
sed -i 's/-lpthread $(X11_LIB_SWITCHES) -ldl -lpthread/-lpthread $(X11_LIB_SWITCHES) -ldl -lpthread -lXau -lxcb/' Makefile
44+
# We are statically linking libX11, and static libraries do not carry
45+
# information about dependencies. pkg-config --static does, but Tcl/Tk's
46+
# build system apparently is too old for that. So we need to manually
47+
# inform the build process that libX11.a needs libxcb.a and libXau.a.
48+
# Note that the order is significant, for static libraries: X11 requires
49+
# xcb, which requires Xau.
50+
MAKE_VARS=(DYLIB_INSTALL_DIR=@rpath)
51+
if [[ "${PYBUILD_PLATFORM}" != macos* ]]; then
52+
MAKE_VARS+=(X11_LIB_SWITCHES="-lX11 -lxcb -lXau")
4953
fi
5054

51-
make -j ${NUM_CPUS}
55+
make -j ${NUM_CPUS} "${MAKE_VARS[@]}"
5256
touch wish
53-
make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out
57+
make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out "${MAKE_VARS[@]}"
5458
make -j ${NUM_CPUS} install-private-headers DESTDIR=${ROOT}/out
5559

5660
# For some reason libtk*.a have weird permissions. Fix that.
57-
chmod 644 /${ROOT}/out/tools/deps/lib/libtk*.a
61+
if [ -n "${STATIC}" ]; then
62+
chmod 644 /${ROOT}/out/tools/deps/lib/libtk*.a
63+
fi
5864

5965
rm ${ROOT}/out/tools/deps/bin/wish*

cpython-unix/extension-modules.yml

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -677,39 +677,23 @@ _tkinter:
677677
- WITH_APPINIT
678678
includes-deps:
679679
- include/X11
680+
build-mode: shared
680681
links:
681682
- tcl8.6
682683
- tk8.6
683-
684-
# Without -ObjC, we get a crash: -[TKApplication tkProcessEvent:]: unrecognized selector sent to instance.
685-
# See also https://core.tcl-lang.org/tk/tktview/85f316beb15108ac43b03fa6c8608e31f3ae5f92.
686-
# This is apparently an issue with static linking Objective-C binaries.
687-
linker-args:
688-
- args: ["-ObjC"]
689-
targets:
690-
- .*-apple-darwin
691684
links-conditional:
692685
- name: X11
693686
targets:
694687
- .*-unknown-linux-.*
688+
build-mode: static
695689
- name: xcb
696690
targets:
697691
- .*-unknown-linux-.*
692+
build-mode: static
698693
- name: Xau
699694
targets:
700695
- .*-unknown-linux-.*
701-
# Many of these are dependencies of libtcl and libtk.
702-
frameworks:
703-
- AppKit
704-
- ApplicationServices
705-
- Carbon
706-
- Cocoa
707-
- CoreFoundation
708-
- CoreServices
709-
- CoreGraphics
710-
- IOKit
711-
- QuartzCore
712-
- UniformTypeIdentifiers
696+
build-mode: static
713697

714698
_tokenize:
715699
minimum-python-version: "3.11"

pythonbuild/cpython.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
"properties": {
7070
"name": {"type": "string"},
7171
"targets": {"type": "array", "items": {"type": "string"}},
72+
"build-mode": {"type": "string"},
7273
},
7374
"additionalProperties": False,
7475
},
@@ -535,7 +536,17 @@ def derive_setup_local(
535536
python_version, entry.get("maximum-python-version", "100.0")
536537
)
537538

538-
if target_match and (python_min_match and python_max_match):
539+
if build_mode := entry.get("build-mode"):
540+
build_mode_match = section == build_mode
541+
else:
542+
build_mode_match = True
543+
544+
if (
545+
target_match
546+
and python_min_match
547+
and python_max_match
548+
and build_mode_match
549+
):
539550
if source := entry.get("source"):
540551
line += f" {source}"
541552
for source in entry.get("sources", []):

src/validation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -822,7 +822,7 @@ const GLOBAL_EXTENSIONS_WINDOWS_PRE_3_13: &[&str] = &["_msi"];
822822
const GLOBAL_EXTENSIONS_WINDOWS_NO_STATIC: &[&str] = &["_testinternalcapi", "_tkinter"];
823823

824824
/// Extension modules that should be built as shared libraries.
825-
const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt"];
825+
const SHARED_LIBRARY_EXTENSIONS: &[&str] = &["_crypt", "_tkinter"];
826826

827827
const PYTHON_VERIFICATIONS: &str = include_str!("verify_distribution.py");
828828

0 commit comments

Comments
 (0)