Opened 6 years ago

Closed 6 years ago

#55641 closed defect (fixed)

zmq @4.2.3 fails to build on 10.7 and 10.8 due to C++11

Reported by: ryandesign (Ryan Carsten Schmidt) Owned by: merijn (Merijn Verstraaten)
Priority: Normal Milestone:
Component: ports Version: 2.4.2
Keywords: lion, mountainlion Cc: stromnov (Andrey Stromnov), michaelld (Michael Dickens)
Port: zmq, zmq-devel

Description

zmq @4.2.3 builds fine on Mac OS X 10.5 and 10.6, and on OS X 10.9 and later, but fails to build on OS X 10.7 and 10.8.

On 10.8 this is the error I see:

  CXX      src/src_libzmq_la-ctx.lo
src/ctx.cpp:466:37: error: no member named 'emplace' in 'std::map<std::basic_string<char>, zmq::endpoint_t, std::less<std::basic_string<char> >, std::allocator<std::pair<const std::basic_string<char>, zmq::endpoint_t> > >'
    const bool inserted = endpoints.ZMQ_MAP_INSERT_OR_EMPLACE (addr_, 
                          ~~~~~~~~~ ^
./src/blob.hpp:39:41: note: expanded from macro 'ZMQ_MAP_INSERT_OR_EMPLACE'
#define ZMQ_MAP_INSERT_OR_EMPLACE(k, v) emplace (k,v)
                                        ^
src/ctx.cpp:540:29: error: no member named 'emplace' in 'std::multimap<std::basic_string<char>, zmq::ctx_t::pending_connection_t, std::less<std::basic_string<char> >, std::allocator<std::pair<const std::basic_string<char>, zmq::ctx_t::pending_connection_t> > >'
        pending_connections.ZMQ_MAP_INSERT_OR_EMPLACE (addr_, pending_connection);
        ~~~~~~~~~~~~~~~~~~~ ^
./src/blob.hpp:39:41: note: expanded from macro 'ZMQ_MAP_INSERT_OR_EMPLACE'
#define ZMQ_MAP_INSERT_OR_EMPLACE(k, v) emplace (k,v)
                                        ^
2 errors generated.

I assume this is a C++11 feature. The configure script earlier checked for C++11 features and found them:

checking whether /usr/bin/clang++ supports C++11 features by default... no
checking whether /usr/bin/clang++ supports C++11 features with -std=gnu++11... yes

Of course, as we know, even though the clang compiler on 10.7 and 10.8 supports C++11 if using libc++, the default C++ stdlib on those systems is libstdc++ which does not support C++11. And changing the C++ stdlib to libc++ for individual ports is generally not advised.

If there were a straightforward way to instruct the configure system not to use C++11, I might suggest modifying the portfile to do so when {${configure.cxx_stdlib} ne "libc++"}. But I didn't see a way to do that.

So instead, I suggest including PortGroup cxx11 1.1 when [string match *clang* ${configure.compiler}]. This should fix the build failure on 10.7 and 10.8 without having any effect for 10.9 and later. Since 10.6 and earlier were happy to build without C++11 support (since they were using gcc-4.2.1 which does not support C++11 at all), I'm inclined to leave them that way.

The zmq-devel subport is of course affected as well. I don't believe the zmq3 or zmq22 subports are affected, given that our buildbot did successfully produce binaries of those subports for all versions of macOS.

My proposed fix almost works for me on 10.8. Everything compiles, but the dylib fails to link because for some reason /usr/bin/clang++ is being used to link instead of the compiler MacPorts specified. I don't yet understand why that's happening.

Attachments (4)

zmq-cxx11.diff (461 bytes) - added by ryandesign (Ryan Carsten Schmidt) 6 years ago.
patch-zmq-disable-cxx11.diff (401 bytes) - added by kencu (Ken) 6 years ago.
patch-zmq-use-have-cxx11.diff (1.7 KB) - added by kencu (Ken) 6 years ago.
zmq.tar.bz2 (2.8 KB) - added by michaelld (Michael Dickens) 6 years ago.

Download all attachments as: .zip

Change History (24)

Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

Attachment: zmq-cxx11.diff added

comment:1 Changed 6 years ago by michaelld (Michael Dickens)

If zmq and zmq-devel require C++11, then why not just include the c++11 PG for those ports, no matter the compiler (not just clang)? Sure modern clang might work with it properly (because it supports c++11), but why not be explicit in compiler selection, to make sure the compiler is compatible?

comment:2 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

It appears that C++11 support in zmq and zmq-devel is optional. If a C++11-supporting compiler is not found, it seems to happily build with C++11 support disabled. This is what currently happens on 10.6 and earlier.

If we change that, it will increase the dependencies for 10.6 and earlier, and might even make the ports fail to build on those systems; I have not tested that but recall the difficulties we had with cmake. And if it succeeds, the build would be different than before, which would necessitate increasing the revision.

I was trying to provide a minimal fix for the 10.7 and 10.8 build failure that would not adversely affect 10.6 and earlier.

comment:3 Changed 6 years ago by michaelld (Michael Dickens)

Ah OK I understand. Maybe there's an option to disable C++11 entirely that we can set? Why use it if it's optional & would result in "different" builds depending on the selected compiler?

comment:4 in reply to:  3 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

Replying to michaelld:

Ah OK I understand. Maybe there's an option to disable C++11 entirely that we can set?

As I said I did not see a configure flag for that.

Why use it if it's optional & would result in "different" builds depending on the selected compiler?

I'm not sure I understand the question.

comment:5 Changed 6 years ago by michaelld (Michael Dickens)

Ok so i haven't read through the code to see, but if ZMQ allows optional use of C++11 then the resulting ABI will be somewhat different for the version using C++11 versus the one not using it. That's not idea for debugging / tickets, to have to know which version we're working with. It would make a lot more sense to either select one or the other and go with it for all installs, so that the ABI is consistent across all installs (or, as consistent as it reasonable can be).

comment:6 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

I don't know if the ABI will be different. Looking at the code, there seem to be #ifdefs that say, effectively, "if C++11, do this; if Windows, do this; if something else, do this". In some cases there appear to be half a dozen different implementations of the same code, depending on what capabilities the system has for accomplishing it.

comment:7 Changed 6 years ago by kencu (Ken)

Several fairly easy ways to disable c++11 on zmq, should that ever be desired:

  1. comment out the test for cxx11 in configure.ac
    #AX_CXX_COMPILE_STDCXX_11([ext], [optional])
    
    (more fancy, that test could be wrapped in an option block to make it a full configure argument (upstream)).
  1. set env variables during configure to preset results of the c++11 tests as failing:
    configure.env-append ax_cv_cxx_compile_cxx11=no
    configure.env-append ax_cv_cxx_compile_cxx11__std_gnupp11=no
    configure.env-append ax_cv_cxx_compile_cxx11__std_gnupp0x=no
    
    (These env variable names are found in config.log.)
  1. post-configure, reinplace the results of the config variable HAVE_CXX11 in source/platform.hpp
  1. switch to the cmake build, and wrap the c++11 tests in an option variable

comment:8 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

AX_CXX_COMPILE_STDCXX_11 sets HAVE_CXX11. But I don't see anywhere in the code that inspects the value of HAVE_CXX11. Therefore, I don't know what the purpose of the configure check is, and I don't think that removing it (1) or overriding it (2 or 3) will have any effect on whether zmq actually uses C++11 or not. See e.g. places in the code that check #elif (defined __cplusplus && __cplusplus >= 201103L). And let's please not even consider switching to cmake (4) since I don't see how that would solve anything either and it brings with it a whole new set of problems.

comment:9 Changed 6 years ago by kencu (Ken)

yes, well, if they ignore the flag they test for and set, that's pretty useless.

comment:10 Changed 6 years ago by kencu (Ken)

I'm a sucker for punishment and clearly looking for diversion from the work I'm supposed to be doing today :>

Here's a patch that fixes the usage of HAVE_CXX11, and another patch that disables cxx11. I note also there was a typo in their code for one of their __cplusplus tests as well; they used _cplusplus by accident.

Last edited 6 years ago by kencu (Ken) (previous) (diff)

Changed 6 years ago by kencu (Ken)

Changed 6 years ago by kencu (Ken)

comment:11 Changed 6 years ago by michaelld (Michael Dickens)

nice work there, Ken! I'll give these a go & see what happens. I know from reviewing my 10.8 install that I just added the cxx11 1.1 PG & that did the trick. That said, if we can find a way to make it work better I'm all for it!

comment:12 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

Has anybody attempted to ask the developers of zmq about this? I think this needs their input.

comment:13 Changed 6 years ago by michaelld (Michael Dickens)

I'll contact them when I have a working patch (which will be based off of Ken's patches; I hope for just 1 ;).

