You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by as...@apache.org on 2019/02/25 18:40:21 UTC

[qpid-proton] 04/06: PROTON-1467: [Python] Get pip install working on Windows

This is an automated email from the ASF dual-hosted git repository.

astitcher pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-proton.git

commit 16e5c35b1fec76dc65b9fbbfb6f6551e5e72723e
Author: Andrew Stitcher <as...@apache.org>
AuthorDate: Fri Mar 23 18:31:45 2018 -0400

    PROTON-1467: [Python] Get pip install working on Windows
---
 c/include/proton/import_export.h |  6 ++-
 python/CMakeLists.txt            |  6 +--
 python/setup.py.in               | 95 +++++++++++++++++++++++-----------------
 python/tox.ini.in                |  2 +-
 4 files changed, 63 insertions(+), 46 deletions(-)

diff --git a/c/include/proton/import_export.h b/c/include/proton/import_export.h
index a79e905..74f56eb 100644
--- a/c/include/proton/import_export.h
+++ b/c/include/proton/import_export.h
@@ -32,7 +32,11 @@
  * PN_IMPORT         - Import declaration
  */
 
-#if defined(_WIN32) && !defined(PROTON_DECLARE_STATIC)
+#if defined(PROTON_DECLARE_STATIC)
+/* Static library - no imports/exports */
+#  define PN_EXPORT
+#  define PN_IMPORT
+#elif defined(_WIN32)
 /* Import and Export definitions for Windows */
 #  define PN_EXPORT __declspec(dllexport)
 #  define PN_IMPORT __declspec(dllimport)
diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt
index cd9c2c7..a7dfe4d 100644
--- a/python/CMakeLists.txt
+++ b/python/CMakeLists.txt
@@ -217,11 +217,11 @@ else ()
   option(ENABLE_TOX_TEST "Enable multi-version python testing with TOX" ON)
 
   set(tox_default "py26,py27,py34,py35,py36")
-  set(TOX_ENVLIST ${tox_default} CACHE STRING "List of python environments for TOX tests" )
+  set(TOX_ENVLIST "" CACHE STRING "List of python environments for TOX tests" )
   mark_as_advanced(TOX_ENVLIST)
 
-  if (NOT (TOX_ENVLIST STREQUAL tox_default))
-    message(WARNING "non-default TOX test set '${TOX_ENVLIST}' (default '${tox_default}')")
+  if (NOT TOX_ENVLIST)
+    set (TOX_ENVLIST ${tox_default})
   endif()
   if (ENABLE_TOX_TEST)
     if (CMAKE_BUILD_TYPE MATCHES "Coverage")
diff --git a/python/setup.py.in b/python/setup.py.in
old mode 100755
new mode 100644
index 76efa14..76434c3
--- a/python/setup.py.in
+++ b/python/setup.py.in
@@ -42,12 +42,9 @@ in the system. The rest of the commands and steps are done normally without any
 of monkey patching.
 """
 
-import glob
 import os
-import subprocess
-import sys
+import shutil
 
-import distutils.spawn as ds_spawn
 import distutils.sysconfig as ds_sys
 from distutils.ccompiler import new_compiler, get_default_compiler
 from distutils.core import setup, Extension
@@ -122,7 +119,7 @@ class Configure(build_ext):
         ext.swig_opts = []
 
     def use_bundled_proton(self):
-        """The proper version of libqpid-proton is not installed on the system,
+        """The proper version of libqpid-proton-core is not installed on the system,
         so use the included proton-c sources to build the extension
         """
         log.info("Building the bundled proton-c sources into the extension")
@@ -132,6 +129,7 @@ class Configure(build_ext):
         build_include = os.path.join(base, 'include')
         proton_base = os.path.abspath(os.path.join(setup_path))
         proton_src = os.path.join(proton_base, 'src')
+        proton_core_src = os.path.join(proton_base, 'src', 'core')
         proton_include = os.path.join(proton_base, 'include')
 
         log.debug("Using Proton C sources: %s" % proton_base)
