Opened 6 years ago

Closed 4 years ago

#55709 closed defect (worksforme)

libcxx @5.0.1_1 build fails with gcc

Reported by: potmj (Michael Pot) Owned by: jeremyhu (Jeremy Huddleston Sequoia)
Priority: Normal Milestone:
Component: ports Version: 2.4.2
Keywords: leopard universal Cc: kencu (Ken), RJVB (René Bertin)
Port: libcxx

Description (last modified by ryandesign (Ryan Carsten Schmidt))

After successfully building libcxx @5.0.1_0+universal, as part of slowly working through LibcxxOnOlderSystems, further ports now want to upgrade the libcxx dependent.

port -v installed libcxx
The following ports are currently installed:
  libcxx @3.9.1_0-universal platform='darwin 9' archs='i386' date='2017-09-09T16:36:04+1200'
  libcxx @3.9.1_1-universal platform='darwin 9' archs='i386' date='2017-12-28T01:13:04+1300'
  libcxx @5.0.1_0-universal platform='darwin 9' archs='i386' date='2017-12-30T09:05:22+1300'
  libcxx @5.0.1_0+universal (active) platform='darwin 9' archs='i386 ppc x86_64' date='2018-01-09T09:07:46+1300'

It looks like +universal is now inserting whole lot of gcc unsupported options like:-

cc1plus: error: unrecognized command line option "-std=c++11"
cc1plus: error: unrecognized command line option "-stdlib=libc++"

