本文介绍了使用 OpenSSL 静态编译 Python 3.6的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用 OpenSSL 在 Linux 上静态编译 Python 3.6.

I'm trying to compile Python 3.6 on Linux statically with OpenSSL.

我的构建发生在 dockerfile 中,但本质上确实如此:

My build happens in a dockerfile, but essentially does:

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

更新 Modules/Setup.local 使其看起来像:

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

我得到一个编译好的二进制文件,但它没有静态链接到 OpenSSL.

I get a compiled binary, but it isn't statically linked to OpenSSL.

我做错了什么?

谢谢!

构建dockerfile:

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/

推荐答案

# 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:

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

档案 (*.a) 只是目标文件 (*.o) 的集合,因此您可以在任何使用目标文件的地方使用档案.

Archives (*.a) are just a collection of object files (*.o), so you can use an archive wherever you use an object file.

另见ld中的-l:filename(2)手册页:

--library=namespec

将 namespec 指定的存档或目标文件添加到列表中要链接的文件.此选项可以使用任意次数.如果namespec 的格式为:filename,ld 将在库路径中搜索一个名为 filename 的文件,否则它将在库路径中搜索一个名为 libnamespec.a. 的文件.

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.

如果您正在使用的 /usr/local 中有其他组件,那么您可能需要添加 -L/usr/local/lib -Wl,-R,/usr/local/lib -Wl,--enable-new-dtags 到您的 LDFLAGS.new-dtags 在 ELF 标头中嵌入了 RUNPATH(相对于 RPATH).RUNPATH 可以被 LD_LIBRARY_PATH 覆盖.

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.

我得到一个编译好的二进制文件,但它没有静态链接到 OpenSSL.

检查方法是将 ldd 与您在运行时使用的路径一起使用.例如,这里来自 Fedora 上的本地 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)

这里有几个相关的问题,但它们似乎没有涵盖与 Python 的静态链接.


Here are a couple of related questions, but it does not look like they cover static linking with Python.

要清楚的是,config.log 有错误,但您没有显示其中的相关部分:

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

静态 OpenSSL 可能(也可能不会)解决问题.

Static OpenSSL may (or may not) fix the problem.

这篇关于使用 OpenSSL 静态编译 Python 3.6的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-18 12:34
查看更多