ENH: minimally activated compilers
One unavoidable consequence of making compilers easily installable (whether as gcc_linux-64 or through the compilers metapackage), is that people and projects started using them, a lot.
This leads to friction because although we never promised to support use outside conda-forge, it is a de facto reality nowadays.
On top of that there are efforts to better handle build profiles (e.g. release/debug/etc.), c.f. conda-forge/ctng-compiler-activation-feedstock#157.
What I'm thinking about is that we should introduce a third level in the hierarchy between (currently):
${<lang>_compiler}_<platform>(fully activated compiler, geared towards conda-forge)${<lang>_compiler}_impl_<platform>(complete dependencies, no activation)
into something like
${<lang>_compiler}-cf_<platform>(fully activated compiler, geared towards conda-forge)${<lang>_compiler}_<platform>(minimally activated compiler, e.g. pointing to$PREFIX, but no extra flags)${<lang>_compiler}_impl_<platform>(complete dependencies, no activation)
That would allow external users of our compiler stack to avoid having to play around with stripping out flags, while conda-forge could keep all its default config (e.g. -O2 -DCMAKE_BUILD_TYPE=Release etc.) in the conda-forge-specific compiler flavours.
FYI @wolfv @ruben-arts @jaimergp @mgorny @rgommers CC @conda-forge/clang-compiler-activation @conda-forge/core
- [x] https://github.com/conda-forge/clangdev-feedstock/pull/387
- [x] https://github.com/conda-forge/clangdev-feedstock/pull/387
- [x] https://github.com/conda-forge/openmp-feedstock/pull/193
- [x] https://github.com/conda-forge/openmp-feedstock/pull/189
- [x] https://github.com/conda-forge/cctools-and-ld64-feedstock/pull/91
- [x] https://github.com/conda-forge/cctools-and-ld64-feedstock/pull/92
- [x] https://github.com/conda-forge/cctools-and-ld64-feedstock/pull/93
- [x] https://github.com/conda-forge/compiler-rt-feedstock/pull/159
- [x] https://github.com/conda-forge/clangdev-feedstock/pull/390
You can already use gcc, gxx, gfortran packages.
Unfortunately the language platform format is baked into conda-build, so inserting cf_ into it will be non-trivial.
You can already use
gcc,gxx,gfortranpackages.
I'm fine with making that the pattern, but it's not compatible with the way that clang / clangxx are currently set up on osx. I opened the issue here, because GCC is the most complicated compiler feedstock, but I'm talking about something across our entire compiler stack.
Unfortunately the language platform format is baked into conda-build, so inserting cf_ into it will be non-trivial.
We fully override this in the global pinning, so we could easily change the names of the compiler packages (assuming the respective outputs are installable). We could also introduce a separate name for the "minimal" compilers, but I liked the aspect that the <lang>-compilers metapackages would do the "more obvious thing", while we confine the cf-specific stuff into a package that the vast majority of people won't install by accident.
This issue largely overlaps with https://github.com/conda-forge/conda-forge.github.io/issues/1998 and https://github.com/conda-forge/conda-forge.github.io/issues/2002, right?
I already referenced the second issue (had forgotten about the first). To me at least, these two were more for discussing the issue(s), whereas this issue is a concrete proposal for how to solve this.
To override in the pinnings we'd have to have compiler('c_cf') etc in recipes. That's not so much fun to me.
To override in the pinnings we'd have to have compiler('c_cf') etc in recipes.
Not at all. It would suffice to do
c_compiler:
- - gcc # [linux]
- - clang # [osx]
- - vs2022 # [win]
+ - gcc-cf # [linux]
+ - clang-cf # [osx]
+ - vs2022-cf # [win]
in the pinning, and so on for cxx_compiler and fortran_compiler, with no changes to individual recipes.
Since there's already gcc, gxx, gfortran in this feedstock that does the minimal thing, I don't see the need to add another output here. So, I suggest you raise this in the clang-compiler-activation-feedstock
Or in the conda-forge.github.io repo where you can talk about the entire compiler stack.
Or in the conda-forge.github.io repo where you can talk about the entire compiler stack.
Transferred
IMO, relying on activation scripts is the wrong solution for letting our compilers be used by users outside of conda-build.
This is because we want the compilers to work in all sorts of build-systems and make it robust enough that users can't tell the difference between our compilers and the ones they usually see on their system. A solution should take into account that some build systems override CFLAGS, some don't really use CFLAGS or LDFLAGS and that g++ hello.cpp should work out of the box, etc.
In Linux with our gcc package the way things work is the following
gcc_impl_linux-64has all executables prefixed withx86_64-conda-linux-gnu-and no activation flags The compiler's default spec file has been customized to use aconda.specsfile if it exists, but it doesn't exist in this package.gcc_linux-64depends ongcc_impl_linux-64only and addsCC, CFLAGS, LDFLAGSenv variables.conda-gcc-specs- this package adds aconda.specsfile that adds-isystem $CONDA_PREFIX/includeto compile flags and-L $$CONDA_PREFIX/lib -Wl,-rpath,$CONDA_PREFIX/libwhen linking.gccdepends onconda-gcc-specs(there's a variant that doesn't, but it's not default and not relevant to this conversation) and also hascc, gcc, cppsymlinks into the prefixed executables.
What this means is that if a user does g++ hello.cpp from an activated environment or /path/to/g++ hello.cpp from a not activated environment or an environment where the user has some values for CFLAGS, LDFLAGS, all of them will do the same thing.
Also the user will not have to do g++ $CXXFLAGS hello.cpp $LDFLAGS and can just do g++ hello.cpp. Technically even without conda-gcc-specs the user can do g++ hello.cpp, but running the executable will sometimes fail because the dynamic loader will be able to load the system libstdc++.so.6, but that maybe old.
TLDR; in Linux g++ hello.cpp with just conda install gxx works perfectly without needing to activate the environment or use environment variables. On macOS, this is not the case since clang doesn't have a concept of spec files. (clang configuration files are not useful for this scenario). We can make macOS work like Linux too with a little bit of work.
IMO, relying on activation scripts is the wrong solution for letting our compilers be used by users outside of conda-build.
I think the "unactivated" use of our compilers is a nice-to-have, but less of a priority to support (than our so-far-explicit lack thereof for any of our compilers) from my POV. Anyone using compilers is already happily using the compilers in activated environments.
But since GCC offers a mechanism to do this without activation scripts, that's great to use it IMO! However, we should also switch the compilers meta-package to depend on gcc / gxx / gfortran IMO.
We can make macOS work like Linux too with a little bit of work.
How do you envision that? I don't mind following this path, but we'd have to come up with some alternate output naming (or rename the existing clang / clangxx, which are just the binaries, not the symlinks with your mechanism).
Also, I'm guessing we won't be able to avoid activation on windows anyway...?
I think this is a nice idea, and the proposed implementation sounds like a good compromise. And it will definitely make it easier for us to adjust the defaults for conda-forge builds in the future without affecting third parties.
I think this is a nice idea, and the proposed implementation sounds like a good compromise.
@mgorny thank you for your input. Which idea in particular are you talking about here?
or rename the existing clang / clangxx, which are just the binaries, not the symlinks with your mechanism
clang, clangxx packages are already symlinks to clang-<major> executable in clang-<major> package.
How do you envision that? I don't mind following this path, but we'd have to come up with some alternate output naming (or rename the existing clang / clangxx, which are just the binaries, not the symlinks with your mechanism).
We can add support to clang to load a configuration file conda-clang.cfg that appends options in addition to the configuration file that prepends. Also add a conda-clang-cfg similar to conda-gcc-specs
Then we can downprioritize the clang * default_* variant and add a new clang * user_* variant that depends on conda-clang-cfg, clang-<major>, compiler-rt and other helper packages and also adds the symlinks.
I think this is a nice idea, and the proposed implementation sounds like a good compromise.
@mgorny thank you for your input. Which idea in particular are you talking about here?
I was talking about the original idea from #c0, i.e. splitting off conda-forge specific activation. Even if we long term don't want people relying on activation scripts, they already are, and the split will permit us to change things without breaking them.
How do you envision that? I don't mind following this path, but we'd have to come up with some alternate output naming (or rename the existing clang / clangxx, which are just the binaries, not the symlinks with your mechanism).
We can add support to clang to load a configuration file
conda-clang.cfgthat appends options in addition to the configuration file that prepends. Also add aconda-clang-cfgsimilar toconda-gcc-specsThen we can downprioritize the
clang * default_*variant and add a newclang * user_*variant that depends onconda-clang-cfg,clang-<major>,compiler-rtand other helper packages and also adds the symlinks.
Well, config files is something Gentoo extensively uses in Clang (I helped implement them), but before you go down that rabbit hole, you should probably note that you may end up using a lot of them. Just FYI:
Scary
$ tree /etc/clang/
/etc/clang/
├── 20
│ ├── gentoo-linker.cfg
│ ├── gentoo-plugins.cfg
│ ├── gentoo-rtlib.cfg
│ ├── gentoo-runtimes.cfg
│ ├── gentoo-stdlib.cfg
│ ├── gentoo-unwindlib.cfg
│ ├── i386-gentoo-linux-gnu-clang++.cfg -> i386-pc-linux-gnu-clang++.cfg
│ ├── i386-gentoo-linux-gnu-clang.cfg -> i386-pc-linux-gnu-clang.cfg
│ ├── i386-gentoo-linux-gnu-clang-cpp.cfg -> i386-pc-linux-gnu-clang-cpp.cfg
│ ├── i386-pc-linux-gnu-clang++.cfg
│ ├── i386-pc-linux-gnu-clang.cfg
│ ├── i386-pc-linux-gnu-clang-cpp.cfg
│ ├── i386-unknown-linux-gnu-clang++.cfg -> i386-pc-linux-gnu-clang++.cfg
│ ├── i386-unknown-linux-gnu-clang.cfg -> i386-pc-linux-gnu-clang.cfg
│ ├── i386-unknown-linux-gnu-clang-cpp.cfg -> i386-pc-linux-gnu-clang-cpp.cfg
│ ├── i686-gentoo-linux-gnu-clang++.cfg -> i686-pc-linux-gnu-clang++.cfg
│ ├── i686-gentoo-linux-gnu-clang.cfg -> i686-pc-linux-gnu-clang.cfg
│ ├── i686-gentoo-linux-gnu-clang-cpp.cfg -> i686-pc-linux-gnu-clang-cpp.cfg
│ ├── i686-pc-linux-gnu-clang++.cfg
│ ├── i686-pc-linux-gnu-clang.cfg
│ ├── i686-pc-linux-gnu-clang-cpp.cfg
│ ├── i686-unknown-linux-gnu-clang++.cfg -> i686-pc-linux-gnu-clang++.cfg
│ ├── i686-unknown-linux-gnu-clang.cfg -> i686-pc-linux-gnu-clang.cfg
│ ├── i686-unknown-linux-gnu-clang-cpp.cfg -> i686-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-gentoo-linux-gnu-clang++.cfg -> x86_64-pc-linux-gnu-clang++.cfg
│ ├── x86_64-gentoo-linux-gnu-clang.cfg -> x86_64-pc-linux-gnu-clang.cfg
│ ├── x86_64-gentoo-linux-gnu-clang-cpp.cfg -> x86_64-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-gentoo-linux-gnux32-clang++.cfg -> x86_64-pc-linux-gnux32-clang++.cfg
│ ├── x86_64-gentoo-linux-gnux32-clang.cfg -> x86_64-pc-linux-gnux32-clang.cfg
│ ├── x86_64-gentoo-linux-gnux32-clang-cpp.cfg -> x86_64-pc-linux-gnux32-clang-cpp.cfg
│ ├── x86_64-pc-linux-gnu-clang++.cfg
│ ├── x86_64-pc-linux-gnu-clang.cfg
│ ├── x86_64-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-pc-linux-gnux32-clang++.cfg
│ ├── x86_64-pc-linux-gnux32-clang.cfg
│ ├── x86_64-pc-linux-gnux32-clang-cpp.cfg
│ ├── x86_64-unknown-linux-gnu-clang++.cfg -> x86_64-pc-linux-gnu-clang++.cfg
│ ├── x86_64-unknown-linux-gnu-clang.cfg -> x86_64-pc-linux-gnu-clang.cfg
│ ├── x86_64-unknown-linux-gnu-clang-cpp.cfg -> x86_64-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-unknown-linux-gnux32-clang++.cfg -> x86_64-pc-linux-gnux32-clang++.cfg
│ ├── x86_64-unknown-linux-gnux32-clang.cfg -> x86_64-pc-linux-gnux32-clang.cfg
│ └── x86_64-unknown-linux-gnux32-clang-cpp.cfg -> x86_64-pc-linux-gnux32-clang-cpp.cfg
├── 21
│ ├── gentoo-linker.cfg
│ ├── gentoo-plugins.cfg
│ ├── gentoo-rtlib.cfg
│ ├── gentoo-runtimes.cfg
│ ├── i386-gentoo-linux-gnu-clang++.cfg -> i386-pc-linux-gnu-clang++.cfg
│ ├── i386-gentoo-linux-gnu-clang.cfg -> i386-pc-linux-gnu-clang.cfg
│ ├── i386-gentoo-linux-gnu-clang-cpp.cfg -> i386-pc-linux-gnu-clang-cpp.cfg
│ ├── i386-pc-linux-gnu-clang++.cfg
│ ├── i386-pc-linux-gnu-clang.cfg
│ ├── i386-pc-linux-gnu-clang-cpp.cfg
│ ├── i386-unknown-linux-gnu-clang++.cfg -> i386-pc-linux-gnu-clang++.cfg
│ ├── i386-unknown-linux-gnu-clang.cfg -> i386-pc-linux-gnu-clang.cfg
│ ├── i386-unknown-linux-gnu-clang-cpp.cfg -> i386-pc-linux-gnu-clang-cpp.cfg
│ ├── i686-gentoo-linux-gnu-clang++.cfg -> i686-pc-linux-gnu-clang++.cfg
│ ├── i686-gentoo-linux-gnu-clang.cfg -> i686-pc-linux-gnu-clang.cfg
│ ├── i686-gentoo-linux-gnu-clang-cpp.cfg -> i686-pc-linux-gnu-clang-cpp.cfg
│ ├── i686-pc-linux-gnu-clang++.cfg
│ ├── i686-pc-linux-gnu-clang.cfg
│ ├── i686-pc-linux-gnu-clang-cpp.cfg
│ ├── i686-unknown-linux-gnu-clang++.cfg -> i686-pc-linux-gnu-clang++.cfg
│ ├── i686-unknown-linux-gnu-clang.cfg -> i686-pc-linux-gnu-clang.cfg
│ ├── i686-unknown-linux-gnu-clang-cpp.cfg -> i686-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-gentoo-linux-gnu-clang++.cfg -> x86_64-pc-linux-gnu-clang++.cfg
│ ├── x86_64-gentoo-linux-gnu-clang.cfg -> x86_64-pc-linux-gnu-clang.cfg
│ ├── x86_64-gentoo-linux-gnu-clang-cpp.cfg -> x86_64-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-gentoo-linux-gnux32-clang++.cfg -> x86_64-pc-linux-gnux32-clang++.cfg
│ ├── x86_64-gentoo-linux-gnux32-clang.cfg -> x86_64-pc-linux-gnux32-clang.cfg
│ ├── x86_64-gentoo-linux-gnux32-clang-cpp.cfg -> x86_64-pc-linux-gnux32-clang-cpp.cfg
│ ├── x86_64-pc-linux-gnu-clang++.cfg
│ ├── x86_64-pc-linux-gnu-clang.cfg
│ ├── x86_64-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-pc-linux-gnux32-clang++.cfg
│ ├── x86_64-pc-linux-gnux32-clang.cfg
│ ├── x86_64-pc-linux-gnux32-clang-cpp.cfg
│ ├── x86_64-unknown-linux-gnu-clang++.cfg -> x86_64-pc-linux-gnu-clang++.cfg
│ ├── x86_64-unknown-linux-gnu-clang.cfg -> x86_64-pc-linux-gnu-clang.cfg
│ ├── x86_64-unknown-linux-gnu-clang-cpp.cfg -> x86_64-pc-linux-gnu-clang-cpp.cfg
│ ├── x86_64-unknown-linux-gnux32-clang++.cfg -> x86_64-pc-linux-gnux32-clang++.cfg
│ ├── x86_64-unknown-linux-gnux32-clang.cfg -> x86_64-pc-linux-gnux32-clang.cfg
│ └── x86_64-unknown-linux-gnux32-clang-cpp.cfg -> x86_64-pc-linux-gnux32-clang-cpp.cfg
├── gentoo-cet.cfg
├── gentoo-common.cfg
├── gentoo-common-ld.cfg
├── gentoo-gcc-install.cfg
├── gentoo-hardened.cfg
├── gentoo-hardened-ld.cfg
├── gentoo-runtimes.cfg
├── i386-gentoo-linux-gnu-clang++.cfg -> i386-pc-linux-gnu-clang++.cfg
├── i386-gentoo-linux-gnu-clang.cfg -> i386-pc-linux-gnu-clang.cfg
├── i386-gentoo-linux-gnu-clang-cpp.cfg -> i386-pc-linux-gnu-clang-cpp.cfg
├── i386-pc-linux-gnu-clang++.cfg
├── i386-pc-linux-gnu-clang.cfg
├── i386-pc-linux-gnu-clang-cpp.cfg
├── i386-unknown-linux-gnu-clang++.cfg -> i386-pc-linux-gnu-clang++.cfg
├── i386-unknown-linux-gnu-clang.cfg -> i386-pc-linux-gnu-clang.cfg
├── i386-unknown-linux-gnu-clang-cpp.cfg -> i386-pc-linux-gnu-clang-cpp.cfg
├── i686-gentoo-linux-gnu-clang++.cfg -> i686-pc-linux-gnu-clang++.cfg
├── i686-gentoo-linux-gnu-clang.cfg -> i686-pc-linux-gnu-clang.cfg
├── i686-gentoo-linux-gnu-clang-cpp.cfg -> i686-pc-linux-gnu-clang-cpp.cfg
├── i686-pc-linux-gnu-clang++.cfg
├── i686-pc-linux-gnu-clang.cfg
├── i686-pc-linux-gnu-clang-cpp.cfg
├── i686-unknown-linux-gnu-clang++.cfg -> i686-pc-linux-gnu-clang++.cfg
├── i686-unknown-linux-gnu-clang.cfg -> i686-pc-linux-gnu-clang.cfg
├── i686-unknown-linux-gnu-clang-cpp.cfg -> i686-pc-linux-gnu-clang-cpp.cfg
├── x86_64-gentoo-linux-gnu-clang++.cfg -> x86_64-pc-linux-gnu-clang++.cfg
├── x86_64-gentoo-linux-gnu-clang.cfg -> x86_64-pc-linux-gnu-clang.cfg
├── x86_64-gentoo-linux-gnu-clang-cpp.cfg -> x86_64-pc-linux-gnu-clang-cpp.cfg
├── x86_64-gentoo-linux-gnux32-clang++.cfg -> x86_64-pc-linux-gnux32-clang++.cfg
├── x86_64-gentoo-linux-gnux32-clang.cfg -> x86_64-pc-linux-gnux32-clang.cfg
├── x86_64-gentoo-linux-gnux32-clang-cpp.cfg -> x86_64-pc-linux-gnux32-clang-cpp.cfg
├── x86_64-pc-linux-gnu-clang++.cfg
├── x86_64-pc-linux-gnu-clang.cfg
├── x86_64-pc-linux-gnu-clang-cpp.cfg
├── x86_64-pc-linux-gnux32-clang++.cfg
├── x86_64-pc-linux-gnux32-clang.cfg
├── x86_64-pc-linux-gnux32-clang-cpp.cfg
├── x86_64-unknown-linux-gnu-clang++.cfg -> x86_64-pc-linux-gnu-clang++.cfg
├── x86_64-unknown-linux-gnu-clang.cfg -> x86_64-pc-linux-gnu-clang.cfg
├── x86_64-unknown-linux-gnu-clang-cpp.cfg -> x86_64-pc-linux-gnu-clang-cpp.cfg
├── x86_64-unknown-linux-gnux32-clang++.cfg -> x86_64-pc-linux-gnux32-clang++.cfg
├── x86_64-unknown-linux-gnux32-clang.cfg -> x86_64-pc-linux-gnux32-clang.cfg
└── x86_64-unknown-linux-gnux32-clang-cpp.cfg -> x86_64-pc-linux-gnux32-clang-cpp.cfg
3 directories, 125 files
Admittedly, some of that complexity is Gentoo-specific. We have made the mistake of originally using a single config directory for all Clang versions (we're in process of finally removing that). The split runtime files are used for bootstrap. It roughly goes like this:
$ clang-21 --version
clang version 21.1.1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/lib/llvm/21/bin
Build config: +assertions
Configuration file: /etc/clang/21/x86_64-pc-linux-gnu-clang.cfg
$ cat /etc/clang/21/x86_64-pc-linux-gnu-clang.cfg
# This configuration file is used by x86_64-pc-linux-gnu-clang driver.
@../x86_64-pc-linux-gnu-clang.cfg
@gentoo-plugins.cfg
@gentoo-runtimes.cfg
$ cat /etc/clang/x86_64-pc-linux-gnu-clang.cfg
# This configuration file is used by x86_64-pc-linux-gnu-clang driver.
@gentoo-common.cfg
@gentoo-common-ld.cfg
@gentoo-cet.cfg
$ cat /etc/clang/gentoo-common.cfg
# This file contains flags common to clang, clang++ and clang-cpp.
@gentoo-gcc-install.cfg
@gentoo-hardened.cfg
# bug #870001
-include "/usr/include/gentoo/maybe-stddefs.h"
...
To override in the pinnings we'd have to have compiler('c_cf') etc in recipes.
Not at all. It would suffice to do
c_compiler:
- gcc # [linux]
- clang # [osx]
- vs2022 # [win]
- gcc-cf # [linux]
- clang-cf # [osx]
- vs2022-cf # [win]
in the pinning, and so on for cxx_compiler and fortran_compiler, with no changes to individual recipes.
It just occurred to me but I guess we'll also need to change the recipes that override the compiler in their conda_build_config.yaml, and probably these that use {{ compiler('clang') }} explicitly (not 100% sure of that, I only recently learned that such a thing works :-)).
I was talking about the original idea from #c0, i.e. splitting off conda-forge specific activation. Even if we long term don't want people relying on activation scripts, they already are, and the split will permit us to change things without breaking them.
It doesn't have to be long term. We can just work on removing reliance on activation scripts in cxx-compiler package etc.
As a quick update, @isuruf did some great work towards this goal in https://github.com/conda-forge/clangdev-feedstock/pull/405 & https://github.com/conda-forge/clangdev-feedstock/pull/407
Now it looks like we're (partially) recreating a pattern of how this was implemented in gcc (with so-called spec files). As of the current state of https://github.com/conda-forge/clangdev-feedstock/pull/407, this would look like
| GCC | Clang | |
|---|---|---|
| configuration files | conda-gcc-specs |
handled via build strings |
| convenience output for bare compiler | gcc-no-conda-specs |
clang-no-conda-cfg? |
I'm not a big fan of the conda- moving around between the positive/negative variant, especially since this is an ouput that's related to conda-forge('s compilers), not conda. To unify these patterns, I suggested to repeat the pattern from gcc (e.g. a separate output for the .cfg files that configure clang), and to avoid the specific configuration file name (specs & cfg) for the outputs, instead using a neutral & common name for both:
| GCC | Clang | |
|---|---|---|
| configuration files | conda-forge-gcc-config |
conda-forge-clang-config |
| convenience output for bare compiler | gcc-minimal |
clang-minimal |
I wanted to make this part of the conversation a bit more visible. Would be happy to hear what other people think.
PS. Obviously there's many other colours in which to paint this bikeshed. I decided to put conda-forge first in the above, but I could similarly imagine {clang,gcc}-config-conda-forge or {clang,gcc}-config-cf
The convenience output is something that is needed rarely, so I don't want to bikeshed on the name and spend a lot of time on this.
The convenience output is something that is needed rarely
There's quite a bit of interest in this from various parties. I don't want to miss the opportunity to design this coherently and then have to live with it ~forever.
I don't want to bikeshed on the name and spend a lot of time on this.
Great, so you accept my above proposal for naming the outputs? Or do you have a better suggestion that I can quickly agree to?
FWIW, I think {gcc,clang}-minimal would hit the nail on the head in terms of expressiveness and ease of use. It's similar in spirit to other recent convenience outputs like python-freethreading. I care less about how we name the config file output, but I think we should have one for clang too, and come up with a consistent name (e.g. one of the several suggestions above).
I don't know why we'd be under time pressure on this, but I've got a PR ready to go, we just need to switch on the allowed outputs once we agree on their names.
There's quite a bit of interest in this from various parties.
No, the interest is to use the ones with the cfg or specs files. There's very little interest in using the nocfg output. gcc-minimal would imply that the package is for minimally activated compilers which is not the case at all.
I like the original name gcc-no-conda-specs because it's very specific and technical and would be understood by power users only and these packages are for power users only. 99% of people would not need them and would be happy with just gcc and clang.
gcc-minimalwould imply that the package is for minimally activated compilers which is not the case at all.
That's a good point. It would be more minimal than what people actually want when we talk about "minimally activated" here. Fair enough that disabling the spec/cfg file is not relevant for most users. Even so, can we please spend a few minutes on designing this? Below are three choices, I'm hoping one of those would be fine for you.
The first is a previous suggestion, based on wanting to to unify this (and better reflecting "conda" -> "conda-forge"):
| GCC | Clang | |
|---|---|---|
| configuration files | conda-forge-gcc-specs |
conda-forge-clang-cfg |
| convenience output for bare compiler | gcc-no-specs |
clang-no-cfg |
That keeps the "power-user-only" aspect of reflecting the technical realities, but at least it'd be internally consistent. This had been leaning on naming the output for the configuration files after its content. But if we decide to lean on on the fact that the output pins the compiler itself, we could also keep the compiler name as first component
| GCC | Clang | |
|---|---|---|
| configuration files | gcc-specs |
clang-cfg |
| convenience output for bare compiler | gcc-no-specs |
clang-no-cfg |
Or, if we want to be verbose:
| GCC | Clang | |
|---|---|---|
| configuration files | gcc-conda-forge-specs |
clang-conda-forge-cfg |
| convenience output for bare compiler | gcc-no-conda-forge-specs |
clang-no-conda-forge-cfg |
I've excluded the variants with only "conda", because I think that is more misleading than either "conda-forge" or its absence.
1 & 2: gcc-no-specs this is misleading because there's already a spec file and the conda spec file is additional.
3: conda-forge is bad since there's a defaults::conda-gcc-specs and having divergent names are bad.
My suggestion:
| GCC | Clang | |
|---|---|---|
| configuration files | conda-gcc-specs |
no need |
| convenience output for bare compiler | gcc-no-conda-specs |
clang-no-conda-cfg |
Edited my suggestion
Those arguments make sense to me. If it's shared across c-f & defaults, "conda" is accurate. I liked it better before the edit though; gcc-conda-specs & gcc-no-conda-specs is definitely more consistent than conda-gcc-specs & gcc-no-conda-specs.
conda-forgeis bad since there's adefaults::conda-gcc-specsand having divergent names are bad.
Of course, any rename of existing outputs runs into this. OTOH, defaults just inherited https://github.com/conda-forge/ctng-compilers-feedstock/pull/91 and the other compiler work 1:1 (see here). And since we know how to do package renames (e.g. add new output with run_constrained: on the old one), this would resolve itself naturally once defaults picks up those changes.
Don't get me wrong, I can see the argument that a rename is not worth the effort, and that your suggestion minimises the amount of work we have to do now. It's just a bit of a hodgepodge in terms of naming & patterns, which makes me sad about cementing this for the long term.
no need
Even if we don't need it, wouldn't it make sense to use the same pattern (e.g. an output for the compiler configuration) between GCC & clang? Some divergences are unavoidable, but where we can avoid them, the less the better. So then
| GCC | Clang | |
|---|---|---|
| configuration files | gcc-conda-specs |
clang-conda-cfg |
| convenience output for bare compiler | gcc-no-conda-specs |
clang-no-conda-cfg |
would only need to rename a single output for GCC, and would otherwise not cause undue extra work.
For clang, we'd need clang-conda-cfg_linux-64 etc and it won't be the same.
The issue with the name gcc-conda-specs and gcc-no-conda-specs is that it feels like they are opposites of each other. It feels like first one is gcc with the conda specs and the second one is gcc without the conda specs, but this is not the case. However conda-gcc-specs is clear that it is just conda specific gcc specs file.
The issue with the name
gcc-conda-specsandgcc-no-conda-specsis that it feels like they are opposites of each other.
Isn't that the case though? Since the specs output pins gcc_impl_<tgt>, and gcc is really just the sum of impl+specs (in other words, equivalent to a convenience wrapper around the specs package by default), that would be a valid interpretation.
I think that kind of consistency in naming would be a huge plus, even if we don't have an explicit cfg output for clang
No, conda-gcc-specs doesn't include the unprefixed gcc.
No,
conda-gcc-specsdoesn't include the unprefixed gcc.
I didn't say that it did. I said that the spec output is the same in terms of dependencies as gcc. The only difference is that gcc contains bin/gcc etc. symlinks, but those could just as well live in gcc-conda-specs if we wanted[^1], and then the result of installing either would be fully equivalent in the spec-ful case; spec-less gcc would keep the symlinks obviously.
That would give gcc-{,no-}conda-specs for an explicit choice of with/without specs, and gcc as the universal option that's compatible with either, defaulting to spec-ful.
[^1]: I understand if this is not the most appealing option from a purist's view about what content belongs in which output, but it would IMO lead to a more cohesive overall story on the usage side.
I really don't like that suggestion. The symlinks should stay in gcc. It would be too confusing if it was any other way.