comment:14 Changed 6 years ago by michaelld (Michael Dickens)

It's pretty simple to patch configure.ac to add an option "--enable-cxx11" which is disabled by default, then to force C++11 checking in the compiler if this option is enabled. If found use it; if not, error out. I'll attach a tarball with these patches & Portfile update.

Changed 6 years ago by michaelld (Michael Dickens)

Attachment: zmq.tar.bz2 added

comment:15 Changed 6 years ago by michaelld (Michael Dickens)

Should be generic & robust enough to work with or without the cxx11 1.1 PG and changing the obvious "--disable-..." to "--enable-...".

comment:16 Changed 6 years ago by kencu (Ken)

I was tempted to learn how to do that, but autotools are intimidating at times. I'll see what you did.

comment:17 Changed 6 years ago by michaelld (Michael Dickens)

autotools isn't for the faint of heart. CMake is a little easier, but can be equally distressing for some things. There is no "one build system to rule them all" in my opinion; they each have strengths and weaknesses, the specifics of which vary from one to another.

comment:18 Changed 6 years ago by michaelld (Michael Dickens)

Unless someone objects, I'm going to commit this fix later today, mid-afternoon in US/ET (so ~5 hours from now). I think it's a robust fix that allows us to enable/disable C++11 dynamically -- which is desirable. I'll push it upstream as well.

comment:19 Changed 6 years ago by michaelld (Michael Dickens)

"later today" meaning "when I can get around to it weeks later" ... work gets the way of these things!

comment:20 Changed 6 years ago by michaelld (Michael Dickens)

Resolution: fixed
Status: newclosed

In 238f4e15ca3e579c23ca8a29e2c67fdcf4a611c4/macports-ports:

zmq[-devel]: fix to disable c++11 for use with older compilers / Ohs

Add a configure option to force enable c++11, or just disable it. Verified both ways on 10.8 (apple-gcc-4.2 and default Xcode clang) and 10.12 (default Xcode clang).

Closes: #55641

Note: See TracTickets for help on using tickets.