Consequences of using MacPorts GCC as a fallback compiler on PowerPC

Ryan Schmidt ryandesign at macports.org
Thu Mar 22 23:11:18 UTC 2018


Ken recently changed the compiler fallbacks for old systems to remove Xcode's gcc-3.3 entirely (presumably on the grounds that anything old enough to require it could just specify "configure.compiler gcc-3.3", as ports like anubis and stegdetect already do), and more importantly to add macports-gcc-6 and macports-gcc-7 when on PowerPC (instead of macports-clang-3.3 or macports-clang-3.4 which are now used only on Intel since clang does not work on PowerPC).

https://github.com/macports/macports-base/pull/62

I am concerned that this breaks C++ ports on PowerPC, and wrote this comment on the PR today:

> Ryan wrote:

> 

>> Doesn't this break C++ ports on PowerPC? You cannot share objects between C++ libraries; you will crash if you try. And this change makes it so that some ports (for example some library foolib) might compile with /usr/bin/g++-4.2 (and link with /usr/lib/libstdc++.6.dylib) as they did before, while ports that blacklist old GCC (for example a program barprog that uses the aforementioned library) might compile with /opt/local/bin/g++-mp-6 (and link with /opt/local/lib/libstdc++.6.dylib). When the barprogprogram allocates a C++ object using /usr/lib/libstdc++.6.dylib and passes it to the foolib library, and it tries to work with that object using /opt/local/lib/libstdc++.6.dylib, it will crash.
>> 
>> We have had a longstanding policy of not using FSF GCC as a general purpose compiler for exactly this reason and I'm very nervous not only about this change in general but also that this change was immediately merged to the stable 2.4 branch.
>> 
>> The only reason why we're able to use gcc6's C++ compiler in the cxx11 1.1 portgroup is that we also put -D_GLIBCXX_USE_CXX11_ABI=0 into CXXFLAGS. Don't we need to do that in MacPorts base now as well, when macports-gcc-6 is chosen due to the above changes (but not when it is chosen in any other existing way, as that would break all the ports that explicitly use gcc6 today)? And if so, how do we do that?

Ken replied by private email, and subsequently gave me permission to share his reply on this list:

Ken wrote:

> Happy to work through this and any similar concerns with you.
> 
> The existing situation for 10.4 and 10.5 PPC was that if gcc-4* series was blacklisted, then clang-3.4 was chosen, and this always failed. So that was no good, and there are - how many - dozens of open tickets about this? So gcc6 and gcc7 are the only other compilers available to use at present, and we had to go down this road to fix this up.
> 
> You are correct that this might surreptitiously build c++11 software with the wrong c++11ABI selected, if the port blacklisting lead to gcc6 being used and if the port author didn't add the c++11 PortGroup to add the flag.  There is really only a small subset of the c++11 ABI affected by this, but it could happen.
> 
> 
> 
> To fix that, we could indeed always add -D_GLIBCXX_USE_CXX11_ABI=0 into CXXFLAGS. on PPC if gcc6+ was being used. I would be in favour of that, and as far as I can tell, there is nothing could break from doing that. 
> 
> c++11 software on PPC should ALWAYS by default be compiled in ABI4 compatible mode. I fully agree. There is no situation I can think of where it should ever be otherwise. I am happy to add that bit to portconfigure.tcl if we find that acceptable. 
> 
> 
> There is another (in my opinion simpler and better) way to accomplish the same end, and this is what the linux distros did that wanted to accomplish this feat of mixing pre-ABI-5 software and post-ABI-5 software ...
> 
> Build libgcc to default into ABI4-compatible mode always.  This is done with this flag when building libgcc:
> 
> configure.args-append --with-default-libstdcxx-abi=gcc4-compatible
> 
> Then all software that links against that library is in ABI4-compatible mode always (unless you force it otherwise), which is exactly what you want, and if that is deemed the better approach, I would be in favour of putting something like this in the libgcc Portfile:
> 
> platform darwin powerpc {
>     default_variants-append +defaultabi4
> }
> variant defaultabi4 description "use gcc4 compatible ABI" {
>     configure.args-append --with-default-libstdcxx-abi=gcc4-compatible
> }
> 
> 
> The advantage to that is:
> 1. works on software that doesn't necessarily always respect the cxxflags correctly.
> 2. most likely never need think about it again
> 3. could potentially be overridden by an individual port by adding -D_GLIBCXX_USE_CXX11_ABI=1  if there was ever a reason to do that (that I can't think of just now).
> 
> 
> After that, we just need to go through all the Portfiles and change the blacklisting from *gcc* to *gcc-4* and we should be in business.


The documentation says:

https://gcc.gnu.org/onlinedocs/gcc-5.2.0/libstdc++/manual/manual/using_dual_abi.html

> Although the changes were made for C++11 conformance, the choice of ABI to use is independent of the -std option used to compile your code, i.e. for a given GCC build the default value of the _GLIBCXX_USE_CXX11_ABI macro is the same for all dialects. This ensures that the -std does not change the ABI, so that it is straightforward to link C++03 and C++11 code together.

There are already ports out there, and installed on user systems, and binaries being distributed that were built by our buildbot, that were built with a MacPorts gcc without -D_GLIBCXX_USE_CXX11_ABI=0 set. These would be ports that do not use the cxx11 1.1 portgroup and that don't use C++11. They might use the compilers 1.0 portgroup, or they might set "configure.compiler macports-gcc-XX" directly. Either way, they are using the new ABI.

If you wanted to change the libgcc port so that it defaults to the old ABI, then after doing so we would have to identify all the ports described previously, that had been built with the new ABI, and increase their revisions to rebuild them to use the old ABI.

If instead you want to add -D_GLIBCXX_USE_CXX11_ABI=0 to the standard set of CXXFLAGS in MacPorts base, either just on PowerPC or on all systems, then we not only have to revbump the ports that were using the old ABI, but we also have to have those ports call the [macports_version] procedure and check that they're running on MacPorts 2.4.3 or later.


I am opposed to adding a defaultabi4 variant to the libgcc port. I do not want users to be able to change the setting, since the setting is infectious and affects other ports that are built with that libgcc. We want reproducible builds, and allowing a variant of the libgcc port to change how other ports build makes those other port builds non-reproducible.





More information about the macports-dev mailing list