Skip to content

Commit 032898b

Browse files
authored
Merge pull request #1839 from jaimergp/platform-noarch
2 parents 6a95669 + 0340b8b commit 032898b

File tree

1 file changed

+115
-0
lines changed

1 file changed

+115
-0
lines changed

src/maintainer/knowledge_base.rst

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,9 +1107,124 @@ In order to qualify as a noarch python package, all of the following criteria mu
11071107
which builds on Linux `and` Windows, with ``build_number`` offsets to create a pair packages, like
11081108
``dataclasses``.
11091109

1110+
.. hint::
1111+
1112+
You can build platform-specific ``noarch`` packages to include runtime requirements depending on the target OS.
1113+
See mini-tutorial below.
1114+
11101115
If an existing python package qualifies to be converted to a noarch package, you can request the required changes
11111116
by opening a new issue and including ``@conda-forge-admin, please add noarch: python``.
11121117

1118+
.. _os_specific_noarch:
1119+
1120+
Noarch packages with OS-specific dependencies
1121+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1122+
1123+
It is possible to build ``noarch`` packages with runtime requirements that depend on the target OS
1124+
(Linux, Windows, MacOS), regardless the architecture (amd64, ARM, PowerPC, etc). This approach
1125+
relies on three concepts:
1126+
1127+
1. `Virtual packages <https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-virtual.html>`__.
1128+
Prefixed with a double underscore, they are used by conda to represent system properties as
1129+
constraints for the solver at install-time. We will use ``__linux``, ``__win`` or ``__osx``,
1130+
which are only present when the running platform is Linux, Windows, or MacOS, respectively.
1131+
``__unix`` is present in both Linux and MacOS. Note that this feature is **only fully available
1132+
on conda 4.10 or above**.
1133+
2. ``conda-forge.yml``'s :ref:`noarch_platforms` option.
1134+
3. **conda-build 3.25.0 or above** changing the build hash depending on virtual packages used.
1135+
1136+
The idea is to generate different noarch packages for each OS needing different dependencies.
1137+
Let's say you have a pure Python package, perfectly eligible for ``noarch: python``, but on Windows
1138+
it requires ``windows-only-dependency``. You might have something like:
1139+
1140+
.. code-block:: yaml
1141+
:caption: recipe/meta.yaml (original)
1142+
1143+
name: package
1144+
source:
1145+
# ...
1146+
build:
1147+
number: 0
1148+
requirements:
1149+
# ...
1150+
run:
1151+
- python
1152+
- numpy
1153+
- windows-only-dependency # [win]
1154+
1155+
Being non-noarch, this means that the build matrix will include at least 12 outputs: three platforms,
1156+
times four Python versions. This gets worse with ``arm64``, ``aarch64`` and ``ppc64le`` in the mix.
1157+
We can get it down to two outputs if replace it with this other approach!
1158+
1159+
.. code-block:: yaml
1160+
:caption: recipe/meta.yaml (modified)
1161+
1162+
name: package
1163+
source:
1164+
# ...
1165+
build:
1166+
number: 0
1167+
noarch: python
1168+
requirements:
1169+
host:
1170+
- python >=3.7
1171+
# ...
1172+
run:
1173+
- python >=3.7
1174+
- numpy
1175+
- __unix # [unix]
1176+
- __win # [win]
1177+
- windows-only-dependency # [win]
1178+
1179+
Do not forget to specify the platform virtual packages with their selectors!
1180+
Otherwise, the solver will not be able to choose the variants correctly.
1181+
1182+
By default, conda-forge will only build ``noarch`` packages on a ``linux_64`` CI runner, so
1183+
only the ``# [unix]`` selectors would be true. However, we can change this behaviour using
1184+
the ``noarch_platforms`` option in ``conda-forge.yml``:
1185+
1186+
.. code-block:: yaml
1187+
:caption: conda-forge.yml
1188+
1189+
noarch_platforms:
1190+
- linux_64
1191+
- win_64
1192+
1193+
This will provide two runners per package! Perfect! All these changes require a
1194+
feedstock rerender to be applied. See :ref:`dev_update_rerender`.
1195+
1196+
If you need conditional dependencies on all three operating systems, this is how you do it:
1197+
1198+
.. code-block:: yaml+jinja
1199+
:caption: recipe/meta.yaml
1200+
1201+
name: package
1202+
source:
1203+
# ...
1204+
build:
1205+
number: 0
1206+
noarch: python
1207+
requirements:
1208+
# ...
1209+
run:
1210+
- python
1211+
- numpy
1212+
- __linux # [linux]
1213+
- __osx # [osx]
1214+
- __win # [win]
1215+
- linux-only-dependency # [linux]
1216+
- osx-only-dependency # [osx]
1217+
- windows-only-dependency # [win]
1218+
1219+
.. code-block:: yaml
1220+
:caption: conda-forge.yml
1221+
1222+
noarch_platforms:
1223+
- linux_64
1224+
- osx_64
1225+
- win_64
1226+
1227+
Again, remember to rerender after adding / modifying these files so the changes are applied.
11131228

11141229
Noarch generic
11151230
--------------

0 commit comments

Comments
 (0)