I'm trying to compile Python 3.6 on Linux statically with OpenSSL.
My build happens in a dockerfile, but essentially does:
$ ./configure --prefix=/task/build --disable-shared LDFLAGS="-static"
$ make altinstall
With an update to Modules/Setup.local
to make it look like:
*static*
# Socket module helper for SSL support; you must comment out the other
# socket line above, and possibly edit the SSL variable:
SSL=/usr/local/ssl
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -lssl -lcrypto
However, on the configure step, I get the error:
Step 9/14 : RUN ./configure --prefix=/task/build --disable-shared LDFLAGS="-static"
---> Running in cb79ee47052b
checking for git... found
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for python3.6... no
checking for python3... no
checking for python... python
checking for --enable-universalsdk... no
checking for --with-universal-archs... no
checking MACHDEP... linux
checking for --without-gcc... no
checking for --with-icc... no
checking for gcc... gcc
checking whether the C compiler works... no
configure: error: in `/task/cpython':
configure: error: C compiler cannot create executables
See `config.log' for more details
The command '/bin/sh -c ./configure --prefix=/task/build --disable-shared LDFLAGS="-static"' returned a non-zero code: 77
If I change the configure command to:
$ ./configure --prefix=/task/build --disable-shared
I get a compiled binary, but it isn't statically linked to OpenSSL.
What am I doing wrong?
Thanks!
Build dockerfile:
FROM amazonlinux:2017.03.1.20170812
ARG python_version=3.6.8
WORKDIR /task
COPY Modules-Setup.local /task/Modules-Setup.local
# Install requirements
RUN yum install -y \
gcc \
git \
gzip \
openssl-devel \
tar \
zlib \
zlib-devel
# Get openssl and python source
RUN git clone https://github.com/python/cpython.git
WORKDIR /task/cpython
RUN git checkout tags/v${python_version}
# Configure the build
RUN ./configure --prefix=/task/build --disable-shared LDFLAGS="-static"
# Append modules setup with custom values
RUN cat /task/Modules-Setup.local >> /task/cpython/Modules/Setup.local
RUN cat /task/cpython/Modules/Setup.local
# Build
RUN make altinstall
# Zip the results
WORKDIR /task/build
RUN tar --create --gzip --file=/task/python-${python_version}.tar.gz \
lib/ bin/
I'm trying to compile Python 3.6 on Linux statically with OpenSSL.
...# Socket module helper for SSL support; you must comment out the other # socket line above, and possibly edit the SSL variable: SSL=/usr/local/ssl _ssl _ssl.c \ -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ -L$(SSL)/lib -lssl -lcrypto
Change -lssl
and -lcrypto
to -l:libssl.a
and -l:libcrypto.a
:
SSL=/usr/local/ssl
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
-L$(SSL)/lib -l:libssl.a -l:libcrypto.a
You can also use the full path to the archive:
SSL=/usr/local/ssl
_ssl _ssl.c \
-DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
$(SSL)/lib/libssl.a $(SSL)/lib/libcrypto.a
Archives (*.a
) are just a collection of object files (*.o
), so you can use an archive wherever you use an object file.
Also see -l:filename
in the ld(2)
man page:
--library=namespec
Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search the library path for a file called libnamespec.a.
If you have other components in /usr/local
you are using, then you might want to add -L/usr/local/lib -Wl,-R,/usr/local/lib -Wl,--enable-new-dtags
to your LDFLAGS
. The new-dtags
embeds a RUNPATH
(as opposed to RPATH
) in the ELF headers. RUNPATH
can be overridden with LD_LIBRARY_PATH
.
I get a compiled binary, but it isn't statically linked to OpenSSL.
The way to check is to use ldd
with the paths you use at runtime. For example, here is from a local OpenSSL build on Fedora:
$ ldd /usr/local/bin/openssl
linux-vdso.so.1 (0x00007fff3cde6000)
libssl.so.1.0.0 => /usr/local/lib64/libssl.so.1.0.0 (0x00007f043dc4e000)
libcrypto.so.1.0.0 => /usr/local/lib64/libcrypto.so.1.0.0 (0x00007f043d9df000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f043d9c0000)
libc.so.6 => /lib64/libc.so.6 (0x00007f043d7fa000)
/lib64/ld-linux-x86-64.so.2 (0x00007f043dcc0000)
Here are a couple of related questions, but it does not look like they cover static linking with Python.
And to be clear, config.log
has the error but you did not show the relevant portion from it:
checking whether the C compiler works... no
configure: error: in `/task/cpython':
configure: error: C compiler cannot create executables
See `config.log' for more details
Static OpenSSL may (or may not) fix the problem.