Opened 3 years ago

Closed 2 months ago

#58898 closed defect (fixed)

libcxx bootstrapping needs a method to upgrade to the +emulatedtls variant on 10.6 and less

Reported by: kencu (Ken) Owned by: kencu (Ken)
Priority: Normal Milestone:
Component: ports Version:
Keywords: snowleopard leopard tiger Cc: jmroot (Joshua Root), mojca (Mojca Miklavec), cjones051073 (Chris Jones), kencu (Ken), dliessi (Davide Liessi), catap (Kirill A. Korinsky), barracuda156
Port: libcxx

Description

during automatic bootstrapping of 10.6 and less, libcxx is installed as a first step, building with clang-3.4.

As clang-3.4 does not support building libcxx +emulatedtls, libcxx is first built without +emulatedtls. The process then leads to the installation of clang-5.0 or greater, and these compilers do support building libcxx +emulatedtls.

The libcxx Portfile will build libcxx +emulatedtls if a suitable compiler is installed that can build it, but it presently requires a manual rebuild to force the upgrade.

For a fully functional older system, this upgrade should be automatic.

One option might be to put a revision increase by 1 in the Portfile, in the block that tests if libcxx +emulatedtls can be built and enables it if so.

Change History (42)

comment:1 Changed 3 years ago by kencu (Ken)

Owner: kencu deleted

comment:2 Changed 3 years ago by mf2k (Frank Schima)

Cc: jeremyhu removed
Owner: set to jeremyhu

comment:3 Changed 3 years ago by kencu (Ken)

jeremy is not going to fix this. At this point in time I might as well consider owning this port, even though I deleted myself from owning this ticket a week ago :}

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

comment:4 Changed 3 years ago by mojca (Mojca Miklavec)

Cc: mojca added

comment:5 Changed 3 years ago by cjones051073 (Chris Jones)

Cc: cjones051073 added

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

so the revision +1 idea if a clang >= 5.0 is found is one way to force the update.

could also exist a libcxx-bootstrap port.

Maybe that is more appropriate?

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

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

the revision +1 approach will get pretty confused by the buildbot's portindex. That's probably not a good idea, in the end...

comment:8 Changed 3 years ago by cjones051073 (Chris Jones)

I also would be wary of an approach that plays games with the revision... seems like a recipe for all sorts of problems.

Last edited 3 years ago by cjones051073 (Chris Jones) (previous) (diff)

comment:9 Changed 3 years ago by cjones051073 (Chris Jones)

I think a dedicated 'bootstrap' version of libcxx that the first bootrap phase of the clang builds use, is the way to go. It would then later on get replaced by the main libcxx build.

comment:10 Changed 3 years ago by kencu (Ken)

shame we can't depend on a port variant..

So libcxx on < 10.7 would have to depend on libcxx-bootstrap. Tha's simple enough. But it would also have to depend on some clang >= 5.0, and that is circular.

unless clang can be satisfied by libcxx-bootstrap. which it can.

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

comment:11 Changed 3 years ago by cjones051073 (Chris Jones)

I was more thinking of something like.... clang-3.4 declares a path like dependency, something like path:lib/something.dylib:libcxx-bootstrap so when it is first built it triggers the installation of libcxx-bootstrap. Then, later on, when clang5 etc. are built they keep the port:libcxx dep. Finally, libcxx would have to have some logic added to forcibly remove libcxx-bootstrap when it is built/installed, so effectively it replaces it.

Last edited 3 years ago by cjones051073 (Chris Jones) (previous) (diff)

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

It's complex. clang-3.4 can't depend on any version of libcxx.

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

libcxx just overwrites to previous, so doesn't have to forcibly remove it ... but then you cannot tell which libcxx is installed with a path dependency either...

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

comment:14 Changed 3 years ago by cjones051073 (Chris Jones)

Hmmmm. How about adding a libcxx-bootstrap sub-port to libcxx, that does everything identically apart from it does not enable emulatedtls whereas libcxx does. Basically give libcxx and libcxx +emulatedtls different port names so you can then more easily tell which is currently installed....

comment:15 Changed 3 years ago by cjones051073 (Chris Jones)

b.t.w. you say clang-3.4 does not itself depend on libcxx. But, something in the dep tree must be the thing that first triggers its installation ? Could you not then make that depend on path:lib/something.dylib:libcxx-bootstrap ?

comment:16 in reply to:  14 ; Changed 3 years ago by kencu (Ken)

Replying to cjones051073:

Hmmmm. How about adding a libcxx-bootstrap sub-port to libcxx, that does everything identically apart from it does not enable emulatedtls whereas libcxx does.

Chris - that is exactly what I suggested :>

But -- you can't tell which one is installed with a path dep.

I would work on this, but history tells me Josh will parachute in with the fix any second now...

comment:17 Changed 3 years ago by kencu (Ken)

Now -- if I actually was a computer science major, perhaps I would have folded the emulated_tls objects in somewhere else, like perhaps in ld64 and adding in tapi, like Iains appears to have done here <https://github.com/iains/tapi/commit/aeab0de3e9ec61c97d8f3cd86928983eba59de49> .

