aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/en/books/porters-handbook/flavors/_index.adoc
blob: 46bace6d073b67f899c2d03688e8d382daf74cdd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
---
title: Chapter 7. Flavors
prev: books/porters-handbook/special
next: books/porters-handbook/plist
description: Flavors are a way to have multiple variations of a port
tags: ["Ports", "Flavors", "introduction", "how-to", "guide"]
showBookMenu: true
weight: 7
path: "/books/porters-handbook/"
---

[[flavors]]
= Flavors
:doctype: book
:toc: macro
:toclevels: 1
:icons: font
:sectnums:
:sectnumlevels: 6
:sectnumoffset: 7
:partnums:
:source-highlighter: rouge
:experimental:
:images-path: books/porters-handbook/

ifdef::env-beastie[]
ifdef::backend-html5[]
:imagesdir: ../../../../images/{images-path}
endif::[]
ifndef::book[]
include::shared/authors.adoc[]
include::shared/mirrors.adoc[]
include::shared/releases.adoc[]
include::shared/attributes/attributes-{{% lang %}}.adoc[]
include::shared/{{% lang %}}/teams.adoc[]
include::shared/{{% lang %}}/mailing-lists.adoc[]
include::shared/{{% lang %}}/urls.adoc[]
toc::[]
endif::[]
ifdef::backend-pdf,backend-epub3[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]
endif::[]

ifndef::env-beastie[]
toc::[]
include::../../../../../shared/asciidoctor.adoc[]
endif::[]

[[flavors-intro]]
== An Introduction to Flavors

Flavors are a way to have multiple variations of a port.
The port is built multiple times, with variations.

For example, a port can have a normal version with many features and quite a few dependencies, and a light "lite" version with only basic features and minimal dependencies.

Another example could be, a port can have a GTK flavor and a QT flavor, depending on which toolkit it uses.

[[flavors-using]]
== Using FLAVORS

To declare a port having multiple flavors, add `FLAVORS` to its [.filename]#Makefile#.
The first flavor in `FLAVORS` is the default flavor.

[TIP]
====
It can help simplify the logic of the [.filename]#Makefile# to also define `FLAVOR` as:

[.programlisting]
....
FLAVOR?=	${FLAVORS:[1]}
....
====

[IMPORTANT]
====
To distinguish flavors from options, which are always uppercase letters, flavor names can _only_ contain lowercase letters, numbers, and the underscore `_`.
====

[[flavors-using-ex1]]
.Basic Flavors Usage
[example]
====
If a port has a "lite" slave port, the slave port can be removed, and the port can be converted to flavors with:

[.programlisting]
....
FLAVORS=	default lite
lite_PKGNAMESUFFIX=	-lite
[...]
.if ${FLAVOR:U} != lite
[enable non lite features]
.endif
....

====

[[flavors-using-ex2]]
.Another Basic Flavors Usage
[example]
====
If a port has a `-nox11` slave port, the slave port can be removed, and the port can be converted to flavors with:

[.programlisting]
....
FLAVORS=	x11 nox11
FLAVOR?=	${FLAVORS:[1]}
nox11_PKGNAMESUFFIX=	-nox11
[...]
.if ${FLAVOR} == x11
[enable x11 features]
.endif
....

====

[[flavors-using-ex3]]
.More Complex Flavors Usage
[example]
====
Here is a slightly edited excerpt of what is present in package:devel/libpeas[], a port that uses the <<flavors-auto-python,Python flavors>>.
With the default Python 2 and 3 versions being 2.7 and 3.6, it will automatically get `FLAVORS=py27 py36`

[.programlisting]
....
USES=		gnome python
USE_PYTHON=	flavors 

.if ${FLAVOR:Upy27:Mpy2*} 
USE_GNOME=	pygobject3 

CONFIGURE_ARGS+=	--enable-python2 --disable-python3

BUILD_WRKSRC=	${WRKSRC}/loaders/python 
INSTALL_WRKSRC=	${WRKSRC}/loaders/python 
.else # py3*
USE_GNOME+=	py3gobject3 

CONFIGURE_ARGS+=	--disable-python2 --enable-python3 \
			ac_cv_path_PYTHON3_CONFIG=${LOCALBASE}/bin/python${PYTHON_VER}-config 

BUILD_WRKSRC=	${WRKSRC}/loaders/python3 
INSTALL_WRKSRC=	${WRKSRC}/loaders/python3 
.endif

py34_PLIST=	${.CURDIR}/pkg-plist-py3 
py35_PLIST=	${.CURDIR}/pkg-plist-py3 
py36_PLIST=	${.CURDIR}/pkg-plist-py3
....

This port does not use `USE_PYTHON=distutils` but needs Python flavors anyway.
To guard against `FLAVOR` being empty, which would cause a man:make[1] error, use `${FLAVOR:U}` in string comparisons instead of `${FLAVOR}`.
The Gnome Python gobject3 bindings have two different names, one for Python 2, pygobject3 and one for Python 3, py3gobject3.
The `configure` script has to run in [.filename]#${WRKSRC}#, but we are only interested in building and installing the Python 2 or Python 3 parts of the software, so set the build and install base directories appropriately.
Hint about the correct Python 3 config script path name.
The packing list is different when the built with Python 3. As there are three possible Python 3 versions, set `PLIST` for all three using the <<flavors-using-helpers,helper>>.
====

[[flavors-using-helpers]]
=== Flavors Helpers

To make the [.filename]#Makefile# easier to write, a few flavors helpers exist.

This list of helpers will set their variable:

