Static Python Build errors

Hi,

We need a static Python build. See the build flags below, but somehow the -shared flag keep being present in the gcc commands. Could somebody please please help us with our static python build getting working?

I’m aware I most likely also need to build openssl and libffi in a static manner. But let’s try to tackle the problem one by one.

We use a Ubuntu 20.04 LTS Docker image. And we try to build the latest version (3.12.2) from source at this moment in time.

This is the configure command:

./configure \
    --enable-optimizations \
    --with-ensurepip=install \
    --prefix="$rollout" \
    --disable-shared \
    --with-static-libpython \
    LDFLAGS="-static -static-libgcc" \
    CFLAGS="-static" \
    CPPFLAGS="-static" \
    CFLAGSFORSHARED="" CCSHARED="" LDSHARED="" LDCXXSHARED="" \
    MODULE_BUILDTYPE=static

Then I also added *static* for the Python modules (to this special Setup.local file):

echo "*static*" >> Modules/Setup.local

And finally the make command itself:

make LINKFORSHARED=" " CCSHARED="" LDSHARED="" LDCXXSHARED=""  -j 10

Now the gcc command will have -static flag but also still the -shared flag!? How to get rid of this -shared flag:

gcc -pthread -shared -static -static-libgcc  -fno-semantic-interposition -fprofile-generate  Modules/_testimportmultiple.o   -o Modules/_testimportmultiple.cpython-312-x86_64-linux-gnu.so
gcc -pthread -shared -static -static-libgcc  -fno-semantic-interposition -fprofile-generate  Modules/_testsinglephase.o   -o Modules/_testsinglephase.cpython-312-x86_64-linux-gnu.so
gcc -pthread -shared -static -static-libgcc  -fno-semantic-interposition -fprofile-generate  Modules/xxlimited.o   -o Modules/xxlimited.cpython-312-x86_64-linux-gnu.so