I can't see why @5.0.1_0 worked, & @5.0.1_1 does not. I think I have wound back all the macports.conf changes correctly, so don't see why it is asking for -stdlib=libc++ with Xcode gcc (e.g. have commented out with #cxx_stdlib libc++).

Attachments (1)

main.log (26.1 KB) - added by potmj (Michael Pot) 6 years ago.
Leopard port -v upgrade libcxx

Download all attachments as: .zip

Change History (14)

Changed 6 years ago by potmj (Michael Pot)

Attachment: main.log added

Leopard port -v upgrade libcxx

comment:1 Changed 6 years ago by RJVB (René Bertin)

Replying to a post from the ticket this discussion was started on:

Replying to potmj:

Replying to RJVB:

Interesting question: is libc++ built with GCC and itself depending on libstdc++ (instead of libc++abi, as on Linux) a viable candidate for the libc++ conversion?

It looks like it is built with gcc (g++4.2).

If GCC 4.2 is new enough to build libc++ 5.0.1 then that would be the easiest way to go, esp. if libc++abi can also be built with that compiler.

I guess the whole idea of bootstrapping is to provide a path to clang from gcc

No, I don't think so, as clang can use libc++ and libstdc++ as the runtime. The need for libc++ stems from the fact that modern C++ variants (starting with C++11) are not implemented by the system libstdc++ version on 10.8 and earlier. Apparently it is not enough just to build a more recent GCC and install its libstdc++ alongside the older system version (as is done on Linux). If that analysis is correct the need for using clang comes from the fact that GCC does not currently have a -stdlib=libc++ option. Hence my (theoretical) interest in the question if a libc++ built like it can be built on Linux would suffice.

I followed the online build-on-Linux instructions and implemented them in a "LinuxPorts" portfile for libc++ (https://github.com/RJVB/lnxports/blob/master/lang/libcxx/Portfile). This gives me

> ldd /usr/lib/libc++.so.1
        linux-vdso.so.1 =>  (0x00007ffc8a762000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f84aa0c5000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f84a9ea6000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f84a9add000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f84a98c6000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f84a95c0000)
        /lib64/ld-linux-x86-64.so.2 (0x0000556284e61000)

which works just fine when I build applications using clang++ -stdlib=libc++ ... (and according to the benchmarks, it's faster in certain domains). I can link in libraries built with GCC, which suggests that this approach could allow a less invasive libc++ conversion.

comment:2 Changed 6 years ago by kencu (Ken)

$ port -v installed libcxx
The following ports are currently installed:
  libcxx @5.0.1_1+universal (active) platform='darwin 9' archs='i386 x86_64' date='2018-01-17T18:04:28-0800'

See recommendation in: 54289#comment:7

comment:3 Changed 6 years ago by ryandesign (Ryan Carsten Schmidt)

Cc: jeremyhu removed
Description: modified (diff)
Owner: set to jeremyhu
Status: newassigned

comment:4 Changed 6 years ago by kencu (Ken)

Looks like the thing that is preventing the build with gcc is the libcxxabi buildit script, which has a number of very clang-specific flags in the EXTRA_FLAGS variable.

EXTRA_FLAGS="-std=c++11 -stdlib=libc++ -fstrict-aliasing -Wstrict-aliasing=2 \
             -Wsign-conversion -Wshadow -Wconversion -Wunused-variable \
             -Wmissing-field-initializers -Wchar-subscripts -Wmismatched-tags \
             -Wmissing-braces -Wshorten-64-to-32 -Wsign-compare \
             -Wstrict-aliasing=2 -Wstrict-overflow=4 -Wunused-parameter \
             -Wnewline-eof -D_LIBCPP_BUILDING_LIBRARY"

probably have to sort out a proper bunch of these flags that are compatible with gcc and then set up a gcc patch for them.

In the meantime, libcxx (and libccabi) will only build with clang.

Last edited 6 years ago by kencu (Ken) (previous) (diff)

comment:5 Changed 6 years ago by kencu (Ken)

Summary: libcxx @5.0.1_1+universal: upgrade failure on Leopardlibcxx @5.0.1_1 build fails with gcc

comment:6 in reply to:  2 Changed 6 years ago by RJVB (René Bertin)

Replying to kencu:

See recommendation in: 54289#comment:7

Why do a universal build (if the host in question isn't 64bit, that is)?

that may be why I redid the port completely in order to build it on Linux.

I no longer have easy access to such an old OS X version otherwise I'd explore following the build instructions for Linux myself. In a sense 10.6 and earlier are more like Linux than 10.9 and later, in the sense that the system compiler and C++ runtime are GCC-based. (I might still try out of curiosity, on 10.9; I think I still have a working apple-gcc 4.2 on there)

comment:7 Changed 6 years ago by kencu (Ken)

Jeremy has written up certain Portfiles to force universal builds for certain parts of the toolchain. He is not going to change that, nor should he IMHO.

potmj currently has his universal_archs set to i386 ppc x86_64 and this is problematic when building with clang. potmj ran into this issue, and has blown up his toolchain trying to get around it. He's now trying to build libcxx with gcc-4.2, which will never work with the toolchain the way Jeremy has it written.

Jeremy uses the buildit scripts to prevent the requirement for cmake which is a circular dependency on older systems the way MacPorts is set up. You have found out that you can build libcxx using the cmake build. That works for you on linux because building c++11 capable versions of gcc does not depend on cmake, and going that route, there is no circular dependency issue. It would work for us on MacPorts too, should we decide to set up the build that way. But we are not going to build cmake with gcc on MacPorts for 100 reasons we all know well. We are going to build libcxx with the buildit script, and the buildit script is not presently gcc-friendly.

So potmj can either go through tremendous hoops that probably only 5 or 6 of us would understand to make this work with gcc for no purpose at all, or he can simply change his universal_archs to i386 x86_64 and then everything will be fine again (once he gets back on the train with his toolchain, and re-enables clang as his default compiler).

Just because his universal_archs are set to i386 x86_64 doesn't mean he will have to build everything universal. There is no need to do that. However, when one of Jeremy's Portfiles forces universal, it will work instead of break.

Last edited 6 years ago by kencu (Ken) (previous) (diff)

comment:8 Changed 6 years ago by RJVB (René Bertin)

I'm trying to help our potmj with his bootstrapping problem, not trying to tell MacPorts or Jeremy what to do.

But FWIW, port:cmake could easily provide a version not requiring C++11 on platforms where this is appropriate.

Just because his universal_archs are set to i386 x86_64 doesn't mean he will have to build everything universal.

Yet this is what will happen unless you add -universal each time you don't want it, and most ports are not available as universal binary builds. Even installing the "wrong" port +universal means you can end up with all dependencies installed that way too, including big ones like clang.

comment:9 Changed 6 years ago by kencu (Ken)

All macports.conf are set up with a default universal_archs. Even if one is not specifically added to macports.conf there is already a default for that setting in base. That setting does not force everything to build universal. It only says what universal would be, if universal is called.

And on a 10.5 Intel machine, universal should not include ppc if you're following LibcxxOnOlderSystems unless you are prepared for the ramifications of that.

Re: cmake -- I also have a personal cmake39 port <https://github.com/kencu/myports/tree/master/devel/cmake39> that doesn't require c++11 as well, but MacPorts has decided not to do that to keep things coherent and maintainable, and Ryan spent the better part of a week working on cmake to make sure it could bootstrap the current version of cmake on all systems (except 10.4, which doesn't build the current cmake).

Last edited 6 years ago by kencu (Ken) (previous) (diff)

comment:10 Changed 6 years ago by RJVB (René Bertin)

I wasn't thinking about a separate port, but that the main cmake port could provide a slightly earlier version on systems where that's appropriate. That's not unheard of, gives hardly more maintenance pressure (3.9 no longer evolves, nor do the target systems) and IIRC the cmake PG is already set up to add a path-style dependency. It was just a thought, and IMVHO this would be a decision for the cmake port maintainer.

Anyway, let's not pollute this ticket with things that won't help the OP.

comment:11 Changed 6 years ago by potmj (Michael Pot)

Many thanks for everyones good thoughts on all this.

From a macports user view, 5.0.1_0 compiled libc++ (& libc++abi) +universal with gcc 4.2, and 5.0.1_1 fails under some conditions, when they upgrade outdated.

On 10.5, I think macports.conf universal_arches defaults to "i386 ppc". It seems 10.5.8 executes ppc, i386, and x86_64, - at least for simple hello world tests. I was testing LibcxxOnOlderSystems and had got all the way to a clang-3.7 that would build simple universals, with the exception of a broken libclang_rt.osx.a with ppc, until the bump to 5.0.1_1.

Being able to build libc++ with a convinent gcc in all cases, will remove dependencies and is helpful to bootstrap clang in a simple way (and those trying to cross compile for 10.4, etc). Rebuilding libc++ later on with better optimization and/or additional arches, is always an option, at the cost of adding an extra step to the clang bootstrap. I notice lots of the apple libraries are universal with 4 arches, so I guess that helps avoid having a missing arch at the bottom of a dependency chain.

Even though libc++abi & libc++ are built with gcc, otool shows they are not dependent on libstdc.dylib

Setting universal_arches to "i386 x86_64", as a temporary work around does get 5.0.1_1 built with gcc.

I worry about upgrading ports, as the web of dependencies goes forever. With many old things installed +universal, upgrade often breaks, so having a tool chain with the same code generation ability as the old Xcode seems a good clang bootstrap goal. I agree with RJVB that you end up with +universal dependencies easily. Even though they might be big, that would be OK, if they worked. Hence a focus on having good +universal libraries.

Thanks for pointing out the EXTRA_FLAGS variable. My portfile skills are probably not up to working out why that line is now invoked in the wrong way for ppc code generation on intel.

I noticed this WARNING flash past, so maybe this has further implications for the port....

buildit is no longer supported and will be removed in the next week!

This might be a problem, perhaps requiring the suggested move to a cmake that can be built with Xcode, or something. I am sure Jeremy has a better understanding on the significance of this, I have no clue.

Many thanks Michael

comment:12 Changed 6 years ago by kencu (Ken)

I'm glad that worked for you.

However, I had some time to redo the experimental ppc section of the LibcxxOnOlderSystems instructions, and guess what? It still works:

$ port -v installed libcxx
The following ports are currently installed:
  libcxx @5.0.1_1+universal (active) platform='darwin 9' archs='i386 ppc x86_64' date='2018-01-20T09:09:03-0800'

libcxx still installs with a ppc slice without any trouble on Leopard, building it with clang-3.7.

The OP's issue is something different yet. Perhaps the "undoing" of the instructions somehow led to gcc-4.2 being called in.

The idea that gcc won't build libcxx with the existing MacPorts Portfile remains accurrate. Exactly what failed for the OP to lead to gcc being asked to build libcxx is less clear.

comment:13 Changed 4 years ago by kencu (Ken)

Resolution: worksforme
Status: assignedclosed

Nothing to fix here.

Note: See TracTickets for help on using tickets.