But I did it the way I understood how to do it, using existing libcxx tools, so we have the setup we have.

Of interest, it is pretty simple to build libcxx +emulated_tls with gcc with some modest hackery <https://github.com/kencu/macports-ports/commits/libcxxfixupgcc> . That's what I do on PowerPC, but I knew/know that is not a method acceptable to MacPorts, so never bothered to propose it here.

comment:18 in reply to:  16 Changed 3 years ago by cjones051073 (Chris Jones)

Replying to kencu:

Replying to cjones051073:

Hmmmm. How about adding a libcxx-bootstrap sub-port to libcxx, that does everything identically apart from it does not enable emulatedtls whereas libcxx does.

Chris - that is exactly what I suggested :>

But -- you can't tell which one is installed with a path dep.

I guess not with path... But we could have each of the flavours of libcxx install some special info file which says which it is (via the file name for instance), and then use that somehow to determine if libcxx-bootstrap is in fact installed, and thus needs to be forcibly replaced with libcxx....

I would work on this, but history tells me Josh will parachute in with the fix any second now...

Last edited 3 years ago by cjones051073 (Chris Jones) (previous) (diff)

comment:19 Changed 3 years ago by kencu (Ken)

You're right -- there is a special include file in /usr/include that I only include with +emulated_tls variant. We could path dep on that.

Edit: nope, I'm wrong. I just expose a new function in the header, but it's not a totally new header. So we would still need a breadcrumb, as Chris said.

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

comment:20 Changed 3 years ago by kencu (Ken)

Cc: kencu added

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

I have been wrapping my head around this, but I always wind up back where I started with circular dependencies if there are to be no manual steps.

The simplest thing would be to make the +emulated_tls variant a default variant, and have Ryan build it manually one time on 10.6. Then it's in the archives, and can be downloaded and installed. But it's a manual step.

It is trivial to make up a port that could either be called libcxx-bootstrap or libcxx +bootstrap that builds the current non-emulated-tls libcxx. And then the standard libcxx port could enable emulated_tls by default. libcxx could depend on libcxx-bootstrap if there is nothing at /usr/lib/libc++.dylib, for example.

But for that to work, everything that is in the line to build libcxx would have also be satisfied by libcxx-bootstrap instead of just by libcxx, and that is a lot of ports leading all the way up to clang-9.0. It's messy.

Alternately, we could build libcxx 7.0 using gcc7 or gcc8. We can bootstrap to gcc7 right now from the base OS, and to gcc8. And those compilers can build libcxx 7.0. Totally different than what we do now, and there is going to be something messy about the libcxxabi ABI linking into gcc I think to be managed somehow.

I could build libcxx mostly with clang-3.4, but use gcc7 to build the troublesome cxa_thread_atexit.cpp file that needs a __thread supporting compiler. That's a bit ugly. Hard to see how that would be the best way forward.

Or I could just download a fully intact, pre-build libcxx+universal+emulated_tls from some webserver or github repo where I keep it, and be done with it. That is dead simple.

Last edited 2 years ago by ryandesign (Ryan Schmidt) (previous) (diff)

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

Owner: changed from jeremyhu to kencu

comment:23 Changed 21 months ago by dliessi (Davide Liessi)

Cc: dliessi added

comment:24 Changed 17 months ago by kencu (Ken)

I actually can build libcxx/libcxxabi by bootstrapping with gcc8.

gcc8 automatically builds llvm & clang, and then uses that clang to build libcxx/libcxxabi with all the toys enabled.

but gcc8 still has deps on things that require libc++, in the end, so we're no further ahead.

I am very (very) tempted to just put up my libcxx built system_roots for 10.6, 10.5, and 10.4, all of which have thread_local enabled properly in them, and have the libcxx port install those binaries. And if I ever get to releasing the clang-7.0 for PPC I have been using, I can add the libc++ for PPC there too.

I can leave some instructions in the wiki on how people can build their own.

comment:25 Changed 8 months ago by catap (Kirill A. Korinsky)

Ken, just an idea: introduce libcxx-bootstrap port which is built with -emulatedtls. After that update dependencies from port:libcxx to path:...:libcxx and use libcxx-bootstrap as build dependency for libcxx.

I feel that it should be enough to bootstrap libcxx with +emulatedtls.

Have I missed something?

comment:26 Changed 8 months ago by catap (Kirill A. Korinsky)

Cc: catap added

comment:27 Changed 8 months ago by kencu (Ken)

Thought of that (see above comments) and started it before, but:

  1. everything that is built against libcxx-bootstrap has to be sequestered in it's own "bootstrap" subprefix (already started that, see cmake-bootstrap and others).
  2. the whole infrastructure that leads to being able to build clang-5.0. has to be there (that is a lot!)
  3. that clang-5.0 will always be linked against the wrong libcxx (libcxx-bootstrap) and all of it's supports
  4. those ports are something of a moving target, ie they change at times with updates to things (that can be overcome).