/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
/usr/bin/ld: Modules/_testimportmultiple.o: relocation R_X86_64_PC32 against symbol `PyInit__testimportmultiple_bar' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: bad value

What do I wrong? Why has the gcc commands still -shared in the commands? Thanks in advance.

Ps. And no you don’t want to add -fPIC, since that is used for shared libs only.

Ps. Ps. Some commands seems fine like: gcc -pthread -fno-strict-overflow -DNDEBUG -g -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -I. -I./Include -static -DPy_BUILD_CORE_BUILTIN -c ./Modules/itertoolsmodule.c -o Modules/itertoolsmodule.o. But then later it swiches to modules and it fails:

rm -f Modules/_hacl/libHacl_Hash_SHA2.a
rm -f Modules/expat/libexpat.a
ar rcs Modules/_hacl/libHacl_Hash_SHA2.a Modules/_hacl/Hacl_Hash_SHA2.o
ar rcs Modules/expat/libexpat.a Modules/expat/xmlparse.o Modules/expat/xmlrole.o Modules/expat/xmltok.o
gcc -pthread -shared -static -static-libgcc  -fno-semantic-interposition -fprofile-generate  Modules/_testimportmultiple.o   -o Modules/_testimportmultiple.cpython-312-x86_64-linux-gnu.so
gcc -pthread -shared -static -static-libgcc  -fno-semantic-interposition -fprofile-generate  Modules/_testsinglephase.o   -o Modules/_testsinglephase.cpython-312-x86_64-linux-gnu.so
gcc -pthread -shared -static -static-libgcc  -fno-semantic-interposition -fprofile-generate  Modules/xxlimited.o   -o Modules/xxlimited.cpython-312-x86_64-linux-gnu.so
gcc -pthread -shared -static -static-libgcc  -fno-semantic-interposition -fprofile-generate  Modules/xxlimited_35.o   -o Modules/xxlimited_35.cpython-312-x86_64-linux-gnu.so
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object

Regards,
Melroy van den Berg

1 Like

I don’t have a solution, but when testing this myself I noticed that this only seems to affect Python 3.12. Your build method successfully produces a static Python binary for Python 3.11.

1 Like

Which Python 3.11? I tried Python 3.11.0, however it might seems to continue futher indeed. If you look at the output, you might notice, still the wrong build flags sometimes (-shared flag again) as well as ld errors (but it’s non-blocking in Python 3.11 build):

2024-02-14T14:12:25.3323680Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/readline.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/readline.o
2024-02-14T14:12:25.3324815Z building '_curses_panel' extension
2024-02-14T14:12:25.3326557Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -DHAVE_NCURSESW=1 -I/usr/include/ncursesw -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_curses_panel.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_curses_panel.o
2024-02-14T14:12:25.3384170Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -DHAVE_NCURSESW=1 -I/usr/include/ncursesw -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_cursesmodule.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_cursesmodule.o
2024-02-14T14:12:25.3433420Z building '_crypt' extension
2024-02-14T14:12:25.3434034Z building '_md5' extension
2024-02-14T14:12:25.3436365Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/md5module.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/md5module.o
2024-02-14T14:12:25.3440023Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_cryptmodule.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_cryptmodule.o
2024-02-14T14:12:25.3441602Z building '_sha1' extension
2024-02-14T14:12:25.3443897Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/sha1module.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/sha1module.o
2024-02-14T14:12:25.3445961Z building '_sha256' extension
2024-02-14T14:12:25.3446696Z building '_sha512' extension
2024-02-14T14:12:25.4214020Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/sha512module.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/sha512module.o
2024-02-14T14:12:25.4323142Z gcc -pthread -fPIC -DNDEBUG -g -fwrapv -O3 -Wall -static -fno-semantic-interposition -std=c11 -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I./Include/internal -I./Include -I. -I/usr/include/x86_64-linux-gnu -I/usr/local/include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Include -I/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0 -c /__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/sha256module.c -o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/sha256module.o
2024-02-14T14:12:25.5252775Z gcc -pthread -shared -static -static-libgcc -fno-semantic-interposition -fprofile-generate build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_contextvarsmodule.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -o build/lib.linux-x86_64-3.11/_contextvars.cpython-311-x86_64-linux-gnu.so
2024-02-14T14:12:25.7213043Z gcc -pthread -shared -static -static-libgcc -fno-semantic-interposition -fprofile-generate build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_statisticsmodule.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lm -o build/lib.linux-x86_64-3.11/_statistics.cpython-311-x86_64-linux-gnu.so
2024-02-14T14:12:25.8214007Z gcc -pthread -shared -static -static-libgcc -fno-semantic-interposition -fprofile-generate build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_typingmodule.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -o build/lib.linux-x86_64-3.11/_typing.cpython-311-x86_64-linux-gnu.so
2024-02-14T14:12:25.8273847Z gcc -pthread -shared -static -static-libgcc -fno-semantic-interposition -fprofile-generate build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_opcode.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -o build/lib.linux-x86_64-3.11/_opcode.cpython-311-x86_64-linux-gnu.so
2024-02-14T14:12:25.8333112Z /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
2024-02-14T14:12:25.9212303Z collect2: error: ld returned 1 exit status
2024-02-14T14:12:25.9222126Z /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
2024-02-14T14:12:25.9222566Z collect2: error: ld returned 1 exit status
2024-02-14T14:12:25.9369774Z /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
2024-02-14T14:12:25.9376547Z collect2: error: ld returned 1 exit status
2024-02-14T14:12:25.9377158Z building '_sha3' extension

Same a bit later in the output:

gcc -pthread -shared -static -static-libgcc build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_ctypes/_ctypes.o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_ctypes/callbacks.o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_ctypes/callproc.o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_ctypes/cfield.o build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_ctypes/stgdict.o -L/sdev_shared/sdev_custom_scripts_tst/lib -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -lffi -ldl -o build/lib.linux-x86_64-3.11/_ctypes.cpython-311-x86_64-linux-gnu.so
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
collect2: error: ld returned 1 exit status

Don’t you see this? Are you willing to share your configuration options? Is it my fault? Do I really do something wrong? What is your setup/ flags/commands?

You should always use the latest maintenance release of a series which will contain bugs fixes and security fixes and should not change the build process. In this case 3.11.8 is the latest.

2 Likes

I used 3.11.8, but looking closer at the build output I do see the “relocation R_X86_64_32 ...” message when building several sub-components. Didn’t notice it before since the build continues, and eventually spits out a seemingly-functional python binary.

The exact configuration and build flags I used were

./configure LDFLAGS="-static -static-libgcc" CPPFLAGS="-static" --disable-shared
make -j$(nproc) LDFLAGS="-static" LINKFORSHARED=" "
1 Like

Sure but Python 3.12.x static build is broken for sure I think…

Thanks. Let me check again with those flags. As you noticed I kept adding more and more flags trying to get it working. If you get those link (ld) errors as well… Then you most likely also still got -shared flag in the gcc command!? Eg:

2024-02-14T14:12:25.8273847Z gcc -pthread -shared -static -static-libgcc -fno-semantic-interposition -fprofile-generate build/temp.linux-x86_64-3.11/__w/OpenRepo-Python/OpenRepo-Python/Python-3.11.0/Modules/_opcode.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -o build/lib.linux-x86_64-3.11/_opcode.cpython-311-x86_64-linux-gnu.so

I’m really the only person that sees this -shared flag still being present?

No, I see the same thing during the 3.11.8 build for the failing modules (and for the 3.12.2 build).

gcc -pthread -shared -static -static-libgcc -static -static build/temp.linux-x86_64-3.11/home/abemtk/tmp/buildpython/Python-3.11.8/Modules/xxlimited_35.o -L/usr/lib/x86_64-linux-gnu -L/usr/local/lib -o build/lib.linux-x86_64-3.11/xxlimited_35.cpython-311-x86_64-linux-gnu.so
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginT.o: relocation R_X86_64_32 against hidden symbol `__TMC_END__' can not be used when making a shared object
collect2: error: ld returned 1 exit status

