Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion Doc/using/configure.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1076,12 +1076,28 @@ Linker options
.. option:: --enable-relocatable

Enable experimental support for relocatable builds (default is no).
This option currently has no effect on the build.

.. warning::

This feature is under active development. Do not use it in production.

Currently, this sets relative runtime library paths on Linux and for
non-framework macOS builds. Framework relocation is not implemented yet.
Combining this option with :option:`--enable-framework` is an error.
Combining it with :option:`--enable-bolt` is an error.

Move the installation as a unit. It must use the default ``bin`` and ``lib``
directories under a common prefix. :option:`--with-platlibdir` may select
a different directory name for the standard library, but not a nested path.
On Linux, these paths use ``DT_RPATH``.

Dependencies stored in other directories, such as ``lib/tcltk``, may
need additional loader search paths.

This option does not bundle dependencies, adjust data-file lookup for
libraries such as Tcl/Tk, or rewrite script shebangs and build-time
paths in :mod:`sysconfig`.

.. versionadded:: 3.16

.. option:: --without-static-libpython
Expand Down
51 changes: 46 additions & 5 deletions Makefile.pre.in
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ DSYMUTIL_PATH= @DSYMUTIL_PATH@

GNULD= @GNULD@
RELOCATABLE= @RELOCATABLE@
RELOCATABLE_PYTHON_LDFLAGS=@RELOCATABLE_PYTHON_LDFLAGS@
RELOCATABLE_LIBPYTHON_LDFLAGS=@RELOCATABLE_LIBPYTHON_LDFLAGS@
RELOCATABLE_EXTENSION_LDFLAGS=@RELOCATABLE_EXTENSION_LDFLAGS@
RELOCATABLE_LIBPYTHON_INSTALL_NAME=@RELOCATABLE_LIBPYTHON_INSTALL_NAME@

# Shell used by make (some versions default to the login shell, which is bad)
SHELL= /bin/sh -e
Expand Down Expand Up @@ -313,6 +317,22 @@ LIBOBJS= @LIBOBJS@
PYTHON= python$(EXE)
BUILDPYTHON= python$(BUILDEXE)

# Build-tree programs run with RUNSHARED where needed. Install variants need
# runtime paths relative to their installed locations.
RELOCATABLE_DIR=build/relocatable
INSTALL_PYTHON=$(BUILDPYTHON)
INSTALL_LDLIBRARY=$(LDLIBRARY)
INSTALL_PY3LIBRARY=$(PY3LIBRARY)
INSTALL_SHAREDMODS=$(SHAREDMODS)
ifeq ($(RELOCATABLE),yes)
INSTALL_PYTHON=$(RELOCATABLE_DIR)/$(BUILDPYTHON)
INSTALL_SHAREDMODS=$(addprefix $(RELOCATABLE_DIR)/,$(SHAREDMODS))
ifeq ($(PY_ENABLE_SHARED),1)
INSTALL_LDLIBRARY=$(RELOCATABLE_DIR)/$(LDLIBRARY)
INSTALL_PY3LIBRARY=$(addprefix $(RELOCATABLE_DIR)/,$(PY3LIBRARY))
endif
endif

HOSTRUNNER= @HOSTRUNNER@

PYTHON_FOR_REGEN?=@PYTHON_FOR_REGEN@
Expand Down Expand Up @@ -788,7 +808,8 @@ list-targets:

.PHONY: build_all
build_all: check-clean-src check-app-store-compliance $(BUILDPYTHON) platform sharedmods \
gdbhooks Programs/_testembed scripts checksharedmods rundsymutil $(BUILD_DETAILS)
gdbhooks Programs/_testembed scripts checksharedmods rundsymutil $(BUILD_DETAILS) \
$(INSTALL_PYTHON) $(INSTALL_LDLIBRARY) $(INSTALL_PY3LIBRARY) $(INSTALL_SHAREDMODS)

.PHONY: build_wasm
build_wasm: check-clean-src $(BUILDPYTHON) platform sharedmods \
Expand Down Expand Up @@ -974,6 +995,10 @@ clinic-tests: check-clean-src $(srcdir)/Lib/test/clinic.test.c
$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS)
$(LINKCC) $(PY_CORE_EXE_LDFLAGS) $(LINKFORSHARED) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)

$(RELOCATABLE_DIR)/$(BUILDPYTHON): Programs/python.o $(LINK_PYTHON_DEPS) $(INSTALL_LDLIBRARY)
@mkdir -p $(@D)
$(LINKCC) $(PY_CORE_EXE_LDFLAGS) $(LINKFORSHARED) $(RELOCATABLE_PYTHON_LDFLAGS) -L$(RELOCATABLE_DIR) -o $@ Programs/python.o $(LINK_PYTHON_OBJS) $(LIBS) $(MODLIBS) $(SYSLIBS)

platform: $(PYTHON_FOR_BUILD_DEPS) pybuilddir.txt
$(RUNSHARED) $(PYTHON_FOR_BUILD) -c 'import sys ; from sysconfig import get_platform ; print("%s-%d.%d" % (get_platform(), *sys.version_info[:2]))' >platform

