35

I have my own OpenSSL installation in a non-standard location (/my/path for the sake of this example) and I want Python 3.4 to build against that when I compile it against source. What I tried is this (directories abbreviated)

CPPFLAGS="-I/my/path/include -I/my/path/include/openssl" ./configure --prefix=/my/path/

I also tried with C_INCLUDE_PATH and colon separated paths.

Then, I run make and get this:

building '_ssl' extension
gcc -pthread -fPIC -fno-strict-aliasing -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I./Include -I. -IInclude -I/my/path/include -I/my/path/include/openssl -I/usr/local/include -I/my/path/Python-3.4.0/Include -I/my/path/Python-3.4.0 -c /my/path/Python-3.4.0/Modules/_ssl.c -o build/temp.linux-x86_64-3.4/my/path/Python-3.4.0/Modules/_ssl.o
gcc -pthread -shared build/temp.linux-x86_64-3.4/my/path/Python-3.4.0/Modules/_ssl.o -L/my/path/lib -L/usr/local/lib -lssl -lcrypto -o build/lib.linux-x86_64-3.4/_ssl.cpython-34m.so
*** WARNING: renaming "_ssl" since importing it failed: build/lib.linux-x86_64-3.4/_ssl.cpython-34m.so: undefined symbol: SSL_get0_next_proto_negotiated

It's looking for SSL_get0_next_proto_negotiated, but that's most certainly defined:

