diff --git a/Mac/Makefile.in b/Mac/Makefile.in index 32e3a0f55c5d71..b2e360cb3e1031 100644 --- a/Mac/Makefile.in +++ b/Mac/Makefile.in @@ -19,6 +19,9 @@ LDFLAGS=@LDFLAGS@ FRAMEWORKUNIXTOOLSPREFIX=@FRAMEWORKUNIXTOOLSPREFIX@ PYTHONFRAMEWORK=@PYTHONFRAMEWORK@ PYTHONFRAMEWORKIDENTIFIER=@PYTHONFRAMEWORKIDENTIFIER@ +PYTHONFRAMEWORKDIR=@PYTHONFRAMEWORKDIR@ +PYTHONFRAMEWORKPREFIX=@PYTHONFRAMEWORKPREFIX@ +PYTHONFRAMEWORKINSTALLNAMEPREFIX=@PYTHONFRAMEWORKINSTALLNAMEPREFIX@ LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@ LIPO_INTEL64_FLAGS=@LIPO_INTEL64_FLAGS@ CC=@CC@ @@ -173,7 +176,8 @@ altinstallunixtools: fi pythonw: $(srcdir)/Tools/pythonw.c Makefile - $(CC) $(LDFLAGS) -DPYTHONFRAMEWORK='"$(PYTHONFRAMEWORK)"' -o $@ \ + $(CC) $(LDFLAGS) -Wl,-headerpad_max_install_names \ + -DPYTHONFRAMEWORK='"$(PYTHONFRAMEWORK)"' -o $@ \ $(srcdir)/Tools/pythonw.c -I.. -I$(srcdir)/../Include \ ../$(PYTHONFRAMEWORK).framework/Versions/$(VERSION)/$(PYTHONFRAMEWORK) @@ -224,6 +228,13 @@ install_Python: done; \ done $(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" + @# Use @rpath to avoid encoded actual prefix in Python.app + install_name_tool \ + -change $(PYTHONFRAMEWORKINSTALLNAMEPREFIX)/$(PYTHONFRAMEWORK) \ + @rpath/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \ + -add_rpath @executable_path/`$(RUNSHARED) $(BUILDPYTHON) -c \ + "import os; print(os.path.relpath('$(PYTHONFRAMEWORKPREFIX)', '$(APPINSTALLDIR)/Contents/MacOS'))"` \ + "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)" sed -e "s!%bundleid%!$(PYTHONFRAMEWORKIDENTIFIER)!g" \ -e "s!%version%!`$(RUNSHARED) $(BUILDPYTHON) \ -c 'import platform; print(platform.python_version())'`!g" \ diff --git a/Makefile.pre.in b/Makefile.pre.in index 8531162943ae35..39c0848e782d24 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -2457,6 +2457,12 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@ $(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ else \ $(INSTALL_PROGRAM) $(STRIPFLAG) Mac/pythonw $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \ + install_name_tool \ + -change $(PYTHONFRAMEWORKINSTALLNAMEPREFIX)/$(PYTHONFRAMEWORK) \ + @rpath/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \ + -add_rpath @executable_path/`$(RUNSHARED) ./$(BUILDPYTHON) -c \ + "import os; print(os.path.relpath('$(PYTHONFRAMEWORKPREFIX)', '$(BINDIR)'))"` \ + "$(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE)"; \ fi -if test "$(VERSION)" != "$(LDVERSION)"; then \ if test -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE) -o -h $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \ @@ -3059,6 +3065,9 @@ frameworkinstallversionedstructure: $(LDLIBRARY) $(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers $(LN) -fsn Versions/Current/Resources $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Resources $(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY) + @# Use @rpath-based install name to avoid encoded actual prefix + install_name_tool -id @rpath/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \ + "$(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)" # iOS/tvOS/watchOS uses a non-versioned framework with Info.plist in the # framework root, no .lproj data, and only stub compilation assistance binaries diff --git a/Misc/NEWS.d/next/macOS/2026-01-28-15-17-41.gh-issue-81218.RMUUr3.rst b/Misc/NEWS.d/next/macOS/2026-01-28-15-17-41.gh-issue-81218.RMUUr3.rst new file mode 100644 index 00000000000000..c41b9367e47361 --- /dev/null +++ b/Misc/NEWS.d/next/macOS/2026-01-28-15-17-41.gh-issue-81218.RMUUr3.rst @@ -0,0 +1,3 @@ +macOS framework builds (``--enable-framework``) now produce relocatable +frameworks that can be moved after installation without requiring +``install_name_tool`` rewriting. diff --git a/configure b/configure index c826a1bb85667b..34afb413ac8ae9 100755 --- a/configure +++ b/configure @@ -13776,7 +13776,7 @@ printf "%s\n" "#define THREAD_STACK_SIZE 0x$stack_size" >>confdefs.h LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" if test "$enable_framework"; then - LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LINKFORSHARED="$LINKFORSHARED -Wl,-headerpad_max_install_names "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' fi LINKFORSHARED="$LINKFORSHARED" elif test $ac_sys_system = "iOS"; then diff --git a/configure.ac b/configure.ac index 322d33dd0e3c99..2beb6b404bb791 100644 --- a/configure.ac +++ b/configure.ac @@ -3633,7 +3633,7 @@ then LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED" if test "$enable_framework"; then - LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' + LINKFORSHARED="$LINKFORSHARED -Wl,-headerpad_max_install_names "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)' fi LINKFORSHARED="$LINKFORSHARED" elif test $ac_sys_system = "iOS"; then