Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the linker to set rpath on just the python binary #794

Merged
merged 3 commits into from
Feb 3, 2023
Merged

Use the linker to set rpath on just the python binary #794

merged 3 commits into from
Feb 3, 2023

Conversation

jimnicholls
Copy link
Contributor

First build Python. Then re-build just the python executable with the linker flag -rpath=$ORIGIN/../lib. With this process, the python binary does not trigger a Rosetta error.

This Dockerfile demonstrates that only the python executable has a runpath set on it. The Python library and other .so files that are built as part of building Python do not have a runpath on them.

Dockerfile

FROM python:3.10-slim-bullseye

SHELL [ "/bin/bash", "-eux", "-c" ]

RUN \
    apt-get update; \
    apt-get install -y --no-install-recommends binutils patchelf; \
    rm -rf /var/lib/apt/lists/*

RUN \
    /usr/local/bin/python3.10 -V; \
    patchelf --print-rpath /usr/local/bin/python3.10; \
    patchelf --print-rpath /usr/local/lib/libpython3.10.so.1.0; \
    find /usr/local/lib/python3.10 -name '*.so' -print -exec patchelf --print-rpath '{}' \; ; \
    readelf -d /usr/local/bin/python3.10; \
    readelf -d /usr/local/lib/libpython3.10.so.1.0

docker buildx build --platform=linux/amd64 --progress=plain .

#6 [3/3] RUN     /usr/local/bin/python3.10 -V;     patchelf --print-rpath /usr/local/bin/python3.10;     patchelf --print-rpath /usr/local/lib/libpython3.10.so.1.0;     find /usr/local/lib/python3.10 -name '*.so' -print -exec patchelf --print-rpath '{}' ; ;     readelf -d /usr/local/bin/python3.10;     readelf -d /usr/local/lib/libpython3.10.so.1.0
#6 0.358 + /usr/local/bin/python3.10 -V
#6 0.374 Python 3.10.9
#6 0.375 + patchelf --print-rpath /usr/local/bin/python3.10
#6 0.389 $ORIGIN/../lib
#6 0.389 + patchelf --print-rpath /usr/local/lib/libpython3.10.so.1.0
#6 0.407
#6 0.409 + find /usr/local/lib/python3.10 -name '*.so' -print -exec patchelf --print-rpath '{}' ';'
#6 0.431 /usr/local/lib/python3.10/lib-dynload/_datetime.cpython-310-x86_64-linux-gnu.so
#6 0.445
#6 0.445 /usr/local/lib/python3.10/lib-dynload/_multibytecodec.cpython-310-x86_64-linux-gnu.so
#6 0.459
#6 0.459 /usr/local/lib/python3.10/lib-dynload/_statistics.cpython-310-x86_64-linux-gnu.so
#6 0.472
#6 0.473 /usr/local/lib/python3.10/lib-dynload/_sha1.cpython-310-x86_64-linux-gnu.so
#6 0.486
#6 0.486 /usr/local/lib/python3.10/lib-dynload/_pickle.cpython-310-x86_64-linux-gnu.so
#6 0.500
#6 0.500 /usr/local/lib/python3.10/lib-dynload/_opcode.cpython-310-x86_64-linux-gnu.so
#6 0.515
#6 0.515 /usr/local/lib/python3.10/lib-dynload/_sha3.cpython-310-x86_64-linux-gnu.so
#6 0.529
#6 0.530 /usr/local/lib/python3.10/lib-dynload/termios.cpython-310-x86_64-linux-gnu.so
#6 0.543
#6 0.543 /usr/local/lib/python3.10/lib-dynload/select.cpython-310-x86_64-linux-gnu.so
#6 0.557
#6 0.557 /usr/local/lib/python3.10/lib-dynload/_uuid.cpython-310-x86_64-linux-gnu.so
#6 0.570
#6 0.571 /usr/local/lib/python3.10/lib-dynload/_codecs_kr.cpython-310-x86_64-linux-gnu.so
#6 0.584
#6 0.585 /usr/local/lib/python3.10/lib-dynload/_elementtree.cpython-310-x86_64-linux-gnu.so
#6 0.598
#6 0.598 /usr/local/lib/python3.10/lib-dynload/_json.cpython-310-x86_64-linux-gnu.so
#6 0.611
#6 0.612 /usr/local/lib/python3.10/lib-dynload/_sha256.cpython-310-x86_64-linux-gnu.so
#6 0.625
#6 0.626 /usr/local/lib/python3.10/lib-dynload/_sha512.cpython-310-x86_64-linux-gnu.so
#6 0.641
#6 0.641 /usr/local/lib/python3.10/lib-dynload/binascii.cpython-310-x86_64-linux-gnu.so
#6 0.655
#6 0.655 /usr/local/lib/python3.10/lib-dynload/_bz2.cpython-310-x86_64-linux-gnu.so
#6 0.669
#6 0.669 /usr/local/lib/python3.10/lib-dynload/_csv.cpython-310-x86_64-linux-gnu.so
#6 0.683
#6 0.683 /usr/local/lib/python3.10/lib-dynload/zlib.cpython-310-x86_64-linux-gnu.so
#6 0.697
#6 0.697 /usr/local/lib/python3.10/lib-dynload/_decimal.cpython-310-x86_64-linux-gnu.so
#6 0.711
#6 0.712 /usr/local/lib/python3.10/lib-dynload/grp.cpython-310-x86_64-linux-gnu.so
#6 0.725
#6 0.726 /usr/local/lib/python3.10/lib-dynload/math.cpython-310-x86_64-linux-gnu.so
#6 0.741
#6 0.742 /usr/local/lib/python3.10/lib-dynload/_sqlite3.cpython-310-x86_64-linux-gnu.so
#6 0.757
#6 0.757 /usr/local/lib/python3.10/lib-dynload/_gdbm.cpython-310-x86_64-linux-gnu.so
#6 0.771
#6 0.772 /usr/local/lib/python3.10/lib-dynload/_hashlib.cpython-310-x86_64-linux-gnu.so
#6 0.786
#6 0.786 /usr/local/lib/python3.10/lib-dynload/_xxsubinterpreters.cpython-310-x86_64-linux-gnu.so
#6 0.799
#6 0.800 /usr/local/lib/python3.10/lib-dynload/syslog.cpython-310-x86_64-linux-gnu.so
#6 0.813
#6 0.814 /usr/local/lib/python3.10/lib-dynload/_testmultiphase.cpython-310-x86_64-linux-gnu.so
#6 0.827
#6 0.828 /usr/local/lib/python3.10/lib-dynload/_queue.cpython-310-x86_64-linux-gnu.so
#6 0.843
#6 0.843 /usr/local/lib/python3.10/lib-dynload/_codecs_iso2022.cpython-310-x86_64-linux-gnu.so
#6 0.857
#6 0.857 /usr/local/lib/python3.10/lib-dynload/_md5.cpython-310-x86_64-linux-gnu.so
#6 0.871
#6 0.872 /usr/local/lib/python3.10/lib-dynload/_curses_panel.cpython-310-x86_64-linux-gnu.so
#6 0.885
#6 0.885 /usr/local/lib/python3.10/lib-dynload/_asyncio.cpython-310-x86_64-linux-gnu.so
#6 0.899
#6 0.899 /usr/local/lib/python3.10/lib-dynload/_crypt.cpython-310-x86_64-linux-gnu.so
#6 0.913
#6 0.913 /usr/local/lib/python3.10/lib-dynload/audioop.cpython-310-x86_64-linux-gnu.so
#6 0.926
#6 0.927 /usr/local/lib/python3.10/lib-dynload/fcntl.cpython-310-x86_64-linux-gnu.so
#6 0.940
#6 0.940 /usr/local/lib/python3.10/lib-dynload/_testbuffer.cpython-310-x86_64-linux-gnu.so
#6 0.955
#6 0.956 /usr/local/lib/python3.10/lib-dynload/_multiprocessing.cpython-310-x86_64-linux-gnu.so
#6 0.970
#6 0.970 /usr/local/lib/python3.10/lib-dynload/mmap.cpython-310-x86_64-linux-gnu.so
#6 0.983
#6 0.984 /usr/local/lib/python3.10/lib-dynload/_testcapi.cpython-310-x86_64-linux-gnu.so
#6 0.997
#6 0.997 /usr/local/lib/python3.10/lib-dynload/_xxtestfuzz.cpython-310-x86_64-linux-gnu.so
#6 1.011
#6 1.011 /usr/local/lib/python3.10/lib-dynload/_posixsubprocess.cpython-310-x86_64-linux-gnu.so
#6 1.025
#6 1.025 /usr/local/lib/python3.10/lib-dynload/resource.cpython-310-x86_64-linux-gnu.so
#6 1.038
#6 1.039 /usr/local/lib/python3.10/lib-dynload/_blake2.cpython-310-x86_64-linux-gnu.so
#6 1.052
#6 1.052 /usr/local/lib/python3.10/lib-dynload/_contextvars.cpython-310-x86_64-linux-gnu.so
#6 1.066
#6 1.067 /usr/local/lib/python3.10/lib-dynload/readline.cpython-310-x86_64-linux-gnu.so
#6 1.081
#6 1.081 /usr/local/lib/python3.10/lib-dynload/cmath.cpython-310-x86_64-linux-gnu.so
#6 1.095
#6 1.095 /usr/local/lib/python3.10/lib-dynload/array.cpython-310-x86_64-linux-gnu.so
#6 1.109
#6 1.109 /usr/local/lib/python3.10/lib-dynload/_random.cpython-310-x86_64-linux-gnu.so
#6 1.123
#6 1.123 /usr/local/lib/python3.10/lib-dynload/_heapq.cpython-310-x86_64-linux-gnu.so
#6 1.136
#6 1.137 /usr/local/lib/python3.10/lib-dynload/pyexpat.cpython-310-x86_64-linux-gnu.so
#6 1.150
#6 1.150 /usr/local/lib/python3.10/lib-dynload/_ctypes_test.cpython-310-x86_64-linux-gnu.so
#6 1.164
#6 1.164 /usr/local/lib/python3.10/lib-dynload/_lzma.cpython-310-x86_64-linux-gnu.so
#6 1.179
#6 1.180 /usr/local/lib/python3.10/lib-dynload/_zoneinfo.cpython-310-x86_64-linux-gnu.so
#6 1.194
#6 1.194 /usr/local/lib/python3.10/lib-dynload/unicodedata.cpython-310-x86_64-linux-gnu.so
#6 1.209
#6 1.209 /usr/local/lib/python3.10/lib-dynload/ossaudiodev.cpython-310-x86_64-linux-gnu.so
#6 1.223
#6 1.223 /usr/local/lib/python3.10/lib-dynload/_struct.cpython-310-x86_64-linux-gnu.so
#6 1.236
#6 1.237 /usr/local/lib/python3.10/lib-dynload/nis.cpython-310-x86_64-linux-gnu.so
#6 1.250
#6 1.251 /usr/local/lib/python3.10/lib-dynload/_codecs_hk.cpython-310-x86_64-linux-gnu.so
#6 1.264
#6 1.265 /usr/local/lib/python3.10/lib-dynload/_codecs_cn.cpython-310-x86_64-linux-gnu.so
#6 1.280
#6 1.281 /usr/local/lib/python3.10/lib-dynload/_codecs_jp.cpython-310-x86_64-linux-gnu.so
#6 1.295
#6 1.295 /usr/local/lib/python3.10/lib-dynload/_lsprof.cpython-310-x86_64-linux-gnu.so
#6 1.308
#6 1.309 /usr/local/lib/python3.10/lib-dynload/_posixshmem.cpython-310-x86_64-linux-gnu.so
#6 1.322
#6 1.322 /usr/local/lib/python3.10/lib-dynload/_codecs_tw.cpython-310-x86_64-linux-gnu.so
#6 1.336
#6 1.336 /usr/local/lib/python3.10/lib-dynload/_bisect.cpython-310-x86_64-linux-gnu.so
#6 1.350
#6 1.350 /usr/local/lib/python3.10/lib-dynload/_curses.cpython-310-x86_64-linux-gnu.so
#6 1.363
#6 1.364 /usr/local/lib/python3.10/lib-dynload/_socket.cpython-310-x86_64-linux-gnu.so
#6 1.378
#6 1.378 /usr/local/lib/python3.10/lib-dynload/_tkinter.cpython-310-x86_64-linux-gnu.so
#6 1.392
#6 1.393 /usr/local/lib/python3.10/lib-dynload/_testimportmultiple.cpython-310-x86_64-linux-gnu.so
#6 1.407
#6 1.407 /usr/local/lib/python3.10/lib-dynload/_testinternalcapi.cpython-310-x86_64-linux-gnu.so
#6 1.421
#6 1.421 /usr/local/lib/python3.10/lib-dynload/_ssl.cpython-310-x86_64-linux-gnu.so
#6 1.435
#6 1.435 /usr/local/lib/python3.10/lib-dynload/xxlimited.cpython-310-x86_64-linux-gnu.so
#6 1.448
#6 1.449 /usr/local/lib/python3.10/lib-dynload/_ctypes.cpython-310-x86_64-linux-gnu.so
#6 1.462
#6 1.463 /usr/local/lib/python3.10/lib-dynload/xxlimited_35.cpython-310-x86_64-linux-gnu.so
#6 1.476
#6 1.476 /usr/local/lib/python3.10/lib-dynload/spwd.cpython-310-x86_64-linux-gnu.so
#6 1.489
#6 1.495 + readelf -d /usr/local/bin/python3.10
#6 1.513
#6 1.513 Dynamic section at offset 0x2dd8 contains 28 entries:
#6 1.513   Tag        Type                         Name/Value
#6 1.513  0x0000000000000001 (NEEDED)             Shared library: [libpython3.10.so.1.0]
#6 1.513  0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
#6 1.513  0x000000000000001d (RUNPATH)            Library runpath: [$ORIGIN/../lib]
#6 1.513  0x000000000000000c (INIT)               0x1000
#6 1.513  0x000000000000000d (FINI)               0x11b4
#6 1.513  0x0000000000000019 (INIT_ARRAY)         0x3dc8
#6 1.513  0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
#6 1.513  0x000000000000001a (FINI_ARRAY)         0x3dd0
#6 1.513  0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
#6 1.513  0x000000006ffffef5 (GNU_HASH)           0x308
#6 1.513  0x0000000000000005 (STRTAB)             0x4d8
#6 1.513  0x0000000000000006 (SYMTAB)             0x358
#6 1.513  0x000000000000000a (STRSZ)              258 (bytes)
#6 1.513  0x000000000000000b (SYMENT)             24 (bytes)
#6 1.513  0x0000000000000015 (DEBUG)              0x0
#6 1.513  0x0000000000000003 (PLTGOT)             0x4000
#6 1.513  0x0000000000000002 (PLTRELSZ)           24 (bytes)
#6 1.513  0x0000000000000014 (PLTREL)             RELA
#6 1.513  0x0000000000000017 (JMPREL)             0x6e0
#6 1.513  0x0000000000000007 (RELA)               0x620
#6 1.513  0x0000000000000008 (RELASZ)             192 (bytes)
#6 1.513  0x0000000000000009 (RELAENT)            24 (bytes)
#6 1.513  0x000000006ffffffb (FLAGS_1)            Flags: PIE
#6 1.513  0x000000006ffffffe (VERNEED)            0x600
#6 1.513  0x000000006fffffff (VERNEEDNUM)         1
#6 1.513  0x000000006ffffff0 (VERSYM)             0x5da
#6 1.513  0x000000006ffffff9 (RELACOUNT)          3
#6 1.513  0x0000000000000000 (NULL)               0x0
#6 1.514 + readelf -d /usr/local/lib/libpython3.10.so.1.0
#6 1.529
#6 1.529 Dynamic section at offset 0x37a608 contains 29 entries:
#6 1.529   Tag        Type                         Name/Value
#6 1.529  0x0000000000000001 (NEEDED)             Shared library: [libpthread.so.0]
#6 1.529  0x0000000000000001 (NEEDED)             Shared library: [libdl.so.2]
#6 1.529  0x0000000000000001 (NEEDED)             Shared library: [libutil.so.1]
#6 1.529  0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
#6 1.529  0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]
#6 1.529  0x000000000000000e (SONAME)             Library soname: [libpython3.10.so.1.0]
#6 1.529  0x000000000000000c (INIT)               0x59000
#6 1.529  0x000000000000000d (FINI)               0x27e64c
#6 1.529  0x0000000000000019 (INIT_ARRAY)         0x377b10
#6 1.529  0x000000000000001b (INIT_ARRAYSZ)       8 (bytes)
#6 1.529  0x000000000000001a (FINI_ARRAY)         0x377b18
#6 1.529  0x000000000000001c (FINI_ARRAYSZ)       8 (bytes)
#6 1.529  0x000000006ffffef5 (GNU_HASH)           0x260
#6 1.529  0x0000000000000005 (STRTAB)             0xeee0
#6 1.529  0x0000000000000006 (SYMTAB)             0x3408
#6 1.529  0x000000000000000a (STRSZ)              36620 (bytes)
#6 1.529  0x000000000000000b (SYMENT)             24 (bytes)
#6 1.529  0x0000000000000003 (PLTGOT)             0x37c000
#6 1.529  0x0000000000000002 (PLTRELSZ)           8544 (bytes)
#6 1.529  0x0000000000000014 (PLTREL)             RELA
#6 1.529  0x0000000000000017 (JMPREL)             0x56540
#6 1.529  0x0000000000000007 (RELA)               0x18f50
#6 1.529  0x0000000000000008 (RELASZ)             251376 (bytes)
#6 1.529  0x0000000000000009 (RELAENT)            24 (bytes)
#6 1.529  0x000000006ffffffe (VERNEED)            0x18d80
#6 1.529  0x000000006fffffff (VERNEEDNUM)         5
#6 1.529  0x000000006ffffff0 (VERSYM)             0x17dec
#6 1.529  0x000000006ffffff9 (RELACOUNT)          9730
#6 1.529  0x0000000000000000 (NULL)               0x0
#6 DONE 1.5s

Fixes #792

@jimnicholls jimnicholls changed the title Use the link to set rpath on just the python binary Use the linker to set rpath on just the python binary Jan 29, 2023
@tianon
Copy link
Member

tianon commented Jan 31, 2023

Nice, thank you! I'd like to try and find a way to combine the new make invocations so we don't have to have quite so much duplication (and thus try and decrease the chance we miss something in the future) -- is that something you're interested in working on or would you prefer if I take it from here?

Not the libraries in /usr/local/lib/python3.x/lib-dynload/ since they use system libraries like libssl (so `$ORIGIN/../lib` doesn't work for them)
@jimnicholls
Copy link
Contributor Author

I refactored EXTRA_CFLAGS, LDFLAGS, and PROFILE_TASK into variables so they could be reused across both invocations to make.

@jimnicholls jimnicholls marked this pull request as draft January 31, 2023 12:02
@jimnicholls jimnicholls marked this pull request as ready for review January 31, 2023 12:24
@jimnicholls
Copy link
Contributor Author

jimnicholls commented Feb 2, 2023

@tianon, was this the direction you were thinking?

I'm not wedded to either this direction or working on this myself. I'm just trying to be helpful.

@yosifkit yosifkit merged commit 06e0db2 into docker-library:master Feb 3, 2023
docker-library-bot added a commit to docker-library-bot/official-images that referenced this pull request Feb 3, 2023
Changes:

- docker-library/python@06e0db2: Merge pull request docker-library/python#794 from jimnicholls/issue-792
- docker-library/python@20c8782: Update 3.9
- docker-library/python@a09f407: Update 3.8
- docker-library/python@0048b55: Update 3.7
- docker-library/python@01cc4c0: Reuse EXTRA_CFLAGS, LDFLAGS, and PROFILE_TASK across both make invokes.
- docker-library/python@b871ae1: Update 3.12-rc
- docker-library/python@1b9fc11: Use the linker to change rpath for python3.x binary.
- docker-library/python@adfcf63: Update 3.11
- docker-library/python@48f998b: Update 3.10
- docker-library/python@74a6eda: Revert "Only change rpath for python3.x binary"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Latest 3.10-slim-bullseye fails on Macbook M1 with Rosetta emulation
3 participants