conda-forge / re2-feedstock

A conda-smithy repository for re2.
BSD 3-Clause "New" or "Revised" License
2 stars 12 forks source link

Use SOVERSION as migration marker? #67

Closed h-vetinari closed 1 year ago

h-vetinari commented 1 year ago

re2 provides a SOVERSION since https://github.com/google/re2/commit/13ebb377c6ad763ca61d12dd6f88b1126bd0b911, and it's only been updated twice since then (roughly once a year). Since it's explicitly marked as "ABI version", I presume we could use this as a reference for migrating re2, which should avoid a whole bunch of rebuilds.

However, we cannot supplant the existing version scheme of re2 (at the very least because the current SOVER 11.0.0 will always be less than the already published 2023.03.02), so it's not obvious to me what we could do without introducing another output (which however doesn't sound very appealing in terms of usage and having to rename it in all recipes)

Thoughts? @conda-forge/re2

CC @conda-forge/core

jaimergp commented 1 year ago

We can technically use an epoch in the version to override 2023, but I don't know if that's a good idea.

It would be like this:

re2 1!11.0.0

But maybe having re2_abi would be more explicit? It's true that it involves more work...

h-vetinari commented 1 year ago

But maybe having re2_abi would be more explicit? It's true that it involves more work...

That would be an obvious fix, but it'd mean we'd have to change the pinning and all feedstocks from re2 to re2_abi, which sounds like a lot of effort. Unless I'm overlooking a simpler way to do it, of course

xhochy commented 1 year ago

That would be an obvious fix, but it'd mean we'd have to change the pinning and all feedstocks from re2 to re2_abi,

Do we? Couldn't we instead have re2? re2_abi itself then would have a dependency on re2 with an appropriate range. Each new re2 version would also upload a re2_abi 11 packages which expands that range.

run_exports:
  - re2_abi 11
h-vetinari commented 1 year ago

Do we? Couldn't we instead have re2? re2_abi itself then would have a dependency on re2 with an appropriate range. Each new re2 version would also upload a re2_abi 11 packages which expands that range.

Thanks for the input! TBH, I just didn't see an obvious solution, but I'd be thrilled if we find a way for that to work!

So thinking through your suggestion a bit: obviously we'd have to change the current run-export, which would do >=2023.06.02,<2023.06.03 for #68. So then we change the run-export as you said (re2_abi ==11).