Expand Down Expand Up @@ -1019,6 +1044,18 @@ libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
$(CC) -dynamiclib $(PY_CORE_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(prefix)/lib/libpython$(LDVERSION).dylib -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACE_OBJS) $(SHLIBS) $(LIBC) $(LIBM); \


$(RELOCATABLE_DIR)/libpython$(LDVERSION).so: $(LIBRARY_OBJS) $(DTRACE_OBJS)
@mkdir -p $(@D)
$(BLDSHARED) $(RELOCATABLE_LIBPYTHON_LDFLAGS) -Wl,-h$(INSTSONAME) -o $(RELOCATABLE_DIR)/$(INSTSONAME) $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM)
$(LN) -f $(RELOCATABLE_DIR)/$(INSTSONAME) $@

$(RELOCATABLE_DIR)/libpython3.so: $(RELOCATABLE_DIR)/libpython$(LDVERSION).so
$(BLDSHARED) $(RELOCATABLE_LIBPYTHON_LDFLAGS) $(NO_AS_NEEDED) -o $@ -Wl,-hlibpython3.so $^

$(RELOCATABLE_DIR)/libpython$(LDVERSION).dylib: $(LIBRARY_OBJS)
@mkdir -p $(@D)
$(CC) -dynamiclib $(PY_CORE_LDFLAGS) $(RELOCATABLE_LIBPYTHON_LDFLAGS) -undefined dynamic_lookup -Wl,-install_name,$(RELOCATABLE_LIBPYTHON_INSTALL_NAME) -Wl,-compatibility_version,$(VERSION) -Wl,-current_version,$(VERSION) -o $@ $(LIBRARY_OBJS) $(DTRACE_OBJS) $(SHLIBS) $(LIBC) $(LIBM)

libpython$(VERSION).sl: $(LIBRARY_OBJS)
$(LDSHARED) -o $@ $(LIBRARY_OBJS) $(MODLIBS) $(SHLIBS) $(LIBC) $(LIBM)

Expand Down Expand Up @@ -2394,7 +2431,7 @@ sharedinstall: all
else true; \
fi; \
done
@for i in X $(SHAREDMODS); do \
@for i in X $(INSTALL_SHAREDMODS); do \
if test $$i != X; then \
echo $(INSTALL_SHARED) $$i $(DESTSHARED)/`basename $$i`; \
$(INSTALL_SHARED) $$i $(DESTDIR)$(DESTSHARED)/`basename $$i`; \
Expand All @@ -2408,7 +2445,11 @@ sharedinstall: all
# Install the interpreter with $(VERSION) affixed
# This goes into $(exec_prefix)
.PHONY: altbininstall
ifeq ($(RELOCATABLE),yes)
altbininstall: all @FRAMEWORKPYTHONW@
else
altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
endif
@for i in $(BINDIR) $(LIBDIR); \
do \
if test ! -d $(DESTDIR)$$i; then \
Expand All @@ -2418,7 +2459,7 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
fi; \
done
if test "$(PYTHONFRAMEWORKDIR)" = "no-framework" ; then \
$(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \
$(INSTALL_PROGRAM) $(INSTALL_PYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \
else \
$(INSTALL_PROGRAM) $(STRIPFLAG) Mac/pythonw $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \
fi
Expand All @@ -2433,13 +2474,13 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
if test -n "$(DLLLIBRARY)" ; then \
$(INSTALL_SHARED) $(DLLLIBRARY) $(DESTDIR)$(BINDIR); \
else \
$(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \
$(INSTALL_SHARED) $(INSTALL_LDLIBRARY) $(DESTDIR)$(LIBDIR)/$(INSTSONAME); \
if test $(LDLIBRARY) != $(INSTSONAME); then \
(cd $(DESTDIR)$(LIBDIR); $(LN) -sf $(INSTSONAME) $(LDLIBRARY)) \
fi \
fi; \
if test -n "$(PY3LIBRARY)"; then \
$(INSTALL_SHARED) $(PY3LIBRARY) $(DESTDIR)$(LIBDIR)/$(PY3LIBRARY); \
$(INSTALL_SHARED) $(INSTALL_PY3LIBRARY) $(DESTDIR)$(LIBDIR)/$(PY3LIBRARY); \
fi; \
else true; \
fi; \
Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Add the experimental :option:`--enable-relocatable` configure option.
The option currently has no effect on the build.
Add the experimental :option:`--enable-relocatable` configure option
to set relative runtime library paths on Linux and non-framework macOS
builds. The feature is under active development.
3 changes: 3 additions & 0 deletions Modules/makesetup
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,9 @@ sed -e 's/[ ]*#.*//' -e '/^[ ]*$/d' |
rule="$file: $objs \$(MODULE_${mods_upper}_LDEPS)"
rule="$rule; \$(BLDSHARED) $objs $libs \$(MODULE_LDFLAGS_SHARED) -o $file"
echo "$rule" >>$rulesf
rule="\$(RELOCATABLE_DIR)/$file: $objs \$(MODULE_${mods_upper}_LDEPS)"
rule="$rule; @mkdir -p \$(@D); \$(BLDSHARED) $objs $libs \$(MODULE_LDFLAGS_SHARED) \$(RELOCATABLE_EXTENSION_LDFLAGS) -o \$@"
echo "$rule" >>$rulesf
done
done

Expand Down
106 changes: 106 additions & 0 deletions configure

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2215,6 +2215,10 @@ else
fi],
[AC_MSG_RESULT([no])])

AS_IF([test "$enable_relocatable" = yes && test "$Py_BOLT" = true], [
AC_MSG_ERROR([--enable-relocatable does not support --enable-bolt yet])
])

AC_SUBST([PREBOLT_RULE])
if test "$Py_BOLT" = 'true' ; then
PREBOLT_RULE="${DEF_MAKE_ALL_RULE}"
Expand Down Expand Up @@ -6874,6 +6878,54 @@ AC_SUBST([BINLIBDEST])
LIBDEST='${prefix}/${PLATLIBDIR}/python$(VERSION)$(ABI_THREAD)'
BINLIBDEST='${exec_prefix}/${PLATLIBDIR}/python$(VERSION)$(ABI_THREAD)'

# Runtime paths are specific to the installed location of each kind of binary.
# Do not add them to LDSHARED: third-party extensions may be installed elsewhere.
RELOCATABLE_PYTHON_LDFLAGS=
RELOCATABLE_LIBPYTHON_LDFLAGS=
RELOCATABLE_EXTENSION_LDFLAGS=
RELOCATABLE_LIBPYTHON_INSTALL_NAME=
AS_IF([test "$enable_relocatable" = yes && test -n "$enable_framework"], [
AC_MSG_ERROR([--enable-relocatable does not support framework builds yet])
])
AS_IF([test "$enable_relocatable" = yes && test -z "$enable_framework"], [
AS_CASE([$ac_sys_system],
[Linux|Darwin], [],
[AC_MSG_ERROR([relocatable builds are not implemented on $ac_sys_system yet])])
AS_VAR_IF([prefix], [NONE], [relocatable_prefix=$ac_default_prefix],
[relocatable_prefix=$prefix])
AS_IF([test "$exec_prefix" != NONE && test "$exec_prefix" != '${prefix}' && test "$exec_prefix" != "$relocatable_prefix"],
[AC_MSG_ERROR([--enable-relocatable requires a common prefix and exec-prefix])])
AS_IF([test "$bindir" != '${exec_prefix}/bin' && test "$bindir" != '${prefix}/bin' && test "$bindir" != "$relocatable_prefix/bin"],
[AC_MSG_ERROR([--enable-relocatable requires the default bin directory])])
AS_IF([test "$libdir" != '${exec_prefix}/lib' && test "$libdir" != '${prefix}/lib' && test "$libdir" != "$relocatable_prefix/lib"],
[AC_MSG_ERROR([--enable-relocatable requires the default lib directory])])
AS_CASE([$PLATLIBDIR], [*/*|.|..],
[AC_MSG_ERROR([--enable-relocatable requires a single directory name for --with-platlibdir])])
AS_CASE([$ac_sys_system],
[Linux], [
# Keep the dollar sign through configure, make, and the shell.
# DT_RPATH entries can also resolve indirect dependencies.
RELOCATABLE_PYTHON_LDFLAGS="-Wl,--disable-new-dtags,-rpath,'\$\$ORIGIN/../lib'"
RELOCATABLE_LIBPYTHON_LDFLAGS="-Wl,--disable-new-dtags,-rpath,'\$\$ORIGIN'"
RELOCATABLE_EXTENSION_LDFLAGS="-Wl,--disable-new-dtags,-rpath,'\$\$ORIGIN/../../../lib'"
save_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,--disable-new-dtags"
AC_LINK_IFELSE([AC_LANG_PROGRAM([], [])], [],
[AC_MSG_ERROR([--enable-relocatable requires linker support for --disable-new-dtags])])
LDFLAGS=$save_LDFLAGS
],
[Darwin], [
RELOCATABLE_LIBPYTHON_INSTALL_NAME='@rpath/libpython$(LDVERSION).dylib'
RELOCATABLE_PYTHON_LDFLAGS='-Wl,-rpath,@executable_path/../lib'
RELOCATABLE_LIBPYTHON_LDFLAGS='-Wl,-rpath,@loader_path'
RELOCATABLE_EXTENSION_LDFLAGS='-Wl,-rpath,@loader_path/../../../lib'
])
])
AC_SUBST([RELOCATABLE_PYTHON_LDFLAGS])
AC_SUBST([RELOCATABLE_LIBPYTHON_LDFLAGS])
AC_SUBST([RELOCATABLE_EXTENSION_LDFLAGS])
AC_SUBST([RELOCATABLE_LIBPYTHON_INSTALL_NAME])

dnl define LIBPL after ABIFLAGS and LDVERSION is defined.
AC_SUBST([PY_ENABLE_SHARED])
if test x$PLATFORM_TRIPLET = x; then
Expand Down
Loading