Skip to content

Commit d8113d1

Browse files
authored
Merge pull request #2596 from mgorny/compiler-refactor
docs(infrastructure/compilers): Refactor and reword to improve clarity
2 parents 196bae9 + 12d5133 commit d8113d1

File tree

2 files changed

+183
-56
lines changed

2 files changed

+183
-56
lines changed

docs/maintainer/infrastructure.md

Lines changed: 180 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -494,15 +494,179 @@ This was sponsored by Prefix.dev. Below are the relevant pull requests for the s
494494
## Compilers and Runtimes
495495

496496
conda-forge builds and maintains its own set of compilers for various languages
497-
and/or systems (e.g., `C`, `FORTRAN`, `C++`, `CUDA`, etc.). These are used
497+
and/or systems (e.g., C, Fortran, C++, CUDA, etc.). These are used
498498
in all of our CI builds to build essentially all artefacts published by conda-forge.
499499

500500
This compiler infrastructure has a critical role beyond building everything, which
501501
is to ensure that packages stay compatible with each other. This is due to how compiled
502502
packages have a so-called [Application Binary Interface](../glossary.md#abi)
503503
(ABI), and how changes in the compiler infrastructure may break this ABI, leading
504504
to crashes, miscalculations, etc. Generally speaking, using a consistent compiler
505-
version greatly reduces the risk of ABI breaks.
505+
setup greatly reduces the risk of ABI breaks.
506+
507+
### Using compilers in feedstocks
508+
509+
There are two kinds of compiler-related packages in conda-forge: implementation packages
510+
that install the compiler itself, and _activation_ packages that install scripts
511+
that set the build environment to use the respective compiler by default. These
512+
scripts set up a number of standard environment variables such as `CC`, and perform
513+
setup actions for the common build systems such as CMake and Meson.
514+
515+
Recipes provide a `compiler` macro that is used to generate the correct dependency
516+
on a compiler for the language specified. Compilers are always added to `build`
517+
dependencies. For example, to depend on a C and C++ compilers, one would specify:
518+
519+
```yaml
520+
requirements:
521+
build:
522+
- {{ compiler('c') }}
523+
- {{ compiler('cxx') }}
524+
- {{ stdlib('c') }}
525+
```
526+
527+
The possible parameter values are listed in the [compilers supplied by conda-forge
528+
](#compilers-supplied-by-conda-forge) section.
529+
530+
Almost always, in addition to a compiler of any programming language, you will
531+
also need to depend on the C standard library via the `stdlib('c')` macro.
532+
Note that currently this macro is only used to refer to the C standard library
533+
and in the vast majority of cases all programming languages use that library,
534+
therefore the macro is always used with the `'c'` parameter. For example,
535+
a regular Rust package would use:
536+
537+
```yaml
538+
requirements:
539+
build:
540+
- {{ compiler('rust') }}
541+
- {{ stdlib('c') }}
542+
```
543+
544+
### Using non-default compilers in feedstocks
545+
546+
Our default compiler stack is made up very differently on each platform; each platform
547+
has its own default compiler, with its own set of feedstocks that provide them.
548+
However, it is often possible to use a different compiler if necessary. For example,
549+
to use Clang 21 as the C and C++ compiler _on all platforms_ (and not just macOS), one would additionally specify
550+
in `recipe/conda_build_config.yaml`:
551+
552+
```yaml
553+
c_compiler:
554+
- clang
555+
c_compiler_version:
556+
- 21
557+
cxx_compiler:
558+
- clangxx
559+
cxx_compiler_version:
560+
- 21
561+
```
562+
563+
Technically, the `{{ compiler(...) }}` macro may accept arbitrary compiler names
564+
as an argument. However, this only works as an incident of the current implementation.
565+
Names other than the listed in this document or the
566+
[conda-forge/conda-forge-pinning-feedstock](https://github.com/conda-forge/conda-forge-pinning-feedstock)
567+
repository should not be used.
568+
569+
### Installing standard compilers manually
570+
571+
While the primary use case for conda-forge compiler packages is to provide build tools
572+
for feedstocks, we try to keep the compilers in their various versions
573+
working also for direct usage in conda environments. In fact, we also provide a few
574+
convenience packages to install the respective compilers. For example, the [compilers feedstock
575+
](https://github.com/conda-forge/compilers-feedstock) provides packages installing the same
576+
C, C++ and Fortran compilers as normally used in build environments, along with their
577+
activation scripts.
578+
579+
For example, to install these three compilers, one could invoke:
580+
581+
```bash
582+
conda install compilers
583+
```
584+
585+
Alternatively, specific compilers can be requested:
586+
587+
```bash
588+
conda install cxx-compiler fortran-compiler
589+
```
590+
591+
Other available convenience packages are listed in the [platform-default
592+
compilers](#platform-default-compilers) list.
593+
594+
Please note that these packages must not be used in a feedstock; instead the macros
595+
listed in [Using compilers in feedstocks](#using-compilers-in-feedstocks) must be used.
596+
597+
### MSVC compiler on Windows
598+
599+
conda-forge is not allowed to redistribute the MSVC compiler used on Windows,
600+
and therefore only provides the activation scripts for an externally installed
601+
compiler. Users who wish to compile code using MSVC, both for local use
602+
and feedstock builds, have to install Microsoft Visual Studio manually.
603+
For more information, see [Notes on native code](/docs/maintainer/knowledge_base/#notes-on-native-code)
604+
in Knowledge Base.
605+
606+
### Compilers supplied by conda-forge
607+
608+
#### Platform-default compilers
609+
610+
Currently conda-forge providers compilers for the following languages, that
611+
can be specified as arguments to the `{{ compiler(...) }}` macro:
612+
613+
- `c`, also provided by `c-compiler` package
614+
- `cxx` (C++), also provided by `cxx-compiler`
615+
- `fortran`, also provided by `fortran-compiler`
616+
- `cuda`, also provided by `cuda-compiler`; see also [Guide for Maintainers of
617+
Recipes That Use CUDA](https://github.com/conda-forge/cuda-feedstock/blob/main/recipe/doc/recipe_guide.md)
618+
- `rust`; see [Rust packages](/docs/maintainer/example_recipes/rust/)
619+
- `go-cgo` and `go-nocgo`; see [Go packages](/docs/maintainer/example_recipes/go/)
620+
621+
The authoritative source of the current compilers and versions for various languages
622+
and platforms is the [conda_build_config.yaml](https://github.com/conda-forge/conda-forge-pinning-feedstock/blob/master/recipe/conda_build_config.yaml) file
623+
in the [conda-forge/conda-forge-pinning-feedstock](https://github.com/conda-forge/conda-forge-pinning-feedstock) repository
624+
as described in [Globally pinned packages](pinning_deps.md#globally-pinned-packages).
625+
626+
The default C and C++ compilers are GCC on Linux, Clang on macOS and VS2022
627+
on Windows. Clang can also be used as the compiler on Linux and Windows.
628+
The default Fortran compiler is the GNU Fortran compiler on Linux and macOS,
629+
and Flang on Windows.
630+
631+
Note that when used in conjunction with CUDA, the GCC version is restricted by the
632+
maximum version supported by nvcc (which is also reflected in the global pinning).
633+
634+
#### clang vs. clang-cl on Windows
635+
636+
The `clang` compiler package installs two frontends, and conda-forge
637+
provides separate activation scripts for Windows, for each of them. Therefore,
638+
the following arguments can be used in `recipe/conda_build_config.yaml`:
639+
640+
- `clang` to use the `clang` frontend with GCC argument syntax
641+
- `clang-cl` to use the `clang-cl` frontend with MSVC argument syntax
642+
643+
To use the `clang-cl` frontend on Windows, and the `clang` frontend on other
644+
systems, the following dependencies can be used:
645+
646+
- `{{ compiler('clang') }}` for the C compiler
647+
- `{{ compiler('clangxx') }}` for the C++ compiler
648+
649+
#### MinGW-based compiler stack for Windows
650+
651+
There exists an alternative, MinGW-based, compiler stack on Windows. To use it,
652+
the following arguments can be passed to the `{[ compiler(...) }}` macro:
653+
654+
- `m2w64_c` for the C compiler
655+
- `m2w64_cxx` for the C++ compiler
656+
- `m2w64_fortran` for the Fortran compiler
657+
658+
Along with these compilers, `stdlib('m2w64_c')` needs to be used.
659+
660+
These compilers correspond to the `gcc`, `gxx` and `gfortran` packages,
661+
respectively. The `m2w64-*` compiler packages (with the exception of
662+
`m2w64-sysroot`) are obsolete and no longer updated.
663+
664+
The MinGW C++ and Fortran compilers are not ABI-compatible with the default
665+
stack, and therefore special care needs to be taken when performing
666+
cross-library calls. The executables produced by them may link to the MinGW
667+
compiler libraries, notably `libgcc`, `libwinpthread` and `libgomp`.
668+
669+
### Compiler ABI stability policy
506670

507671
Compilers generally strive to maintain ABI-compatibility across versions, meaning that
508672
combining artefacts for the same target produced by different versions of the same
@@ -527,10 +691,6 @@ While we do not have any formal promises of support for a generation of ABI-comp
527691
compilers, we have historically maintained them according to the following (non-binding)
528692
principles.
529693

530-
- The authoritative source of the current compilers and versions for various languages
531-
and platforms is the [conda_build_config.yaml](https://github.com/conda-forge/conda-forge-pinning-feedstock/blob/master/recipe/conda_build_config.yaml)
532-
in the [conda-forge/conda-forge-pinning-feedstock](https://github.com/conda-forge/conda-forge-pinning-feedstock)
533-
as described in [Globally pinned packages](pinning_deps.md#globally-pinned-packages).
534694
- We provide no support of any kind in terms of the long-term stability/support of a given compiler generation.
535695
- We upgrade them in an ad-hoc manner on a periodic basis as we have the time and energy to do so.
536696
Note that because of the way we enforce runtime constraints, these compiler upgrades will not break
@@ -555,23 +715,23 @@ feedstocks get rerendered.
555715

556716
For such ABI-compatible upgrades, similar but looser principles apply:
557717

558-
- The pins are similarly defined in the global pinning, see [Globally Pinned Packages](pinning_deps.md#globally-pinned-packages).
559718
- We provide no support of any kind in terms of the long-term availability of a given compiler version.
560719
- We generally provide notice in the form of an announcement when a compiler is going to be upgraded.
561720
- Without promising any timelines, our compilers on Linux and OSX are normally
562721
very recent; on Windows, we generally use the last supported VS version.
563722

564-
Despite the lack of explicit support, we try to keep the compilers in their various versions
565-
working also outside of conda-forge, and even provide an easy way to install them
566-
(through the [compilers feedstock](https://github.com/conda-forge/compilers-feedstock)).
723+
### More on compiler feedstocks
567724

568-
More specifically, each compiler uses an _activation_ package that makes the difference
569-
between it being merely present in a build environment, and it being used by default.
570-
These will be installed when using `{{ compiler('xyz') }}` in `meta.yaml`, where
571-
`'xyz'` is one of `'c', 'cxx', 'fortran', 'cuda', 'rust', 'go-cgo', 'go-nocgo'`.
725+
The compiler activation and implementation packages are built by two separate
726+
feedstocks, with a few exceptions. The activation packages install scripts
727+
into `/etc/conda/activate.d` and `/etc/conda/deactivate.d` directories, which
728+
are invoked automatically when those environments are activated during the build. These
729+
scripts are then used by the build tool to respectively prepare for building
730+
with the given compiler, and clean up afterwards. The implementation packages
731+
install the compilers themselves. More details can be found in the [Anaconda compiler tools
732+
section of conda-build documentation](https://docs.conda.io/projects/conda-build/en/latest/resources/compiler-tools.html).
572733

573-
Our default compiler stack is made up very differently on each platform; each platform
574-
has its own default compiler, with its own set of feedstocks that provide them. Due to historical
734+
Due to historical
575735
reasons (the way compilers are integrated with their OS, and the amount of
576736
software written in them, etc.), the most impactful languages are C & C++ (though
577737
Fortran is considered part of the default, not least because GCC compiles all three).
@@ -580,10 +740,8 @@ Linux (GCC):
580740

581741
- [C, C++, Fortran] Activation: https://github.com/conda-forge/ctng-compiler-activation-feedstock/
582742
- [C, C++, Fortran] Implementation: https://github.com/conda-forge/ctng-compilers-feedstock
583-
- Note that when used in conjunction with CUDA, compiler versions are restricted by the
584-
maximum GCC version supported by nvcc (which is also reflected in the global pinning).
585743

586-
OSX (Clang):
744+
OSX (Clang + GNU Fortran):
587745

588746
- [C, C++] Activation: https://github.com/conda-forge/clang-compiler-activation-feedstock/
589747
- [C, C++] Required feedstocks:
@@ -597,17 +755,12 @@ OSX (Clang):
597755
- [Fortran] Activation: https://github.com/conda-forge/gfortran_osx-64-feedstock/
598756
- [Fortran] Implementation: https://github.com/conda-forge/gfortran_impl_osx-64-feedstock/
599757

600-
Windows (MSVC):
758+
Windows (MSVC + Flang):
601759

602760
- [C, C++] Activation: https://github.com/conda-forge/vc-feedstock
603761
(we cannot redistribute the actual MSVC compilers due to licensing constraints)
604762
- [Fortran] Activation & Implementation: https://github.com/conda-forge/flang-feedstock
605763

606-
There exists an alternative, MinGW-based, compiler stack on Windows, which is available
607-
with a `m2w64_` prefix (e.g. `{{ compiler('m2w64_c') }}`). However, it is falling out
608-
of use now that most projects will natively support compilation also with MSVC, in addition
609-
to several complications arising from mixing compiler stacks.
610-
611764
Additionally, there is a possibility to use `clang` as a compiler on Linux & Windows:
612765

613766
- Activation (Linux): https://github.com/conda-forge/ctng-compiler-activation-feedstock/
@@ -621,6 +774,8 @@ Aside from the main C/C++/Fortran compilers, these are the feedstocks for the ot
621774
- [Go] [Activation](https://github.com/conda-forge/go-activation-feedstock)
622775
and [Implementation](https://github.com/conda-forge/go-feedstock)
623776

777+
### Conda-forge compiler maintenance
778+
624779
To upgrade the compiler version of our default compilers in the global pinning for
625780
Linux or OSX, ensure that the respective above-mentioned feedstocks have been rebuilt
626781
for the new major version, that all interrelated versions are lifted at the same time,

docs/maintainer/knowledge_base.md

Lines changed: 3 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -244,8 +244,8 @@ if errorlevel 1 exit 1
244244

245245
The following feedstocks are examples of this build structure deployed:
246246

247-
- [libpng](https://github.com/conda-forge/libpng-feedstock/blob/master/recipe/bld.bat)
248-
- [Pugixml](https://github.com/conda-forge/pugixml-feedstock/blob/master/recipe/bld.bat)
247+
- [libpng](https://github.com/conda-forge/libpng-feedstock/blob/main/recipe/build.bat)
248+
- [Pugixml](https://github.com/conda-forge/pugixml-feedstock/blob/main/recipe/bld.bat)
249249

250250
<a id="building-for-different-vc-versions"></a>
251251

@@ -351,35 +351,7 @@ Batch syntax is a bit different from Bash and friends on Unix, so we have collec
351351

352352
### Compilers
353353

354-
Compilers are dependencies with a special syntax and are always added to `requirements/build`.
355-
356-
There are currently five supported compilers:
357-
358-
- C
359-
- cxx
360-
- Fortran
361-
- Go
362-
- Rust
363-
364-
A package that needs all five compilers would define
365-
366-
```yaml
367-
requirements:
368-
build:
369-
- {{ compiler('c') }}
370-
- {{ compiler('cxx') }}
371-
- {{ compiler('fortran') }}
372-
- {{ compiler('go') }}
373-
- {{ compiler('rust') }}
374-
```
375-
376-
:::note
377-
378-
Appropriate compiler runtime packages will be automatically added to the package's runtime requirements and therefore
379-
there's no need to specify `libgcc` or `libgfortran`. There are additional informations about how conda-build 3 treats
380-
compilers in the [conda docs](https://docs.conda.io/projects/conda-build/en/stable/resources/compiler-tools.html).
381-
382-
:::
354+
Dependencies on compilers are explained in detail in [Compilers and Runtimes](/docs/maintainer/infrastructure/#compilers-and-runtimes) infrastructure documentation.
383355

384356
<a id="cross-compilation"></a>
385357

0 commit comments

Comments
 (0)