$ grep SSL_get0_next_proto_negotiated /my/path/include/openssl/*
/my/path/include/openssl/ssl.h:void SSL_get0_next_proto_negotiated(const SSL *s,

I'm not sure what I'm doing wrong, any ideas?

jww
  • 97,681
  • 90
  • 411
  • 885
Scott Frazer
  • 2,145
  • 2
  • 23
  • 36

3 Answers3

52

I managed to figure it out after a lot of hair-pulling. It was a bunch of environment variables... I think I might have done a little overkill, but this basically worked:

# OpenSSL 1.0.1g
./config shared --prefix=/my/path --openssldir=/my/path/openssl
make
make install

# Python 3.4
export LDFLAGS="-L/my/path/lib/ -L/my/path/lib64/"
export LD_LIBRARY_PATH="/my/path/lib/:/my/path/lib64/"
export CPPFLAGS="-I/my/path/include -I/my/path/include/openssl"
./configure --prefix=/my/path/
make
make install
Scott Frazer
  • 2,145
  • 2
  • 23
  • 36
  • 8
    You'll probably want `-Wl,-rpath=/my/path/openssl/lib` in your `LDFLAGS` so the custom openssl lib dir gets baked into the resulting executable. I.e. so you don't need to set `LD_LIBRARY_PATH` when running your python. Not tested (sorry). – Steve Kehlet Jun 04 '15 at 17:48
  • Thanks, this one at least resulted in a build with openssl extensions (which various other recipes wouldn't accomplish). python 2.7.10, openssl 1.0.1 in openbuildservice environment. – Roman Grazhdan Oct 13 '15 at 10:01
  • Full disclosure though - I have all the libs we use in the same openbuildserver project so I can rebuild them in batch anytime, otherwise it wouldn't worth to bother with all this. – Roman Grazhdan Oct 13 '15 at 10:07
  • Thank you, I an inordinate amount of time on this problem before your solution worked perfectly. For Python-2.7.11 and 3.5. – PonyEars Jan 31 '16 at 01:53
  • I've been wasting hours to get SSL support. This solution finally did it for my on python 2.7.12 – jonthalpy Jul 29 '16 at 04:44
  • `CPPFLAGS` is for the C preprocessor. You probably want to use `CFLAGS`. It is the compiler diver's job to pass relevant `CFLAGS` down to the preprocessor. The preprocessor does not pass relevant flags up to the compiler driver. – jww Dec 16 '16 at 23:22
  • @Scott Frazer I am using Ubuntu 18, where I can find python directory to change the configurations? – user9371654 Aug 05 '18 at 04:05
  • In year 2021, for those who are trying to build python 3.10+ with Apple Silicon (M1 ARM)chip, use flag `--with-openssl=/path/to/openssl` it works on Apple Silicon. – dotslash Jan 06 '21 at 23:30
  • Here is an example that worked for me on Debian 8: `LDFLAGS="${LDFLAGS} -Wl,-rpath=/usr/local/ssl/lib" CFLAGS="${CFLAGS} -I/usr/local/ssl/include" ./configure --prefix=/home/lawlist/opt/python_3_9_13 --with-openssl=/usr/local/ssl` The key ingredients to a successful Python build and to avoid a `_hashlib` failure when building same were to use the `shared` flag when building `openssl` and use the `--with-openssl` flag when building Python. – lawlist Oct 27 '22 at 23:48
17

Thanks @ScottFrazer for his answer. Saved me a lot of troubles.

Here is a script I used in ubuntu to compile python with the latest openssl 1.0.2g.

# new openssl install
curl https://www.openssl.org/source/openssl-1.0.2g.tar.gz | tar xz && cd openssl-1.0.2g && ./config shared --prefix=/usr/local/ && make && make install

# Python install script
export LDFLAGS="-L/usr/local/lib/"
export LD_LIBRARY_PATH="/usr/local/lib/"
export CPPFLAGS="-I/usr/local/include -I/usr/local/include/openssl"
apt-get update
apt-get install build-essential checkinstall -y
apt-get install libreadline-gplv2-dev libncursesw5-dev libssl-dev libsqlite3-dev tk-dev libgdbm-dev libc6-dev libbz2-dev -y
cd /home/web/
wget https://www.python.org/ftp/python/2.7.11/Python-2.7.11.tgz | tar xzf Python-2.7.11.tgz && cd Python-2.7.11 
./configure --prefix=/usr/local/ 
make altinstall

Notice, the install is an altinstall which means it will not override the default python on ubuntu. To verify the installation was successful:

/usr/local/bin/python2.7
>>> import ssl
>>> ssl.OPENSSL_VERSION
'OpenSSL 1.0.2g  1 Mar 2016'
Hassek
  • 8,715
  • 6
  • 47
  • 59
  • 1
    `CPPFLAGS` is for the C preprocessor. You probably want to use `CFLAGS`. It is the compiler diver's job to pass relevant `CFLAGS` down to the preprocessor. The preprocessor does not pass relevant flags up to the compiler driver. – jww Dec 16 '16 at 23:24
4

This is how I solved it in 3.4. It is applicable for 2.7 and 3.4. The important is --with-ssl config argument in the ./configure:

wget https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tgz
tar -xf Python-3.4.3.tgz
cd Python-3.4.3/
sudo yum install gcc
./configure --with-ssl
make && make install
# If you like to live dangerously since this will overwrite default python executable
make && make altinstall
# Safer because you access your new Python using python3.4
Dex
  • 388
  • 1
  • 2
  • 9
  • 8
    configure: WARNING: unrecognized options: --with-ssl – tsh Jul 31 '15 at 13:07
  • Did the ./configure pass with that warning? Did the compiled Python have ssl enabled? To me it looks like configure does not recognise the parameter but it still is passed on and is then honed by make. I digged into this back in the time according to these sources: https://bugs.python.org/issue21541 and http://stackoverflow.com/questions/22409092/coredump-when-compiling-python-with-a-custom-openssl-version – Dex Sep 08 '15 at 07:19
  • Furthermore, if the above does not work, then it may be (though I dont recall with certainty) that I integrated the patch from the above ticket http://bugs.python.org/file35304/issue21541-patch.diff Let me know if it works for you please! – Dex Sep 08 '15 at 07:32
  • I got this warning from configure and the resulting python lacked the ssl module. I used Scott Frazer's solution together with editing Modules/Setup to contain: SSL=YOUR_PREFIX _ssl _ssl.c \ -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ -L$(SSL)/lib -lssl -lcrypto ` – tsh Sep 08 '15 at 12:45
  • 2
    When I look through the documentation or do `./configure --help` I don't see the `--with-ssl` option, but this fixed my python 3.5 installation. Now pip is installing properly. – None Oct 14 '15 at 23:51
  • Did not resolve it for me on 2.7 with multiple openssl versions. – Adam Erickson Aug 19 '16 at 15:02
  • bizarrely,the --with-ssl option to the configure script does indeed seem to be the solution. Like others here, I have tried many suggestions to set the paths correctly, including editing the setup.py script to point to my custom openssl installation and it still didn't work. When I ran configure with --with-ssl, make did indeed warn that this is an unrecognized option and again there was a warning that _ssl could not be built because of missing bits but when I ran make install and then tested the ssl module, it was there and fully working. No idea how this worked but it did. – tospo Jul 18 '18 at 15:32