After reading up on this some more, I think the problem may be related to glibc. Specifically, I don’t think Ubuntu ships a static version of glibc, and there seem to be good reasons for that.

Here’s an old build script that uses a static build of musl libc in place of glibc. I haven’t tried it, but it might be a possible way forward.

Are you sure it’s glibc related. I still see -shared flag in the gcc command. Which can not be correct. This the whole problem, I suspect.

You can’t have static and shared flag together. But the python build is broken in that sense.

That’s a good point, you would need to get rid of -shared. But you also need a static libc to build a static binary, but I guess that’s a later problem.

1 Like

Of course… But my first issue is with Python source build is that I can’t get rid of this -shared flag. Not in Python 3.11.x and not in 3.12.x. Not even in 3.10.x… Any idea how to get rid of this shared flag?

I have the feeling this bug is in the Python build system for several months/years. And nobody is validating the static build of Python, causing more and more regression over time. Which is a pity.

2 Likes

Too bad no follow-up or fix of static builds…

In ye oldie times I used to use Autotools, so my “solution” might not work.

I think you can, after running ./configure script, open the Makefile and manually remove all -shared flags. Just use a find-and-delete tool in your favorite text editor :wink:

Five minutes later…

Okay, I think I got something: when running ./configure add LDSHARED="gcc" (instead of gcc you can write your compiler of course)

Why I think it may work? Well, I have read the configure.ac from the repo (over 7000 lines of code o…m…g) and found this:

AC_MSG_CHECKING([LDSHARED])
if test -z "$LDSHARED"
then
...
Linux*|GNU*|QNX*|VxWorks*|Haiku*)
		LDSHARED='$(CC) -shared'
		LDCXXSHARED='$(CXX) -shared';;

In other words you MUST provide the LDSHARED= value that can’t be an empty value. If you don’t then the code that adds -shared flags are executed.

I must say this sounds counter-intuitive but it might work :slight_smile: