Build python3.11.5 with static openssl and libffi on centos7

I am trying to build python3.11.5 with static openssl and libffi so it can work on any linux 64bit without any issue but i am seeing still its linking dynamically to libcrypto.so

i have statically build openssl and libffi and i see libssl.a and libcrypto.a present in /customer_path/openssl/lib/
and same for libffi

[root@localhost Python-3.11.5]# cat test.sh

!/bin/sh

export LDFLAGS=“-L/home/test/openssl/lib -L/home/test/libffi/lib64 -L/usr/lib -L/usr/lib64 -lffi -ldl -lssl -lcrypto”

export CPPFLAGS=“-I/home/test/openssl/include -I/home/test/libffi/include -I/usr/include”

export CFLAGS=“-static-libgcc”

export LD_LIBRARY_PATH=“/home/test/openssl/lib:/home/test/libffi/lib64”

make clean

./configure --prefix=/home/test/python_static/ --with-openssl=/home/test/openssl --with-system-ffi=/home/test/libffi/lib64 --enable-optimizations --enable-shared=no

make LINKFORSHARED=" "

make install

But still its showing python3.11 binary linking as below

[root@localhost Python-3.11.5]# ldd /home/test/python_static/bin/python3.11
	linux-vdso.so.1 =>  (0x00007ffd521a5000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007fb7fdeff000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fb7fdce3000)
	libutil.so.1 => /lib64/libutil.so.1 (0x00007fb7fdae0000)
	libm.so.6 => /lib64/libm.so.6 (0x00007fb7fd7de000)
	libz.so.1 => /lib64/libz.so.1 (0x00007fb7fd5c8000)
	librt.so.1 => /lib64/librt.so.1 (0x00007fb7fd3c0000)
	libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fb7fd189000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fb7fcdbb000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fb7fe103000)
	libfreebl3.so => /lib64/libfreebl3.so (0x00007fb7fcbb8000)
1 Like

Hey there seems that this issue was discussed Dynamic Linking of OpenSSL - #4 by barry-scott
And what I’m getting is that you should specify the path to your statically built libraries before configuring, if not then by default it will pick up the dynamic version

Are these the path to your static libs directory?

yes i have build openssl and libffi statically with prefix /home/test/openssl and /home/test/libffi.
also passed same during python build

Hey did you read through comments on the link or you didn’t find anything substantial… It seems building a custom Openssl is really troublesome that the issue was closed damn nywy check this… if you can scheme through I’m sure you can get a thing or two coz it still seems python is reading from the default dynamic versions of the libs even though you have explicitly specified path to the static libs…

There is a part @zuhu2195

then you need to set the linker to not to look for standard locations for openssl dll’s 
first and look for your location first, use -Wl,-rpath option to linker,

but if you managed also keep us posted lol

–with-openssl option is used to link dynamic libraries(as you can see from my conversation on dynamic linking of openssl with python), if you have set LDFLAGS, CPPFLAGS, and LD_LIBRARY_PATH appropriately you need not use this option, python should automatically pick up the openssl archives(.a files) from this location, if they are not first found in standard locations. If you have another ssl in standard location then you need to change the runtime library preference using a linker option.

Ah Moha thankyou for coming to the party…so are you saying --with-openssl will not be necessary for his case? And if I’m not getting wrong… if one has already specified the --enable-shared=no then there’s no need for the LD_LIBRARY_PATH. Since this path essentially sets up a PATH for shared libraries, why do we still need it in his scenario?

Hi @kyle

Yes —with-openssl won’t be required, and yes LD_LIBRARY_PATH won’t be required, I was quoting the variables set by @Rushikumar earlier and hence included this environment variable. Thanks for pointing that out.

if we dont pass --with-openssl or dont set LD_LIBRARY_PATH then we are seeing libcrypto.so.x dependency in ldd output.

but if i pass this --with-openssl option then its not coming and import ssl also working fine and showing correct openssl version.

i dont know why still this libcrypt.so.1 present still
is it different from libcrypto.so? and do we have any way to get rid of libcrypt.so dependency here.

i dont want to build python3.11 completely statically but i just want to build python3.11 with static openssl and libffi here.

Hi!
Here are the key lines of my build script for ffi, zlib, and openssl, plus the exact steps I’ve been using to build python. Works for me on intel and M1. (I have only been using Ubuntu and Alpine recently; however it was definitely working on CentOS 7 the last time I tried).

# ffi
./configure --prefix=$PREFIX_DIR --enable-static --disable-shared
# zlib
./configure --prefix=$PREFIX_DIR
# openssl 
# (Not sure if the -fPIC is still needed;
# several years ago it was the only way I could make things 
./config -fPIC --prefix=$PREFIX_DIR --openssldir=$PREFIX_DIR

# I think I did this specifically for CentOS 7, although have not re-tested that in many months
for FILE in libssl.a libcrypto.a libffi.a; do
    if [ ! -f $PREFIX_DIR/lib/$FILE ]; then
        echodo ln -s $PREFIX_DIR/lib64/$FILE $PREFIX_DIR/lib/$FILE
    fi
done

# Python (tested with 3.11.x, 3.12)
(
    cd $SW_DIR/$MY_PYTHON
    cp $MY_BUILD_DIR/source/Setup.linux Modules/Setup.local

    # NOTE: Don't enable optimizations if installation fails with these errors:
    # Fatal Python error: init_import_site: Failed to import the site module
    # SystemError: <built-in function compile> returned NULL without setting an error
    # Building on CentOS 7 requires disabling python optimization.
    CENTOS7="`grep "CentOS Linux 7" /etc/os-release || true`"

    # Centos 7
    PY_OPTIMIZE=
    touch $PREFIX_DIR/include/stdatomic.h  # For new cython

    ./configure \
        --prefix=$PREFIX_DIR \
        --with-libs=$PREFIX_DIR/lib/*.a \
        --with-openssl=$PREFIX_DIR \
        --disable-shared \
        $PY_OPTIMIZE
)
# ubuntu on macbook pro M1:
pete@flow:/work/build_xpack/source$ ldd `which python`
	linux-vdso.so.1 (0x0000ffffaa101000)
	libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffffa90e0000)
	libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffa8f30000)
	/lib/ld-linux-aarch64.so.1 (0x0000ffffaa0c8000)

CentOS 7 had a few more shared lib dependencies, but no libcrypt.
If this does not work for you, I’ll retry on CentOS 7 and see if any additional details from my build are helpful.

Regards,
Pete

Hi @Peter schay thanks for reply.
i moved to ubuntu now and trying on ubuntu16 and script which i am using to build is as follow and seeing still same issue.

export LDFLAGS=“-static-libgcc -static-libstdc++ -L/home/test/openssl/lib -L/home/test/libffi/lib -L/home/test/readline/lib -L/home/test/libz/lib -L/home/test/ncurses/lib -L/usr/lib -L/usr/lib64 -lffi -ldl -lssl -lcrypto -lcrypt -lreadline -ltinfo -rdynamic”
export CPPFLAGS=“-I/home/test/openssl/include -I/home/test/libffi/include -I/home/test/readline/include -I/home/test/libz/include -I/home/test/ncurses/include -I/usr/include”
export CFLAGS=“-static-libgcc”
export LD_LIBRARY_PATH=“/home/test/openssl/lib:/home/test/libffi/lib64:/home/test/readline/lib:/home/test/libz/lib:/home/test/ncurses/lib”

make clean
./configure --prefix=/home/test/python_static/
–with-openssl=/home/test/openssl
–with-system-ffi=/home/test/libffi/lib
–with-readline=/home/test/readline
–with-zlib=/home/test/libz
–with-ncurses=/home/test/ncurses
–enable-shared=no
–enable-optimizations
make LINKFORSHARED=" "
make install

also i am enabling readline as well from Setup/Modules but its showing libtinfo.so dependency as well here

root@test-AHV:/home/test/Python-3.11.5# ldd …/python_static/python3
linux-gate.so.1 => (0xb778b000)
libpthread.so.0 => /lib/i386-linux-gnu/libpthread.so.0 (0xb7754000)
libdl.so.2 => /lib/i386-linux-gnu/libdl.so.2 (0xb774f000)
libutil.so.1 => /lib/i386-linux-gnu/libutil.so.1 (0xb774a000)
libm.so.6 => /lib/i386-linux-gnu/libm.so.6 (0xb76f5000)
librt.so.1 => /lib/i386-linux-gnu/librt.so.1 (0xb76ec000)
libcrypt.so.1 => /lib/i386-linux-gnu/libcrypt.so.1 (0xb76ba000)
libtinfo.so.5 => /lib/i386-linux-gnu/libtinfo.so.5 (0xb7697000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb74e0000)
/lib/ld-linux.so.2 (0x80055000)
root@test-AHV:/home/test/Python-3.11.5#

root@test-AHV:/home/test# find . -name ‘libtinfo.*’
./ncurses/lib/libtinfo.a
./ncurses-6.2/lib/libtinfo.a
root@test-AHV:/home/test#

libtinfo.a is already statically build and present as well but still python binary pointing dynamic to .so file

version i am using for other statically build library is
zlib-1.3
readline-8.2
openssl-1.1.1l
ncurses-6.2
libffi-3.3

I am ok with other dynamic .so files but wanted to get rid of libcrypt and libtinfo mainly. any help and guidance really appreciated .

1 Like