From b33bc7492520df47881c12308f701ca9cb63af02 Mon Sep 17 00:00:00 2001 From: MinRK Date: Wed, 16 May 2012 22:19:24 -0700 Subject: [PATCH 01/32] drop in files from pyzmq-static include_* and initlibzmq.c --- buildutils/include_darwin/platform.hpp | 229 ++++++++++++++++++++++++ buildutils/include_freebsd/platform.hpp | 226 +++++++++++++++++++++++ buildutils/include_linux/platform.hpp | 229 ++++++++++++++++++++++++ buildutils/initlibzmq.c | 14 ++ 4 files changed, 698 insertions(+) create mode 100644 buildutils/include_darwin/platform.hpp create mode 100644 buildutils/include_freebsd/platform.hpp create mode 100644 buildutils/include_linux/platform.hpp create mode 100644 buildutils/initlibzmq.c diff --git a/buildutils/include_darwin/platform.hpp b/buildutils/include_darwin/platform.hpp new file mode 100644 index 000000000..212cfabee --- /dev/null +++ b/buildutils/include_darwin/platform.hpp @@ -0,0 +1,229 @@ +/* src/platform.hpp. Generated from platform.hpp.in by configure. */ +/* src/platform.hpp.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `freeifaddrs' function. */ +#define HAVE_FREEIFADDRS 1 + +/* Define to 1 if you have the `getifaddrs' function. */ +#define HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +/* #undef HAVE_LIBCRYPTO */ + +/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ +/* #undef HAVE_LIBIPHLPAPI */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ +/* #undef HAVE_LIBRPCRT4 */ + +/* Define to 1 if you have the `rt' library (-lrt). */ +/* #undef HAVE_LIBRT */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `uuid' library (-luuid). */ +/* #undef HAVE_LIBUUID */ + +/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ +/* #undef HAVE_LIBWS2_32 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the `perror' function. */ +#define HAVE_PERROR 1 + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if stdbool.h conforms to C99. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if the system has the type `_Bool'. */ +/* #undef HAVE__BOOL */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "zeromq" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "zeromq-dev@lists.zeromq.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "zeromq" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "zeromq 2.1.11" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "zeromq" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.1.11" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define VERSION "2.1.11" + +/* Force to use mutexes */ +/* #undef ZMQ_FORCE_MUTEXES */ + +/* Have AIX OS */ +/* #undef ZMQ_HAVE_AIX */ + +/* Have Cygwin */ +/* #undef ZMQ_HAVE_CYGWIN */ + +/* Have FreeBSD OS */ +/* #undef ZMQ_HAVE_FREEBSD */ + +/* Have HPUX OS */ +/* #undef ZMQ_HAVE_HPUX */ + +/* Have ifaddrs.h header. */ +#define ZMQ_HAVE_IFADDRS 1 + +/* Have Linux OS */ +/* #undef ZMQ_HAVE_LINUX */ + +/* Have MinGW32 */ +/* #undef ZMQ_HAVE_MINGW32 */ + +/* Have NetBSD OS */ +/* #undef ZMQ_HAVE_NETBSD */ + +/* Have OpenBSD OS */ +/* #undef ZMQ_HAVE_OPENBSD */ + +/* Have OpenPGM extension */ +/* #undef ZMQ_HAVE_OPENPGM */ + +/* Have DarwinOSX OS */ +#define ZMQ_HAVE_OSX 1 + +/* Have QNX Neutrino OS */ +/* #undef ZMQ_HAVE_QNXNTO */ + +/* Have Solaris OS */ +/* #undef ZMQ_HAVE_SOLARIS */ + +/* Have Windows OS */ +/* #undef ZMQ_HAVE_WINDOWS */ + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT32_T */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +/* #undef ssize_t */ + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint32_t */ + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +/* #undef volatile */ diff --git a/buildutils/include_freebsd/platform.hpp b/buildutils/include_freebsd/platform.hpp new file mode 100644 index 000000000..7b88ff107 --- /dev/null +++ b/buildutils/include_freebsd/platform.hpp @@ -0,0 +1,226 @@ +/* src/platform.hpp. Generated from platform.hpp.in by configure. */ +/* src/platform.hpp.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `freeifaddrs' function. */ +#define HAVE_FREEIFADDRS 1 + +/* Define to 1 if you have the `getifaddrs' function. */ +#define HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +/* #undef HAVE_LIBCRYPTO */ + +/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ +/* #undef HAVE_LIBIPHLPAPI */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ +/* #undef HAVE_LIBRPCRT4 */ + +/* Define to 1 if you have the `rt' library (-lrt). */ +/* #undef HAVE_LIBRT */ + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `uuid' library (-luuid). */ +/* #undef HAVE_LIBUUID */ + +/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ +/* #undef HAVE_LIBWS2_32 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the `perror' function. */ +#define HAVE_PERROR 1 + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if stdbool.h conforms to C99. */ +/* #undef HAVE_STDBOOL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if the system has the type `_Bool'. */ +/* #undef HAVE__BOOL */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "zeromq" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "zeromq-dev@lists.zeromq.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "zeromq" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "zeromq 2.1.11" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "zeromq" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.1.11" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define VERSION "2.1.11" + +/* Force to use mutexes */ +/* #undef ZMQ_FORCE_MUTEXES */ + +/* Have AIX OS */ +/* #undef ZMQ_HAVE_AIX */ + +/* Have Cygwin */ +/* #undef ZMQ_HAVE_CYGWIN */ + +/* Have FreeBSD OS */ +#define ZMQ_HAVE_FREEBSD 1 + +/* Have HPUX OS */ +/* #undef ZMQ_HAVE_HPUX */ + +/* Have ifaddrs.h header. */ +#define ZMQ_HAVE_IFADDRS 1 + +/* Have Linux OS */ +/* #undef ZMQ_HAVE_LINUX */ + +/* Have MinGW32 */ +/* #undef ZMQ_HAVE_MINGW32 */ + +/* Have NetBSD OS */ +/* #undef ZMQ_HAVE_NETBSD */ + +/* Have OpenBSD OS */ +/* #undef ZMQ_HAVE_OPENBSD */ + +/* Have OpenPGM extension */ +/* #undef ZMQ_HAVE_OPENPGM */ + +/* Have DarwinOSX OS */ +/* #undef ZMQ_HAVE_OSX */ + +/* Have QNX Neutrino OS */ +/* #undef ZMQ_HAVE_QNXNTO */ + +/* Have Solaris OS */ +/* #undef ZMQ_HAVE_SOLARIS */ + +/* Have Windows OS */ +/* #undef ZMQ_HAVE_WINDOWS */ + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT32_T */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +/* #undef ssize_t */ + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint32_t */ + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +/* #undef volatile */ diff --git a/buildutils/include_linux/platform.hpp b/buildutils/include_linux/platform.hpp new file mode 100644 index 000000000..89632e6ad --- /dev/null +++ b/buildutils/include_linux/platform.hpp @@ -0,0 +1,229 @@ +/* src/platform.hpp. Generated from platform.hpp.in by configure. */ +/* src/platform.hpp.in. Generated from configure.in by autoheader. */ + +/* Define to 1 if you have the header file. */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ARPA_INET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_ERRNO_H 1 + +/* Define to 1 if you have the `freeifaddrs' function. */ +#define HAVE_FREEIFADDRS 1 + +/* Define to 1 if you have the `getifaddrs' function. */ +#define HAVE_GETIFADDRS 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_IFADDRS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `crypto' library (-lcrypto). */ +/* #undef HAVE_LIBCRYPTO */ + +/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */ +/* #undef HAVE_LIBIPHLPAPI */ + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +/* #undef HAVE_LIBNSL */ + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#define HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */ +/* #undef HAVE_LIBRPCRT4 */ + +/* Define to 1 if you have the `rt' library (-lrt). */ +#define HAVE_LIBRT 1 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +/* #undef HAVE_LIBSOCKET */ + +/* Define to 1 if you have the `uuid' library (-luuid). */ +#define HAVE_LIBUUID 1 + +/* Define to 1 if you have the `ws2_32' library (-lws2_32). */ +/* #undef HAVE_LIBWS2_32 */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_NETINET_TCP_H 1 + +/* Define to 1 if you have the `perror' function. */ +#define HAVE_PERROR 1 + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Define to 1 if stdbool.h conforms to C99. */ +#define HAVE_STDBOOL_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDDEF_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINDOWS_H */ + +/* Define to 1 if the system has the type `_Bool'. */ +/* #undef HAVE__BOOL */ + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "zeromq" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "zeromq-dev@lists.zeromq.org" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "zeromq" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "zeromq 2.1.11" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "zeromq" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "2.1.11" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Version number of package */ +#define VERSION "2.1.11" + +/* Force to use mutexes */ +/* #undef ZMQ_FORCE_MUTEXES */ + +/* Have AIX OS */ +/* #undef ZMQ_HAVE_AIX */ + +/* Have Cygwin */ +/* #undef ZMQ_HAVE_CYGWIN */ + +/* Have FreeBSD OS */ +/* #undef ZMQ_HAVE_FREEBSD */ + +/* Have HPUX OS */ +/* #undef ZMQ_HAVE_HPUX */ + +/* Have ifaddrs.h header. */ +#define ZMQ_HAVE_IFADDRS 1 + +/* Have Linux OS */ +#define ZMQ_HAVE_LINUX 1 + +/* Have MinGW32 */ +/* #undef ZMQ_HAVE_MINGW32 */ + +/* Have NetBSD OS */ +/* #undef ZMQ_HAVE_NETBSD */ + +/* Have OpenBSD OS */ +/* #undef ZMQ_HAVE_OPENBSD */ + +/* Have OpenPGM extension */ +/* #undef ZMQ_HAVE_OPENPGM */ + +/* Have DarwinOSX OS */ +/* #undef ZMQ_HAVE_OSX */ + +/* Have QNX Neutrino OS */ +/* #undef ZMQ_HAVE_QNXNTO */ + +/* Have Solaris OS */ +/* #undef ZMQ_HAVE_SOLARIS */ + +/* Have Windows OS */ +/* #undef ZMQ_HAVE_WINDOWS */ + +/* Define for Solaris 2.5.1 so the uint32_t typedef from , + , or is not used. If the typedef were allowed, the + #define below would cause a syntax error. */ +/* #undef _UINT32_T */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define to `int' if does not define. */ +/* #undef ssize_t */ + +/* Define to the type of an unsigned integer type of width exactly 32 bits if + such a type exists and the standard includes do not define it. */ +/* #undef uint32_t */ + +/* Define to empty if the keyword `volatile' does not work. Warning: valid + code using `volatile' can become incorrect without. Disable with care. */ +/* #undef volatile */ diff --git a/buildutils/initlibzmq.c b/buildutils/initlibzmq.c new file mode 100644 index 000000000..8c143d20e --- /dev/null +++ b/buildutils/initlibzmq.c @@ -0,0 +1,14 @@ +#include + +/* Provide the init function that Visual Studio will be told to look for + when we compile libzmq by pretending it is a Python extension. */ + +static PyMethodDef Methods[] = { + {NULL, NULL, 0, NULL} +}; + +PyMODINIT_FUNC +initlibzmq(void) +{ + (void) Py_InitModule("libzmq", Methods); +} From 9958e9837a837aa3c3edf1a6ab42cb61e3b9b081 Mon Sep 17 00:00:00 2001 From: MinRK Date: Wed, 2 May 2012 21:42:57 -0700 Subject: [PATCH 02/32] step towards bundling libzmq as an Extension --- .gitignore | 4 +- buildutils.py | 261 ----------------------------------------- buildutils/__init__.py | 9 ++ buildutils/bundle.py | 154 ++++++++++++++++++++++++ buildutils/config.py | 118 +++++++++++++++++++ buildutils/detect.py | 96 +++++++++++++++ buildutils/msg.py | 39 ++++++ buildutils/vers.c | 11 ++ setup.py | 104 ++++++++++++++-- zmq/__init__.py | 22 ++-- 10 files changed, 536 insertions(+), 282 deletions(-) delete mode 100644 buildutils.py create mode 100644 buildutils/__init__.py create mode 100644 buildutils/bundle.py create mode 100644 buildutils/config.py create mode 100644 buildutils/detect.py create mode 100644 buildutils/msg.py create mode 100644 buildutils/vers.c diff --git a/.gitignore b/.gitignore index 1890c1da5..c8794cba3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,14 @@ *.pyc -*.c +zmq/*/*.c build dist conf +bundled_libzmq *.egg-info *.so *.pyd *.dll +*.dylib docs/source/api/generated docs/gh-pages setup.cfg diff --git a/buildutils.py b/buildutils.py deleted file mode 100644 index 868d42f80..000000000 --- a/buildutils.py +++ /dev/null @@ -1,261 +0,0 @@ -"""Detect zmq version""" -#----------------------------------------------------------------------------- -# Copyright (C) 2011 Brian Granger, Min Ragan-Kelley -# -# This file is part of pyzmq, copied and adapted from h5py. -# h5py source used under the New BSD license -# -# h5py: -# -# Distributed under the terms of the New BSD License. The full license is in -# the file COPYING.BSD, distributed as part of this software. -#----------------------------------------------------------------------------- - -import shutil -import sys -import os -import logging -import pickle -import platform -from distutils import ccompiler -from distutils.sysconfig import customize_compiler -from subprocess import Popen, PIPE - -try: - from configparser import ConfigParser -except: - from ConfigParser import ConfigParser - -pjoin = os.path.join - -#----------------------------------------------------------------------------- -# Logging (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- -logger = logging.getLogger() -logger.addHandler(logging.StreamHandler(sys.stderr)) - -def debug(what): - pass - -def fatal(instring, code=1): - logger.error("Fatal: "+instring) - exit(code) - -def warn(instring): - logger.error("Warning: "+instring) - - -#----------------------------------------------------------------------------- -# Utility functions (adapted from h5py: http://h5py.googlecode.com) -#----------------------------------------------------------------------------- - -def detect_zmq(basedir, **compiler_attrs): - """Compile, link & execute a test program, in empty directory `basedir`. - - The C compiler will be updated with any keywords given via setattr. - - Parameters - ---------- - - basedir : path - The location where the test program will be compiled and run - **compiler_attrs : dict - Any extra compiler attributes, which will be set via ``setattr(cc)``. - - Returns - ------- - - A dict of properties for zmq compilation, with the following two keys: - - vers : tuple - The ZMQ version as a tuple of ints, e.g. (2,2,0) - options : dict - The compiler options used to compile the test function, e.g. `include_dirs`, - `library_dirs`, `libs`, etc. - """ - - cc = ccompiler.new_compiler() - customize_compiler(cc) - for name, val in compiler_attrs.items(): - setattr(cc, name, val) - - cfile = pjoin(basedir, 'vers.c') - efile = pjoin(basedir, 'vers') - - f = open(cfile, 'w') - try: - f.write( -r""" -#include -#include "zmq.h" - -int main(void){ - int major, minor, patch; - zmq_version(&major, &minor, &patch); - fprintf(stdout, "vers: %d.%d.%d\n", major, minor, patch); - return 0; -} -""") - finally: - f.close() - - cpreargs = lpreargs = None - if sys.platform == 'darwin': - # use appropriate arch for comiler - if platform.architecture()[0]=='32bit': - cpreargs = ['-arch','i386'] - lpreargs = ['-arch', 'i386', '-undefined', 'dynamic_lookup'] - else: - # allow for missing UB arch, since it will still work: - lpreargs = ['-undefined', 'dynamic_lookup'] - - objs = cc.compile([cfile],extra_preargs=cpreargs) - cc.link_executable(objs, efile, extra_preargs=lpreargs) - - result = Popen(efile, stdout=PIPE, stderr=PIPE) - so, se = result.communicate() - # for py3k: - so = so.decode() - se = se.decode() - if result.returncode: - msg = "Error running version detection script:\n%s\n%s" % (so,se) - logging.error(msg) - raise IOError(msg) - - handlers = {'vers': lambda val: tuple(int(v) for v in val.split('.'))} - - props = {} - for line in (x for x in so.split('\n') if x): - key, val = line.split(':') - props[key] = handlers[key](val) - - props['options'] = compiler_attrs - return props - -def localpath(*args): - plist = [os.path.dirname(__file__)]+list(args) - return os.path.abspath(pjoin(*plist)) - -def loadpickle(name): - """ Load object from pickle file, or None if it can't be opened """ - name = pjoin('conf', name) - try: - f = open(name,'rb') - except IOError: - # raise - return None - try: - return pickle.load(f) - except Exception: - # raise - return None - finally: - f.close() - -def savepickle(name, data): - """ Save to pickle file, exiting if it can't be written """ - if not os.path.exists('conf'): - os.mkdir('conf') - name = pjoin('conf', name) - try: - f = open(name, 'wb') - except IOError: - fatal("Can't open pickle file \"%s\" for writing" % name) - try: - pickle.dump(data, f, 0) - finally: - f.close() - -def v_str(v_tuple): - """turn (2,0,1) into '2.0.1'.""" - return ".".join(str(x) for x in v_tuple) - -def get_eargs(): - """ Look for options in environment vars """ - - settings = {} - - zmq = os.environ.get("ZMQ_DIR", '') - if zmq != '': - debug("Found environ var ZMQ_DIR=%s" % zmq) - settings['zmq'] = zmq - - return settings - -def get_cfg_args(): - """ Look for options in setup.cfg """ - - settings = {} - zmq = '' - if not os.path.exists('setup.cfg'): - return settings - cfg = ConfigParser() - cfg.read('setup.cfg') - if 'build_ext' in cfg.sections() and \ - cfg.has_option('build_ext', 'include_dirs'): - includes = cfg.get('build_ext', 'include_dirs') - include = includes.split(os.pathsep)[0] - if include.endswith('include') and os.path.isdir(include): - zmq = include[:-8] - if zmq != '': - debug("Found ZMQ=%s in setup.cfg" % zmq) - settings['zmq'] = zmq - - return settings - -def get_cargs(): - """ Look for global options in the command line """ - settings = loadpickle('buildconf.pickle') - if settings is None: settings = {} - for arg in sys.argv[:]: - if arg.find('--zmq=') == 0: - zmq = arg.split('=')[-1] - if zmq.lower() == 'default': - settings.pop('zmq', None) - else: - settings['zmq'] = zmq - sys.argv.remove(arg) - savepickle('buildconf.pickle', settings) - return settings - -def discover_settings(): - """ Discover custom settings for ZMQ path""" - settings = get_cfg_args() # lowest priority - settings.update(get_eargs()) - settings.update(get_cargs()) # highest priority - return settings.get('zmq') - -def copy_and_patch_libzmq(ZMQ, libzmq): - """copy libzmq into source dir, and patch it if necessary. - - This command is necessary prior to running a bdist on Linux or OS X. - """ - if sys.platform.startswith('win'): - return - # copy libzmq into zmq for bdist - local = localpath('zmq',libzmq) - if ZMQ is None and not os.path.exists(local): - fatal("Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` " - "or copy libzmq into zmq/ manually prior to running bdist.") - try: - # resolve real file through symlinks - lib = os.path.realpath(pjoin(ZMQ, 'lib', libzmq)) - print ("copying %s -> %s"%(lib, local)) - shutil.copy(lib, local) - except Exception: - if not os.path.exists(local): - fatal("Could not copy libzmq into zmq/, which is necessary for bdist. " - "Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` " - "or copy libzmq into zmq/ manually.") - - if sys.platform == 'darwin': - # patch install_name on darwin, instead of using rpath - cmd = ['install_name_tool', '-id', '@loader_path/../%s'%libzmq, local] - try: - p = Popen(cmd, stdout=PIPE,stderr=PIPE) - except OSError: - fatal("install_name_tool not found, cannot patch libzmq for bundling.") - out,err = p.communicate() - if p.returncode: - fatal("Could not patch bundled libzmq install_name: %s"%err, p.returncode) - diff --git a/buildutils/__init__.py b/buildutils/__init__.py new file mode 100644 index 000000000..3ce0a6516 --- /dev/null +++ b/buildutils/__init__.py @@ -0,0 +1,9 @@ +"""utilities for building pyzmq. + +Largely adapted from h5py +""" + +from msg import * +from config import * +from detect import * +from bundle import * diff --git a/buildutils/bundle.py b/buildutils/bundle.py new file mode 100644 index 000000000..4fa5d0e8c --- /dev/null +++ b/buildutils/bundle.py @@ -0,0 +1,154 @@ +"""utilities for fetching build dependencies. + +This code is adapted from pyzmq-static's get.sh by Brandon Craig Rhodes +http://bitbucket.org/brandon/pyzmq-static + +""" + +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import os +import shutil +import sys +import tarfile +import urllib +from subprocess import Popen, PIPE + +from msg import fatal, debug, info, warn + +pjoin = os.path.join + +#----------------------------------------------------------------------------- +# Constants +#----------------------------------------------------------------------------- + +libzmq = "zeromq-2.2.0.tar.gz" +libzmq_url = "http://download.zeromq.org/" + libzmq +util = "util-linux-2.21.tar.gz" +util_url = "http://www.kernel.org/pub/linux/utils/util-linux/v2.21/" + util + +HERE = os.path.dirname(__file__) + +#----------------------------------------------------------------------------- +# functions +#----------------------------------------------------------------------------- + + +def untgz(archive): + return archive.replace('.tar.gz', '') + +def localpath(*args): + plist = [HERE]+list(args) + return os.path.abspath(pjoin(*plist)) + +def fetch_archive(savedir, url, fname, force=False): + dest = pjoin(savedir, fname) + if os.path.exists(dest) and not force: + info("already have %s" % fname) + return dest + if not os.path.exists(savedir): + os.makedirs(savedir) + req = urllib.urlopen(url) + with open(dest, 'w') as f: + f.write(req.read()) + return dest + +def fetch_libzmq(savedir): + info("fetching libzmq from %s into %s" % (libzmq_url, savedir)) + dest = pjoin(savedir, 'zeromq') + if os.path.exists(dest): + info("already have %s" % dest) + return + fname = fetch_archive(savedir, libzmq_url, libzmq) + tf = tarfile.open(fname) + with_version = pjoin(savedir, tf.firstmember.path) + tf.extractall(savedir) + tf.close() + # remove version suffix: + shutil.move(with_version, dest) + +def stage_platform_hpp(zmqroot): + platform_hpp = pjoin(zmqroot, 'src', 'platform.hpp') + if os.path.exists(platform_hpp): + info("already have platform.hpp") + return + if os.name == 'nt': + # stage msvc platform header + platform_dir = pjoin(zmqroot, 'builds', 'msvc', 'platform.hpp') + else: + info("attempting ./configure to generate platform.hpp") + + p = Popen('./configurez', cwd=zmqroot, shell=True, + stdout=PIPE, stderr=PIPE, + ) + o,e = p.communicate() + if p.returncode: + warn("failed to configure libzmq:\n%s" % e) + if sys.platform == 'darwin': + platform_dir = pjoin(HERE, 'include_darwin') + elif sys.platform.startswith('freebsd'): + platform_dir = pjoin(HERE, 'include_freebsd') + else: + platform_dir = pjoin(HERE, 'include_linux') + else: + return + + info("staging platform.hpp from: %s" % platform_dir) + shutil.copy(pjoin(platform_dir, 'platform.hpp'), platform_hpp) + + +def fetch_uuid(savedir): + info("fetching libuuid from %s into %s" % (util_url, savedir)) + fname = fetch_archive(savedir, util_url, util) + tf = tarfile.open(fname) + util_name = untgz(util) + uuid_path = util_name+'/libuuid/src' + uuid = filter( + lambda m: m.name.startswith(uuid_path) and not m.name.endswith("nt.c"), + tf.getmembers() + ) + # uuid_members = map(tf.getmember, uuid_names) + tf.extractall(savedir, uuid) + dest = pjoin(savedir, 'uuid') + if os.path.exists(dest): + shutil.rmtree(dest) + shutil.move(pjoin(savedir, util_name, 'libuuid', 'src'), dest) + shutil.rmtree(pjoin(savedir, util_name)) + + +def copy_and_patch_libzmq(ZMQ, libzmq): + """copy libzmq into source dir, and patch it if necessary. + + This command is necessary prior to running a bdist on Linux or OS X. + """ + if sys.platform.startswith('win'): + return + # copy libzmq into zmq for bdist + local = localpath('zmq',libzmq) + if ZMQ is None and not os.path.exists(local): + fatal("Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` " + "or copy libzmq into zmq/ manually prior to running bdist.") + try: + # resolve real file through symlinks + lib = os.path.realpath(pjoin(ZMQ, 'lib', libzmq)) + print ("copying %s -> %s"%(lib, local)) + shutil.copy(lib, local) + except Exception: + if not os.path.exists(local): + fatal("Could not copy libzmq into zmq/, which is necessary for bdist. " + "Please specify zmq prefix via `setup.py configure --zmq=/path/to/zmq` " + "or copy libzmq into zmq/ manually.") + + if sys.platform == 'darwin': + # patch install_name on darwin, instead of using rpath + cmd = ['install_name_tool', '-id', '@loader_path/../%s'%libzmq, local] + try: + p = Popen(cmd, stdout=PIPE,stderr=PIPE) + except OSError: + fatal("install_name_tool not found, cannot patch libzmq for bundling.") + out,err = p.communicate() + if p.returncode: + fatal("Could not patch bundled libzmq install_name: %s"%err, p.returncode) + diff --git a/buildutils/config.py b/buildutils/config.py new file mode 100644 index 000000000..e705088c9 --- /dev/null +++ b/buildutils/config.py @@ -0,0 +1,118 @@ +"""Config functions""" +#----------------------------------------------------------------------------- +# Copyright (C) 2011 Brian Granger, Min Ragan-Kelley +# +# This file is part of pyzmq, copied and adapted from h5py. +# h5py source used under the New BSD license +# +# h5py: +# +# Distributed under the terms of the New BSD License. The full license is in +# the file COPYING.BSD, distributed as part of this software. +#----------------------------------------------------------------------------- + +import sys +import os +import pickle + +try: + from configparser import ConfigParser +except: + from ConfigParser import ConfigParser + +pjoin = os.path.join +from msg import debug, fatal, warn + +#----------------------------------------------------------------------------- +# Utility functions (adapted from h5py: http://h5py.googlecode.com) +#----------------------------------------------------------------------------- + + +def loadpickle(name): + """ Load object from pickle file, or None if it can't be opened """ + name = pjoin('conf', name) + try: + f = open(name,'rb') + except IOError: + # raise + return None + try: + return pickle.load(f) + except Exception: + # raise + return None + finally: + f.close() + +def savepickle(name, data): + """ Save to pickle file, exiting if it can't be written """ + if not os.path.exists('conf'): + os.mkdir('conf') + name = pjoin('conf', name) + try: + f = open(name, 'wb') + except IOError: + fatal("Can't open pickle file \"%s\" for writing" % name) + try: + pickle.dump(data, f, 0) + finally: + f.close() + +def v_str(v_tuple): + """turn (2,0,1) into '2.0.1'.""" + return ".".join(str(x) for x in v_tuple) + +def get_eargs(): + """ Look for options in environment vars """ + + settings = {} + + zmq = os.environ.get("ZMQ_DIR", '') + if zmq != '': + debug("Found environ var ZMQ_DIR=%s" % zmq) + settings['zmq'] = zmq + + return settings + +def get_cfg_args(): + """ Look for options in setup.cfg """ + + settings = {} + zmq = '' + if not os.path.exists('setup.cfg'): + return settings + cfg = ConfigParser() + cfg.read('setup.cfg') + if 'build_ext' in cfg.sections() and \ + cfg.has_option('build_ext', 'include_dirs'): + includes = cfg.get('build_ext', 'include_dirs') + include = includes.split(os.pathsep)[0] + if include.endswith('include') and os.path.isdir(include): + zmq = include[:-8] + if zmq != '': + debug("Found ZMQ=%s in setup.cfg" % zmq) + settings['zmq'] = zmq + + return settings + +def get_cargs(): + """ Look for global options in the command line """ + settings = loadpickle('buildconf.pickle') + if settings is None: settings = {} + for arg in sys.argv[:]: + if arg.find('--zmq=') == 0: + zmq = arg.split('=')[-1] + if zmq.lower() == 'default': + settings.pop('zmq', None) + else: + settings['zmq'] = zmq + sys.argv.remove(arg) + savepickle('buildconf.pickle', settings) + return settings + +def discover_settings(): + """ Discover custom settings for ZMQ path""" + settings = get_cfg_args() # lowest priority + settings.update(get_eargs()) + settings.update(get_cargs()) # highest priority + return settings.get('zmq') diff --git a/buildutils/detect.py b/buildutils/detect.py new file mode 100644 index 000000000..693b5c997 --- /dev/null +++ b/buildutils/detect.py @@ -0,0 +1,96 @@ +"""Detect zmq version""" +#----------------------------------------------------------------------------- +# Copyright (C) 2011 Brian Granger, Min Ragan-Kelley +# +# This file is part of pyzmq, copied and adapted from h5py. +# h5py source used under the New BSD license +# +# h5py: +# +# Distributed under the terms of the New BSD License. The full license is in +# the file COPYING.BSD, distributed as part of this software. +#----------------------------------------------------------------------------- + +import shutil +import sys +import os +import logging +import platform +from distutils import ccompiler +from distutils.sysconfig import customize_compiler +from subprocess import Popen, PIPE + +pjoin = os.path.join + +#----------------------------------------------------------------------------- +# Utility functions (adapted from h5py: http://h5py.googlecode.com) +#----------------------------------------------------------------------------- + +def detect_zmq(basedir, **compiler_attrs): + """Compile, link & execute a test program, in empty directory `basedir`. + + The C compiler will be updated with any keywords given via setattr. + + Parameters + ---------- + + basedir : path + The location where the test program will be compiled and run + **compiler_attrs : dict + Any extra compiler attributes, which will be set via ``setattr(cc)``. + + Returns + ------- + + A dict of properties for zmq compilation, with the following two keys: + + vers : tuple + The ZMQ version as a tuple of ints, e.g. (2,2,0) + options : dict + The compiler options used to compile the test function, e.g. `include_dirs`, + `library_dirs`, `libs`, etc. + """ + + cc = ccompiler.new_compiler() + customize_compiler(cc) + for name, val in compiler_attrs.items(): + setattr(cc, name, val) + + cfile = pjoin(basedir, 'vers.c') + efile = pjoin(basedir, 'vers') + + shutil.copy(pjoin(os.path.dirname(__file__), 'vers.c'), cfile) + + cpreargs = lpreargs = None + if sys.platform == 'darwin': + # use appropriate arch for compiler + if platform.architecture()[0]=='32bit': + cpreargs = ['-arch','i386'] + lpreargs = ['-arch', 'i386', '-undefined', 'dynamic_lookup'] + else: + # allow for missing UB arch, since it will still work: + lpreargs = ['-undefined', 'dynamic_lookup'] + + objs = cc.compile([cfile],extra_preargs=cpreargs) + cc.link_executable(objs, efile, extra_preargs=lpreargs) + + result = Popen(efile, stdout=PIPE, stderr=PIPE) + so, se = result.communicate() + # for py3k: + so = so.decode() + se = se.decode() + if result.returncode: + msg = "Error running version detection script:\n%s\n%s" % (so,se) + logging.error(msg) + raise IOError(msg) + + handlers = {'vers': lambda val: tuple(int(v) for v in val.split('.'))} + + props = {} + for line in (x for x in so.split('\n') if x): + key, val = line.split(':') + props[key] = handlers[key](val) + + props['options'] = compiler_attrs + return props + diff --git a/buildutils/msg.py b/buildutils/msg.py new file mode 100644 index 000000000..5f63a9a71 --- /dev/null +++ b/buildutils/msg.py @@ -0,0 +1,39 @@ +"""logging""" +#----------------------------------------------------------------------------- +# Copyright (C) 2011 Brian Granger, Min Ragan-Kelley +# +# This file is part of pyzmq, copied and adapted from h5py. +# h5py source used under the New BSD license +# +# h5py: +# +# Distributed under the terms of the New BSD License. The full license is in +# the file COPYING.BSD, distributed as part of this software. +#----------------------------------------------------------------------------- + +import sys +import logging + +#----------------------------------------------------------------------------- +# Logging (adapted from h5py: http://h5py.googlecode.com) +#----------------------------------------------------------------------------- + + +logger = logging.getLogger() +logger.setLevel(logging.INFO) +logger.addHandler(logging.StreamHandler(sys.stderr)) + +def debug(msg): + pass + +def info(msg): + logger.info(msg) + +def fatal(msg, code=1): + logger.error("Fatal: " + msg) + exit(code) + +def warn(msg): + logger.error("Warning: " + msg) + + diff --git a/buildutils/vers.c b/buildutils/vers.c new file mode 100644 index 000000000..362564f38 --- /dev/null +++ b/buildutils/vers.c @@ -0,0 +1,11 @@ +// check libzmq version + +#include +#include "zmq.h" + +int main(int argc, char **argv){ + int major, minor, patch; + zmq_version(&major, &minor, &patch); + fprintf(stdout, "vers: %d.%d.%d\n", major, minor, patch); + return 0; +} diff --git a/setup.py b/setup.py index 48c4b36ca..f41678d6c 100755 --- a/setup.py +++ b/setup.py @@ -53,8 +53,11 @@ nose = None # local script imports: -from buildutils import (discover_settings, v_str, localpath, savepickle, loadpickle, detect_zmq, - warn, fatal, copy_and_patch_libzmq) +from buildutils import ( + discover_settings, v_str, savepickle, loadpickle, detect_zmq, + warn, fatal, debug, copy_and_patch_libzmq, + fetch_uuid, fetch_libzmq, stage_platform_hpp, + ) #----------------------------------------------------------------------------- # Flags @@ -88,37 +91,60 @@ ZMQ = discover_settings() -if ZMQ is not None and not os.path.exists(ZMQ): +if ZMQ is not None and ZMQ != "bundled" and not os.path.exists(ZMQ): warn("ZMQ directory \"%s\" does not appear to exist" % ZMQ) # bundle_libzmq flag for whether libzmq will be included in pyzmq: if sys.platform.startswith('win'): bundle_libzmq = True elif ZMQ is not None: - bundle_libzmq = doing_bdist + bundle_libzmq = doing_bdist or ZMQ == "bundled" else: bundle_libzmq = False # --- compiler settings ------------------------------------------------- +def bundled_settings(): + settings = { + 'libraries' : [], + 'include_dirs' : ["bundled/zeromq/include"], + 'library_dirs' : [], + } + + + + libzmq_sources = glob("") + if sys.platform.startswith('win'): + libzmq = Extension('zmq.libzmq',) + + def settings_from_prefix(zmq=None): """load appropriate library/include settings from ZMQ prefix""" if sys.platform.startswith('win'): settings = { - 'libraries' : ['libzmq'], + 'libraries' : [], 'include_dirs' : [], 'library_dirs' : [], } + if zmq: + if zmq == "bundled": + settings['libraries'] = [] + else: + settings['libraries'].append("libzmq") if zmq is not None: settings['include_dirs'] += [pjoin(zmq, 'include')] settings['library_dirs'] += [pjoin(zmq, 'lib')] else: settings = { - 'libraries' : ['zmq'], + 'libraries' : [], 'include_dirs' : [], 'library_dirs' : [], 'define_macros' : [('PYZMQ_POSIX', 1)], } + if zmq != "bundled": + settings['libraries'].append('zmq') + else: + zmq = pjoin("bundled", "zeromq") # add pthread on freebsd if sys.platform.startswith('freebsd'): @@ -211,6 +237,10 @@ def getcached(self): def check_zmq_version(self): zmq = self.zmq + if zmq == "bundled": + print('*'*42) + print("Using bundled libzmq") + return if zmq is not None and not os.path.isdir(zmq): fatal("Custom zmq directory \"%s\" does not exist" % zmq) @@ -254,6 +284,9 @@ def check_zmq_version(self): def run(self): self.create_tempdir() settings = self.settings + if self.zmq == "bundled": + self.config = {'vers' : (2,2,0)} + return if bundle_libzmq and not sys.platform.startswith('win'): # rpath slightly differently here, because libzmq not in .. but ../zmq: settings['library_dirs'] = ['zmq'] @@ -497,14 +530,63 @@ def run(self): configure = self.distribution.get_command_obj('configure') configure.check_zmq_version() build_ext.run(self) + +class BundledLibZMQ(build_ext): + """subclass build_ext for building libzmq as a Python extension. + + Code principally derived from pyzmq-static""" + bundledir = "bundled" + + def build_extensions(self): + ext = Extension( + 'zmq.libzmq', + sources = glob(pjoin(self.bundledir, 'zeromq', 'src', '*.cpp')), + include_dirs = [ + pjoin(self.bundledir, 'zeromq', 'include'), + ] + ) + if sys.platform.startswith('win'): + # When compiling the C++ code inside of libzmq itself, we want to + # avoid "warning C4530: C++ exception handler used, but unwind + # semantics are not enabled. Specify /EHsc". + + ext.extra_compile_args.append('/EHsc') + + # Because Visual Studio is given the option "/EXPORT:initlibzmq" + # when compiling libzmq, so we need to provide such a function. + + ext.sources.append(r'src_nt\initlibzmq.c') + + # And things like sockets come from libraries that must be named. + + ext.libraries.append('rpcrt4') + ext.libraries.append('ws2_32') + elif not sys.platform.startswith(('darwin', 'freebsd')): + ext.include_dirs.append(pjoin(self.bundledir, 'uuid')) + ext.sources.append(pjoin(self.bundledir, 'uuid', '*.c')) + + self.extensions = [ext] + self.check_extensions_list(self.extensions) + self.build_extension(ext) + + def run(self): + if not os.path.exists(self.bundledir): + os.makedirs(self.bundledir) + if not sys.platform.startswith(('darwin', 'freebsd', 'win')): + fetch_uuid(self.bundledir) + fetch_libzmq(self.bundledir) + + stage_platform_hpp(pjoin(self.bundledir, 'zeromq')) + build_ext.run(self) + #----------------------------------------------------------------------------- # Extensions #----------------------------------------------------------------------------- cmdclass = {'test':TestCommand, 'clean':CleanCommand, 'revision':GitRevisionCommand, - 'configure': Configure, 'build': CopyingBuild} + 'configure': Configure, 'build': CopyingBuild, 'libzmq': BundledLibZMQ} def pxd(subdir, name): return os.path.abspath(pjoin('zmq', subdir, name+'.pxd')) @@ -546,7 +628,7 @@ def dotc(subdir, name): ) try: - from Cython.Distutils import build_ext + from Cython.Distutils import build_ext as build_ext_c cython=True except ImportError: cython=False @@ -556,14 +638,14 @@ def dotc(subdir, name): suffix = '.pyx' - class CythonCommand(build_ext): + class CythonCommand(build_ext_c): """Custom distutils command subclassed from Cython.Distutils.build_ext to compile pyx->c, and stop there. All this does is override the C-compile method build_extension() with a no-op.""" def build_extension(self, ext): pass - class zbuild_ext(build_ext): + class zbuild_ext(build_ext_c): def run(self): configure = self.distribution.get_command_obj('configure') configure.check_zmq_version() @@ -586,7 +668,7 @@ def run(self): ) extensions.append(ext) -# + package_data = {'zmq':['*.pxd'], 'zmq.core':['*.pxd'], 'zmq.devices':['*.pxd'], diff --git a/zmq/__init__.py b/zmq/__init__.py index c78df1be3..ff025fbb0 100644 --- a/zmq/__init__.py +++ b/zmq/__init__.py @@ -13,15 +13,19 @@ #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- -import sys - -if sys.platform.startswith('win'): - import os, ctypes - here = os.path.dirname(__file__) - libzmq = os.path.join(here, 'libzmq.dll') - if os.path.exists(libzmq): - ctypes.cdll.LoadLibrary(libzmq) - del here, libzmq, ctypes, os + +import os +import glob + +here = os.path.dirname(__file__) +bundled = glob.glob(os.path.join(here, 'libzmq.*')) +if bundled: + import ctypes + _libzmq = ctypes.CDLL(bundled[0], mode=ctypes.RTLD_GLOBAL) + print _libzmq + del ctypes + +del os, glob, here, bundled from zmq.utils import initthreads # initialize threads initthreads.init_threads() From b569a70ae8812400359363138037eefba1d4827f Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 13:12:24 -0700 Subject: [PATCH 03/32] include both uuid/ and uuid parent --- setup.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index f41678d6c..f45a8e557 100755 --- a/setup.py +++ b/setup.py @@ -534,12 +534,13 @@ def run(self): class BundledLibZMQ(build_ext): """subclass build_ext for building libzmq as a Python extension. - Code principally derived from pyzmq-static""" + Code principally derived from pyzmq-static + """ bundledir = "bundled" def build_extensions(self): - ext = Extension( + ext = Extension( 'zmq.libzmq', sources = glob(pjoin(self.bundledir, 'zeromq', 'src', '*.cpp')), include_dirs = [ @@ -563,8 +564,10 @@ def build_extensions(self): ext.libraries.append('rpcrt4') ext.libraries.append('ws2_32') elif not sys.platform.startswith(('darwin', 'freebsd')): + # add uuid as both `uuid/uuid.h` and `uuid.h`: ext.include_dirs.append(pjoin(self.bundledir, 'uuid')) - ext.sources.append(pjoin(self.bundledir, 'uuid', '*.c')) + ext.include_dirs.append(self.bundledir) + ext.sources.extend(glob(pjoin(self.bundledir, 'uuid', '*.c'))) self.extensions = [ext] self.check_extensions_list(self.extensions) From e19147fdafda81d3e5d8f58cdd365b5bfeb09cb0 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 13:26:27 -0700 Subject: [PATCH 04/32] patch gen_uuid.c from pyzmq-static --- buildutils/bundle.py | 24 ++++++++++++++++++++++++ setup.py | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 4fa5d0e8c..6ed88a035 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -118,6 +118,30 @@ def fetch_uuid(savedir): shutil.rmtree(pjoin(savedir, util_name)) +def patch_uuid(uuid_dir): + """patch uuid.h + + from pyzmq-static + """ + info("patching gen_uuid.c") + gen_uuid = pjoin(uuid_dir, "gen_uuid.c") + with open(gen_uuid) as f: + lines = f.readlines() + + if 'pyzmq-patch' in lines[0]: + info("already patched") + return + else: + lines.insert(0, "// end pyzmq-patch\n") + for h in ('UNISTD', 'STDLIB', 'SYS_FILE'): + lines.insert(0, "#define HAVE_%s_H\n" % h) + lines.insert(0, "// begin pyzmq-patch\n") + + with open(gen_uuid, 'w') as f: + f.writelines(lines) + + + def copy_and_patch_libzmq(ZMQ, libzmq): """copy libzmq into source dir, and patch it if necessary. diff --git a/setup.py b/setup.py index f45a8e557..20e422d30 100755 --- a/setup.py +++ b/setup.py @@ -56,7 +56,7 @@ from buildutils import ( discover_settings, v_str, savepickle, loadpickle, detect_zmq, warn, fatal, debug, copy_and_patch_libzmq, - fetch_uuid, fetch_libzmq, stage_platform_hpp, + fetch_uuid, fetch_libzmq, stage_platform_hpp, patch_uuid, ) #----------------------------------------------------------------------------- @@ -578,6 +578,7 @@ def run(self): os.makedirs(self.bundledir) if not sys.platform.startswith(('darwin', 'freebsd', 'win')): fetch_uuid(self.bundledir) + patch_uuid(pjoin(self.bundledir, 'uuid')) fetch_libzmq(self.bundledir) stage_platform_hpp(pjoin(self.bundledir, 'zeromq')) From 7cc48b53dabed74e7828cc8985d8a9bcddba5f02 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 13:36:13 -0700 Subject: [PATCH 05/32] avoid rebuilding libzmq --- setup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 20e422d30..952db74f5 100755 --- a/setup.py +++ b/setup.py @@ -570,8 +570,9 @@ def build_extensions(self): ext.sources.extend(glob(pjoin(self.bundledir, 'uuid', '*.c'))) self.extensions = [ext] - self.check_extensions_list(self.extensions) - self.build_extension(ext) + build_ext.build_extensions(self) + # self.check_extensions_list(self.extensions) + # self.build_extension(ext) def run(self): if not os.path.exists(self.bundledir): From 5974795558e8162cca440720cd0f3a80886fb35d Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 13:36:37 -0700 Subject: [PATCH 06/32] only display "fetching" message when downloading --- buildutils/bundle.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 6ed88a035..55dd6e554 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -48,6 +48,7 @@ def fetch_archive(savedir, url, fname, force=False): if os.path.exists(dest) and not force: info("already have %s" % fname) return dest + info("fetching %s into %s" % (url, savedir)) if not os.path.exists(savedir): os.makedirs(savedir) req = urllib.urlopen(url) @@ -56,7 +57,6 @@ def fetch_archive(savedir, url, fname, force=False): return dest def fetch_libzmq(savedir): - info("fetching libzmq from %s into %s" % (libzmq_url, savedir)) dest = pjoin(savedir, 'zeromq') if os.path.exists(dest): info("already have %s" % dest) @@ -100,7 +100,6 @@ def stage_platform_hpp(zmqroot): def fetch_uuid(savedir): - info("fetching libuuid from %s into %s" % (util_url, savedir)) fname = fetch_archive(savedir, util_url, util) tf = tarfile.open(fname) util_name = untgz(util) From 9a3cd4ef15d24bafabf073448f79acdda4dc3a99 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 14:08:14 -0700 Subject: [PATCH 07/32] use JSON for config, now that we require 2.6 --- buildutils/config.py | 47 +++++++++++++++++++------------------------- setup.py | 21 ++++++++++++-------- 2 files changed, 33 insertions(+), 35 deletions(-) diff --git a/buildutils/config.py b/buildutils/config.py index e705088c9..910f69f5b 100644 --- a/buildutils/config.py +++ b/buildutils/config.py @@ -13,7 +13,7 @@ import sys import os -import pickle +import json try: from configparser import ConfigParser @@ -28,35 +28,28 @@ #----------------------------------------------------------------------------- -def loadpickle(name): - """ Load object from pickle file, or None if it can't be opened """ - name = pjoin('conf', name) - try: - f = open(name,'rb') - except IOError: - # raise +def load_config(name): + """Load config dict from JSON""" + fname = pjoin('conf', name+'.json') + if not os.path.exists(fname): return None try: - return pickle.load(f) - except Exception: - # raise - return None - finally: - f.close() + with open(fname) as f: + cfg = json.load(f) + except Exception as e: + warn("Couldn't load %s: %s" % (fname, e)) + cfg = None + return cfg + -def savepickle(name, data): - """ Save to pickle file, exiting if it can't be written """ +def save_config(name, data): + """Save config dict to JSON""" if not os.path.exists('conf'): os.mkdir('conf') - name = pjoin('conf', name) - try: - f = open(name, 'wb') - except IOError: - fatal("Can't open pickle file \"%s\" for writing" % name) - try: - pickle.dump(data, f, 0) - finally: - f.close() + fname = pjoin('conf', name+'.json') + with open(fname, 'w') as f: + json.dump(data, f) + def v_str(v_tuple): """turn (2,0,1) into '2.0.1'.""" @@ -97,7 +90,7 @@ def get_cfg_args(): def get_cargs(): """ Look for global options in the command line """ - settings = loadpickle('buildconf.pickle') + settings = load_config('buildconf') if settings is None: settings = {} for arg in sys.argv[:]: if arg.find('--zmq=') == 0: @@ -107,7 +100,7 @@ def get_cargs(): else: settings['zmq'] = zmq sys.argv.remove(arg) - savepickle('buildconf.pickle', settings) + save_config('buildconf', settings) return settings def discover_settings(): diff --git a/setup.py b/setup.py index 952db74f5..b1fb05d38 100755 --- a/setup.py +++ b/setup.py @@ -54,7 +54,7 @@ # local script imports: from buildutils import ( - discover_settings, v_str, savepickle, loadpickle, detect_zmq, + discover_settings, v_str, save_config, load_config, detect_zmq, warn, fatal, debug, copy_and_patch_libzmq, fetch_uuid, fetch_libzmq, stage_platform_hpp, patch_uuid, ) @@ -233,15 +233,11 @@ def erase_tempdir(self): pass def getcached(self): - return loadpickle('configure.pickle') + return load_config('configure') def check_zmq_version(self): zmq = self.zmq - if zmq == "bundled": - print('*'*42) - print("Using bundled libzmq") - return - if zmq is not None and not os.path.isdir(zmq): + if zmq is not None and zmq is not "bundled" and not os.path.isdir(zmq): fatal("Custom zmq directory \"%s\" does not exist" % zmq) config = self.getcached() @@ -251,6 +247,11 @@ def check_zmq_version(self): else: self.config = config + if zmq == "bundled": + print('*'*42) + print("Using bundled libzmq") + return + vers = config['vers'] vs = v_str(vers) if vers < min_zmq: @@ -281,6 +282,10 @@ def check_zmq_version(self): "Please specify zmq prefix via configure --zmq=/path/to/zmq or copy " "libzmq into zmq/ manually.") + + def use_bundled(self): + self.config + def run(self): self.create_tempdir() settings = self.settings @@ -340,7 +345,7 @@ def run(self): """%(action, v_str(min_zmq))) else: - savepickle('configure.pickle', config) + save_config('configure', config) print (" ZMQ version detected: %s" % v_str(config['vers'])) finally: print ("*"*42) From 83582c9a672dbe7f42ded113cc16c8fa699e936a Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 14:12:16 -0700 Subject: [PATCH 08/32] add line function to buildutils.msg --- buildutils/msg.py | 2 ++ setup.py | 12 ++++++------ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/buildutils/msg.py b/buildutils/msg.py index 5f63a9a71..664c706a2 100644 --- a/buildutils/msg.py +++ b/buildutils/msg.py @@ -36,4 +36,6 @@ def fatal(msg, code=1): def warn(msg): logger.error("Warning: " + msg) +def line(c='*', width=48): + print (c * (width / len(c))) diff --git a/setup.py b/setup.py index b1fb05d38..25b8e4ca4 100755 --- a/setup.py +++ b/setup.py @@ -55,7 +55,7 @@ # local script imports: from buildutils import ( discover_settings, v_str, save_config, load_config, detect_zmq, - warn, fatal, debug, copy_and_patch_libzmq, + warn, fatal, debug, line, copy_and_patch_libzmq, fetch_uuid, fetch_libzmq, stage_platform_hpp, patch_uuid, ) @@ -248,7 +248,7 @@ def check_zmq_version(self): self.config = config if zmq == "bundled": - print('*'*42) + line() print("Using bundled libzmq") return @@ -264,10 +264,10 @@ def check_zmq_version(self): warn("Detected ZMQ version: %s, but pyzmq targets zmq %s."%( vs, pyzmq_version)) warn("libzmq features and fixes introduced after %s will be unavailable."%vs) - print('*'*42) + line() elif vs >= '3.0': warn("Detected ZMQ version: %s. pyzmq's support for libzmq-dev is experimental."%vs) - print('*'*42) + line() if sys.platform.startswith('win'): # fetch libzmq.dll into local dir @@ -302,7 +302,7 @@ def run(self): else: settings['runtime_library_dirs'] = ['$ORIGIN/../zmq'] try: - print ("*"*42) + line() print ("Configure: Autodetecting ZMQ settings...") print (" Custom ZMQ dir: %s" % (self.zmq,)) config = detect_zmq(self.tempdir, **settings) @@ -348,7 +348,7 @@ def run(self): save_config('configure', config) print (" ZMQ version detected: %s" % v_str(config['vers'])) finally: - print ("*"*42) + line() self.erase_tempdir() self.config = config From c993341ee93beceeedbde43797c8d2355fe46203 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 14:19:21 -0700 Subject: [PATCH 09/32] preempt with error msg if attempted with Python 2.5. --- setup.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/setup.py b/setup.py index 25b8e4ca4..6da09d5e6 100755 --- a/setup.py +++ b/setup.py @@ -27,6 +27,13 @@ import sys from traceback import print_exc +if sys.version_info < (2,6): + print("ERROR: PyZMQ >= 2.2.0 requires Python 2.6 or later. \n" + + " PyZMQ 2.1.11 was the last release to support Python 2.5." + ) + sys.exit(1) + + from distutils.core import setup, Command from distutils.ccompiler import get_default_compiler from distutils.extension import Extension @@ -62,6 +69,7 @@ #----------------------------------------------------------------------------- # Flags #----------------------------------------------------------------------------- + # ignore unused-function and strict-aliasing warnings, of which there # will be many from the Cython generated code: # note that this is only for gcc-style compilers From 72a948a1bfbe2f83a1d45d005357bfff393636ae Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 14:42:38 -0700 Subject: [PATCH 10/32] load different settings for bundled libzmq --- setup.py | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/setup.py b/setup.py index 6da09d5e6..6b4db6797 100755 --- a/setup.py +++ b/setup.py @@ -118,16 +118,23 @@ def bundled_settings(): 'include_dirs' : ["bundled/zeromq/include"], 'library_dirs' : [], } + # add pthread on freebsd + # is this necessary? + if sys.platform.startswith('freebsd'): + settings['libraries'].append('pthread') + elif sys.platform.startswith('win'): + # link against libzmq in build dir: + plat = distutils.util.get_platform() + temp = 'temp.%s-%s' % (plat, sys.version[0:3]) + settings['libraries'].append('libzmq') + settings['library_dirs'].append(pjoin('build', temp, 'Release', 'src')) - - - libzmq_sources = glob("") - if sys.platform.startswith('win'): - libzmq = Extension('zmq.libzmq',) + return settings def settings_from_prefix(zmq=None): """load appropriate library/include settings from ZMQ prefix""" + if sys.platform.startswith('win'): settings = { 'libraries' : [], @@ -178,13 +185,21 @@ def settings_from_prefix(zmq=None): elif sys.platform != 'darwin': settings['runtime_library_dirs'] = [os.path.abspath(x) for x in settings['library_dirs']] - # suppress common warnings + return settings +def init_settings(zmq=None): + if zmq == 'bundled': + settings = bundled_settings() + else: + settings = settings_from_prefix(zmq) + + # suppress common warnings + extra_flags = [] if ignore_common_warnings: for warning in ('unused-function', 'strict-aliasing'): extra_flags.append('-Wno-'+warning) - + settings['extra_compile_args'] = extra_flags # include internal directories @@ -192,7 +207,8 @@ def settings_from_prefix(zmq=None): return settings -COMPILER_SETTINGS = settings_from_prefix(ZMQ) + +COMPILER_SETTINGS = init_settings(ZMQ) #----------------------------------------------------------------------------- @@ -255,7 +271,7 @@ def check_zmq_version(self): else: self.config = config - if zmq == "bundled": + if self.zmq == "bundled": line() print("Using bundled libzmq") return @@ -291,7 +307,7 @@ def check_zmq_version(self): "libzmq into zmq/ manually.") - def use_bundled(self): + def bundle_libzmq(self): self.config def run(self): @@ -542,6 +558,8 @@ def run(self): # check version, to prevent confusing undefined constant errors configure = self.distribution.get_command_obj('configure') configure.check_zmq_version() + libzmq = self.distribution.get_command_obj('libzmq') + libzmq.run() build_ext.run(self) class BundledLibZMQ(build_ext): @@ -667,6 +685,8 @@ class zbuild_ext(build_ext_c): def run(self): configure = self.distribution.get_command_obj('configure') configure.check_zmq_version() + libzmq = self.distribution.get_command_obj('libzmq') + libzmq.run() return build_ext.run(self) cmdclass['cython'] = CythonCommand From 58e8d55017d46f4a941f45ee00fc9bd6a461f342 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 14:59:25 -0700 Subject: [PATCH 11/32] add bundled libzmq to regular extension list, and setup inside configure, rather than as separate Command. --- setup.py | 113 ++++++++++++++++++++++++++----------------------------- 1 file changed, 53 insertions(+), 60 deletions(-) diff --git a/setup.py b/setup.py index 6b4db6797..8105c8b0f 100755 --- a/setup.py +++ b/setup.py @@ -308,13 +308,63 @@ def check_zmq_version(self): def bundle_libzmq(self): - self.config + bundledir = "bundled" + if self.distribution.ext_modules[0].name == 'zmq.libzmq': + # I've already been run + return + + # fetch sources for libzmq extension: + if not os.path.exists(bundledir): + os.makedirs(self.bundledir) + if not sys.platform.startswith(('darwin', 'freebsd', 'win')): + fetch_uuid(bundledir) + patch_uuid(pjoin(bundledir, 'uuid')) + + fetch_libzmq(bundledir) + + stage_platform_hpp(pjoin(bundledir, 'zeromq')) + + # construct the Extension: + + ext = Extension( + 'zmq.libzmq', + sources = glob(pjoin(bundledir, 'zeromq', 'src', '*.cpp')), + include_dirs = [ + pjoin(bundledir, 'zeromq', 'include'), + ] + ) + + if sys.platform.startswith('win'): + # When compiling the C++ code inside of libzmq itself, we want to + # avoid "warning C4530: C++ exception handler used, but unwind + # semantics are not enabled. Specify /EHsc". + + ext.extra_compile_args.append('/EHsc') + + # Because Visual Studio is given the option "/EXPORT:initlibzmq" + # when compiling libzmq, so we need to provide such a function. + + ext.sources.append(r'src_nt\initlibzmq.c') + + # And things like sockets come from libraries that must be named. + + ext.libraries.append('rpcrt4') + ext.libraries.append('ws2_32') + elif not sys.platform.startswith(('darwin', 'freebsd')): + # add uuid as both `uuid/uuid.h` and `uuid.h`: + ext.include_dirs.append(pjoin(bundledir, 'uuid')) + ext.include_dirs.append(bundledir) + ext.sources.extend(glob(pjoin(bundledir, 'uuid', '*.c'))) + + # insert the extension: + self.distribution.ext_modules.insert(0, ext) def run(self): self.create_tempdir() settings = self.settings if self.zmq == "bundled": self.config = {'vers' : (2,2,0)} + self.bundle_libzmq() return if bundle_libzmq and not sys.platform.startswith('win'): # rpath slightly differently here, because libzmq not in .. but ../zmq: @@ -558,62 +608,6 @@ def run(self): # check version, to prevent confusing undefined constant errors configure = self.distribution.get_command_obj('configure') configure.check_zmq_version() - libzmq = self.distribution.get_command_obj('libzmq') - libzmq.run() - build_ext.run(self) - -class BundledLibZMQ(build_ext): - """subclass build_ext for building libzmq as a Python extension. - - Code principally derived from pyzmq-static - """ - - bundledir = "bundled" - - def build_extensions(self): - ext = Extension( - 'zmq.libzmq', - sources = glob(pjoin(self.bundledir, 'zeromq', 'src', '*.cpp')), - include_dirs = [ - pjoin(self.bundledir, 'zeromq', 'include'), - ] - ) - if sys.platform.startswith('win'): - # When compiling the C++ code inside of libzmq itself, we want to - # avoid "warning C4530: C++ exception handler used, but unwind - # semantics are not enabled. Specify /EHsc". - - ext.extra_compile_args.append('/EHsc') - - # Because Visual Studio is given the option "/EXPORT:initlibzmq" - # when compiling libzmq, so we need to provide such a function. - - ext.sources.append(r'src_nt\initlibzmq.c') - - # And things like sockets come from libraries that must be named. - - ext.libraries.append('rpcrt4') - ext.libraries.append('ws2_32') - elif not sys.platform.startswith(('darwin', 'freebsd')): - # add uuid as both `uuid/uuid.h` and `uuid.h`: - ext.include_dirs.append(pjoin(self.bundledir, 'uuid')) - ext.include_dirs.append(self.bundledir) - ext.sources.extend(glob(pjoin(self.bundledir, 'uuid', '*.c'))) - - self.extensions = [ext] - build_ext.build_extensions(self) - # self.check_extensions_list(self.extensions) - # self.build_extension(ext) - - def run(self): - if not os.path.exists(self.bundledir): - os.makedirs(self.bundledir) - if not sys.platform.startswith(('darwin', 'freebsd', 'win')): - fetch_uuid(self.bundledir) - patch_uuid(pjoin(self.bundledir, 'uuid')) - fetch_libzmq(self.bundledir) - - stage_platform_hpp(pjoin(self.bundledir, 'zeromq')) build_ext.run(self) @@ -622,7 +616,8 @@ def run(self): #----------------------------------------------------------------------------- cmdclass = {'test':TestCommand, 'clean':CleanCommand, 'revision':GitRevisionCommand, - 'configure': Configure, 'build': CopyingBuild, 'libzmq': BundledLibZMQ} + 'configure': Configure, 'build': CopyingBuild, + } def pxd(subdir, name): return os.path.abspath(pjoin('zmq', subdir, name+'.pxd')) @@ -685,8 +680,6 @@ class zbuild_ext(build_ext_c): def run(self): configure = self.distribution.get_command_obj('configure') configure.check_zmq_version() - libzmq = self.distribution.get_command_obj('libzmq') - libzmq.run() return build_ext.run(self) cmdclass['cython'] = CythonCommand From b210833f850d7cf8ffee5d32b53916b9f07cb6b5 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 15:02:20 -0700 Subject: [PATCH 12/32] create tempdir only if not bundled --- setup.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 8105c8b0f..eaf6b2bf7 100755 --- a/setup.py +++ b/setup.py @@ -360,12 +360,14 @@ def bundle_libzmq(self): self.distribution.ext_modules.insert(0, ext) def run(self): - self.create_tempdir() - settings = self.settings if self.zmq == "bundled": self.config = {'vers' : (2,2,0)} self.bundle_libzmq() return + + self.create_tempdir() + settings = self.settings + if bundle_libzmq and not sys.platform.startswith('win'): # rpath slightly differently here, because libzmq not in .. but ../zmq: settings['library_dirs'] = ['zmq'] From d1892aaa4753412750ce5a04b1c569ff7af32d68 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 15:03:04 -0700 Subject: [PATCH 13/32] fix missing distutils import --- setup.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index eaf6b2bf7..dd84fb011 100755 --- a/setup.py +++ b/setup.py @@ -34,6 +34,7 @@ sys.exit(1) +import distutils from distutils.core import setup, Command from distutils.ccompiler import get_default_compiler from distutils.extension import Extension @@ -62,7 +63,7 @@ # local script imports: from buildutils import ( discover_settings, v_str, save_config, load_config, detect_zmq, - warn, fatal, debug, line, copy_and_patch_libzmq, + warn, fatal, debug, line, copy_and_patch_libzmq, localpath, fetch_uuid, fetch_libzmq, stage_platform_hpp, patch_uuid, ) @@ -315,7 +316,7 @@ def bundle_libzmq(self): # fetch sources for libzmq extension: if not os.path.exists(bundledir): - os.makedirs(self.bundledir) + os.makedirs(bundledir) if not sys.platform.startswith(('darwin', 'freebsd', 'win')): fetch_uuid(bundledir) patch_uuid(pjoin(bundledir, 'uuid')) From 0f0969eb829d1e2a7bd6ffa0ef3277a8f8008764 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 15:10:50 -0700 Subject: [PATCH 14/32] windows bundling fixes --- buildutils/bundle.py | 4 ++-- setup.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 55dd6e554..67c2031e9 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -52,7 +52,7 @@ def fetch_archive(savedir, url, fname, force=False): if not os.path.exists(savedir): os.makedirs(savedir) req = urllib.urlopen(url) - with open(dest, 'w') as f: + with open(dest, 'wb') as f: f.write(req.read()) return dest @@ -76,7 +76,7 @@ def stage_platform_hpp(zmqroot): return if os.name == 'nt': # stage msvc platform header - platform_dir = pjoin(zmqroot, 'builds', 'msvc', 'platform.hpp') + platform_dir = pjoin(zmqroot, 'builds', 'msvc') else: info("attempting ./configure to generate platform.hpp") diff --git a/setup.py b/setup.py index dd84fb011..dac16afd1 100755 --- a/setup.py +++ b/setup.py @@ -128,7 +128,7 @@ def bundled_settings(): plat = distutils.util.get_platform() temp = 'temp.%s-%s' % (plat, sys.version[0:3]) settings['libraries'].append('libzmq') - settings['library_dirs'].append(pjoin('build', temp, 'Release', 'src')) + settings['library_dirs'].append(pjoin('build', temp, 'Release', 'buildutils')) return settings @@ -345,7 +345,7 @@ def bundle_libzmq(self): # Because Visual Studio is given the option "/EXPORT:initlibzmq" # when compiling libzmq, so we need to provide such a function. - ext.sources.append(r'src_nt\initlibzmq.c') + ext.sources.insert(0, pjoin('buildutils', 'initlibzmq.c')) # And things like sockets come from libraries that must be named. From dcfb5448cc1af6b847791658a9d862a8e48c2ff5 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 15:37:28 -0700 Subject: [PATCH 15/32] Windows loading in __init__ --- zmq/__init__.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/zmq/__init__.py b/zmq/__init__.py index ff025fbb0..1f0c115e8 100644 --- a/zmq/__init__.py +++ b/zmq/__init__.py @@ -15,17 +15,25 @@ #----------------------------------------------------------------------------- import os +import sys import glob here = os.path.dirname(__file__) -bundled = glob.glob(os.path.join(here, 'libzmq.*')) + +bundled = [] +for ext in ('pyd', 'so', 'dll', 'dylib'): + bundled.extend(glob.glob(os.path.join(here, 'libzmq.%s' % ext))) + if bundled: import ctypes - _libzmq = ctypes.CDLL(bundled[0], mode=ctypes.RTLD_GLOBAL) - print _libzmq + if bundled[0].endswith('.pyd'): + # a Windows Extension + _libzmq = ctypes.cdll.LoadLibrary(bundled[0]) + else: + _libzmq = ctypes.CDLL(bundled[0], mode=ctypes.RTLD_GLOBAL) del ctypes -del os, glob, here, bundled +del os, sys, glob, here, bundled, ext from zmq.utils import initthreads # initialize threads initthreads.init_threads() From 346ba36cc2633580641725476f9d06a20dd97511 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 16:30:39 -0700 Subject: [PATCH 16/32] include FD_SETSIZE define in bundled libzmq on Windows --- setup.py | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/setup.py b/setup.py index dac16afd1..466f21892 100755 --- a/setup.py +++ b/setup.py @@ -105,6 +105,8 @@ # bundle_libzmq flag for whether libzmq will be included in pyzmq: if sys.platform.startswith('win'): + if ZMQ is None: + ZMQ = "bundled" bundle_libzmq = True elif ZMQ is not None: bundle_libzmq = doing_bdist or ZMQ == "bundled" @@ -118,6 +120,7 @@ def bundled_settings(): 'libraries' : [], 'include_dirs' : ["bundled/zeromq/include"], 'library_dirs' : [], + 'define_macros' : [], } # add pthread on freebsd # is this necessary? @@ -136,31 +139,18 @@ def bundled_settings(): def settings_from_prefix(zmq=None): """load appropriate library/include settings from ZMQ prefix""" + settings = { + 'libraries' : [], + 'include_dirs' : [], + 'library_dirs' : [], + 'define_macros' : [], + } if sys.platform.startswith('win'): - settings = { - 'libraries' : [], - 'include_dirs' : [], - 'library_dirs' : [], - } - if zmq: - if zmq == "bundled": - settings['libraries'] = [] - else: - settings['libraries'].append("libzmq") - if zmq is not None: - settings['include_dirs'] += [pjoin(zmq, 'include')] - settings['library_dirs'] += [pjoin(zmq, 'lib')] + settings['libraries'].append('libzmq') + settings['include_dirs'] += [pjoin(zmq, 'include')] + settings['library_dirs'] += [pjoin(zmq, 'lib')] else: - settings = { - 'libraries' : [], - 'include_dirs' : [], - 'library_dirs' : [], - 'define_macros' : [('PYZMQ_POSIX', 1)], - } - if zmq != "bundled": - settings['libraries'].append('zmq') - else: - zmq = pjoin("bundled", "zeromq") + settings['libraries'].append('zmq') # add pthread on freebsd if sys.platform.startswith('freebsd'): @@ -194,6 +184,9 @@ def init_settings(zmq=None): else: settings = settings_from_prefix(zmq) + if not sys.platform.startswith('win'): + settings['define_macros'].append(('PYZMQ_POSIX', 1)) + # suppress common warnings extra_flags = [] @@ -332,10 +325,13 @@ def bundle_libzmq(self): sources = glob(pjoin(bundledir, 'zeromq', 'src', '*.cpp')), include_dirs = [ pjoin(bundledir, 'zeromq', 'include'), - ] + ], ) if sys.platform.startswith('win'): + # include defines from msvc project: + ext.define_macros.append(('FD_SETSIZE', 1024)) + # When compiling the C++ code inside of libzmq itself, we want to # avoid "warning C4530: C++ exception handler used, but unwind # semantics are not enabled. Specify /EHsc". From 6b379d5cc8985d58023d6f3d9c7ad91a5062fa53 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 20:54:36 -0700 Subject: [PATCH 17/32] first stab at fallback to bundled libzmq --- buildutils/bundle.py | 3 +- buildutils/config.py | 2 +- buildutils/detect.py | 4 +- setup.py | 156 ++++++++++++++++++++++++++++--------------- 4 files changed, 107 insertions(+), 58 deletions(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 67c2031e9..0435f32ea 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -24,7 +24,8 @@ # Constants #----------------------------------------------------------------------------- -libzmq = "zeromq-2.2.0.tar.gz" +bundled_version = (2,2,0) +libzmq = "zeromq-%i.%i.%i.tar.gz" % (bundled_version) libzmq_url = "http://download.zeromq.org/" + libzmq util = "util-linux-2.21.tar.gz" util_url = "http://www.kernel.org/pub/linux/utils/util-linux/v2.21/" + util diff --git a/buildutils/config.py b/buildutils/config.py index 910f69f5b..54e5b68b4 100644 --- a/buildutils/config.py +++ b/buildutils/config.py @@ -48,7 +48,7 @@ def save_config(name, data): os.mkdir('conf') fname = pjoin('conf', name+'.json') with open(fname, 'w') as f: - json.dump(data, f) + json.dump(data, f, indent=2) def v_str(v_tuple): diff --git a/buildutils/detect.py b/buildutils/detect.py index 693b5c997..ed95d041c 100644 --- a/buildutils/detect.py +++ b/buildutils/detect.py @@ -46,7 +46,7 @@ def detect_zmq(basedir, **compiler_attrs): vers : tuple The ZMQ version as a tuple of ints, e.g. (2,2,0) - options : dict + settings : dict The compiler options used to compile the test function, e.g. `include_dirs`, `library_dirs`, `libs`, etc. """ @@ -91,6 +91,6 @@ def detect_zmq(basedir, **compiler_attrs): key, val = line.split(':') props[key] = handlers[key](val) - props['options'] = compiler_attrs + props['settings'] = compiler_attrs return props diff --git a/setup.py b/setup.py index 466f21892..c4299d0b3 100755 --- a/setup.py +++ b/setup.py @@ -25,6 +25,7 @@ import re import shutil import sys +import time from traceback import print_exc if sys.version_info < (2,6): @@ -65,6 +66,7 @@ discover_settings, v_str, save_config, load_config, detect_zmq, warn, fatal, debug, line, copy_and_patch_libzmq, localpath, fetch_uuid, fetch_libzmq, stage_platform_hpp, patch_uuid, + bundled_version, ) #----------------------------------------------------------------------------- @@ -259,7 +261,7 @@ def check_zmq_version(self): fatal("Custom zmq directory \"%s\" does not exist" % zmq) config = self.getcached() - if config is None or config['options'] != self.settings: + if not config or config.get('settings') != self.settings: self.run() config = self.config else: @@ -307,6 +309,9 @@ def bundle_libzmq(self): # I've already been run return + line() + print ("Using bundled libzmq") + # fetch sources for libzmq extension: if not os.path.exists(bundledir): os.makedirs(bundledir) @@ -329,7 +334,7 @@ def bundle_libzmq(self): ) if sys.platform.startswith('win'): - # include defines from msvc project: + # include defines from zeromq msvc project: ext.define_macros.append(('FD_SETSIZE', 1024)) # When compiling the C++ code inside of libzmq itself, we want to @@ -355,16 +360,48 @@ def bundle_libzmq(self): # insert the extension: self.distribution.ext_modules.insert(0, ext) - - def run(self): - if self.zmq == "bundled": - self.config = {'vers' : (2,2,0)} - self.bundle_libzmq() - return - self.create_tempdir() - settings = self.settings + # update other extensions, with bundled settings + settings = init_settings("bundled") + + for ext in self.distribution.ext_modules[1:]: + for attr, value in settings.items(): + setattr(ext, attr, value) + + return dict(vers=bundled_version, settings=settings) + + + def fallback_on_bundled(self): + """Couldn't build, fallback after waiting a while""" + + print (""" + Failed to build or run libzmq test program. Please check to make sure: + + * You have a C compiler installed + * A development version of Python is installed (including header files) + * A development version of ZMQ >= %s is installed (including header files) + * If ZMQ is not in a default location, supply the argument --zmq= + * If you did recently install ZMQ to a default location, + try rebuilding the ld cache with `sudo ldconfig` + or specify zmq's location with `--zmq=/usr/local` + + """ % (v_str(min_zmq))) + + print ("I will fetch the libzmq sources and build libzmq as a Python extension") + for i in range(10,0,-1): + sys.stdout.write('\r') + sys.stdout.write("unless you interrupt me (^C) in the next %2i seconds..." % i) + sys.stdout.flush() + time.sleep(1) + + print ("") + + return self.bundle_libzmq() + + + def test_build(self, zmq, settings): + self.create_tempdir() if bundle_libzmq and not sys.platform.startswith('win'): # rpath slightly differently here, because libzmq not in .. but ../zmq: settings['library_dirs'] = ['zmq'] @@ -374,56 +411,66 @@ def run(self): # settings['extra_link_args'] = ['-Wl,-rpath','-Wl,$ORIGIN/../zmq'] else: settings['runtime_library_dirs'] = ['$ORIGIN/../zmq'] + + line() + print ("Configure: Autodetecting ZMQ settings...") + print (" Custom ZMQ dir: %s" % zmq) try: - line() - print ("Configure: Autodetecting ZMQ settings...") - print (" Custom ZMQ dir: %s" % (self.zmq,)) config = detect_zmq(self.tempdir, **settings) - except Exception: - # if zmq unspecified on *ix, try again with explicit /usr/local - if self.zmq is None and not sys.platform.startswith('win'): - self.erase_tempdir() - print ("Failed with default libzmq, trying again with /usr/local") - self.zmq = '/usr/local' - self.settings = settings_from_prefix(self.zmq) - - self.run() + finally: + self.erase_tempdir() + + print (" ZMQ version detected: %s" % v_str(config['vers'])) + + return config + + def run(self): + if self.zmq == "bundled": + self.config = self.bundle_libzmq() + return + + config = None + + # There is no available default on Windows, so start with fallback unless + # zmq was given explicitly. + if self.zmq is None and sys.platform.startswith("win"): + config = self.fallback_on_bundled() + + if config is None: + # first try with given config or defaults + try: + config = self.test_build(self.zmq, self.settings) + except Exception: + etype, evalue, tb = sys.exc_info() + # print the error as distutils would if we let it raise: + print ("\nerror: %s\n" % evalue) + + # try fallback on /usr/local on *ix + if config is None and self.zmq is None and not sys.platform.startswith('win'): + print ("Failed with default libzmq, trying again with /usr/local") + time.sleep(1) + zmq = '/usr/local' + settings = settings_from_prefix(self.zmq) + try: + config = self.test_build(zmq, settings) + except Exception: + etype, evalue, tb = sys.exc_info() + # print the error as distutils would if we let it raise: + print ("\nerror: %s\n" % evalue) + else: # if we get here the second run succeeded, so we need to update compiler # settings for the extensions with /usr/local prefix for ext in self.distribution.ext_modules: - for key,value in self.settings.iteritems(): - setattr(ext, key, value) - return - - etype, evalue, tb = sys.exc_info() - # print the error as distutils would if we let it raise: - print ("error: %s" % evalue) - if etype is CompileError: - action = 'compile' - elif etype is LinkError: - action = 'link' - else: - action = 'build or run' - - fatal(""" - Failed to %s ZMQ test program. Please check to make sure: - - * You have a C compiler installed - * A development version of Python is installed (including header files) - * A development version of ZMQ >= %s is installed (including header files) - * If ZMQ is not in a default location, supply the argument --zmq= - * If you did recently install ZMQ to a default location, - try rebuilding the ld cache with `sudo ldconfig` - or specify zmq's location with `--zmq=/usr/local` - """%(action, v_str(min_zmq))) - - else: - save_config('configure', config) - print (" ZMQ version detected: %s" % v_str(config['vers'])) - finally: - line() - self.erase_tempdir() + for attr,value in settings.items(): + setattr(ext, attr, value) + + # finally, fallback on bundled + if config is None: + config = self.fallback_on_bundled() + + save_config('configure', config) self.config = config + line() class TestCommand(Command): """Custom distutils command to run the test suite.""" @@ -601,6 +648,7 @@ def build_extensions(self): self.check_extensions_list(self.extensions) for ext in self.extensions: + self.build_extension(ext) def run(self): From 181dd93de310504fce2e29e3b656b34c9a56cc0e Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 20:58:55 -0700 Subject: [PATCH 18/32] add buildutils to manifest --- MANIFEST.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MANIFEST.in b/MANIFEST.in index 58ec44665..f9b0747d9 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -7,12 +7,12 @@ include setup.cfg.template include setup.py include setupegg.py include zmqversion.py -include buildutils.py graft docs prune docs/build prune docs/gh-pages +graft buildutils graft examples graft zmq graft perf From 2eb7ddc83a49e52a9737e21b034bcd8dc4e8a86e Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 21:15:44 -0700 Subject: [PATCH 19/32] always use initlibzmq --- setup.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index c4299d0b3..a88794b18 100755 --- a/setup.py +++ b/setup.py @@ -327,7 +327,8 @@ def bundle_libzmq(self): ext = Extension( 'zmq.libzmq', - sources = glob(pjoin(bundledir, 'zeromq', 'src', '*.cpp')), + sources = [pjoin('buildutils', 'initlibzmq.c')] + + glob(pjoin(bundledir, 'zeromq', 'src', '*.cpp')), include_dirs = [ pjoin(bundledir, 'zeromq', 'include'), ], @@ -343,11 +344,6 @@ def bundle_libzmq(self): ext.extra_compile_args.append('/EHsc') - # Because Visual Studio is given the option "/EXPORT:initlibzmq" - # when compiling libzmq, so we need to provide such a function. - - ext.sources.insert(0, pjoin('buildutils', 'initlibzmq.c')) - # And things like sockets come from libraries that must be named. ext.libraries.append('rpcrt4') From 379b351df832b888fff92cd210197d2bd530fc6d Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 21:21:14 -0700 Subject: [PATCH 20/32] buildutils py3compat relative imports, division, urllib --- buildutils/__init__.py | 8 ++++---- buildutils/bundle.py | 12 +++++++++--- buildutils/config.py | 2 +- buildutils/msg.py | 4 +++- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/buildutils/__init__.py b/buildutils/__init__.py index 3ce0a6516..df449d23e 100644 --- a/buildutils/__init__.py +++ b/buildutils/__init__.py @@ -3,7 +3,7 @@ Largely adapted from h5py """ -from msg import * -from config import * -from detect import * -from bundle import * +from .msg import * +from .config import * +from .detect import * +from .bundle import * diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 0435f32ea..38de61776 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -13,10 +13,16 @@ import shutil import sys import tarfile -import urllib from subprocess import Popen, PIPE -from msg import fatal, debug, info, warn +try: + # py2 + from urllib2 import urlopen +except ImportError: + # py3 + from urllib.request import urlopen + +from .msg import fatal, debug, info, warn pjoin = os.path.join @@ -52,7 +58,7 @@ def fetch_archive(savedir, url, fname, force=False): info("fetching %s into %s" % (url, savedir)) if not os.path.exists(savedir): os.makedirs(savedir) - req = urllib.urlopen(url) + req = urlopen(url) with open(dest, 'wb') as f: f.write(req.read()) return dest diff --git a/buildutils/config.py b/buildutils/config.py index 54e5b68b4..49f5ccadd 100644 --- a/buildutils/config.py +++ b/buildutils/config.py @@ -21,7 +21,7 @@ from ConfigParser import ConfigParser pjoin = os.path.join -from msg import debug, fatal, warn +from .msg import debug, fatal, warn #----------------------------------------------------------------------------- # Utility functions (adapted from h5py: http://h5py.googlecode.com) diff --git a/buildutils/msg.py b/buildutils/msg.py index 664c706a2..a040f0977 100644 --- a/buildutils/msg.py +++ b/buildutils/msg.py @@ -11,6 +11,8 @@ # the file COPYING.BSD, distributed as part of this software. #----------------------------------------------------------------------------- +from __future__ import division + import sys import logging @@ -37,5 +39,5 @@ def warn(msg): logger.error("Warning: " + msg) def line(c='*', width=48): - print (c * (width / len(c))) + print (c * (width // len(c))) From 80d8920466b37c52b32550f7566791eef1b25cf7 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 22:28:40 -0700 Subject: [PATCH 21/32] adjustments to fallback message --- setup.py | 53 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 16 deletions(-) diff --git a/setup.py b/setup.py index a88794b18..6c9443835 100755 --- a/setup.py +++ b/setup.py @@ -364,30 +364,51 @@ def bundle_libzmq(self): for attr, value in settings.items(): setattr(ext, attr, value) + save_config("buildconf", dict(zmq="bundled")) + return dict(vers=bundled_version, settings=settings) def fallback_on_bundled(self): """Couldn't build, fallback after waiting a while""" - print (""" - Failed to build or run libzmq test program. Please check to make sure: - - * You have a C compiler installed - * A development version of Python is installed (including header files) - * A development version of ZMQ >= %s is installed (including header files) - * If ZMQ is not in a default location, supply the argument --zmq= - * If you did recently install ZMQ to a default location, - try rebuilding the ld cache with `sudo ldconfig` - or specify zmq's location with `--zmq=/usr/local` - - """ % (v_str(min_zmq))) - - print ("I will fetch the libzmq sources and build libzmq as a Python extension") + print ('\n'.join([ + "Failed to build or run libzmq detection test.", + "", + "If you expected pyzmq to link against an installed libzmq, please check to make sure:", + "", + " * You have a C compiler installed", + " * A development version of Python is installed (including headers)", + " * A development version of ZMQ >= %s is installed (including headers)" % v_str(min_zmq), + " * If ZMQ is not in a default location, supply the argument --zmq=", + " * If you did recently install ZMQ to a default location,", + " try rebuilding the ld cache with `sudo ldconfig`", + " or specify zmq's location with `--zmq=/usr/local`", + "", + ])) + + # ultra-lazy pip detection: + if 'pip' in ' '.join(sys.argv) or True: + print ('\n'.join([ + "If you expected to get a binary install (egg), we have those for", + "current Pythons on OSX and Windows. These can be installed with", + "easy_install, but PIP DOES NOT SUPPORT EGGS.", + "", + ])) + + print ('\n'.join([ + "I will fetch the libzmq sources and build libzmq as a Python extension", + "unless you interrupt me (^C) in the next 10 seconds...", + "", + "You can skip all this detection/waiting nonsense if you know", + "you want pyzmq to bundle libzmq as an extension by passing:", + "", + " `--zmq=bundled`", + "", + ])) for i in range(10,0,-1): - sys.stdout.write('\r') - sys.stdout.write("unless you interrupt me (^C) in the next %2i seconds..." % i) + sys.stdout.write('\r%2i...' % i) sys.stdout.flush() time.sleep(1) From 1aa2c37a708fd8ce346cdea7b05b537cce634faa Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 22:55:13 -0700 Subject: [PATCH 22/32] some license/author notes in setup/buildutils --- buildutils/bundle.py | 18 ++++++++++++------ buildutils/initlibzmq.c | 8 ++++++-- setup.py | 31 +++++++++++++++++-------------- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 38de61776..2ddbb9b1c 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -1,9 +1,15 @@ -"""utilities for fetching build dependencies. - -This code is adapted from pyzmq-static's get.sh by Brandon Craig Rhodes -http://bitbucket.org/brandon/pyzmq-static - -""" +"""utilities for fetching build dependencies.""" +#----------------------------------------------------------------------------- +# Copyright (c) 2012 Min Ragan-Kelley +# +# This file is part of pyzmq +# +# Distributed under the terms of the New BSD License. The full license is in +# the file COPYING.BSD, distributed as part of this software. +# +# This bundling code is largely adapted from pyzmq-static's get.sh by +# Brandon Craig-Rhodes, which is itself BSD licensed. +#----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports diff --git a/buildutils/initlibzmq.c b/buildutils/initlibzmq.c index 8c143d20e..ac35eee7c 100644 --- a/buildutils/initlibzmq.c +++ b/buildutils/initlibzmq.c @@ -1,7 +1,11 @@ #include +/* +This file is from pyzmq-static by Brandon Craig-Rhodes, +and used under the BSD license -/* Provide the init function that Visual Studio will be told to look for - when we compile libzmq by pretending it is a Python extension. */ +Provide the init function that Python expects +when we compile libzmq by pretending it is a Python extension. +*/ static PyMethodDef Methods[] = { {NULL, NULL, 0, NULL} diff --git a/setup.py b/setup.py index 6c9443835..427e9ba21 100755 --- a/setup.py +++ b/setup.py @@ -1,6 +1,4 @@ #!/usr/bin/env python - - #----------------------------------------------------------------------------- # Copyright (c) 2012 Brian Granger, Min Ragan-Kelley # @@ -13,6 +11,11 @@ # h5py source used under the New BSD license # # h5py: +# +# The code to bundle libzmq as an Extension is from pyzmq-static +# pyzmq-static source used under the New BSD license +# +# pyzmq-static: #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- @@ -105,15 +108,15 @@ if ZMQ is not None and ZMQ != "bundled" and not os.path.exists(ZMQ): warn("ZMQ directory \"%s\" does not appear to exist" % ZMQ) -# bundle_libzmq flag for whether libzmq will be included in pyzmq: +# bundle_libzmq_dylib flag for whether external libzmq library will be included in pyzmq: if sys.platform.startswith('win'): if ZMQ is None: ZMQ = "bundled" - bundle_libzmq = True -elif ZMQ is not None: - bundle_libzmq = doing_bdist or ZMQ == "bundled" + bundle_libzmq_dylib = True +elif ZMQ is not None and ZMQ != "bundled": + stage = doing_bdist else: - bundle_libzmq = False + bundle_libzmq_dylib = False # --- compiler settings ------------------------------------------------- @@ -166,7 +169,7 @@ def settings_from_prefix(zmq=None): settings['include_dirs'] += ['/opt/local/include'] settings['library_dirs'] += ['/opt/local/lib'] - if bundle_libzmq: + if bundle_libzmq_dylib: # bdist should link against bundled libzmq settings['library_dirs'] = ['zmq'] if sys.platform == 'darwin': @@ -303,7 +306,7 @@ def check_zmq_version(self): "libzmq into zmq/ manually.") - def bundle_libzmq(self): + def bundle_libzmq_extension(self): bundledir = "bundled" if self.distribution.ext_modules[0].name == 'zmq.libzmq': # I've already been run @@ -414,12 +417,12 @@ def fallback_on_bundled(self): print ("") - return self.bundle_libzmq() + return self.bundle_libzmq_extension() def test_build(self, zmq, settings): self.create_tempdir() - if bundle_libzmq and not sys.platform.startswith('win'): + if bundle_libzmq_dylib and not sys.platform.startswith('win'): # rpath slightly differently here, because libzmq not in .. but ../zmq: settings['library_dirs'] = ['zmq'] if sys.platform == 'darwin': @@ -443,7 +446,7 @@ def test_build(self, zmq, settings): def run(self): if self.zmq == "bundled": - self.config = self.bundle_libzmq() + self.config = self.bundle_libzmq_extension() return config = None @@ -642,7 +645,7 @@ class CopyingBuild(build): """subclass of build that copies libzmq if doing bdist.""" def run(self): - if bundle_libzmq and not sys.platform.startswith('win'): + if bundle_libzmq_dylib and not sys.platform.startswith('win'): # always rebuild before bdist, because linking may be wrong: self.run_command('clean') copy_and_patch_libzmq(ZMQ, 'libzmq'+lib_ext) @@ -770,7 +773,7 @@ def run(self): 'zmq.utils':['*.pxd', '*.h'], } -if bundle_libzmq: +if bundle_libzmq_dylib: package_data['zmq'].append('libzmq'+lib_ext) def extract_version(): From 34832210ccf004e81514a64563007d56748abd61 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 22:56:23 -0700 Subject: [PATCH 23/32] remove disabled configure --- buildutils/bundle.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 2ddbb9b1c..655ee8c2f 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -93,7 +93,7 @@ def stage_platform_hpp(zmqroot): else: info("attempting ./configure to generate platform.hpp") - p = Popen('./configurez', cwd=zmqroot, shell=True, + p = Popen('./configure', cwd=zmqroot, shell=True, stdout=PIPE, stderr=PIPE, ) o,e = p.communicate() From e3a6bc8535941790efd94438166d7eb6cc4abe79 Mon Sep 17 00:00:00 2001 From: MinRK Date: Thu, 17 May 2012 23:20:19 -0700 Subject: [PATCH 24/32] bundle_libzmq_dylib typo --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 427e9ba21..5f28401ff 100755 --- a/setup.py +++ b/setup.py @@ -114,7 +114,7 @@ ZMQ = "bundled" bundle_libzmq_dylib = True elif ZMQ is not None and ZMQ != "bundled": - stage = doing_bdist + bundle_libzmq_dylib = doing_bdist else: bundle_libzmq_dylib = False From c1afb6b8bc3247b574f590336528e611b2f1a9d8 Mon Sep 17 00:00:00 2001 From: MinRK Date: Fri, 18 May 2012 12:51:36 -0700 Subject: [PATCH 25/32] allow fallback dialog on Windows --- setup.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 5f28401ff..33b796817 100755 --- a/setup.py +++ b/setup.py @@ -110,8 +110,6 @@ # bundle_libzmq_dylib flag for whether external libzmq library will be included in pyzmq: if sys.platform.startswith('win'): - if ZMQ is None: - ZMQ = "bundled" bundle_libzmq_dylib = True elif ZMQ is not None and ZMQ != "bundled": bundle_libzmq_dylib = doing_bdist @@ -152,8 +150,10 @@ def settings_from_prefix(zmq=None): } if sys.platform.startswith('win'): settings['libraries'].append('libzmq') - settings['include_dirs'] += [pjoin(zmq, 'include')] - settings['library_dirs'] += [pjoin(zmq, 'lib')] + + if zmq is not None: + settings['include_dirs'] += [pjoin(zmq, 'include')] + settings['library_dirs'] += [pjoin(zmq, 'lib')] else: settings['libraries'].append('zmq') From 65485a1f4a84003e713b52079d13909d42dba5e4 Mon Sep 17 00:00:00 2001 From: MinRK Date: Fri, 18 May 2012 12:53:50 -0700 Subject: [PATCH 26/32] more flexible names for auto zmq --- buildutils/config.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildutils/config.py b/buildutils/config.py index 49f5ccadd..ec1e62d25 100644 --- a/buildutils/config.py +++ b/buildutils/config.py @@ -95,7 +95,7 @@ def get_cargs(): for arg in sys.argv[:]: if arg.find('--zmq=') == 0: zmq = arg.split('=')[-1] - if zmq.lower() == 'default': + if zmq.lower() in ('default', 'auto', ''): settings.pop('zmq', None) else: settings['zmq'] = zmq From c3d34ff100f6273c4ae8b8edc989f08bf975dfbf Mon Sep 17 00:00:00 2001 From: MinRK Date: Fri, 18 May 2012 13:43:29 -0700 Subject: [PATCH 27/32] tweak fallback chain and message --- setup.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index 33b796817..356a7e017 100755 --- a/setup.py +++ b/setup.py @@ -400,14 +400,14 @@ def fallback_on_bundled(self): ])) print ('\n'.join([ - "I will fetch the libzmq sources and build libzmq as a Python extension", - "unless you interrupt me (^C) in the next 10 seconds...", - "", "You can skip all this detection/waiting nonsense if you know", "you want pyzmq to bundle libzmq as an extension by passing:", "", " `--zmq=bundled`", "", + "I will now fetch the libzmq sources and build libzmq as a Python extension", + "unless you interrupt me (^C) in the next 10 seconds...", + "", ])) for i in range(10,0,-1): @@ -455,6 +455,7 @@ def run(self): # zmq was given explicitly. if self.zmq is None and sys.platform.startswith("win"): config = self.fallback_on_bundled() + self.zmq = "bundled" if config is None: # first try with given config or defaults @@ -470,7 +471,7 @@ def run(self): print ("Failed with default libzmq, trying again with /usr/local") time.sleep(1) zmq = '/usr/local' - settings = settings_from_prefix(self.zmq) + settings = settings_from_prefix(zmq) try: config = self.test_build(zmq, settings) except Exception: @@ -480,13 +481,15 @@ def run(self): else: # if we get here the second run succeeded, so we need to update compiler # settings for the extensions with /usr/local prefix + self.zmq = zmq for ext in self.distribution.ext_modules: for attr,value in settings.items(): setattr(ext, attr, value) # finally, fallback on bundled - if config is None: + if config is None and self.zmq is None: config = self.fallback_on_bundled() + self.zmq = "bundled" save_config('configure', config) self.config = config From 6376c0abd274cc6f931907690b34865d0bab3545 Mon Sep 17 00:00:00 2001 From: MinRK Date: Fri, 18 May 2012 14:57:26 -0700 Subject: [PATCH 28/32] py3compat in initlibzmq --- buildutils/initlibzmq.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/buildutils/initlibzmq.c b/buildutils/initlibzmq.c index ac35eee7c..ec299f0a9 100644 --- a/buildutils/initlibzmq.c +++ b/buildutils/initlibzmq.c @@ -1,18 +1,45 @@ -#include /* This file is from pyzmq-static by Brandon Craig-Rhodes, and used under the BSD license +py3compat from http://wiki.python.org/moin/PortingExtensionModulesToPy3k + Provide the init function that Python expects when we compile libzmq by pretending it is a Python extension. */ +#include "Python.h" static PyMethodDef Methods[] = { {NULL, NULL, 0, NULL} }; +#if PY_MAJOR_VERSION >= 3 + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "libzmq", + NULL, + -1, + Methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC +PyInit_libzmq(void) +{ + PyObject *module = PyModule_Create(&moduledef); + return module; +} + +#else // py2 + PyMODINIT_FUNC initlibzmq(void) { (void) Py_InitModule("libzmq", Methods); } + +#endif From 4db1bcf44bb2f3cc9621d9a58739029721a31f14 Mon Sep 17 00:00:00 2001 From: MinRK Date: Fri, 18 May 2012 15:39:05 -0700 Subject: [PATCH 29/32] add wildcards to bundled libzmq glob sometimes the name can be mangled (such as 'libzmq.cpython-32mu.so' or 'libzmq.so.1') --- zmq/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zmq/__init__.py b/zmq/__init__.py index 1f0c115e8..969e34d1e 100644 --- a/zmq/__init__.py +++ b/zmq/__init__.py @@ -22,7 +22,7 @@ bundled = [] for ext in ('pyd', 'so', 'dll', 'dylib'): - bundled.extend(glob.glob(os.path.join(here, 'libzmq.%s' % ext))) + bundled.extend(glob.glob(os.path.join(here, 'libzmq*.%s*' % ext))) if bundled: import ctypes From 73399aa58e04c78a642331cdb6ff3507cceefdec Mon Sep 17 00:00:00 2001 From: MinRK Date: Fri, 18 May 2012 19:35:56 -0700 Subject: [PATCH 30/32] minor cleanup of
s during build --- buildutils/msg.py | 4 ++-- setup.py | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/buildutils/msg.py b/buildutils/msg.py index a040f0977..704e1924e 100644 --- a/buildutils/msg.py +++ b/buildutils/msg.py @@ -26,7 +26,7 @@ logger.addHandler(logging.StreamHandler(sys.stderr)) def debug(msg): - pass + logger.debug(msg) def info(msg): logger.info(msg) @@ -39,5 +39,5 @@ def warn(msg): logger.error("Warning: " + msg) def line(c='*', width=48): - print (c * (width // len(c))) + print(c * (width // len(c))) diff --git a/setup.py b/setup.py index 356a7e017..d2ad64779 100755 --- a/setup.py +++ b/setup.py @@ -269,10 +269,9 @@ def check_zmq_version(self): config = self.config else: self.config = config + line() if self.zmq == "bundled": - line() - print("Using bundled libzmq") return vers = config['vers'] @@ -375,6 +374,8 @@ def bundle_libzmq_extension(self): def fallback_on_bundled(self): """Couldn't build, fallback after waiting a while""" + line() + print ('\n'.join([ "Failed to build or run libzmq detection test.", "", @@ -447,6 +448,7 @@ def test_build(self, zmq, settings): def run(self): if self.zmq == "bundled": self.config = self.bundle_libzmq_extension() + line() return config = None @@ -536,7 +538,7 @@ def run(self): sys.exit(1) if nose is None: - print ("nose unavailable, falling back on unittest. Skipped tests will appear as ERRORs.") + warn("nose unavailable, falling back on unittest. Skipped tests will appear as ERRORs.") return self.run_unittest() else: return self.run_nose() From 73c27b24040127322f0a2d9233555a84c535b981 Mon Sep 17 00:00:00 2001 From: MinRK Date: Wed, 23 May 2012 21:43:51 -0700 Subject: [PATCH 31/32] add fetchbundle command --- buildutils/bundle.py | 8 +++++++- setup.py | 29 ++++++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index 655ee8c2f..f9747299a 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -113,6 +113,11 @@ def stage_platform_hpp(zmqroot): def fetch_uuid(savedir): + dest = pjoin(savedir, 'uuid') + if os.path.exists(dest): + info("already have %s" % dest) + return + fname = fetch_archive(savedir, util_url, util) tf = tarfile.open(fname) util_name = untgz(util) @@ -123,11 +128,12 @@ def fetch_uuid(savedir): ) # uuid_members = map(tf.getmember, uuid_names) tf.extractall(savedir, uuid) - dest = pjoin(savedir, 'uuid') if os.path.exists(dest): shutil.rmtree(dest) shutil.move(pjoin(savedir, util_name, 'libuuid', 'src'), dest) shutil.rmtree(pjoin(savedir, util_name)) + + patch_uuid(dest) def patch_uuid(uuid_dir): diff --git a/setup.py b/setup.py index d2ad64779..56d9df735 100755 --- a/setup.py +++ b/setup.py @@ -68,7 +68,7 @@ from buildutils import ( discover_settings, v_str, save_config, load_config, detect_zmq, warn, fatal, debug, line, copy_and_patch_libzmq, localpath, - fetch_uuid, fetch_libzmq, stage_platform_hpp, patch_uuid, + fetch_uuid, fetch_libzmq, stage_platform_hpp, bundled_version, ) @@ -319,7 +319,6 @@ def bundle_libzmq_extension(self): os.makedirs(bundledir) if not sys.platform.startswith(('darwin', 'freebsd', 'win')): fetch_uuid(bundledir) - patch_uuid(pjoin(bundledir, 'uuid')) fetch_libzmq(bundledir) @@ -497,6 +496,30 @@ def run(self): self.config = config line() + +class FetchCommand(Command): + """Fetch libzmq and uuid sources, that's it.""" + + user_options = [ ] + + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + # fetch sources for libzmq extension: + bundledir = "bundled" + if not os.path.exists(bundledir): + os.makedirs(bundledir) + fetch_uuid(bundledir) + fetch_libzmq(bundledir) + for tarball in glob(pjoin(bundledir, '*.tar.gz')): + os.remove(tarball) + + + class TestCommand(Command): """Custom distutils command to run the test suite.""" @@ -688,7 +711,7 @@ def run(self): #----------------------------------------------------------------------------- cmdclass = {'test':TestCommand, 'clean':CleanCommand, 'revision':GitRevisionCommand, - 'configure': Configure, 'build': CopyingBuild, + 'configure': Configure, 'build': CopyingBuild, 'fetchbundle': FetchCommand, } def pxd(subdir, name): From 3f1afddc188cb2a63aeae36d82dc557edd59fd75 Mon Sep 17 00:00:00 2001 From: MinRK Date: Wed, 23 May 2012 21:58:16 -0700 Subject: [PATCH 32/32] docstrings and defines --- buildutils/bundle.py | 15 +++++++++++++-- setup.py | 9 +++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/buildutils/bundle.py b/buildutils/bundle.py index f9747299a..eb1fb02ae 100644 --- a/buildutils/bundle.py +++ b/buildutils/bundle.py @@ -43,6 +43,7 @@ util_url = "http://www.kernel.org/pub/linux/utils/util-linux/v2.21/" + util HERE = os.path.dirname(__file__) +ROOT = os.path.dirname(HERE) #----------------------------------------------------------------------------- # functions @@ -53,10 +54,12 @@ def untgz(archive): return archive.replace('.tar.gz', '') def localpath(*args): - plist = [HERE]+list(args) + """construct an absolute path from a list relative to the root pyzmq directory""" + plist = [ROOT] + list(args) return os.path.abspath(pjoin(*plist)) def fetch_archive(savedir, url, fname, force=False): + """download an archive to a specific location""" dest = pjoin(savedir, fname) if os.path.exists(dest) and not force: info("already have %s" % fname) @@ -70,6 +73,7 @@ def fetch_archive(savedir, url, fname, force=False): return dest def fetch_libzmq(savedir): + """download and extract libzmq""" dest = pjoin(savedir, 'zeromq') if os.path.exists(dest): info("already have %s" % dest) @@ -83,6 +87,12 @@ def fetch_libzmq(savedir): shutil.move(with_version, dest) def stage_platform_hpp(zmqroot): + """stage platform.hpp into libzmq sources + + Tries ./configure first (except on Windows), + then falls back on included platform.hpp previously generated. + """ + platform_hpp = pjoin(zmqroot, 'src', 'platform.hpp') if os.path.exists(platform_hpp): info("already have platform.hpp") @@ -113,6 +123,7 @@ def stage_platform_hpp(zmqroot): def fetch_uuid(savedir): + """download, extract, and patch libuuid sources""" dest = pjoin(savedir, 'uuid') if os.path.exists(dest): info("already have %s" % dest) @@ -137,7 +148,7 @@ def fetch_uuid(savedir): def patch_uuid(uuid_dir): - """patch uuid.h + """patch uuid.h with a few defines from pyzmq-static """ diff --git a/setup.py b/setup.py index 56d9df735..4806233f0 100755 --- a/setup.py +++ b/setup.py @@ -500,6 +500,8 @@ def run(self): class FetchCommand(Command): """Fetch libzmq and uuid sources, that's it.""" + description = "Fetch libuuid and libzmq sources into bundled" + user_options = [ ] def initialize_options(self): @@ -523,6 +525,8 @@ def run(self): class TestCommand(Command): """Custom distutils command to run the test suite.""" + description = "Test PyZMQ (must have been built inplace: `setup.py build_ext --inplace`)" + user_options = [ ] def initialize_options(self): @@ -569,6 +573,8 @@ def run(self): class GitRevisionCommand(Command): """find the current git revision and add it to zmq.core.verion.__revision__""" + description = "Store current git revision in version.py" + user_options = [ ] def initialize_options(self): @@ -768,6 +774,9 @@ class CythonCommand(build_ext_c): """Custom distutils command subclassed from Cython.Distutils.build_ext to compile pyx->c, and stop there. All this does is override the C-compile method build_extension() with a no-op.""" + + description = "Compile Cython sources to C" + def build_extension(self, ext): pass