Skip to content

Commit

Permalink
macos: build gettext from source
Browse files Browse the repository at this point in the history
Python's configure searches for a usable libintl, which is provided by gettext.

If you have a libintl shared library on your system, configure will pick it
up and add a dynamic library dependency on it, making binaries non-portable.

To work around this, we build gettext from source and have Python statically
link against its libintl.

The configure workaround feels a bit shady to me. I'm not sure why the test
program finding the textdomain symbol fails to build. But we can link against
libintl.a and Python functions calling into it seem to work. So who knows.
  • Loading branch information
indygreg committed Aug 23, 2020
1 parent 3aa4306 commit 51a442d
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 0 deletions.
6 changes: 6 additions & 0 deletions cpython-unix/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ ifeq ($(HOST_PLATFORM),linux64)
NEED_GCC := 1
NEED_MUSL :=
NEED_GDBM := 1
NEED_GETTEXT :=
NEED_X11 := 1
NEED_READLINE := 1
NEED_TIX := 1
Expand All @@ -55,6 +56,7 @@ ifeq ($(HOST_PLATFORM),macos)
NEED_GCC :=
NEED_MUSL :=
NEED_GDBM :=
NEED_GETTEXT := 1
NEED_X11 :=
NEED_READLINE :=
NEED_TIX := 1
Expand Down Expand Up @@ -128,6 +130,9 @@ $(OUTDIR)/bzip2-$(BZIP2_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(
$(OUTDIR)/gdbm-$(GDBM_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-gdbm.sh
$(RUN_BUILD) gdbm

$(OUTDIR)/gettext-$(GETTEXT_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-gettext.sh
$(RUN_BUILD) gettext

$(OUTDIR)/inputproto-$(INPUTPROTO_VERSION)-$(PACKAGE_SUFFIX).tar: $(PYTHON_DEP_DEPENDS) $(HERE)/build-inputproto.sh
$(RUN_BUILD) inputproto

Expand Down Expand Up @@ -260,6 +265,7 @@ PYTHON_DEPENDS := \
$(OUTDIR)/bdb-$(BDB_VERSION)-$(PACKAGE_SUFFIX).tar \
$(OUTDIR)/bzip2-$(BZIP2_VERSION)-$(PACKAGE_SUFFIX).tar \
$(if $(NEED_GDBM),$(OUTDIR)/gdbm-$(GDBM_VERSION)-$(PACKAGE_SUFFIX).tar) \
$(if $(NEED_GETTEXT),$(OUTDIR)/gettext-$(GETTEXT_VERSION)-$(PACKAGE_SUFFIX).tar) \
$(OUTDIR)/libedit-$(LIBEDIT_VERSION)-$(PACKAGE_SUFFIX).tar \
$(OUTDIR)/libffi-$(LIBFFI_VERSION)-$(PACKAGE_SUFFIX).tar \
$(if $(NEED_LIBRESSL),$(OUTDIR)/libressl-$(LIBRESSL_VERSION)-$(PACKAGE_SUFFIX).tar) \
Expand Down
6 changes: 6 additions & 0 deletions cpython-unix/build-cpython.sh
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ if [ -n "${CPYTHON_LTO}" ]; then
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --with-lto"
fi

if [ "${PYBUILD_PLATFORM}" = "macos" ]; then
# Configure fails to find the textdomain symbol with our libintl
# for some reason. So force it.
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} ac_cv_lib_intl_textdomain=yes"
fi

CFLAGS=$CFLAGS CPPFLAGS=$CFLAGS LDFLAGS=$LDFLAGS \
./configure ${CONFIGURE_FLAGS}

Expand Down
42 changes: 42 additions & 0 deletions cpython-unix/build-gettext.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

set -ex

ROOT=`pwd`

export PATH=${TOOLS_PATH}/${TOOLCHAIN}/bin:${TOOLS_PATH}/host/bin:$PATH

tar -xf gettext-${GETTEXT_VERSION}.tar.gz

pushd gettext-${GETTEXT_VERSION}

# If libunistring exists on the system, it can get picked up and introduce
# an added dependency. So we force use of the bundled version.
CLFAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" ./configure \
--build=${BUILD_TRIPLE} \
--target=${TARGET_TRIPLE} \
--prefix=/tools/deps \
--disable-shared \
--disable-java \
--disable-dependency-tracking \
--with-included-libcroco \
--with-included-gettext \
--with-included-glib \
--with-included-libunistring \
--with-included-libxml \
--without-libiconv-prefix \
--without-libintl-prefix \
--without-libncurses-prefix \
--without-libtermcap-prefix \
--without-libxcurses-prefix \
--without-libcurses-prefix \
--without-libtextstyle-prefix \
--without-libunistring-prefix \
--without-libxml2-prefix \
--without-git

make -j ${NUM_CPUS}
make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out
16 changes: 16 additions & 0 deletions cpython-unix/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -498,6 +498,17 @@ def process_setup_line(line, variant=None):
else:
links.append({"name": libname, "system": True})

if platform == "macos":
# For some reason, Python's build system adds libintl as a link
# against libpythonX.Y/pythonX.Y instead of the _locale extension
# despite the _location extension being the only user of its
# symbols. We add libintl here to work around that.
links.append({"name": "intl", "path_static": "build/lib/libintl.a"})

# And symbols in our built libintl reference iconv symbols. So we
# need to include that dependency as well.
links.append({"name": "iconv", "system": True})

entry = {
"in_core": False,
"init_fn": "PyInit_%s" % extension,
Expand Down Expand Up @@ -663,6 +674,10 @@ def build_cpython(
if ncurses:
packages.add("ncurses")

gettext = host_platform == "macos"
if gettext:
packages.add("gettext")

readline = host_platform != "macos"
if readline:
packages.add("readline")
Expand Down Expand Up @@ -921,6 +936,7 @@ def main():
"bdb",
"bzip2",
"gdbm",
"gettext",
"inputproto",
"kbproto",
"libffi",
Expand Down
6 changes: 6 additions & 0 deletions pythonbuild/downloads.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,12 @@
"licenses": ["GPL-3.0-or-later"],
"license_file": "LICENSE.gdbm.txt",
},
"gettext": {
"url": "https://ftp.gnu.org/pub/gnu/gettext/gettext-0.21.tar.gz",
"size": 24181849,
"sha256": "c77d0da3102aec9c07f43671e60611ebff89a996ef159497ce8e59d075786b12",
"version": "0.21",
},
# gmp 6.2 does not build on wheezy.
"gmp": {
"url": "https://ftp.gnu.org/gnu/gmp/gmp-6.1.2.tar.xz",
Expand Down

0 comments on commit 51a442d

Please sign in to comment.