Opened 8 years ago

Closed 8 years ago

Last modified 7 years ago

#38374 closed defect (fixed)

boost: stdlibc++ linkage prevents dependencies from using libc++

Reported by: macportbugs@… Owned by: adfernandes (Andrew Fernandes)
Priority: Normal Milestone:
Component: ports Version: 2.1.3
Keywords: Cc: jeremyhu (Jeremy Huddleston Sequoia), arto@…
Port: boost


Compilation of software using Xcode 4.6 (Apple LLVM version 4.2) with -std=c++11 and -stdlib=libc++ fails if this software depends on boost because boost is linked against stdlibc++. The following patch fixes this problem (probably not a perfect solution though):

--- Portfile.orig	2013-03-10 02:00:39.000000000 +0100
+++ Portfile	2013-03-13 17:27:48.000000000 +0100
@@ -90,7 +90,7 @@

     if {[string length ${configure.sdkroot}] == 0} {
-        write_jam "using darwin : : ${configure.cxx} : : ;"
+        write_jam "using darwin : : ${configure.cxx} : <cxxflags>\"-std=c++11 -stdlib=libc++\" <linkflags>\"-stdlib=libc++\" : ;"
     } else {
         write_jam "using darwin : : ${configure.cxx} : <compileflags>\"-isysroot ${configure.sdkroot}\" : ;"

Change History (11)

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

Owner: changed from macports-tickets@… to adfernandes@…

Does that fix still work with older Xcode versions? Including those that don't use clang?

comment:2 Changed 8 years ago by larryv (Lawrence Velázquez)

Cc: jeremyhu@… added
Keywords: c++11 libc++ clang boost removed
Summary: clang/libc++ based c++11 compilation against macports boost not possibleboost: stdlibc++ linkage prevents dependencies from using libc++

Also Cc-ing jeremyhu.

comment:3 Changed 8 years ago by macportbugs@…

It probably does not work with older versions (that's why it is probably not a perfect solution). I think some guards or even a variant (c++11) should be added...

comment:4 Changed 8 years ago by jeremyhu (Jeremy Huddleston Sequoia)

That doesn't look like a valid change. Anything that shares C++ objects across an API boundary needs to use the same STL. You can't realistically mix libc++ and libstdc++ usage across an API boundary. When built against the same ABI, they can exist in the same process and share some of the same very-low-level objects, but that's about all.

If you build boost against libc++, you won't be able to build anything using libstdc++ against it.

I suggest that if you want to use libc++, you rebuild *ALL* of MacPorts using libc++ by setting configure.cxxflags in /opt/local/etc/macports.conf

comment:5 Changed 8 years ago by macportbugs@…

As far as I remember configure.cxxflags does not affect the funny build system of boost, does it?

comment:6 Changed 8 years ago by jeremyhu (Jeremy Huddleston Sequoia)

If that's the case, then *that* is the bug we should fix ;)

comment:7 Changed 8 years ago by macportbugs@…

If your prefer it this way I agree - for me the important point is that I want to be able to use C++11 and boost at the same time. And I found quite a number of people trying the same. look for example at this post:

I tried different methods to achieve this for about a day (including configure.cxxflags in the portfile) and the patch above was the only solution that worked. However I am not a macports expert and in fact this was the first time I had a look into a portfile at all.

Last edited 8 years ago by macportbugs@… (previous) (diff)

comment:8 Changed 8 years ago by adfernandes (Andrew Fernandes)

For my two cents, I agree with jeremyhu, but only sort-of. For sure the boost build system should respect the system configure.cxx setting. However, it is sad fact of life that the boost build system does not, by default, support this.

I will warn everyone that using libc++, while it appears to work, may not actually work since this configuration is not supported nor tested by the boost team on MacOS.

I can patch the Portfile such that

write_jam "using darwin : : ${configure.cxx} : <cxxflags>\"${configure.cxxflags}\" <linkflags>\"${configure.ldflags}\" : ;"

with an include-guard to make sure that all variables are set, etc.

The problem we're having is that, as part of MacPorts, boost really should be built as if it were a system library, that is, with all build values at default. What people want is a boost installation that is customized for their particular project. As jeremyhu points out, then we start to mix libc++ ABIs, and weird breakage results.

Any thoughts from anyone before I patch the Portfile as above?

comment:9 Changed 8 years ago by adfernandes (Andrew Fernandes)

Okay - here is my (trivial) portfile patch.

--- Portfile	(revision 104122)
+++ Portfile	(working copy)
@@ -89,12 +89,11 @@
     reinplace -E "s|-install_name \"|&${prefix}/lib/|" \
-    if {[string length ${configure.sdkroot}] == 0} {
-        write_jam "using darwin : : ${configure.cxx} : : ;"
-    } else {
-        write_jam "using darwin : : ${configure.cxx} : <compileflags>\"-isysroot ${configure.sdkroot}\" : ;"
-    }
+    set compileflags ""
+    if {[string length ${configure.sdkroot}] != 0} { set compileflags "<compileflags>\"-isysroot ${configure.sdkroot}\"" }
+    write_jam "using darwin : : ${configure.cxx} : <cxxflags>\"${configure.cxxflags}\" ${compileflags} <linkflags>\"${configure.ldflags}\" : ;"

The problem with it is that it replaces the boost-default -O3 optimization level with -O2. No big deal, really... except one never really knows what they've assumed (in the threading libraries, etc etc etc) about optimization levels.

You get libraries built with

"/usr/bin/clang++"  -ftemplate-depth-128 -O2 -O3 -finline-functions -Wno-inline [...]

So if we assume that the last-most specified -O3 flag is the one in effect, which it should be, then this is just fine.

Comments, anyone?

comment:10 Changed 8 years ago by adfernandes (Andrew Fernandes)

Resolution: fixed
Status: newclosed

comment:11 Changed 7 years ago by arto@…

Cc: arto@… added

Cc Me!

Note: See TracTickets for help on using tickets.