So -- I abandoned the libcxx-bootstrap idea for those reasons, but feel free to go for it if you think you can make it work and keep it working!

I thought the clean gcc -> clang-5.0 linked against clean gcc approach was more robust, myself.

That is actually pretty doable, for someone with enough time and enthusiasm.

Last edited 8 months ago by kencu (Ken) (previous) (diff)

comment:28 Changed 8 months ago by catap (Kirill A. Korinsky)

Ken, another question: have you tried to patch libcxx to fix build under old gcc?

comment:29 Changed 8 months ago by kencu (Ken)

It does, with some mess. I last did it in 2018 on 10.5 PPC. But it then has to be linked against the old libgcc parts forever to get the supports it needs, unless someone wants to figure out how to static link libgcc into it.

And then libcxx is built differently, with gcc, than the way Apple does it.

So, in. the end, I figured if you're going to do that (build libcxx with an isolated gcc) just build clang-5.0 with the isolated gcc instead, and let all the normal existing MacPorts portfiles stay as they are.

At least, that is what I thought.

comment:30 Changed 8 months ago by kencu (Ken)

Here's the gcc7-bootstrap I was working on last year

https://github.com/macports/macports-ports/pull/11641

Probably today I would use gcc10 instead, maybe.

Last edited 8 months ago by kencu (Ken) (previous) (diff)

comment:31 Changed 8 months ago by kencu (Ken)

Getting it to build on 10.6.8 was not too hard.

Getting it to build reliably on Tiger/Leopard PPC and Intel without "Bootstrap Comparison Failures" etc was harder.

Last edited 8 months ago by kencu (Ken) (previous) (diff)

comment:32 Changed 8 months ago by catap (Kirill A. Korinsky)

I see, that seems like a nightmare. Huh.

comment:33 Changed 8 months ago by kencu (Ken)

It is doable... at the time it was just me, and I was deep in nutty discussions about other things.

Now there is you and Evan who are up to speed at least, and a few others, and it could be more of a group effort for you.

Maybe ;>

comment:34 Changed 8 months ago by catap (Kirill A. Korinsky)

Wired idea: let bump revision of libcxx. If I understand things right it should allow to build libcxx with +emulatedtls what allows to prebuild by buildbots tons of ports.

comment:35 in reply to:  34 Changed 8 months ago by kencu (Ken)

Replying to catap:

Wired idea: let bump revision of libcxx. If I understand things right it should allow to build libcxx with +emulatedtls what allows to prebuild by buildbots tons of ports.

Yes, that might work if the logic was changed in the libcxx port a bit. I thought of this too, at one time.

ie, when processing sudo port install libcxx:

if no /usr/lib/libc++.dylib
  then build a bootstrap libc++.dylib (partly broken)
else
  skip a bunch of bootstrapping and install clang-5.0 somehow then use it to to rebuild libc++.dylib (not broken)

but this, in the end couldn't fly as too -- random -- it was felt, rightly I guess.

I also thought of having a built-in revbump somehow, where the revision of libcxx bumps by +1 if clang-5.0 or greater is installed, so it would update itself second time through:

https://trac.macports.org/ticket/58898#comment:6

but that was also, in the end, no bueno.

Last edited 8 months ago by kencu (Ken) (previous) (diff)

comment:36 Changed 8 months ago by catap (Kirill A. Korinsky)

After some time to think: I really love an idea to finish minimal bootstrap toolchain: gcc10 (testing right now), cmake (you did it) and maybe something else which is required to build some clang which is depends on how much additional work it needed.

comment:37 Changed 8 months ago by catap (Kirill A. Korinsky)

In d188293ef2d278484389445ba437ecd5087ab04e/macports-ports (master):

gcc10-bootstrap: new port

See: #58898

comment:38 Changed 7 months ago by barracuda156

Cc: barracuda156 added

comment:39 in reply to:  37 Changed 7 months ago by barracuda156

Replying to catap:

In d188293ef2d278484389445ba437ecd5087ab04e/macports-ports (master):

gcc10-bootstrap: new port

See: #58898

Thanks to your gcc10-bootstrap we got gcc11 on PPC, and that in turn builds llvm-6.0 and libtapi. Not sure of libcxx yet, but things did improve: libtapi was failing earlier, for example.

comment:40 Changed 7 months ago by kencu (Ken)

llvm-6.0 will build with gcc5

comment:41 Changed 7 months ago by kencu (Ken)

And of course, just because it will build on PPC does not mean it will actually work... as we all know, llvm builds broken code on PPC Darwin.

Someday, somebody might straighten llvm out for PowerPC Darwin maybe. Iain, once he retires, perhaps :>

comment:42 Changed 2 months ago by catap (Kirill A. Korinsky)

Resolution: fixed
Status: assignedclosed

In 2a6125bbce37dabecf26246a253e79e9f58eb820/macports-ports (master):

libcxx: bootstrap with +emulated_tls on 10.6

Closes: #58898

Note: See TracTickets for help on using tickets.