From 82ea3b8c7be04abeb03f8879764f0e37459af3a3 Mon Sep 17 00:00:00 2001 From: Oleg Pudeyev Date: Sun, 12 Jan 2014 20:57:13 -0500 Subject: [PATCH] Look in --static-libs for SSL library hints even if --libs succeeded. Closes #147. --- ChangeLog | 4 ++++ setup.py | 57 ++++++++++++++++++++++++++++++++++++--------- tests/setup_test.py | 4 ---- 3 files changed, 50 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index 77616ca9a..7898fbdf6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,10 @@ master ------ + * SSL detection logic changed to consult `curl-config --static-libs` + even if `curl-config --libs` succeeded. This should achieve + pre-7.19.3 behavior with respect to automatic SSL detection. + Version 7.19.3 [requires libcurl-7.19.0 or better] - 2014-01-09 --------------------------------------------------------------- diff --git a/setup.py b/setup.py index a239e9bfc..84d3c3977 100644 --- a/setup.py +++ b/setup.py @@ -126,27 +126,54 @@ def configure_unix(self): # In theory, all we should need is `curl-config --libs`. # Apparently on some platforms --libs fails and --static-libs works, # so try that. - # If --libs succeeds do not try --static libs; see + # If --libs succeeds do not try --static-libs; see # https://github.com/pycurl/pycurl/issues/52 for more details. # If neither --libs nor --static-libs work, fail. - optbuf = "" + # + # --libs/--static-libs are also used for SSL detection. + # libcurl may be configured such that --libs only includes -lcurl + # without any of libcurl's dependent libraries, but the dependent + # libraries would be included in --static-libs (unless libcurl + # was built with static libraries disabled). + # Therefore we largely ignore (see below) --static-libs output for + # libraries and flags if --libs succeeded, but consult both outputs + # for hints as to which SSL library libcurl is linked against. + # More information: https://github.com/pycurl/pycurl/pull/147 + # + # The final point is we should link agaist the SSL library in use + # even if libcurl does not tell us to, because *we* invoke functions + # in that SSL library. This means any SSL libraries found in + # --static-libs are forwarded to our libraries. + optbuf = '' + sslhintbuf = '' errtext = '' for option in ["--libs", "--static-libs"]: p = subprocess.Popen((CURL_CONFIG, option), stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = p.communicate() if p.wait() == 0: - optbuf = stdout.decode() - break + if optbuf == '': + # first successful call + optbuf = stdout.decode() + # optbuf only has output from this call + sslhintbuf += optbuf + else: + # second successful call + sslhintbuf += stdout.decode() else: - errtext += stderr.decode() + if optbuf == '': + # no successful call yet + errtext += stderr.decode() + else: + # first call succeeded and second call failed + # ignore stderr and the error exit + pass if optbuf == "": msg = "Neither curl-config --libs nor curl-config --static-libs" +\ " succeeded and produced output" if errtext: msg += ":\n" + errtext raise ConfigurationError(msg) - libs = split_quoted(optbuf) ssl_lib_detected = False if 'PYCURL_SSL_LIBRARY' in os.environ: @@ -170,22 +197,30 @@ def configure_unix(self): ssl_lib_detected = True self.define_macros.append((ssl_options[option], 1)) - for arg in libs: + # libraries and options - all libraries and options are forwarded + # but if --libs succeeded, --static-libs output is ignored + for arg in split_quoted(optbuf): if arg[:2] == "-l": self.libraries.append(arg[2:]) + elif arg[:2] == "-L": + self.library_dirs.append(arg[2:]) + else: + self.extra_link_args.append(arg) + # ssl detection - ssl libraries are forwarded + for arg in split_quoted(sslhintbuf): + if arg[:2] == "-l": if not ssl_lib_detected and arg[2:] == 'ssl': self.define_macros.append(('HAVE_CURL_OPENSSL', 1)) ssl_lib_detected = True + self.libraries.append('ssl') if not ssl_lib_detected and arg[2:] == 'gnutls': self.define_macros.append(('HAVE_CURL_GNUTLS', 1)) ssl_lib_detected = True + self.libraries.append('gnutls') if not ssl_lib_detected and arg[2:] == 'ssl3': self.define_macros.append(('HAVE_CURL_NSS', 1)) ssl_lib_detected = True - elif arg[:2] == "-L": - self.library_dirs.append(arg[2:]) - else: - self.extra_link_args.append(arg) + self.libraries.append('ssl3') if not ssl_lib_detected: p = subprocess.Popen((CURL_CONFIG, '--features'), stdout=subprocess.PIPE, stderr=subprocess.PIPE) diff --git a/tests/setup_test.py b/tests/setup_test.py index b6ec4213c..d5b302ec5 100644 --- a/tests/setup_test.py +++ b/tests/setup_test.py @@ -74,8 +74,6 @@ def test_ssl_in_libs(self): @using_curl_config('curl-config-ssl-in-static-libs') def test_ssl_in_static_libs(self): - raise nose.plugins.skip.SkipTest('this test fails') - config = pycurl_setup.ExtensionConfiguration() # should link against openssl assert 'ssl' in config.libraries @@ -94,8 +92,6 @@ def test_ssl_in_libs_sets_ssl_define(self): @using_curl_config('curl-config-ssl-in-static-libs') def test_ssl_in_static_libs_sets_ssl_define(self): - raise nose.plugins.skip.SkipTest('this test fails') - config = pycurl_setup.ExtensionConfiguration() # ssl define should be on assert 'HAVE_CURL_SSL' in config.define_symbols