Update BUILD instructions.
authorDavin McCall <davmac@davmac.org>
Mon, 5 Jun 2017 22:55:00 +0000 (23:55 +0100)
committerDavin McCall <davmac@davmac.org>
Mon, 5 Jun 2017 22:55:00 +0000 (23:55 +0100)
BUILD
mconfig

diff --git a/BUILD b/BUILD
index 2efbc5714cc7d6abe8504c2347a5859bcf27a180..7e040eb58859c57b22a8d600daf3a43eca1ea4d0 100644 (file)
--- a/BUILD
+++ b/BUILD
@@ -1,20 +1,62 @@
 Building Dinit
 =-=-=-=-=-=-=-
 
-Buildingn Dinit should be a straight-forward process. It requires GNU make.
+Building Dinit should be a straight-forward process. It requires GNU make.
 
 Edit the "mconfig" file to choose appropriate values for the configuration variables defined
 within. In particular:
 
   CXX : should be set to the name of the C++ compiler (and linker)
-  CXXOPTS :  are options passed to the compiler during compilation
+  CXXOPTS :  are options passed to the compiler during compilation (see note for GCC below)
   EXTRA_LIBS : are any extra libraries required for linking; should not normally be needed.
 
-Defaults for Linux and OpenBSD are provided. Note that the "eg++" package must be installed
-on OpenBSD as the default "g++" compiler is too old.
+Defaults for Linux and OpenBSD are provided. Note that the "eg++" or "clang++" package must
+be installed on OpenBSD as the default "g++" compiler is too old. Clang is part of the base
+system in recent releases.
 
 Then, change into the "src" directory, and run "make" (or "gmake" if the system make is not
-GNU make):
+GNU make, such as on most BSD systems):
 
     cd src
     make
+
+If everything goes smoothly this will build dinit, dinitctl, and optionally the shutdown
+utility. Use "make install" to install; you can specify an alternate installation by
+setting the "DESTDIR" variable, eg "make DESTDIR=/tmp/temporary-install-path install".
+
+
+Special note for GCC/Libstdc++
+=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
+
+GCC 5.x onwards includes a "dual ABI" in its standard library implementation, aka Libstdc++.
+Compiling against the newer (C++11 and later) ABI can be achieved by adding
+-D_GLIBCXX_USE_CXX11_ABI=1 to the compiler command line; this uses a non-standard language
+extension to differently mangle symbol names in order to link against the new ABI versions.
+
+(Some systems may be configured to build with the new ABI by default, and in that case you
+build against the old ABI using D_GLIBCXX_USE_CXX11_ABI=1).
+
+This is problematic for several reasons. First, it prevents linking against the new ABI with
+other compilers that do not understand the language extension (LLVM i.e. clang++ does so
+in recent versions, so this is perhaps no longer much of a problem in practice). Secondly,
+some aspects of library behavior are ABI-dependent but cannot be changed using the ABI
+macro; in particular, exceptions thrown as a result of failed I/O operations are, in GCC
+versions 5.x and 6.x, always "old ABI" exceptions which cannot be caught by code compiled
+against the new ABI, and in GCC version 7.x they are always "new ABI" exceptions which cannot
+be caught by code compiled against the old ABI. Since the one library object now supposedly
+houses both ABIs, this means that at least one of the two ABIs is always broken.
+
+A blog post describing the dual ABI mechanism can be found here:
+
+    https://developers.redhat.com/blog/2015/02/05/gcc5-and-the-c11-abi/
+
+The bug regarding the issue with catching other-ABI exceptions is here:
+
+    https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66145
+
+Since Dinit is affected by this bug, the unfortunate possibility exists to break Dinit by
+upgrading GCC. If you have libstdc++ corresponding to GCC 5.x or 6.x, you *must* build with
+the old ABI, but Dinit will be broken if you upgrade to GCC 7. If you have libstdc++ from
+GCC 7, you *must* build with the new ABI. If the wrong ABI is used, Dinit may still run
+successfully but any attempt to load a non-existing service, for example, will cause Dinit
+to crash.
diff --git a/mconfig b/mconfig
index b173e19d1b2eb31143fe8a8adeffcba0e4a8c7fa..48c8e984e9aa1751120b89527ae8a936a9af7682 100644 (file)
--- a/mconfig
+++ b/mconfig
@@ -1,12 +1,16 @@
-# Linux (GCC). Note with GCC 5,5.1,5.2 the new C++11 ABI is buggy.
+# Linux (GCC). Note with GCC 5.x/6.x you must use the old ABI, with GCC 7.x you must use
+# the new ABI. See BUILD file for more information.
 CXX=g++
-CXXOPTS=-D_GLIBCXX_USE_CXX11_ABI=0 -std=gnu++11 -Os -Wall -Wno-invalid-offsetof -fno-rtti
+CXXOPTS=-D_GLIBCXX_USE_CXX11_ABI=1 -std=gnu++11 -Os -Wall -Wno-invalid-offsetof -fno-rtti
 EXTRA_LIBS=
 BUILD_SHUTDOWN=yes
 
 # OpenBSD, tested with GCC 4.9.3 and gmake:
-#CXX=eg++
-#CXXOPTS=-D_GLIBCXX_USE_CXX11_ABI=0 -std=gnu++11 -Os -Wall -fno-rtti
+#CXX=clang++
+#CXXOPTS=-std=gnu++11 -Os -Wall -fno-rtti
 #EXTRA_LIBS=
 #BUILD_SHUTDOWN=no
 # (shutdown command not available for OpenBSD yet).
+
+# MacOS: use Linux settings, but don't build shutdown:
+#BUILD_SHUTDOWN=no