@@ -140,35 +138,22 @@ class Configure(build_ext):
         # anything windows and configuration-dependent
 
         sources = []
-        cfgdep = ['openssl.c',
-                  'schannel.c',
-                  'ssl_stub.c',
-                  'cyrus_sasl.c',
-                  'cyrus_stub.c',
-                  'snprintf.c']
-
-        stripdirs = ['proactor',
-                     'msvc',
-                     'windows']
-
-        for root, dirs, files in os.walk(proton_src):
-            for dir_ in stripdirs:
-                if dir_ in dirs:
-                    dirs.remove(dir_)
-
+        for root, _, files in os.walk(proton_core_src):
             for file_ in files:
-                if file_.endswith('.c') and file_ not in cfgdep:
+                if file_.endswith(('.c', '.cpp')):
                     sources.append(os.path.join(root, file_))
 
         # Look for any optional libraries that proton needs, and adjust the
         # source list and compile flags as necessary.
         libraries = []
         includes = []
+        macros = []
 
         # -D flags (None means no value, just define)
-        macros=[('qpid_proton_EXPORTS', None),
-                ('USE_ATOLL', None),
-                ('USE_STRERROR_R', None)]
+        macros += [('PROTON_DECLARE_STATIC', None)]
+
+        if self.compiler_type=='msvc':
+            sources.append(os.path.join(proton_src, 'compiler' , 'msvc', 'snprintf.c'))
 
         # Check whether openssl is installed by poking
         # pkg-config for a minimum version 0. If it's installed, it should
@@ -177,6 +162,9 @@ class Configure(build_ext):
             libraries += ['ssl', 'crypto']
             includes += [misc.pkg_config_get_var('openssl', 'includedir')]
             sources.append(os.path.join(proton_src, 'ssl', 'openssl.c'))
+        elif os.name=='nt':
+            libraries += ['crypt32', 'secur32']
+            sources.append(os.path.join(proton_src, 'ssl', 'schannel.c'))
         else:
             sources.append(os.path.join(proton_src, 'ssl', 'ssl_stub.c'))
             log.warn("OpenSSL not installed - disabling SSL support!")
@@ -185,19 +173,12 @@ class Configure(build_ext):
         cc = new_compiler(compiler=self.compiler_type)
         cc.output_dir = self.build_temp
 
-        # Some systems need to link to `rt`. Check whether `clock_gettime` is
-        # around and if librt is needed
-        if cc.has_function('clock_gettime'):
-            macros.append(('USE_CLOCK_GETTIME', None))
-        else:
-            if cc.has_function('clock_gettime', libraries=['rt']):
-                libraries.append('rt')
-                macros.append(('USE_CLOCK_GETTIME', None))
-
         # 0.10 added an implementation for cyrus. Check
         # if it is available before adding the implementation to the sources
-        # list. Eventually, `sasl.c` will be added and one of the existing
+        # list. 'sasl.c` and 'default_sasl.c' are added and one of the existing
         # implementations will be used.
+        sources.append(os.path.join(proton_src, 'sasl', 'sasl.c'))
+        sources.append(os.path.join(proton_src, 'sasl', 'default_sasl.c'))
         if cc.has_function('sasl_client_done', includes=['sasl/sasl.h'],
                            libraries=['sasl2']):
             libraries.append('sasl2')
@@ -207,6 +188,35 @@ class Configure(build_ext):
                      " PLAIN mechanisms will be supported!")
             sources.append(os.path.join(proton_src, 'sasl', 'cyrus_stub.c'))
 
