From 6120251d86bc85138305c1bf02b1000dc435fdb5 Mon Sep 17 00:00:00 2001 From: Nathaniel Nicandro Date: Thu, 16 May 2019 17:47:57 -0500 Subject: [PATCH] Support linking a custom libzmq again Closes #13. --- .travis.yml | 3 ++ Makefile | 25 ++++++----- README.org | 21 +++++++-- src/Makefile.am | 9 ++-- src/configure.ac | 111 ++++++++++++++++++++++++++++------------------- 5 files changed, 107 insertions(+), 62 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6693ad..4345d8b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,9 @@ sudo: required env: - EMACS_VERSION=26.1 - EMACS_VERSION=git-snapshot +# Emacs with modules does not compile correctly on Xenial due to a compiler bug +# in gcc +dist: trusty script: # Install an Emacs with module support - | diff --git a/Makefile b/Makefile index 302e90c..8d34932 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,8 @@ export ZMQ_VERSION ?= 4.3.1 export ZMQ_BUILD_HOST ?= # Directory in which the emacs-zmq module will be written EZMQ_LIBDIR ?= $(CURDIR)/$(ZMQ_BUILD_HOST) +# NOTE: The ZMQ_LIBS and ZMQ_CFLAGS can be set before configuring the project +# to point to the ZMQ to build with. # Get the module extension for this build ifeq ($(ZMQ_BUILD_HOST),) @@ -36,27 +38,28 @@ SHARED := emacs-zmq$(SHARED_EXT) .PHONY: all all: $(EZMQ_LIBDIR)/$(SHARED) compile +.PHONY: configure +configure: src/configure + cd src && ./configure CPPFLAGS="$(CPPFLAGS)" \ + --host=$(ZMQ_BUILD_HOST) --prefix=$(CURDIR) \ + --enable-shared=emacs-zmq --enable-static=zeromq \ + --without-docs --enable-drafts=yes --enable-libunwind=no \ + --disable-curve-keygen --disable-perf --disable-eventfd + $(EZMQ_LIBDIR)/$(SHARED): src/Makefile $(MAKE) -C src mkdir -p $(EZMQ_LIBDIR) cp src/.libs/$(SHARED) $(EZMQ_LIBDIR)/$(SHARED) +src/Makefile: src/configure + $(MAKE) configure + # Needed for static Windows builds of libzmq, see libzmq/INSTALL ifeq ($(SHARED_EXT),.dll) CPPFLAGS += -DZMQ_STATIC endif -src/Makefile: src/Makefile.am src/configure - cd src && ./configure CPPFLAGS="$(CPPFLAGS)" \ - --host=$(ZMQ_BUILD_HOST) --prefix=$(CURDIR) \ - --enable-shared=emacs-zmq --enable-static=zeromq \ - --without-docs --enable-drafts=yes --enable-libunwind=no \ - --disable-curve-keygen --disable-perf --disable-eventfd - -src/libzmq/.git: - @if test ! -d src/libzmq/.git; then git clone $(ZMQ_GIT_REPO) src/libzmq; fi - -src/configure: src/configure.ac src/libzmq/.git +src/configure: src/configure.ac src/Makefile.am cd src && autoreconf -i .PHONY: test diff --git a/README.org b/README.org index 869c8a6..909365e 100644 --- a/README.org +++ b/README.org @@ -47,10 +47,23 @@ when running =(require 'zmq)= and the module is not built already, you will be asked to build it. Note, the =autotools= collection must be available on your system in order to -build the module. - -The default version of =libzmq= built is 4.3.1 and can be changed by specifying -the environment variable =ZMQ_VERSION=, e.g. to something like +build the module as well as the =pkg-config= tool. + +By default =pkg-config= is used to search for a usable =libzmq= to use, falling +back to downloading and building a local copy if necessary. + +You can tell =pkg-config= to use a specific =libzmq= by setting the environment +variables =ZMQ_LIBS= and =ZMQ_CFLAGS= before building the module. The module +will link to the =libzmq= that those variables point to if it can. Note, when +linking =libzmq= in this way, the =zmq_poller= interface is required. This +means that the linked =libzmq= needs to have been configured using the option +=--enable-drafts=yes= if =libzmq= < 4.3.1. + +If =ZMQ_LIBS= and =ZMQ_CFLAGS= are not set or they point to a =libzmq= that +isn't usable, a local copy of =libzmq= is downloaded, built, and statically +linked into the resulting module. The default version of =libzmq= built in this +case is 4.3.1 and can be changed by specifying the environment variable +=ZMQ_VERSION=, e.g. to something like #+BEGIN_SRC shell ZMQ_VERSION=4.3.0 diff --git a/src/Makefile.am b/src/Makefile.am index c2351eb..285a98a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,16 +1,19 @@ -SUBDIRS = libzmq +SUBDIRS = $(MAYBE_LIBZMQ) ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = emacs-zmq.la +emacs_zmq_la_CFLAGS = emacs_zmq_la_LDFLAGS = -module -avoid-version if WINDOWS emacs_zmq_la_LDFLAGS += -no-undefined endif +if ZMQ_BUILD_LOCALLY # Its necessary to pass static libraries directly to the linker since libtool # won't build emacs-zmq as a dynamic module on Windows otherwise. emacs_zmq_la_LDFLAGS += -Wl,libzmq/src/.libs/libzmq.a -emacs_zmq_la_SOURCES = socket.c context.c msg.c constants.c util.c core.c poll.c emacs-zmq.c +emacs_zmq_la_CFLAGS += -Ilibzmq/include emacs_zmq_la_CPPFLAGS = -DZMQ_BUILD_DRAFT_API=1 -emacs_zmq_la_CFLAGS = -O3 -Ilibzmq/include +endif +emacs_zmq_la_SOURCES = socket.c context.c msg.c constants.c util.c core.c poll.c emacs-zmq.c diff --git a/src/configure.ac b/src/configure.ac index 0638c56..07dbe5d 100644 --- a/src/configure.ac +++ b/src/configure.ac @@ -1,58 +1,81 @@ AC_PREREQ([2.69]) AC_INIT([emacs-zmq], [0.10.9], [nathanielnicandro@gmail.com]) -# Ensure the libzmq/configure script is generated -cd libzmq -if test "`git describe --candidates=0 2>/dev/null || echo x`" != v$ZMQ_VERSION; then - echo "Checking out libzmq" - git checkout --quiet master - git pull --quiet origin - git checkout v$ZMQ_VERSION - rm -f configure -fi -if test ! -e configure; then - echo "Generating libzmq configure script" - ./autogen.sh -fi -cd .. - AC_CONFIG_SRCDIR([core.c]) AC_CONFIG_MACRO_DIRS([m4]) AM_INIT_AUTOMAKE([-Wall -Wno-override foreign]) AC_PROG_CC AM_PROG_AR AC_CANONICAL_HOST -AC_CONFIG_SUBDIRS([libzmq]) -case "${host_os}" in - *darwin*) - ;; - *mingw*|*msys*|*cygwin*) - export CXXFLAGS="-static-libgcc -static-libstdc++ $CXXFLAGS" - # Its necessary to pass these to the linker directly since libtool - # won't build emacs-zmq as a dynamic module otherwise on Windows. - export LDFLAGS="-Wl,-l:libstdc++.a -Wl,-l:libgcc.a -Wl,-lws2_32 -Wl,-liphlpapi $LDFLAGS" - on_windows=yes - ;; - *) - # Assume GCC compatible compiler - # TODO: Actually check for this - # Prevent dynamic linkage of libzmq dependencies - # - # PIC is needed since we are most likely building libzmq statically, - # but would like to link it to the dynamic emacs-zmq library. GCC needs - # to have this explicitly specified. - # - # The -fPIC for CFLAGS is needed even though emacs-zmq is already a dynamic - # library since libzmq comes packaged with tweetnacl which is a C library and - # it builds that by default. - export CXXFLAGS="-fPIC -static-libgcc -static-libstdc++ $CXXFLAGS" - export CFLAGS="-fPIC $CFLAGS" - export LDFLAGS="-Wl,-l:libstdc++.a -Wl,-l:libgcc.a $LDFLAGS" - ;; -esac +PKG_CHECK_MODULES([ZMQ], [libzmq], [ + AC_SEARCH_LIBS([zmq_poller_new], [zmq], [ + dnl FIXME: This isn't necessarily true in ZMQ >= 4.3 + AC_DEFINE([ZMQ_BUILD_DRAFT_API], 1) + ], [ + AC_MSG_NOTICE([incompatible libzmq, building one locally]) + ZMQ_BUILD_LOCALLY=yes + ]) +], [ + AC_MSG_NOTICE([libzmq not found by pkg-config, building one locally]) + ZMQ_BUILD_LOCALLY=yes +]) -AM_CONDITIONAL(WINDOWS, [test "x$on_windows" != x]) +if test "x$ZMQ_BUILD_LOCALLY" != x; then + if test "x$ZMQ_VERSION" == x; then ZMQ_VERSION="4.3.1"; fi + if test "x$ZMQ_GIT_REPO" == x; then ZMQ_GIT_REPO="https://github.com/zeromq/libzmq"; fi + if test ! -d libzmq/.git; then git clone $ZMQ_GIT_REPO libzmq; fi + AC_CONFIG_SUBDIRS([libzmq]) + # Ensure the libzmq/configure script is generated + cd libzmq + if test "`git describe --candidates=0 2>/dev/null || echo x`" != "v${ZMQ_VERSION}"; then + git checkout --quiet master + git pull --quiet origin + git checkout "v$ZMQ_VERSION" + rm -f configure + fi + if test ! -e configure; then + echo "Generating libzmq configure script" + ./autogen.sh + fi + cd .. + case "${host_os}" in + *darwin*) + ;; + *mingw*|*msys*|*cygwin*) + export CXXFLAGS="-static-libgcc -static-libstdc++ $CXXFLAGS" + # Its necessary to pass these to the linker directly since libtool + # won't build emacs-zmq as a dynamic module otherwise on Windows. + export LDFLAGS="-Wl,-l:libstdc++.a -Wl,-l:libgcc.a -Wl,-lws2_32 -Wl,-liphlpapi $LDFLAGS" + ON_WINDOWS=yes + ;; + *) + # Assume GCC compatible compiler + # TODO: Actually check for this + # Prevent dynamic linkage of libzmq dependencies + # + # PIC is needed since we are most likely building libzmq + # statically, but would like to link it to the dynamic emacs-zmq + # library. GCC needs to have this explicitly specified. + # + # The -fPIC for CFLAGS is needed even though emacs-zmq is already a + # dynamic library since libzmq comes packaged with tweetnacl which + # is a C library and it builds that by default. + export CXXFLAGS="-fPIC -static-libgcc -static-libstdc++ $CXXFLAGS" + export CFLAGS="-fPIC $CFLAGS" + export LDFLAGS="-Wl,-l:libstdc++.a -Wl,-l:libgcc.a $LDFLAGS" + ;; + esac +fi + +AM_CONDITIONAL(WINDOWS, [test "x$ON_WINDOWS" != x]) +AM_CONDITIONAL(ZMQ_BUILD_LOCALLY, [test "x$ZMQ_BUILD_LOCALLY" != x]) +if test "x$ZMQ_BUILD_LOCALLY" != x; then + MAYBE_LIBZMQ=libzmq +else + MAYBE_LIBZMQ= +fi +AC_SUBST([MAYBE_LIBZMQ]) LT_INIT([win32-dll shared disable-static]) AC_CONFIG_FILES([Makefile])