Скомпилируйте Python 3.6 статически с OpenSSL - PullRequest
2 голосов
/ 30 апреля 2019

Я пытаюсь статически скомпилировать Python 3.6 для Linux с OpenSSL.

Моя сборка происходит в dockerfile, но, по сути, происходит:

$ ./configure --prefix=/task/build --disable-shared LDFLAGS="-static"
$ make altinstall

С обновлением до Modules/Setup.local, чтобы оно выглядело как:

*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

Однако на этапе настройки я получаю сообщение об ошибке:

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

Если я изменю команду настройки на:

$ ./configure --prefix=/task/build --disable-shared

Я получаю скомпилированный двоичный файл, но он не связан статически с OpenSSL.

Что я делаю не так?

Спасибо!


Сборка 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/

1 Ответ

2 голосов
/ 30 апреля 2019

Я пытаюсь компилировать Python 3.6 в Linux статически с 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

Измените -lssl и -lcrypto на -l:libssl.a и -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

Вы также можете использовать полный путь к архиву:

SSL=/usr/local/ssl
_ssl _ssl.c \
  -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \
  $(SSL)/lib/libssl.a $(SSL)/lib/libcrypto.a

Архивы (*.a) - это просто набор объектных файлов (*.o), поэтому вы можете использовать архив везде, где вы используете объектный файл.

Также см. -l:filename в справочной странице ld(2) :

--library=namespec

Добавить архив или объектный файл, указанный в namespec, в список файлы для ссылки. Эта опция может использоваться любое количество раз. Если namespec имеет вид: имя файла, ld будет искать путь к библиотеке файл с именем filename, в противном случае он будет искать путь к библиотеке файл с именем libnamespec.a.

Если у вас есть другие компоненты в /usr/local, который вы используете, то вы можете добавить -L/usr/local/lib -Wl,-R,/usr/local/lib -Wl,--enable-new-dtags к LDFLAGS. new-dtags встраивает RUNPATH (в отличие от RPATH) в заголовки ELF. RUNPATH можно переопределить с помощью LD_LIBRARY_PATH.


Я получаю скомпилированный двоичный файл, но он не связан статически с OpenSSL.

Способ проверки заключается в использовании ldd с путями, которые вы используете во время выполнения. Например, вот из локальной сборки OpenSSL на 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)

Вот пара связанных вопросов, но, похоже, они не охватывают статическое связывание с Python.


И чтобы было ясно, config.log имеет ошибку, но вы не показали соответствующую часть из нее:

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

Статический OpenSSL может (или не может) решить проблему.

...