tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: a concrete proposal for fixing the gcc c++ mixed-compiler issue



On 07/04/17 10:13, Greg Troxel wrote:
We've had a lot of discussion about this, and it seems we have rough
consensus that:

   Mixing gcc versions (and hence runtime versions) in c++ programs is in
   general unsound, even if it often works within 4.x and especially if
   the highest version is used to link.

   Putting GCC_REQD=4.8 on programs that use c++11 is not ok, because
   depending packages might be built with an earlier compiler,
   because it leads to mixed compiler usage, and because
   USE_LANGUAGES+=c++11 ought to take care of this.

   This is a major issue in pkgsrc, resulting in significant breakage on
   systems with older gcc in the base.  We really need to fix this well
   before the next branch.

   (This is apparently not a problem in clang or other compilers, because
   nobody has been talking about that.)

I have a concrete proposal, which is to define a variable that is the
minimum gcc version for any program that uses C++.  This can be set by
the user, and has a platform-specific default.  This will not fix all
gcc-mixing woes, but it should resolve the vast majority of them.

The following patch implements the variable, resulting in the declared
version being added to GCC_REQD if any c++ flavor is in USE_LANGUAGES.

It defaults the variable to 4.8 for any NetBSD version.  Probably NetBSD
6 and earlier should choose 6 instead.

I've tested this building cmake on NetBSD 7, which results in using the
base 4.8 and the package is as it was before.  Changing the default to
4.9 results in cmake being built with gcc49 from pkgsrc, and linked with
and depending on gcc49's libs.

Obviously GNU/Linux, particularly RH/Centos 6, needs a default.  I left
that out, trying to make incremental progress.

I realize this approach is not perfect.  One can still get mixed
compilation from individual programs with GCC_REQD (e.g firefox and
4.9).  So I think the questions are if there is anything broken or
confused with this approach/patch, and if it is a useful step forward.

Index: mk/compiler/gcc.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/compiler/gcc.mk,v
retrieving revision 1.179
diff -u -p -r1.179 gcc.mk
--- mk/compiler/gcc.mk	25 Jun 2017 01:41:15 -0000	1.179
+++ mk/compiler/gcc.mk	4 Jul 2017 15:10:17 -0000
@@ -23,6 +23,19 @@
  # GCC_VERSION_SUFFIX
  #	Optional suffix for GCC binaries, i.e. if the installed names are like
  #	/usr/bin/g++-5, /usr/bin/gcc-5 etc.
+#
+# PKGSRC_GCC_CXX_VERSION
+#
+#	When compiling C++ with gcc, in the general case, all programs
+#	and libraries must be compiled with the same version, or more
+#	precisely an ABI-compatibole runtime version.  This variable
+#	declares the version of gcc to be used if any C++ flavor is in
+#	USE_LANGUAGES.  The default is platform specific; the general
+#	notion is that the default is always new enough for c++11, and
+#	will typically support c++14 if gcc needs to be built anyway.
+#	Note that this is implemented via GCC_REQD, so a package with
+#	an explicit higher requirement will use that version, and that
+#	this is in general unsound.
# Package-settable variables:
  #
@@ -101,6 +114,12 @@ GCC_REQD+=	2.8.0
  GCC_REQD+=	3.0
  .endif
+# For any C++ flavor, require at least the version declared by the
+# user or the platform for use with C++.
+.if defined(PKGSRC_GCC_CXX_VERSION) && !empty(USE_LANGUAGES:Mc++)
+GCC_REQD+=	${PKGSRC_GCC_CXX_VERSION}
+.endif
+
  # Only one compiler defined here supports Ada: lang/gcc5-aux
  # If the Ada language is requested, force lang/gcc5-aux to be selected
  .if !empty(USE_LANGUAGES:Mada)
Index: mk/platform/NetBSD.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/platform/NetBSD.mk,v
retrieving revision 1.50
diff -u -p -r1.50 NetBSD.mk
--- mk/platform/NetBSD.mk	31 May 2017 22:55:01 -0000	1.50
+++ mk/platform/NetBSD.mk	4 Jul 2017 15:10:17 -0000
@@ -118,6 +118,12 @@ DEFAULT_SERIAL_DEVICE?=	/dev/null
  SERIAL_DEVICES?=	/dev/null
  .endif
+# Require gcc 4.8 (if using gcc) for compiling C++. This results in
+# the base compiler being usable on 7 and higher, and 4.8 being built
+# on 6 and earlier.
+# TODO: choose more wisely for older systems, perhaps picking gcc6.
+PKGSRC_GCC_CXX_VERSION?= 4.8
+
  # Add -mieee to CFLAGS and FFLAGS for NetBSD->=1.5V-alpha
  .for __tmp__ in 1.5[V-Z] 1.5[A-Z][A-Z]* 1.[6-9]* [2-9].*
  .  if ${MACHINE_PLATFORM:MNetBSD-${__tmp__}-alpha} != ""

I think this will work well.

I'd suggest a default of 4.8 for Linux as well. Most Linux distros, including RHEL7 derivatives, will be unaffected by this, so it's a conservative first move. This will buy us time to test the concept thoroughly without impacting most Linux users. It will also solve the vast majority of the issues with RHEL6, so I see no need for a later version at this time.

FYI, I've built MesaLib and a few other common dependencies with 4.8 and then built dependents with 4.4, without any issues. That might change when more packages start using 5 or 6.

I also suggest adding a caution in the comments/documentation. Users should be advised to rebuild previously installed packages after changing PKGSRC_GCC_CXX_VERSION, to avoid potential ABI clashes.

Regards,

    JB

--
Earth is a beta site.



Home | Main Index | Thread Index | Old Index