Opened 3 years ago

Closed 3 years ago

#62881 closed defect (worksforme)

gcc11: port is deactivating libgcc10, resulting in broken dependent ports

Reported by: mascguy (Christopher Nielsen) Owned by: cjones051073 (Chris Jones)
Priority: Normal Milestone:
Component: ports Version:
Keywords: Cc:
Port: gcc11

Description (last modified by mascguy (Christopher Nielsen))

When updating ports today, I notice that libgcc10 was deactivated, despite a number of ports having a lib or runtime dependency on it.

Reviewing new port gcc11, it looks like it's occurring there:

    pre-activate {
        if {![catch {set installed [lindex [registry_active libgcc10] 0]}]} {
            # Extract the epoch of the installed libgcc9
            set _epoch [lindex $installed 5]
            # If < 3 need to deactivate
            if {[vercmp $_epoch 6] < 0} {
                registry_deactivate_composite libgcc10 "" [list ports_nodepcheck 1]
            }

Change History (33)

comment:1 Changed 3 years ago by mascguy (Christopher Nielsen)

Description: modified (diff)

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

this is intentional, as the update migrates from libgcc10 to libgcc11 as the primary runtime provider.

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

no ports (other than the specific gccX ports) should depend on a specific libgccX. They should all depend on libgcc which is designed to then bring in the correct runtime.

comment:4 Changed 3 years ago by mascguy (Christopher Nielsen)

Ports like openmpi-gcc10 and mpich-gcc10 do indeed directly depend on libgcc10.

comment:5 Changed 3 years ago by mascguy (Christopher Nielsen)

What was the goal of removing libgcc10? We're not doing that for older libgccXX versions...

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

ok, but even then it is fine as libgcc10 now depends on libgcc11 (via libgcc) so once the update is complete then will still get the complete gcc10 runtime.

no, libgcc10 is not removed, it is required to satisfy the dependency tree.

This behaviour is all by design, to ensure all gcc ports share the same consistent runtime.

comment:7 in reply to:  6 ; Changed 3 years ago by mascguy (Christopher Nielsen)

Replying to cjones051073:

ok, but even then it is fine as libgcc10 now depends on libgcc11 (via libgcc) so once the update is complete then will still get the complete gcc10 runtime.

no, libgcc10 is not removed, it is required to satisfy the dependency tree.

This behaviour is all by design, to ensure all gcc ports share the same consistent runtime.

By deactivating libgcc10, the port is subsequently removed by port reclaim. So yes, you are breaking dependent ports.

Please fix this...

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

So, this is how it works. libgcc decides which is the primary runtime for a given OS. For most but the very oldest it is now provided by libgcc11 which it depends on

Oberon ~/Projects/MacPorts/ports > port info libgcc  
libgcc @4.0 (lang)
Variants:             universal

Description:          Provides the appropriate gcc runtime. Picks the version to use based on macOS version.
Homepage:             https://www.macports.org/

Library Dependencies: libgcc11
Conflicts with:       libgcc-devel
Platforms:            darwin
License:              BSD
Maintainers:          none

libgcc11 then contains the complete runtime provided by gcc11

 > port contents libgcc11
<snip>
/opt/local/lib/libgcc/libasan.6.dylib
  /opt/local/lib/libgcc/libatomic.1.dylib
  /opt/local/lib/libgcc/libgcc_ext.10.4.dylib
  /opt/local/lib/libgcc/libgcc_ext.10.5.dylib
  /opt/local/lib/libgcc/libgcc_s.1.dylib
  /opt/local/lib/libgcc/libgfortran.5.dylib
  /opt/local/lib/libgcc/libgomp.1.dylib
  /opt/local/lib/libgcc/libitm.1.dylib
  /opt/local/lib/libgcc/libobjc-gnu.4.dylib
  /opt/local/lib/libgcc/libquadmath.0.dylib
  /opt/local/lib/libgcc/libssp.0.dylib
  /opt/local/lib/libgcc/libstdc++.6.dylib
  /opt/local/lib/libgcc/libubsan.1.dylib
  /opt/local/lib/libstdc++.6.dylib

The older libgccX then *only* provide older versions of the dylibs than thosein the newer ones. e.g.

Oberon ~/Projects/MacPorts/ports > port contents libgcc10   
Port libgcc10 contains:
  /opt/local/share/doc/libgcc10/README
Oberon ~/Projects/MacPorts/ports > port contents libgcc9 
Port libgcc9 contains:
  /opt/local/lib/libgcc/libasan.5.dylib

what the above shows is gcc10 does not add any older libraries, the README is there because a port must install at least one file, but libgcc9 provides an older version of the address sanitiser library.

comment:9 in reply to:  7 ; Changed 3 years ago by cjones051073 (Chris Jones)

Replying to mascguy:

Replying to cjones051073:

ok, but even then it is fine as libgcc10 now depends on libgcc11 (via libgcc) so once the update is complete then will still get the complete gcc10 runtime.

no, libgcc10 is not removed, it is required to satisfy the dependency tree.

This behaviour is all by design, to ensure all gcc ports share the same consistent runtime.

By deactivating libgcc10, the port is subsequently removed by port reclaim. So yes, you are breaking dependent ports.

Please fix this...

if reclaim is removing it then it is not being depended on by any installed port.

comment:10 in reply to:  9 ; Changed 3 years ago by mascguy (Christopher Nielsen)

Replying to cjones051073:

if reclaim is removing it then it is not being depended on by any installed port.

The port is being removed by port reclaim because it's been deactivated.

Test locally please.

comment:11 in reply to:  10 Changed 3 years ago by cjones051073 (Chris Jones)

Replying to mascguy:

Replying to cjones051073:

if reclaim is removing it then it is not being depended on by any installed port.

The port is being removed by port reclaim because it's been deactivated.

Test locally please.

I did, extensively. I installed all the (lib)gcc ports from before the gcc11 update, and then ran a regular 'port sync ; port upgrade outdated'. what happens is this

  • libgcc11 needs to be installed because libgcc now depends on it.
  • libgcc11 cannot be installed whilst the *current* libgcc10 is activated because it conflicts. this is why libgcc11 has to force deactivate it first.
  • once libgcc11 is installed port can carry on upgrading other ports, which should involve reinstalling the new libgc10, which no longer conflicts.

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

you are going to have to send me the exact sequence of steps to reproduce, as I have never seen problems myself.

comment:13 Changed 3 years ago by mascguy (Christopher Nielsen)

Okay, so why does libgcc11 conflict with libgcc10 in the first place? libgcc8, libgcc9, and libgcc10 all coexist peacefully while active.

comment:14 Changed 3 years ago by mascguy (Christopher Nielsen)

And have you run port reclaim locally?

comment:15 in reply to:  14 ; Changed 3 years ago by cjones051073 (Chris Jones)

Replying to mascguy:

And have you run port reclaim locally?

yes

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

Replying to mascguy:

Okay, so why does libgcc11 conflict with libgcc10 in the first place? libgcc8, libgcc9, and libgcc10 all coexist peacefully while active.

It only temporarily conflicts whilst the upgrade is happening. Before the update libgcc10 provides the primary runtime, whilst after the update libgcc11 does. The problem is the update process tries to install the new libgcc11 before the old libgcc10 is updated, leading to a temporary situation where they conflict.

comment:17 in reply to:  15 Changed 3 years ago by mascguy (Christopher Nielsen)

Replying to cjones051073:

Replying to mascguy:

And have you run port reclaim locally?

yes

To be more specific, did you answer 'Y' to all prompts? Or did you run port -N reclaim, which implies Yes for everything?

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

I said yes to everything

comment:19 in reply to:  16 ; Changed 3 years ago by mascguy (Christopher Nielsen)

And was libgcc10 still installed, and active, afterward?

comment:20 in reply to:  16 ; Changed 3 years ago by mascguy (Christopher Nielsen)

Replying to cjones051073:

Replying to mascguy:

Okay, so why does libgcc11 conflict with libgcc10 in the first place? libgcc8, libgcc9, and libgcc10 all coexist peacefully while active.

It only temporarily conflicts whilst the upgrade is happening. Before the update libgcc10 provides the primary runtime, whilst after the update libgcc11 does. The problem is the update process tries to install the new libgcc11 before the old libgcc10 is updated, leading to a temporary situation where they conflict.

Can you clarify what you mean by "before the old libgcc10 is updated?"

comment:21 in reply to:  19 Changed 3 years ago by cjones051073 (Chris Jones)

Replying to mascguy:

And was libgcc10 still installed, and active, afterward?

yes

comment:22 Changed 3 years ago by mascguy (Christopher Nielsen)

Is there an update to libgcc10, that eliminates the conflict? As that port wasn't updated.

comment:23 in reply to:  20 ; Changed 3 years ago by cjones051073 (Chris Jones)

Replying to mascguy:

Replying to cjones051073:

Replying to mascguy:

Okay, so why does libgcc11 conflict with libgcc10 in the first place? libgcc8, libgcc9, and libgcc10 all coexist peacefully while active.

It only temporarily conflicts whilst the upgrade is happening. Before the update libgcc10 provides the primary runtime, whilst after the update libgcc11 does. The problem is the update process tries to install the new libgcc11 before the old libgcc10 is updated, leading to a temporary situation where they conflict.

Can you clarify what you mean by "before the old libgcc10 is updated?"

Not really sure how else I can put it...

The gcc ports are all self consistent, before and after the update. The problem is to get to the consistent state after the update *both* libgcc11 and libgcc10 have to be updated. Now, things can only happen one at a time so if port decides to install libgcc11 before it has updated the old libgc10, then we hit this situation. The force deactivate resolves it.

comment:24 in reply to:  22 Changed 3 years ago by cjones051073 (Chris Jones)

Replying to mascguy:

Is there an update to libgcc10, that eliminates the conflict? As that port wasn't updated.

yes it was. https://github.com/macports/macports-ports/commit/8759dbd93fb71e89a59cd58be4ca2d854db24535

comment:25 in reply to:  23 Changed 3 years ago by mascguy (Christopher Nielsen)

Replying to cjones051073:

The gcc ports are all self consistent, before and after the update. The problem is to get to the consistent state after the update *both* libgcc11 and libgcc10 have to be updated. Now, things can only happen one at a time so if port decides to install libgcc11 before it has updated the old libgc10, then we hit this situation. The force deactivate resolves it.

This happened because, like many users, I had to defer my update to gcc11 until after the buildbots provided updated binaries for your subsequent gcc11 patch. (The JIT patch from Homebrew, I think?)

So gcc10 (and libgcc10) were already updated when I was finally able to update gcc11 this morning.

Yet, despite being up-to-date, libgcc10 was still deactivated by the gcc11/libgcc11 update.

And since libgcc10 was already updated, no new update came along to provide an active port. Resulting in it being uninstalled during port reclaim.

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

I don't see how that could happen. The updated libgcc10 has an increased epoch, which is what the check in libgcc11 checks to see if it needs to first deactivate libgc10. If you already had the latest libgcc10 installed, then installing libgcc11 would not have touched it.

Also note, updating libgcc10 without the corresponding libgcc11 update would have lead you to having no runtime installed at all, and most probably rev-upgrade would then trigger due to missing libraries. For this reason I find it hard to believe this is actually the situation you where in.

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

perhaps if each version of libgccN depended on the previous version libgccN-1 this situation could be better handled than the force-deactivate approach.

comment:28 in reply to:  27 Changed 3 years ago by cjones051073 (Chris Jones)

Replying to kencu:

perhaps if each version of libgccN depended on the previous version libgccN-1 this situation could be better handled than the force-deactivate approach.

no, it has to be the other way around. We want the newest libgcc to provide as much of the runtime it can, and then libgccN-1, to only install older versions not provided by any of the newer ones. This is why libgccN-1 depends on libgccN.

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

If libgcc11 depended on libgcc10, then libgcc10 would always be updated first (good) and libgcc10 would not be accidentally deactivated (good).

Doesn't affect which port provides the runtime.

comment:30 in reply to:  29 Changed 3 years ago by cjones051073 (Chris Jones)

Replying to kencu:

If libgcc11 depended on libgcc10, then libgcc10 would always be updated first (good) and libgcc10 would not be accidentally deactivated (good).

Doesn't affect which port provides the runtime.

It does, because it means anyone who just wants the most recent runtime, libgcc, they would have to have installed

libgcc -> libgcc11 -> libgcc10 -> libgcc9 -> libgcc8 -> .....

we specifically wanted to avoid that, for what should be the most common scenario, which is just needing libgcc

comment:31 in reply to:  26 Changed 3 years ago by mascguy (Christopher Nielsen)

Replying to cjones051073:

I don't see how that could happen. The updated libgcc10 has an increased epoch, which is what the check in libgcc11 checks to see if it needs to first deactivate libgc10. If you already had the latest libgcc10 installed, then installing libgcc11 would not have touched it.

Also note, updating libgcc10 without the corresponding libgcc11 update would have lead you to having no runtime installed at all, and most probably rev-upgrade would then trigger due to missing libraries. For this reason I find it hard to believe this is actually the situation you where in.

I can't explain it, but I can say this happened across all of my local setups: MacOS 10.12, 10.13, 10.14, and 10.15. In all four cases, the same issue occurred.

comment:32 Changed 3 years ago by mascguy (Christopher Nielsen)

Priority: HighNormal

comment:33 Changed 3 years ago by mascguy (Christopher Nielsen)

Resolution: worksforme
Status: assignedclosed

Closing for now, as perhaps this was simply a fluke. We can reopen if others encounter the same issue.

Note: See TracTickets for help on using tickets.