So then re2_abi ==11 would depend on re2 >=2023.06.02,<X.Y.Z+1, where X.Y.Z is the last known version with SOVER 11 (conveniently, the pkg-config tests will fail if the SOVER changes, but the recipe hasn't been adapted yet).

I had been thinking that we'd then have to set re2_abi ==11 in the pinning (and thus need to change the consuming recipes). But perhaps we can keep re2 in the pinning and just ignore PRs for new re2-migrators (like we do for aws-sdk-cpp), as long as the SOVER doesn't change?

Is that along the lines of what you had in mind?

isuruf commented 1 year ago

You can do the same as what libgfortran and libgfortran5 does. 5 is the SOVERSION here.

h-vetinari commented 1 year ago

Not sure if re211 is such a self-explanatory name... 😅

I can model it after that of course, and naming can be adapted/bikeshedded. Though how is it different from the re2_abi setup? What would be in the global pinning, what would re2-consumers be expected to have in their recipes, and how/when would a migrator get started?

If I understand the parallel correctly (which isn't 1:1 because gfortran is a compiler not a lib), you're suggesting that re2 run-exports re2<sover>, and that re2 stays in the pinning (like gfortran's version is pinned there too)? That would still give us "false positive" migrator PRs every time a new version on this feedstock is built (which would be manageable though).

Assuming I haven't misunderstood something, I kinda prefer the range-idea from @xhochy so far.

xhochy commented 1 year ago

The libgfortran5 approach has the benefit that you can install several versions at the same time.

h-vetinari commented 1 year ago

The libgfortran5 approach has the benefit that you can install several versions at the same time.

Has there ever been a substantial issue with re2-migrations? From what I've seen they've all been quite smooth. What I mean is: do we need the ability to install different versions? I guess the upside would be to avoid the migrator and just bump re2 in the pinning and it percolates out? I think that'd be nice (though we would have to migrate when the ABI changes, obviously).

I don't have a strong preference on this (well, except that I don't like re211, but we could call it re2_abi11 / re2_11 / re2_sover11 / ...), we just need to decide what we want to do.

xhochy commented 1 year ago

Has there ever been a substantial issue with re2-migrations?

No, they were all super-smooth. I'd rather use the same approach as libgfortran5 for consistency across libs in conda-forge on how things are done. Should we call it libre2-11? That's what debian is using for the naming.

h-vetinari commented 1 year ago

I'd rather use the same approach as libgfortran5 for consistency across libs in conda-forge on how things are done.

To me, libgfortran is the outlier so far (in addition to the fact that it's a compiler-support lib). I don't know of other libraries that run-export a different SOVER than their base version. That said, I'm fine with this approach, it's an elegant & already established solution.

Should we call it libre2-11? That's what debian is using for the naming.

Fine by me. I'll prepare that in #68.

h-vetinari commented 1 year ago

I see two options how to package everything but the libs:

The gfortran way:

outputs:
  - name: re2
    # contains $PREFIX/include/re2

  - name: libre2-{{ soversion }}
    # contains $PREFIX/lib/...

But then I don't know if the headers can never change between soversions...? 🤔

The alternative would be:

outputs:
  - name: re2
    # only a metapackage

  - name: libre2-{{ soversion }}
    # contains everything

Any preferences or advice?

h-vetinari commented 1 year ago

I see two options how to package everything but the libs:

The gfortran way:

Actually, gfortran still contains an unversioned libgfortran.so symlink, which is problematic AFAICT with co-installation of a potential libgfortran6.

I decided to model this after zlib, which really only contains the versioned libs on unix, resp the DLL without the import library on windows.

isuruf commented 1 year ago

Why would you want a co-installation? Isn't this about having a migration marker?

h-vetinari commented 1 year ago

@xhochy: The libgfortran5 approach has the benefit that you can install several versions at the same time.

☝️

I'm trying to follow along here... If we have the sover in the output name, obviously coinstallation becomes (much more easily) possible. IIUC, this would obviate the need for migrations at all, because we could just bump the pinning and let it percolate (as artifacts built against different re2 soversions would remain co-installable).

If we have one migration per year (average sover bump in re2), that's already very nice - perhaps no migrations is even better? I was trying to follow the inputs here (and the best practice example from zlib), but I don't feel strongly about the setup.

I saw an opportunity to cut down on the number of migrants and opened this issue, that's pretty much it.

isuruf commented 1 year ago

co-installability is not easy to enforce. Following situation is not desirable

h-vetinari commented 1 year ago

Following situation is not desirable

Makes sense, thanks for the explanation. Do we want to explicitly suppress co-installability, or just ensure we migrate for new soversions? If the former, how do we suppress it, given the sover in the output name? Something like a run-constraint on libre2-{{ soversion - 1 }} <0.0a0?

Regarding which files should go into the lib-package and which into the metapackage, please let me know in #68 (currently following zlib model, as I said; aside from the naming of the output obviously).

isuruf commented 1 year ago

If the former, how do we suppress it, given the sover in the output name? Something like a run-constraint on libre2-{{ soversion - 1 }} <0.0a0?

Again, please have a look at how libgfortran does it.

h-vetinari commented 1 year ago

I've looked at https://github.com/conda-forge/ctng-compilers-feedstock/blob/main/recipe/meta.yaml and it's not obvious. Perhaps you mean

    run_exports:
      strong:
        - libgfortran{{ libgfortran_soname }} {{ gcc_version }}.*

together with

  - name: libgfortran{{ libgfortran_soname }}
    requirements:
      run_constrained:
        - libgfortran-ng {{ gcc_version }}

and

  - name: libgfortran-ng
    requirements:
      run:
        - {{ pin_subpackage('libgfortran' ~ libgfortran_soname, exact=True) }}

?

Then gcc_version would be the regular re2-version here, and pinning exactly to that would defeat the point of having to migrate less often. So something like

    run_exports:
      - libre2-{{ soversion }} >={{ version }}.*

and

  - name: libgre2-{{ soversion }}
    requirements:
      run_constrained:
        - re2 {{ version }}

?

If so, this is effectively what's implemented in #68 - please review there. If not, please explain what should be done.

isuruf commented 1 year ago

You have to look at https://github.com/conda-forge/ctng-compiler-activation-feedstock/blob/main/recipe/meta.yaml too because that's where run_exports come from.

h-vetinari commented 1 year ago

You have to look at https://github.com/conda-forge/ctng-compiler-activation-feedstock/blob/main/recipe/meta.yaml too because that's where run_exports come from.

OK, so that adds:

    run_exports:
      strong:
        - libgfortran{{ libgfortran_soname }} >={{ ctng_gcc }}
        - libgfortran-ng

on top of what I described above. It's the same run-export as for gfortran_impl_{{ cross_target_platform }} (which is what the activation-side gfortran depends on directly), so I don't see how this changes the picture.

I'm wondering if we can find a way to interact more constructively here? Either I've understood the situation (and already implemented it in #68), or I'm not getting what you want to point me to. Could you please either review #68, or explain what should be done?

isuruf commented 1 year ago

I'm wondering if we can find a way to interact more constructively here?

It would have been easier to tell you exactly what to do, but I didn't do that because then I'd have to explain the next time another issue comes up as well. I"m just trying to nudge you towards the solution. Hope that you don't find it condescending or anything like that.

    run_exports:
      strong:
        - libgfortran{{ libgfortran_soname }} >={{ ctng_gcc }}
        - libgfortran-ng

Above run_exports ensures that two versions are not co-installable whereas below ensures co-installability.

    run_exports:
      strong:
        - libgfortran{{ libgfortran_soname }} >={{ ctng_gcc }}
h-vetinari commented 1 year ago

because then I'd have to explain the next time another issue comes up as well.

That presupposes that I'd be unable to learn from the explanation, which is somewhat condescending, actually. But water under the bridge, thanks for the answer.

I've mentioned before that there's no 1:1 correspondence between the compiler setup (which needs an activation package) and the situation here, which is what's making it hard for me to see what you're trying to nudge me towards.

So far the discussion in this thread referred only to outputs re2 and libre2-{{ sover }}, whereas libgfortran{{ sover }} is involved also in libgfortran-ng, gfortran_impl_{{ cross_target_platform }} and gfortran.

If - for example - you want me to add an unversioned libre2 that wraps libre2-{{ sover }}, could you please say so?


Trying to build on your hint, libgfortran-ng has the role of the wrapper around the versioned output here (i.e. re2 in our setup, or perhaps libre2 if we add that), and I don't see how that condition would block anything.

Concretely, say I add a run-export on re2 like you mention (assuming I haven't misunderstood something), as well as a pkgX built against re2=2023-06-02 & libre2-11=2023-06-02, and a pkgY built against re2=2024-12-12 & libre2-12=2024-12-12 and pkgX. Installing all that into the same environment:

  - pkgX
    # has run-exports:   
    - libre2-11 >=2023-06-02
    - re2
  - pkgY
    # has run-exports:
    - pkgX
    - libre2-12 >=2024-12-12
    - re2
  - re2 =2024-12-12        # does not conflict with the above
    # depends on
    - libre2-12 =2024-12-12
  - libre2-11 =2023-06-02  # does not conflict with the above
  - libre2-12 =2024-12-12  # does not conflict with the above

So this doesn't avoid co-installation. Looking again at https://github.com/conda-forge/ctng-compiler-activation-feedstock/blob/main/recipe/meta.yaml, the run-export actually has a pin, i.e. libgfortran-ng {{ ctng_gcc }}.*. But translating this to the situation here, we'd be hard-pinning to the re2-version again, which defeats the purpose of having to rebuild less often.

isuruf commented 1 year ago

Looking again at https://github.com/conda-forge/ctng-compiler-activation-feedstock/blob/main/recipe/meta.yaml, the run-export actually has a pin, i.e. libgfortran-ng {{ ctng_gcc }}.*.

Not true

So this doesn't avoid co-installation.

It does, if you follow libgfortran pattern. For eg the following does not work.

mamba create -n test libgfortran-ng libgfortran4 libgfortran5

See https://github.com/conda-forge/ctng-compilers-feedstock/blob/main/recipe/meta.yaml#L563-L564

isuruf commented 1 year ago

If - for example - you want me to add an unversioned libre2 that wraps libre2-{{ sover }}, could you please say so?

Not needed. You can have re2 be analogous to libgfortran-ng.

h-vetinari commented 1 year ago

Not needed. You can have re2 be analogous to libgfortran-ng.

OK cool.

See https://github.com/conda-forge/ctng-compilers-feedstock/blob/main/recipe/meta.yaml#L563-L564

So this would translate to

      # for output libre2-{{ soversion }}
      run_constrained:
        - re2 {{ version }}

How does this allow us to reduce the number of rebuilds we need for re2? If we need to migrate for every re2 version (even if they share their SOVER), we haven't gained anything over the current setup.

h-vetinari commented 1 year ago

To recap, we want both:

Looking again at @xhochy's suggestion, this looks like a substantially more straight-forward way to achieve this:

  - name: re2
    build:
      run_exports:
        - {{ pin_subpackage("libre2-" ~ soversion) }}
    requirements:
      host:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}
      run:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}

  - name: libre2-{{ soversion }}
    build:
      run_exports:
        - {{ pin_subpackage("libre2-" ~ soversion) }}
    requirements:
      run_constrained:
        # lower bound corresponds to re2-version that bumped the soversion
        - re2 >=2023.06.02,<={{ version }}

That way, it's trivially impossible to co-install libre2-11 and libre2-12, because they have a non-overlapping constraint on the re2-version. Plus the run-constraint of libre2-{{ soversion }} is self-updating, and we won't ship broken artefacts because the build will fail if the upstream soversion changes but hasn't been updated in the recipe (due to the pkgconfig check validating that).

isuruf commented 1 year ago

How does this allow us to reduce the number of rebuilds we need for re2? If we need to migrate for every re2 version (even if they share their SOVER), we haven't gained anything over the current setup.

I don't understand this question.

First of all, do you agree with the following statements?

  1. Pkg A built with libgfortran4 and Pkg B built with libgfortran5 are no co-installable?
  2. Pkg A built with libgfortran5=11.1.0 did not need a rebuild with libgfortran5=12.1.0 ?

I've mentioned before that there's no 1:1 correspondence between the compiler setup

There is. re2 -> libgfortran-ng, libre2-11 -> libgfortran5`.

isuruf commented 1 year ago

That way, it's trivially impossible to co-install libre2-11 and libre2-12, because they have a non-overlapping constraint on the re2-version.

Not true either. Since downstream packages will be depending on only libre2-11 or libre2-12 because of your run_exports mentioned, they will be co-installable.

h-vetinari commented 1 year ago

First of all, do you agree with the following statements?

  1. Pkg A built with libgfortran4 and Pkg B built with libgfortran5 are not co-installable?
  2. Pkg A built with libgfortran5=11.1.0 did not need a rebuild with libgfortran5=12.1.0 ?

Yes, I agree with them, though it's not exactly obvious to me from the various run-exports and constraints, for one because it's spread across 4 outputs in two feedstocks, with no cross-references or explanations, and two because it's just not trivial to run a brain-based resolver on these constraints.

I've mentioned before that there's no 1:1 correspondence between the compiler setup

There is. re2 -> libgfortran-ng, libre2-11 -> libgfortran5.

I think what tripped me up so badly was how the constraint of libgfortran5 on libgfortran-ng {{ gcc_version }} would translate into a run-dependence on the re2-version, and that just looked like it's going to make it necessary to re-migrate for every re2-version, rather than SOVERSION.

The penny may have finally dropped though that libre2-11 can afford to run-depend on the newest re2-version, because that can still satisfy the run-export libre2-11 >=x from an older version without having to rebuild anything.

That way, it's trivially impossible to co-install libre2-11 and libre2-12, because they have a non-overlapping constraint on the re2-version.

Not true either. Since downstream packages will be depending on only libre2-11 or libre2-12 because of your run_exports mentioned, they will be co-installable.

That'd be pretty easy to solve by letting libre2-{{ soversion }} run-depend on (any version of) re2, then the hard requirement on a single libre2-X takes hold.


For me the overall situation is that there's one proposed solution that I find really hard to understand[^1], and there's one solution that takes far less mental gymnastics (for me) to verify as doing what it's supposed to.

[^1]: despite your explanations and spending a bunch of time looking at it

isuruf commented 1 year ago

there's one solution that takes far less mental gymnastics (for me) to verify as doing what it's supposed to.

What solution are you talking about? All the solutions you have mentioned so far do allow co-installibility.

I'm suggesting the option

  - name: re2
    build:
      run_exports:
        - {{ pin_subpackage("libre2-" ~ soversion) }}
        - re2
    requirements:
      host:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}
      run:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}

  - name: libre2-{{ soversion }}
    requirements:
      run_constrained:
        - re2 {{ version }}.*

It's a very simple recipe.

isuruf commented 1 year ago

You can also do

  - name: re2
    build:
      run_exports:
        - {{ pin_subpackage("libre2-" ~ soversion) }}
        - libre2
    requirements:
      host:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}
        - {{ pin_subpackage("libre2", exact=True) }}
      run:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}
        - {{ pin_subpackage("libre2", exact=True) }}

  - name: libre2
    requirements:
      host:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}
      run:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }} 
      run_constrained:
        - re2 {{ version }}.*
        - libre2 {{ version }}.*

  - name: libre2-{{ soversion }}
    requirements:
      run_constrained:
        - re2 {{ version }}.*
        - libre2 {{ version }}.*

if you want to separate the library from the headers, pkg-config files etc.

h-vetinari commented 1 year ago

What solution are you talking about?

The one where I said "That'd be pretty easy to solve by [adding a run-dep on re2]" to your criticism about co-installability:

  - name: re2
    build:
      run_exports:
        - {{ pin_subpackage("libre2-" ~ soversion) }}
    requirements:
      host:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}
      run:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}

  - name: libre2-{{ soversion }}
    requirements:
      run:
        - re2  # should be merged with the below, separate for clarity
      run_constrained:
        # lower bound corresponds to re2-version that bumped the soversion
        - re2 >=2023.06.02,<={{ version }}

I claim that this is functionally equivalent to your proposal, which I'm including below for comparison (with the annotations I'd want to add for mere mortals like my future self).

  - name: re2
    build:
      run_exports:
        - {{ pin_subpackage("libre2-" ~ soversion) }}
        # by adding this constraint, we ensure that only a single libre2-X can be installed,
        # because libre2 requires a specific re2-version, which in turn requires a specific soversion
        - re2
    requirements:
      host:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}
      run:
        - {{ pin_subpackage("libre2-" ~ soversion, exact=True) }}

  - name: libre2-{{ soversion }}
    requirements:
      run_constrained:
        # the version pin ensures that libre2-{X,Y} are not co-installable (see above), but doesn't hinder 
        # satifsfying libre2-{{ soversion }} >= {{ version }} from the run-export (by taking newest build)
        - re2 {{ version }}.*

I'm pretty confident I can prove that equivalence in terms of constraints if you don't believe me. To me the former is clearly easier to parse/resolve mentally, because it doesn't need as much indirection.


That said, let's take a step back. We (@xhochy and I) started down the libgfortran road with the apparent misconception

@xhochy: The libgfortran5 approach has the benefit that you can install several versions at the same time.

As you explained we want to avoid co-installability. So the question arises why we want to version the outputs at all, rather than just have re2_abi be versioned by the soversion, which would trivially avoid co-installability.

  - name: re2
    build:
      run_exports:
        - re2_abi {{ soversion }}
    requirements:
      host:
        - {{ pin_subpackage("re2_abi", exact=True) }}
      run:
        - {{ pin_subpackage("re2_abi", exact=True) }}

  - name: re2_abi
    version: {{ soversion }}
    requirements:
        # lower bound corresponds to re2-version that bumped the soversion
        - re2 >=2023.06.02,<={{ version }}

If you don't think this is a better solution, please explain why (without rhetorical questions).

isuruf commented 1 year ago
  1. This is introducing a new way of specifiying ABIs that would lead to confusion to users about what it really means whereas using the an output name like libre2-11 is the standard in other binary distro packagers. As I've mentioned this multiple times before, we should be taking the experience of other package management software and not introduce different concepts that do the same thing. (I know that python-abi and pybind11-abi exists, but they are different than this use case

  2. If at some point, re2 or any other package that wishes to follow this pattern needs to separate out the libraries, then a libre2 package would be natural to have the libre2.so file and libre2-11 to have the versioned so file.

h-vetinari commented 1 year ago

OK, both of these make sense to me, thanks. OTOH "taking the experience of other package management software" is a bit fuzzy, so having an argument that justifies the extra complexity in the context of our setup is still a reasonable ask IMO.

In any case, I'm fine with "paying" for the libre2-X setup (it's probably be good to document that approach w.r.t. library patterns in conda-forge).

I've updated the implemented the implementation in #68 to use the run-export on re2 (as the run-dependence I wanted to use leads to circular build deps), which now follows the libgfortran pattern (though I kept the version range approach for the libre2 constraint, as that's more easily explainable IMO).

hmaarrfk commented 1 year ago

binary distro packagers.

If you could be specific on a few that you like that would help point our readings.

I like RPM

h-vetinari commented 1 year ago

OTOH "taking the experience of other package management software" is a bit fuzzy, so having an argument that justifies the extra complexity in the context of our setup is still a reasonable ask IMO.

To this point: it would be important to know if distro's have designed their libre2-X to be co-installable or not. For example, it would make no sense to follow a design that was intended to allow co-installability if we want to explicitly avoid it.

Looking at ubuntu & debian, there's only one lib per OS-version (with the exception of the testing-ground of debian-sid), so I couldn't immediately test what happens when trying to install both. fedora and arch don't make use of the soversion it seems.

So I looked at the libgfortran situation, where both 4 & 5 exist for ubuntu 20.04. Spinning up a container and installing both succeeds:

Installation log for apt-get install libgfortran4 libgfortran5 ``` root@b66a466b4701:/# apt-get install libgfortran4 libgfortran5 Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: gcc-7-base libquadmath0 The following NEW packages will be installed: gcc-7-base libgfortran4 libgfortran5 libquadmath0 0 upgraded, 4 newly installed, 0 to remove and 46 not upgraded. Need to get 1394 kB of archives. After this operation, 5434 kB of additional disk space will be used. Do you want to continue? [Y/n] y Get:1 http://archive.ubuntu.com/ubuntu focal/universe amd64 gcc-7-base amd64 7.5.0-6ubuntu2 [18.5 kB] Get:2 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libquadmath0 amd64 10.3.0-1ubuntu1~20.04 [146 kB] Get:3 http://archive.ubuntu.com/ubuntu focal/universe amd64 libgfortran4 amd64 7.5.0-6ubuntu2 [493 kB] Get:4 http://archive.ubuntu.com/ubuntu focal-updates/main amd64 libgfortran5 amd64 10.3.0-1ubuntu1~20.04 [736 kB] Fetched 1394 kB in 1s (1515 kB/s) debconf: delaying package configuration, since apt-utils is not installed Selecting previously unselected package gcc-7-base:amd64. (Reading database ... 4127 files and directories currently installed.) Preparing to unpack .../gcc-7-base_7.5.0-6ubuntu2_amd64.deb ... Unpacking gcc-7-base:amd64 (7.5.0-6ubuntu2) ... Selecting previously unselected package libquadmath0:amd64. Preparing to unpack .../libquadmath0_10.3.0-1ubuntu1~20.04_amd64.deb ... Unpacking libquadmath0:amd64 (10.3.0-1ubuntu1~20.04) ... Selecting previously unselected package libgfortran4:amd64. Preparing to unpack .../libgfortran4_7.5.0-6ubuntu2_amd64.deb ... Unpacking libgfortran4:amd64 (7.5.0-6ubuntu2) ... Selecting previously unselected package libgfortran5:amd64. Preparing to unpack .../libgfortran5_10.3.0-1ubuntu1~20.04_amd64.deb ... Unpacking libgfortran5:amd64 (10.3.0-1ubuntu1~20.04) ... Setting up gcc-7-base:amd64 (7.5.0-6ubuntu2) ... Setting up libquadmath0:amd64 (10.3.0-1ubuntu1~20.04) ... Setting up libgfortran5:amd64 (10.3.0-1ubuntu1~20.04) ... Setting up libgfortran4:amd64 (7.5.0-6ubuntu2) ... Processing triggers for libc-bin (2.31-0ubuntu9.2) ... root@b66a466b4701:/# ```

I'm all for not repeating mistakes that other have figured out already, but I struggle to understand which lessons we're picking and choosing to apply (e.g. we want outputs with the soversion in the name, but not co-installability -- does that still mean their setup is applicable to us? I have a hard time to tell...)

h-vetinari commented 1 year ago

I'm reviving #68 now, which follows the gfortran pattern (versioned output-names; not co-installable). If anyone still has concerns, please comment on the PR.

h-vetinari commented 8 months ago

First version bump to take advantage of this new infrastructure: https://github.com/conda-forge/conda-forge-pinning-feedstock/pull/5555