* `_flavor__PKGNAMEPREFIX`
* `_flavor__PKGNAMESUFFIX`
* `_flavor__PLIST`
* `_flavor__DESCR`

This list of helpers will append to their variable:

* `_flavor__CONFLICTS`
* `_flavor__CONFLICTS_BUILD`
* `_flavor__CONFLICTS_INSTALL`
* `_flavor__PKG_DEPENDS`
* `_flavor__EXTRACT_DEPENDS`
* `_flavor__PATCH_DEPENDS`
* `_flavor__FETCH_DEPENDS`
* `_flavor__BUILD_DEPENDS`
* `_flavor__LIB_DEPENDS`
* `_flavor__RUN_DEPENDS`
* `_flavor__TEST_DEPENDS`


[[flavors-helpers-ex1]]
.Flavor Specific `PKGNAME`
[example]
====
As all packages must have a different package name, flavors must change theirs, using `_flavor__PKGNAMEPREFIX` and `_flavor__PKGNAMESUFFIX` makes this easy:

[.programlisting]
....
FLAVORS=	normal lite
lite_PKGNAMESUFFIX=	-lite
....

====

[[flavors-auto-php]]
== `USES=php` and Flavors

When using crossref:uses[uses-php,`php`] with one of these arguments, `phpize`, `ext`, `zend`, or `pecl`,
the port will automatically have `FLAVORS` filled in with the PHP versions it supports.

[[flavors-auto-php-ex1]]
.Simple `USES=php` Extension
[example]
====
This will generate package for all the supported versions:

[.programlisting]
....
PORTNAME=	some-ext
PORTVERSION=	0.0.1
PKGNAMEPREFIX=	${PHP_PKGNAMEPREFIX}

USES=		php:ext
....

This will generate package for all the supported versions but 7.2:

[.programlisting]
....
PORTNAME=	some-ext
PORTVERSION=	0.0.1
PKGNAMEPREFIX=	${PHP_PKGNAMEPREFIX}

USES=		php:ext
IGNORE_WITH_PHP=	72
....

====

[[flavors-auto-php-app]]
=== PHP Flavors with PHP Applications

PHP applications can also be flavorized.

This allows generating packages for all PHP versions, so that users can use them with whatever version they need on their servers.

[IMPORTANT]
====
PHP applications that are flavorized _must_ append `PHP_PKGNAMESUFFIX` to their package names.
====

[[flavors-auto-php-app-ex1]]
.Flavorizing a PHP Application
[example]
====
Adding Flavors support to a PHP application is straightforward:

[.programlisting]
....
PKGNAMESUFFIX=	${PHP_PKGNAMESUFFIX}

USES=	php:flavors
....

====

[TIP]
====
When adding a dependency on a PHP flavored port, use `@${PHP_FLAVOR}`.
_Never_ use `FLAVOR` directly.
====

[[flavors-auto-python]]
== `USES=python` and Flavors

When using crossref:uses[uses-python,`python`] and `USE_PYTHON=distutils`,
the port will automatically have `FLAVORS` filled in with the Python versions it supports.

[[flavors-auto-python-ex1]]
.Simple `USES=python`
[example]
====
Supposing the current Python supported versions are 2.7, 3.4, 3.5, and 3.6, and the default Python 2 and 3 versions are 2.7 and 3.6, a port with:

[.programlisting]
....
USES=	python
USE_PYTHON=	distutils
....

Will get these flavors: `py27`, and `py36`.

[.programlisting]
....
USES=	python
USE_PYTHON=	distutils allflavors
....

Will get these flavors: `py27`, `py34`, `py35` and `py36`.
====

[[flavors-auto-python-ex2]]
.`USES=python` with Version Requirements
[example]
====
Supposing the current Python supported versions are 2.7, 3.4, 3.5, and 3.6, and the default Python 2 and 3 versions are 2.7 and 3.6, a port with:

[.programlisting]
....
USES=	python:-3.5
USE_PYTHON=	distutils
....

Will get this flavor: `py27`.

[.programlisting]
....
USES=	python:-3.5
USE_PYTHON=	distutils allflavors
....

Will get these flavors: `py27`, `py34`, and `py35`.

[.programlisting]
....
USES=	python:3.4+
USE_PYTHON=	distutils
....

Will get this flavor: `py36`.

[.programlisting]
....
USES=	python:3.4+
USE_PYTHON=	distutils allflavors
....

Will get these flavors: `py34`, `py35`, and `py36`.
====

`PY_FLAVOR` is available to depend on the correct version of Python modules.
All dependencies on flavored Python ports should use `PY_FLAVOR`, and not `FLAVOR` directly..

[[flavors-auto-python-ex3]]
.For a Port Not Using `distutils`
[example]
====
If the default Python 3 version is 3.6, the following will set `PY_FLAVOR` to `py36`:

[.programlisting]
....
RUN_DEPENDS=	${PYTHON_PKGNAMEPREFIX}mutagen>0:audio/py-mutagen@${PY_FLAVOR}

USES=	python:3.5+
....

====

[[flavors-auto-lua]]
== `USES=lua` and Flavors

When using crossref:uses[uses-lua,`lua:module`] or crossref:uses[uses-lua,`lua:flavors`],
the port will automatically have `FLAVORS` filled in with the Lua versions it supports.
However, it is not expected that ordinary applications (rather than Lua modules) should use this feature;
most applications that embed or otherwise use Lua should simply use `USES=lua`.

`LUA_FLAVOR` is available (and must be used) to depend on the correct version of dependencies regardless of whether the port used the `flavors` or `module` parameters.

See crossref:special[using-lua,Using Lua] for further information.