Skip to content

Commit 31893c4

Browse files
gh-81218: Make macOS framework builds relocatable via @rpath
macOS framework builds (--enable-framework) now produce relocatable frameworks. The installed framework can be moved to any location and will work without requiring install_name_tool rewriting by users. This uses install-time transformation: build-time behavior is unchanged (absolute install names), and install_name_tool transforms the installed binaries to use @rpath. Changes: - Add -headerpad_max_install_names to LINKFORSHARED and pythonw build - Transform dylib install name to @rpath at install time - Add LC_RPATH entries to installed binaries (bin/python3, Python.app) - Compute rpath depths dynamically via os.path.relpath() Signed-off-by: Dominique Fuchs <df@0x9d.net>
1 parent 6b45381 commit 31893c4

File tree

5 files changed

+26
-3
lines changed

5 files changed

+26
-3
lines changed

Mac/Makefile.in

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ LDFLAGS=@LDFLAGS@
1919
FRAMEWORKUNIXTOOLSPREFIX=@FRAMEWORKUNIXTOOLSPREFIX@
2020
PYTHONFRAMEWORK=@PYTHONFRAMEWORK@
2121
PYTHONFRAMEWORKIDENTIFIER=@PYTHONFRAMEWORKIDENTIFIER@
22+
PYTHONFRAMEWORKDIR=@PYTHONFRAMEWORKDIR@
23+
PYTHONFRAMEWORKPREFIX=@PYTHONFRAMEWORKPREFIX@
24+
PYTHONFRAMEWORKINSTALLNAMEPREFIX=@PYTHONFRAMEWORKINSTALLNAMEPREFIX@
2225
LIPO_32BIT_FLAGS=@LIPO_32BIT_FLAGS@
2326
LIPO_INTEL64_FLAGS=@LIPO_INTEL64_FLAGS@
2427
CC=@CC@
@@ -173,7 +176,8 @@ altinstallunixtools:
173176
fi
174177

175178
pythonw: $(srcdir)/Tools/pythonw.c Makefile
176-
$(CC) $(LDFLAGS) -DPYTHONFRAMEWORK='"$(PYTHONFRAMEWORK)"' -o $@ \
179+
$(CC) $(LDFLAGS) -Wl,-headerpad_max_install_names \
180+
-DPYTHONFRAMEWORK='"$(PYTHONFRAMEWORK)"' -o $@ \
177181
$(srcdir)/Tools/pythonw.c -I.. -I$(srcdir)/../Include \
178182
../$(PYTHONFRAMEWORK).framework/Versions/$(VERSION)/$(PYTHONFRAMEWORK)
179183

@@ -224,6 +228,13 @@ install_Python:
224228
done; \
225229
done
226230
$(INSTALL_PROGRAM) $(STRIPFLAG) $(BUILDPYTHON) "$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"
231+
@# Use @rpath to avoid encoded actual prefix in Python.app
232+
install_name_tool \
233+
-change $(PYTHONFRAMEWORKINSTALLNAMEPREFIX)/$(PYTHONFRAMEWORK) \
234+
@rpath/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \
235+
-add_rpath @executable_path/`$(RUNSHARED) $(BUILDPYTHON) -c \
236+
"import os; print(os.path.relpath('$(PYTHONFRAMEWORKPREFIX)', '$(APPINSTALLDIR)/Contents/MacOS'))"` \
237+
"$(DESTDIR)$(APPINSTALLDIR)/Contents/MacOS/$(PYTHONFRAMEWORK)"
227238
sed -e "s!%bundleid%!$(PYTHONFRAMEWORKIDENTIFIER)!g" \
228239
-e "s!%version%!`$(RUNSHARED) $(BUILDPYTHON) \
229240
-c 'import platform; print(platform.python_version())'`!g" \

Makefile.pre.in

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,6 +2457,12 @@ altbininstall: $(BUILDPYTHON) @FRAMEWORKPYTHONW@
24572457
$(INSTALL_PROGRAM) $(BUILDPYTHON) $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \
24582458
else \
24592459
$(INSTALL_PROGRAM) $(STRIPFLAG) Mac/pythonw $(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE); \
2460+
install_name_tool \
2461+
-change $(PYTHONFRAMEWORKINSTALLNAMEPREFIX)/$(PYTHONFRAMEWORK) \
2462+
@rpath/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \
2463+
-add_rpath @executable_path/`$(RUNSHARED) ./$(BUILDPYTHON) -c \
2464+
"import os; print(os.path.relpath('$(PYTHONFRAMEWORKPREFIX)', '$(BINDIR)'))"` \
2465+
"$(DESTDIR)$(BINDIR)/python$(LDVERSION)$(EXE)"; \
24602466
fi
24612467
-if test "$(VERSION)" != "$(LDVERSION)"; then \
24622468
if test -f $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE) -o -h $(DESTDIR)$(BINDIR)/python$(VERSION)$(EXE); \
@@ -3059,6 +3065,9 @@ frameworkinstallversionedstructure: $(LDLIBRARY)
30593065
$(LN) -fsn Versions/Current/Headers $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Headers
30603066
$(LN) -fsn Versions/Current/Resources $(DESTDIR)$(PYTHONFRAMEWORKINSTALLDIR)/Resources
30613067
$(INSTALL_SHARED) $(LDLIBRARY) $(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)
3068+
@# Use @rpath-based install name to avoid encoded actual prefix
3069+
install_name_tool -id @rpath/$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK) \
3070+
"$(DESTDIR)$(PYTHONFRAMEWORKPREFIX)/$(LDLIBRARY)"
30623071

30633072
# iOS/tvOS/watchOS uses a non-versioned framework with Info.plist in the
30643073
# framework root, no .lproj data, and only stub compilation assistance binaries
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
macOS framework builds (``--enable-framework``) now produce relocatable
2+
frameworks that can be moved after installation without requiring
3+
``install_name_tool`` rewriting.

configure

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

configure.ac

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3633,7 +3633,7 @@ then
36333633
LINKFORSHARED="-Wl,-stack_size,$stack_size $LINKFORSHARED"
36343634

36353635
if test "$enable_framework"; then
3636-
LINKFORSHARED="$LINKFORSHARED "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
3636+
LINKFORSHARED="$LINKFORSHARED -Wl,-headerpad_max_install_names "'$(PYTHONFRAMEWORKDIR)/Versions/$(VERSION)/$(PYTHONFRAMEWORK)'
36373637
fi
36383638
LINKFORSHARED="$LINKFORSHARED"
36393639
elif test $ac_sys_system = "iOS"; then

0 commit comments

Comments
 (0)