简体   繁体   中英

Compile Python 3.6 statically with OpenSSL

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.

I ran across the same issue and solved it by installing the static glibc libraries:

yum install glibc-static

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM