standard way to require c++11?

Mihai Moldovan ionic at macports.org
Mon Apr 13 18:54:56 PDT 2015


As a reply to what we discussed on IRC today, here's the relevant
changes for the "C++11 on steroids" part of one of my ports
(audacious-core):

Revision: 135031
          https://trac.macports.org/changeset/135031
Author:   ionic at macports.org
Date:     2015-04-13 09:24:21 -0700 (Mon, 13 Apr 2015)
Log Message:
-----------
audacious{,-{core,plugins}}: update to 3.6.1. Also:

  - Upstream now uses C++11. Insert abomination to make that work on
    10.6+.
  - Re-do patches. Replace -std=gnu++11 with -std=c++11 to not pull in
    libstdc++ unnecessarily.
[...]

Modified: trunk/dports/multimedia/audacious-core/Portfile
===================================================================
--- trunk/dports/multimedia/audacious-core/Portfile	2015-04-13 16:07:33
UTC (rev 135030)
+++ trunk/dports/multimedia/audacious-core/Portfile	2015-04-13 16:24:21
UTC (rev 135031)
@@ -3,12 +3,13 @@

 PortSystem          1.0
 PortGroup           conflicts_build 1.0
+PortGroup           compiler_blacklist_versions 1.0

 name                audacious-core
[...]
@@ -31,12 +32,15 @@
 master_sites        http://distfiles.audacious-media-player.org
 distname            ${real_name}-${version}
 use_bzip2           yes
[...]

-patchfiles          patch-buildsys.diff
+patchfiles          patch-buildsys.diff \
+
patch-acinclude.m4-drop-libc++-switch-from-gnu++11-to-c++11.diff

 depends_build       path:bin/pkg-config:pkgconfig \
                     path:bin/aclocal:automake \
@@ -59,17 +62,48 @@
 autoreconf.cmd      ./autogen.sh
 autoreconf.args

+# A compiler supporting C++11 is required to build audacious and its
plugins.
+# The newer, the merrier.
+# Compilers supporting C++11 are GCC >= 4.6 and clang >= 3.3.
+# We do not know what "cc" is, so blacklist it as well.
+compiler.blacklist-append   {*gcc-4.[0-5]} {clang < 500}
macports-clang-2.* \
+                            {macports-clang-3.[0-2]} cc
+
 platform darwin {
[...]
+    if {${os.major} >= 13} {
+        if {${configure.cxx_stdlib} ne {} &&
+            [string equal ${configure.cxx_stdlib} "libc++"]} {
+            # Blacklist all GCC compilers to not accidentally pull in
libstdc++.
+            compiler.blacklist-append {*gcc*}
+
+            # Make sure binary runs on 10.9+ only.
+            configure.ldflags-append  "-mmacosx-version-min=10.9"
         } else {
[...]
+            ui_error "The system libraries in OS X 10.9 and higher use
libc++. Thus, libstdc++ is not supported for this port."
+            error "libstdc++ supported on <= 10.8 only."
         }
     } else {
[...]
+        if {${configure.cxx_stdlib} ne {} &&
+            [string equal ${configure.cxx_stdlib} "libc++"]} {
+            ui_error "The system libraries in OS X 10.8 and lower use
libstdc++. Thus, libstdc++ is not supported for this port."
+            error "libc++ supported on >= 10.9 only."
+        } else {
+            # Shameless copy from rust.
+            depends_lib-append
{path:lib/libstdc\\+\\+.6.dylib:libgcc}
+
+            # Force GCC 4.9.
+            compiler.blacklist-append   {*clang*}
+            compiler.fallback-append    macports-gcc-4.9
+
+            # Make sure binary runs on 10.5+ only.
+            configure.ldflags-append    "-mmacosx-version-min=10.5"
+
+            notes-append {
+                            Upstream for some reason requires libc++.
+                            Your build will use libstdc++. The
maintainer assumes this
+                            to be OK, but you're on your own if stuff
breaks.\
+            }
+        }
     }
 }

Added:
trunk/dports/multimedia/audacious-core/files/patch-acinclude.m4-drop-libc++-switch-from-gnu++11-to-c++11.diff
===================================================================
---
trunk/dports/multimedia/audacious-core/files/patch-acinclude.m4-drop-libc++-switch-from-gnu++11-to-c++11.diff
                        (rev 0)
+++
trunk/dports/multimedia/audacious-core/files/patch-acinclude.m4-drop-libc++-switch-from-gnu++11-to-c++11.diff
2015-04-13 16:24:21 UTC (rev 135031)
@@ -0,0 +1,22 @@
+--- acinclude.m4.orig
++++ acinclude.m4
+@@ -83,8 +83,8 @@ AC_REQUIRE([AC_SYS_LARGEFILE])
+ if test "x$GCC" = "xyes"; then
+     CFLAGS="$CFLAGS -std=gnu99 -ffast-math -Wall -pipe"
+     if test "x$HAVE_DARWIN" = "xyes"; then
+-        CXXFLAGS="$CXXFLAGS -stdlib=libc++ -std=gnu++11 -ffast-math
-Wall -pipe"
+-        LDFLAGS="$LDFLAGS -lc++ -stdlib=libc++"
++        CXXFLAGS="$CXXFLAGS -std=c++11 -ffast-math -Wall -pipe"
++        LDFLAGS="$LDFLAGS"
+     else
+         CXXFLAGS="$CXXFLAGS -std=gnu++11 -ffast-math -Wall -pipe"
+     fi
+@@ -101,7 +101,7 @@ if test "x$HAVE_DARWIN" = "xyes"; then
+     AC_PROG_OBJCXX
+     AC_PROG_OBJCXXCPP
+
+-    OBJCXXFLAGS="$OBJCXXFLAGS -stdlib=libc++ -std=c++11"
++    OBJCXXFLAGS="$OBJCXXFLAGS -std=c++11"
+ fi
+
+ dnl Enable "-Wl,-z,defs" only on Linux


-------------------------------------------------------------------------

Human-readable explanation:

I've added the compiler_blacklist_versions PortGroup and blacklisted GCC
< 4.6 and clang < 3.3, as only newer versions than that are fully
C++11-compatible for all platforms.

Then, I'm patching out -lc++ added by upstream for not very smart
reasons ("I need this on my machine") -- AND CHANGED -std=gnu++11 TO
-std=c++11. This is getting important soonish.

Next up: checking the OS X version. For 10.9 (darwin 13) and higher, I
error out if configure.cxx_stdlib is set to libstdc++. Likewise, I error
out on 10.8 (darwin 12) and lower if configure.cxx_stdlib is set to libc++.

This leaves us with libc++ on 10.9+ and libstdc++ on 10.8-. Compatible
with the system C++ runtime. Good.

For 10.9+ with libc++, only blacklisting all GCC versions is necessary
to not pull in libstdc++ accidentally.

===
Caveat: make sure the port does not use -std=gnu++11 on 10.9+. It WILL
make clang link to libstdc++ (even if passing -stdlib=libc++!), because
gnu++11 is "c++11 with GNU extensions", which libc++ naturally does not
provide.
===

10.8- is a little bit more complicated. We need to make sure a recent
libstdc++ is available. What Apple ships might not be recent enough,
especially on 10.7 and 10.6.

Thus comes:

depends_lib-append          {path:lib/libstdc\\+\\+.6.dylib:libgcc}

In my experiments with a 10.6 VM, mp-clang-3.4 -std=c++11
-stdlib=libstdc++ chokes on #include <type_traits>.

Hence, I blacklist all clang versions on 10.8-.

This will leave us with quite a mess. Now all compilers are blacklisted
on older systems. Great.

Not a big deal, though. We can set compiler.fallback to macports-gcc-4.9
and port will use this specific compiler, given all others are blacklisted.

With that, compiling C++11 code on 10.8- works great (I've tested it in
a 10.6 VM) -- and the binaries even run correctly.



Mihai

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 884 bytes
Desc: OpenPGP digital signature
URL: <https://lists.macosforge.org/pipermail/macports-dev/attachments/20150414/bc2075e0/attachment.sig>


More information about the macports-dev mailing list