+        # Hack for Windows/msvc: We need to compile proton as C++, but it seems the only way to
+        # force this in setup.py is to use a .cpp extension! So copy all the source files to .cpp
+        # and use these as the compile sources
+        if self.compiler_type=='msvc':
+            targets = []
+            target_base = os.path.join(self.build_temp, 'srcs')
+            try:
+                os.mkdir(target_base)
+            except FileExistsError:
+	            pass
+
+            for f in sources:
+                # We know each file ends in '.c' as we filtered on that above so just add 'pp' to end
+                target = os.path.join(target_base, os.path.basename(f) + 'pp')
+                shutil.copy(f, target)
+                targets.append(target)
+
+            # Copy .h files into temp tree too as we need them to compile
+            for root, _, files in os.walk(proton_core_src):
+                for file_ in files:
+                    if file_.endswith('.h'):
+                        shutil.copy(os.path.join(root, file_), os.path.join(target_base, file_))
+
+            # Copy ssl/sasl .h files
+            shutil.copy(os.path.join(proton_src, 'sasl', 'sasl-internal.h'), os.path.join(target_base, 'sasl-internal.h'))
+            shutil.copy(os.path.join(proton_src, 'ssl', 'ssl-internal.h'), os.path.join(target_base, 'ssl-internal.h'))
+
+            sources = targets
+
         # compile all the proton sources.  We'll add the resulting list of
         # objects to the _cproton extension as 'extra objects'.  We do this
         # instead of just lumping all the sources into the extension to prevent
@@ -216,13 +226,16 @@ class Configure(build_ext):
         cc = new_compiler(compiler=self.compiler_type)
         ds_sys.customize_compiler(cc)
 
+        extra = []
+        if self.compiler_type=='unix':
+            extra.append('-std=gnu99')
         objects = cc.compile(sources,
                              macros=macros,
                              include_dirs=[build_include,
                                            proton_include,
                                            proton_src]+includes,
                              # compiler command line options:
-                             extra_postargs=['-std=gnu99'],
+                             extra_preargs=extra,
                              output_dir=self.build_temp)
 
         #
@@ -238,7 +251,7 @@ class Configure(build_ext):
         _cproton.swig_opts.append('-I%s' % build_include)
         _cproton.swig_opts.append('-I%s' % proton_include)
 
-        # lastly replace the libqpid-proton dependency with libraries required
+        # lastly replace the libqpid-proton-core dependency with libraries required
         # by the Proton objects:
         _cproton.libraries=libraries
 
@@ -246,7 +259,7 @@ class Configure(build_ext):
         """Check to see if the proper version of the Proton development library
         and headers are already installed
         """
-        return misc.pkg_config_version_installed('libqpid-proton', version)
+        return misc.pkg_config_version_installed('libqpid-proton-core', version)
 
     def use_installed_proton(self):
         """The Proton development headers and library are installed, update the
@@ -255,11 +268,11 @@ class Configure(build_ext):
         # update the Extension instance passed to setup() to use the installed
         # headers and link library
         _cproton = self.distribution.ext_modules[-1]
-        incs = misc.pkg_config_get_var('libqpid-proton', 'includedir')
+        incs = misc.pkg_config_get_var('libqpid-proton-core', 'includedir')
         for i in incs.split():
             _cproton.swig_opts.append('-I%s' % i)
             _cproton.include_dirs.append(i)
-        ldirs = misc.pkg_config_get_var('libqpid-proton', 'libdir')
+        ldirs = misc.pkg_config_get_var('libqpid-proton-core', 'libdir')
         _cproton.library_dirs.extend(ldirs.split())
 
     def run(self):
@@ -330,4 +343,4 @@ setup(name='python-qpid-proton',
                              sources=['cproton.i', 'cproton_wrap.c'],
                              swig_opts=['-threads'],
                              extra_compile_args=['-pthread'],
-                             libraries=['qpid-proton'])])
+                             libraries=['qpid-proton-core'])])
diff --git a/python/tox.ini.in b/python/tox.ini.in
index 931519b..29e41b5 100644
--- a/python/tox.ini.in
+++ b/python/tox.ini.in
@@ -2,7 +2,7 @@
 envlist = @TOX_ENVLIST@
 minversion = 1.4
 skipdist = True
-setupdir = @py_bin@/dist
+setupdir = @py_dist_dir@
 
 [testenv]
 usedevelop = False


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org