@@ -1028,10 +1028,137 @@ In order to qualify as a noarch python package, all of the following criteria mu
1028
1028
which builds on Linux `and ` Windows, with ``build_number `` offsets to create a pair packages, like
1029
1029
``dataclasses ``.
1030
1030
1031
+ .. hint ::
1032
+
1033
+ You can build platform-specific ``noarch `` packages to include runtime requirements depending on the target OS.
1034
+ See mini-tutorial below.
1035
+
1031
1036
If an existing python package qualifies to be converted to a noarch package, you can request the required changes
1032
1037
by opening a new issue and including ``@conda-forge-admin, please add noarch: python ``.
1033
1038
1039
+ .. _os_specific_noarch :
1040
+
1041
+ Noarch packages with OS-specific dependencies
1042
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1043
+
1044
+ It is possible to build ``noarch `` packages with runtime requirements that depend on the target OS (Linux, Windows,
1045
+ MacOS), regardless the architecture (amd64, ARM, PowerPC, etc). This approach relies on four concepts:
1046
+
1047
+ 1. Virtual packages. Prefixed with a double underscore, they are used by conda to represent properties of the running system
1048
+ as constraints for the solver. We will use ``__linux ``, ``__win `` or ``__osx ``, which are only present when
1049
+ the running platform is Linux, Windows, or MacOS, respectively. ``__unix `` is present in both Linux and MacOS. Note
1050
+ that this feature is **only fully available on conda 4.10 or above **.
1051
+ 2. Jinja conditionals, which can be used to mimic platform selectors.
1052
+ 3. ``conda-forge.ymls ``'s :ref: `noarch_platforms ` option.
1053
+ 4. conda-build's ``conda_build_config.yaml `` to create a matrix build that depends on the ``noarch_platforms `` values.
1054
+
1055
+ The idea is to generate OS-specific noarch packages for the OS that need different dependencies. Let's say you have a pure
1056
+ Python package, perfectly eligible for ``noarch: python ``, but on Windows it requires ``windows-only-dependency ``. You might
1057
+ have something like:
1058
+
1059
+ .. code-block :: yaml
1060
+
1061
+ # recipe/meta.yaml
1062
+ name : package
1063
+ source :
1064
+ ...
1065
+ build :
1066
+ number : 0
1067
+ requirements :
1068
+ ...
1069
+ run :
1070
+ - python
1071
+ - numpy
1072
+ - windows-only-dependency # [win]
1073
+
1074
+ We can replace it with:
1075
+
1076
+ .. code-block :: yaml
1077
+
1078
+ # recipe/meta.yaml
1079
+ name : package
1080
+ source :
1081
+ ...
1082
+ build :
1083
+ number : 0
1084
+ noarch : python
1085
+ requirements :
1086
+ ...
1087
+ run :
1088
+ - python
1089
+ - numpy
1090
+ - __{{ target_os }}
1091
+ {% if target_os == 'win' %}
1092
+ - windows-only-dependency
1093
+ {% endif %}
1094
+
1095
+ Cool! Where does ``target_os `` come from? We need to define it in ``conda_build_config.yaml ``.
1096
+ Note how the values have been chosen carefully so they match the virtual packages names:
1097
+
1098
+ .. code-block :: yaml
1099
+
1100
+ # recipe/conda_build_config.yaml
1101
+ target_os :
1102
+ - unix # [unix]
1103
+ - win # [win]
1104
+
1105
+ By default, conda-forge will only build ``noarch `` packages on a ``linux-64 `` CI runner, so
1106
+ the ``target_os `` matrix would only provide the ``unix `` value (because the ``# [win] `` selector
1107
+ would never be true). Fortunately, we can change the default behaviour in ``conda-forge.yml ``:
1108
+
1109
+ .. code-block :: yaml
1110
+
1111
+ # conda-forge.yml
1112
+ noarch_platforms :
1113
+ - linux-64
1114
+ - win-64
1115
+
1116
+ This will provide two runners per package! But since we are using selectors in ``conda_build_config.yaml ``,
1117
+ only one is true at a time. Perfect! All these changes require a feedstock rerender to be applied:
1118
+ :ref: `_dev_update_rerender `.
1119
+
1120
+ Last but not least, what if you need conditional dependencies on all three operating systems? Do it like this:
1121
+
1122
+ .. code-block :: yaml
1123
+
1124
+ # recipe/meta.yaml
1125
+ name : package
1126
+ source :
1127
+ ...
1128
+ build :
1129
+ number : 0
1130
+ noarch : python
1131
+ requirements :
1132
+ ...
1133
+ run :
1134
+ - python
1135
+ - numpy
1136
+ - __{{ target_os }}
1137
+ {% if target_os == 'osx' %}
1138
+ - osx-only-dependency
1139
+ {% elif target_os == 'win' %}
1140
+ - windows-only-dependency
1141
+ {% else %}
1142
+ - linux-only-dependency
1143
+ {% endif %}
1144
+
1145
+ .. code-block :: yaml
1146
+
1147
+ # recipe/conda_build_config.yaml
1148
+ target_os :
1149
+ - linux # [linux]
1150
+ - osx # [osx]
1151
+ - win # [win]
1152
+
1153
+ .. code-block :: yaml
1154
+
1155
+ # conda-forge.yml
1156
+ noarch_platforms :
1157
+ - linux-64
1158
+ - osx-64
1159
+ - win-64
1034
1160
1161
+ Again, d
1035
1162
Noarch generic
1036
1163
--------------
1037
1164
0 commit comments