Install python ssl module on linux without recompiling

前端 未结 2 1980
有刺的猬
有刺的猬 2021-02-20 07:10

Is it possible to install the SSL module for python on a linux box that already has OpenSSL installed without recompiling python? I was hoping it would be as simple as copying

2条回答
  •  刺人心
    刺人心 (楼主)
    2021-02-20 07:44

    Is it possible to install the SSL module for python on a linux box that already has OpenSSL installed without recompiling python?

    Yes. Python's setup.py uses the following logic to detect OpenSSL:

    search_for_ssl_incs_in = [
                          '/usr/local/ssl/include',
                          '/usr/contrib/ssl/include/'
                         ]
    
    ssl_incs = find_file('openssl/ssl.h', inc_dirs,
                         search_for_ssl_incs_in
    
    ssl_libs = find_library_file(self.compiler, 'ssl',lib_dirs,
                                 ['/usr/local/ssl/lib',
                                  '/usr/contrib/ssl/lib/'
                                 ] )
    
    if (ssl_incs is not None and
        ssl_libs is not None):
        exts.append( Extension('_ssl', ['_ssl.c'],
                               include_dirs = ssl_incs,
                               library_dirs = ssl_libs,
                               libraries = ['ssl', 'crypto'],
                               depends = ['socketmodule.h']), )
    

    The point is Python is not static linking against libssl and libcrypto. (Some static linking occurs with cctyes, but nothing else).

    Now, the bad thing is that the project uses system paths before your locally installed paths. For example, the project uses inc_dirs (system) before search_for_ssl_incs_in (local). (See more on this below).

    After you run configure, you will have a Modules/Setup with the following lines commented out:

    # 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
    

    Again, no static linking. (And this assumes the previous version of Python uncommented those lines).

    So you should be able to build a binary compatible version of OpenSSL and use LD_LIBRARY_PATH or LD_PREOLAD to ensure Python uses your updated version of OpenSSL.

    OpenSSL 0.9.7 and 0.9.8 are binary compatible. OpenSSL 1.0.0, 1.0.1 and 1.0.2 are binary compatible. OpenSSL 0.9.8 and 1.0.0 are not binary compatible.

    ----------

    Here's the problem with Python's setup placing system includes before local includes:

    export CFLAGS="-I/usr/local/ssl/darwin/include"; export LDFLAGS="-L/usr/local/ssl/darwin/lib"
    
    ./configure
    
    make
    ...
    /Users/jww/Python-3.4.2/Modules/_ssl.c:390:9: warning: 
          'ERR_peek_last_error' is deprecated [-Wdeprecated-declarations]
        e = ERR_peek_last_error();
            ^
    /usr/include/openssl/err.h:274:15: note: 'ERR_peek_last_error' declared here
    unsigned long ERR_peek_last_error(void) DEPRECATED_IN_MAC_OS_X_VERSION_1...
                  ^
    /Users/jww/Python-3.4.2/Modules/_ssl.c:393:15: warning: 
          'SSL_get_error' is deprecated [-Wdeprecated-declarations]
            err = SSL_get_error(obj->ssl, ret);
    ...
    

    Python used the down level version 0.9.8 version of OpenSSL provided by Apple, and not my recent OpenSSL 1.0.1k. That's despite me (1) exporting them in CFLAGS and LDFLAGS; (2) editing Setup; and (3) editing Modules/Setup.

    And I still have runtime path problems to contend with, so I'll need to use LD_PRELOAD_PATH, DYNLIB_LIBRARY_PATH, etc.

提交回复
热议问题