Gentoo Archives: gentoo-dev

From: "Michał Górny" <mgorny@g.o>
To: gentoo-dev@l.g.o
Cc: "Haelwenn (lanodan) Monnier" <contact@×××××××××.me>
Subject: Re: [gentoo-dev] [PATCH v2] gstreamer-meson.eclass: New eclass required for gstreamer-1.18.0+
Date: Tue, 23 Mar 2021 13:05:10
Message-Id: 61187be99e657f610db82acd414a02690f03862d.camel@gentoo.org
In Reply to: [gentoo-dev] [PATCH v2] gstreamer-meson.eclass: New eclass required for gstreamer-1.18.0+ by "Haelwenn (lanodan) Monnier"
1 On Tue, 2021-03-23 at 13:44 +0100, Haelwenn (lanodan) Monnier wrote:
2 > Gstreamer switched to meson in 1.16.0 and removed autotools support in 1.18.0,
3 > this eclass is an update of gstreamer.eclass.
4 >
5 > One significant change between autotools and meson is that in the latter we
6 > don't have easily extractable semantics in the buildsystem to get a list
7 > of plugins with extraneous dependencies that we currently split in other
8 > packages.
9 > Hence the rather ugly but currently required GST_PLUGINS_DISABLED block.
10 > The gstreamer_system_link function also got lost in translation.
11 >
12 > Differences from version 1:
13 > - Move to EAPI-7, including moving deps from DEPEND to BDEPEND when appropriate
14 > - Port python script to perl, this allows to avoid having to add PYTHON_COMPAT
15 >   into a python-unrelated eclass
16 > - Drop errorneous MULTILIB_USEDEP on virtual/pkgconfig
17 > - Fix running tests: defining multilib_src_test, media-libs/gstreamer[test] dep
18 > - Fix ebuild emesonargs being ignored
19 > - Remove legacy prune_libtool_files
20 > - virtualx wrapped for testing
21 >
22 > Fixes: https://bugs.gentoo.org/690468
23 >
24 > Signed-off-by: Haelwenn (lanodan) Monnier <contact@×××××××××.me>
25 > ---
26 >  eclass/gstreamer-meson.eclass | 320 ++++++++++++++++++++++++++++++++++
27 >  1 file changed, 320 insertions(+)
28 >  create mode 100644 eclass/gstreamer-meson.eclass
29 >
30 > diff --git a/eclass/gstreamer-meson.eclass b/eclass/gstreamer-meson.eclass
31 > new file mode 100644
32 > index 00000000000..14a825f76b5
33 > --- /dev/null
34 > +++ b/eclass/gstreamer-meson.eclass
35 > @@ -0,0 +1,320 @@
36 > +# Copyright 1999-2021 Gentoo Authors
37 > +# Distributed under the terms of the GNU General Public License v2
38 > +
39 > +# @ECLASS: gstreamer-meson.eclass
40 > +# @MAINTAINER:
41 > +# gstreamer@g.o
42 > +# @AUTHOR:
43
44 I think the list actually goes the other way around, i.e. you should add
45 yourself on top.
46
47 > +# Michał Górny <mgorny@g.o>
48 > +# Gilles Dartiguelongue <eva@g.o>
49 > +# Saleem Abdulrasool <compnerd@g.o>
50 > +# foser <foser@g.o>
51 > +# zaheerm <zaheerm@g.o>
52 > +# Steven Newbury
53 > +# Haelwenn (lanodan) Monnier <contact@×××××××××.me>
54 > +# @SUPPORTED_EAPIS: 7
55 > +# @BLURB: Helps building core & split gstreamer plugins.
56
57 No full stop here, it's not a proper sentence.
58
59 > +# @DESCRIPTION:
60 > +# Eclass to make external gst-plugins emergable on a per-plugin basis
61 > +# and to solve the problem with gst-plugins generating far too much
62 > +# unneeded dependencies.
63 > +#
64 > +# GStreamer consuming applications should depend on the specific plugins
65 > +# they need as defined in their source code. Usually you can find that
66 > +# out by grepping the source tree for 'factory_make'. If it uses playbin
67 > +# plugin, consider adding media-plugins/gst-plugins-meta dependency, but
68 > +# also list any packages that provide explicitly requested plugins.
69 > +
70 > +inherit multilib virtualx meson toolchain-funcs xdg-utils multilib-minimal
71
72 I'm pretty sure you can sort them a bit.
73
74 > +
75 > +case "${EAPI:-0}" in
76 > + 7)
77 > + ;;
78 > + *)
79 > + die "EAPI=\"${EAPI}\" is not supported"
80 > + ;;
81 > +esac
82 > +
83 > +# @ECLASS-VARIABLE: GST_PLUGINS_ENABLED
84 > +# @DESCRIPTION:
85 > +# Defines the plugins to be built.
86 > +# May be set by an ebuild and contain more than one indentifier, space
87 > +# seperated (only src_configure can handle mutiple plugins at this time).
88 > +: ${GST_PLUGINS_ENABLED:=${PN/gst-plugins-/}}
89 > +
90 > +# @ECLASS-VARIABLE: GST_PLUGINS_DISABLED
91 > +# @DESCRIPTION:
92 > +# Defines the plugins to not be built, GST_PLUGINS_ENABLED overrides it.
93 > +# May be set by an ebuild and contain more than one indentifier, space
94 > +# seperated (only src_configure can handle mutiple plugins at this time).
95 > +case "${GST_ORG_MODULE}" in
96 > + # copied GST_PLUGINS_DISABLED from media-libs/${GST_ORG_MODULE} then added GST_PLUGINS_ENABLED
97 > + gst-plugins-bad)
98 > + # removed from list: shm ipcpipeline gl
99 > + GST_PLUGINS_DISABLED="aom avtp androidmedia applemedia assrender bluez bs2b bz2 chromaprint closedcaption colormanagement curl curl-ssh2 d3dvideosink d3d11 dash dc1394 decklink directfb directsound dtls dts dvb faac faad fbdev fdkaac flite fluidsynth gme gsm iqa kate kms ladspa libde265 libmms lv2 mediafoundation microdns modplug mpeg2enc mplex msdk musepack neon nvcodec ofa openal openexr openh264 openjpeg openmpt openni2 opensles opus resindvd rsvg rtmp sbc sctp smoothstreaming sndfile soundtouch spandsp srt srtp svthevcenc teletext tinyalsa transcode ttml uvch264 va voaacenc voamrwbenc vulkan wasapi wasapi2 webp webrtc webrtcdsp wildmidi winks winscreencap x265 zbar zxing wpe magicleap v4l2codecs hls opencv"
100 > + GST_PLUGINS_DISABLED="${GST_PLUGINS_DISABLED} accurip adpcmdec adpcmenc aiff asfmux audiobuffersplit audiofxbad audiolatency audiomixmatrix audiovisualizers autoconvert bayer camerabin2 coloreffects deb ugutils dvbsubenc dvbsuboverlay dvdspu faceoverlay festival fieldanalysis freeverb frei0r gaudieffects gdp geometrictransform id3tag inter interlace ivfpars e ivtc jp2kdecimator jpegformat librfb midi mpegdemux mpegpsmux mpegtsdemux mpegtsmux mxf netsim onvif pcapparse pnm proxy rawparse removesilence rist rtmp2 rtp sdp segmentclip siren smooth speed subenc switchbin timecode videofilters videoframe_audiolevel videoparsers videosignal vmnc y4m"
101 > + ;;
102 > + gst-plugins-base)
103 > + GST_PLUGINS_DISABLED="cdparanoia libvisual opus tremor"
104 > + GST_PLUGINS_DISABLED="${GST_PLUGINS_DISABLED} adder app audioconvert audiomixer audiorate audioresample audiotestsrc compositor encoding gio gio-typefinder overlaycomposition pbtypes playback rawparse subparse tcp typefind videoconvert videorate videoscale videotestsrc volume"
105 > + ;;
106 > + gst-plugins-good)
107 > + GST_PLUGINS_DISABLED="aalib cairo directsound dv dv1394 flac gdk-pixbuf gtk3 jack jpeg lame libcaca mpg123 oss oss4 osxaudio osxvideo png pulse qt5 shout2 soup speex taglib twolame vpx waveform wavpack rpicamsrc ximagesrc v4l2"
108 > + GST_PLUGINS_DISABLED="${GST_PLUGINS_DISABLED} alpha apetag audiofx audioparsers auparse autodetect avi cutter debugutils deinterlace dtmf effectv equalizer flv flx goom goom2k1 icydemux id3demux imagefreeze interleave isomp4 law level matroska monoscope multifile multipart replaygain rtp rtpmanager rtsp shapewipe smpte spectrum udp videobox videocrop videofilter videomixer wavenc wavparse y4m"
109 > + ;;
110 > + gst-plugins-ugly)
111 > + GST_PLUGINS_DISABLED="a52dec amrnb amrwbdec cdio dvdread mpeg2dec sidplay x264"
112 > + GST_PLUGINS_DISABLED="${GST_PLUGINS_DISABLED} asfdemux dvdlpcmdec dvdsub realmedia xingmux"
113 > + ;;
114 > +esac
115
116 Wrap these lists, please.
117
118 Are these supposed to be settable by ebuild? If yes, you need not to
119 override them. If no, then look into available eclassdoc tags
120 and choose one.
121
122 > +
123 > +# @ECLASS-VARIABLE: GST_PLUGINS_BUILD_DIR
124 > +# @DESCRIPTION:
125 > +# Actual build directories of the plugins.
126 > +# Most often the same as the configure switch name.
127 > +# FIXME: Change into a bash array
128 > +: ${GST_PLUGINS_BUILD_DIR:=${PN/gst-plugins-/}}
129 > +
130 > +# @ECLASS-VARIABLE: GST_TARBALL_SUFFIX
131 > +# @DESCRIPTION:
132 > +# Most projects hosted on gstreamer.freedesktop.org mirrors provide
133 > +# tarballs as tar.bz2 or tar.xz. This eclass defaults to xz. This is
134 > +# because the gstreamer mirrors are moving to only have xz tarballs for
135 > +# new releases.
136 > +: ${GST_TARBALL_SUFFIX:="xz"}
137 > +
138 > +# Even though xz-utils are in @system, they must still be added to BDEPEND; see
139 > +# https://archives.gentoo.org/gentoo-dev/msg_a0d4833eb314d1be5d5802a3b710e0a4.xml
140 > +if [[ ${GST_TARBALL_SUFFIX} == "xz" ]]; then
141 > + BDEPEND="${BDEPEND} app-arch/xz-utils"
142 > +fi
143 > +
144 > +# @ECLASS-VARIABLE: GST_ORG_MODULE
145 > +# @DESCRIPTION:
146 > +# Name of the module as hosted on gstreamer.freedesktop.org mirrors.
147 > +# Leave unset if package name matches module name.
148 > +: ${GST_ORG_MODULE:=$PN}
149
150 Always use ${...} for vars.
151
152 > +
153 > +# @ECLASS-VARIABLE: GST_ORG_PVP
154 > +# @INTERNAL
155 > +# @DESCRIPTION:
156 > +# Major and minor numbers of the version number.
157 > +: ${GST_ORG_PVP:=$(ver_cut 1-2)}
158 > +
159 > +
160 > +DESCRIPTION="${BUILD_GST_PLUGINS} plugin for gstreamer"
161 > +HOMEPAGE="https://gstreamer.freedesktop.org/"
162 > +SRC_URI="https://gstreamer.freedesktop.org/src/${GST_ORG_MODULE}/${GST_ORG_MODULE}-${PV}.tar.${GST_TARBALL_SUFFIX}"
163 > +
164 > +LICENSE="GPL-2"
165 > +case ${GST_ORG_PVP} in
166 > + 1.*) SLOT="1.0"; GST_MIN_PV="1.2.4-r1" ;;
167 > + *) die "Unkown gstreamer release."
168 > +esac
169 > +
170 > +S="${WORKDIR}/${GST_ORG_MODULE}-${PV}"
171
172 These days we put S immediately below SRC_URI as they're closely
173 associated.
174
175 > +
176 > +RDEPEND="
177 > + >=dev-libs/glib-2.40.0:2[${MULTILIB_USEDEP}]
178 > + >=media-libs/gstreamer-${GST_MIN_PV}:${SLOT}[${MULTILIB_USEDEP}]
179 > +"
180 > +BDEPEND="
181 > + >=sys-apps/sed-4
182 > + virtual/pkgconfig
183 > + virtual/perl-JSON-PP
184 > +"
185 > +
186 > +# Export common multilib phases.
187 > +multilib_src_configure() { gstreamer_multilib_src_configure; }
188 > +
189 > +if [[ ${PN} != ${GST_ORG_MODULE} ]]; then
190 > + # Do not run test phase for invididual plugin ebuilds.
191 > + RESTRICT="test"
192 > + RDEPEND="${RDEPEND}
193 > + >=media-libs/${GST_ORG_MODULE}-${PV}:${SLOT}[${MULTILIB_USEDEP}]"
194 > +
195 > + # Export multilib phases used for split builds.
196 > + multilib_src_compile() { gstreamer_multilib_src_compile; }
197 > + multilib_src_install() { gstreamer_multilib_src_install; }
198 > + multilib_src_install_all() { gstreamer_multilib_src_install_all; }
199 > +else
200 > + IUSE="nls test"
201 > + RESTRICT="!test? ( test )"
202 > + BDEPEND="${DEPEND}
203 > + nls? ( >=sys-devel/gettext-0.17 )
204 > + test? ( media-libs/gstreamer[test] )
205 > + "
206 > +
207 > + multilib_src_compile() { eninja; }
208 > + multilib_src_test() { gstreamer_multilib_src_test; }
209 > + multilib_src_install() { DESTDIR="${D}" eninja install; }
210
211 I find it a bit confusing that there are two conditional defaults.
212 Maybe it'd make more sense to put the conditions inside
213 gstreamer_multilib*?
214
215 > +fi
216 > +
217 > +DEPEND="${DEPEND} ${RDEPEND}"
218 > +
219 > +# @FUNCTION: gstreamer_environment_reset
220 > +# @INTERNAL
221 > +# @DESCRIPTION:
222 > +# Clean up environment for clean builds.
223 > +# >=dev-lang/orc-0.4.23 rely on environment variables to find a place to
224 > +# allocate files to mmap.
225 > +gstreamer_environment_reset() {
226 > + xdg_environment_reset
227 > +}
228
229 I don't really understand why you need to wrap xdg_environment_reset
230 in another function.
231
232 > +
233 > +# @FUNCTION: gstreamer_get_plugin_dir
234 > +# @USAGE: gstreamer_get_plugin_dir [<build_dir>]
235 > +# @INTERNAL
236 > +# @DESCRIPTION:
237 > +# Finds plugin build directory and output it.
238 > +# Defaults to ${GST_PLUGINS_BUILD_DIR} if argument is not provided
239 > +gstreamer_get_plugin_dir() {
240 > + local build_dir=${1:-${GST_PLUGINS_BUILD_DIR}}
241 > +
242 > + if [[ ! -d ${S}/ext/${build_dir} ]]; then
243 > + if [[ ! -d ${S}/sys/${build_dir} ]]; then
244 > + ewarn "No such plugin directory"
245 > + die
246 > + fi
247 > + einfo "Got system plugin in ${build_dir}..." >&2
248 > + echo sys/${build_dir}
249 > + else
250 > + einfo "Got external plugin in ${build_dir}..." >&2
251 > + echo ext/${build_dir}
252 > + fi
253 > +}
254 > +
255 > +# @FUNCTION: gstreamer_multilib_src_configure
256 > +# @DESCRIPTION:
257 > +# Handles logic common to configuring gstreamer plugins
258 > +gstreamer_multilib_src_configure() {
259 > + local plugin gst_conf=( ) EMESON_SOURCE=${EMESON_SOURCE:-${S}}
260 > +
261 > + gstreamer_environment_reset
262 > +
263 > + # app-editor/vis regex for meson_options.txt: :x/option\('([^']*)'.*/ c/\1/
264 > + for plugin in ${GST_PLUGINS_DISABLED} ; do
265 > + gst_conf+=( -D${plugin}=disabled )
266 > + done
267 > +
268 > + for plugin in ${GST_PLUGINS_ENABLED} ; do
269 > + gst_conf+=( -D${plugin}=enabled )
270 > + done
271 > +
272 > + if grep -q "option('orc'" "${EMESON_SOURCE}"/meson_options.txt ; then
273
274 Hmm, doesn't meson provide a cleaner way than grepping the sources?
275
276 > + if in_iuse orc ; then
277 > + gst_conf+=( -Dorc=$(usex orc enabled disabled) )
278 > + else
279 > + gst_conf+=( -Dorc=disabled )
280 > + eqawarn "QA: IUSE=orc is missing while plugin supports it"
281 > + fi
282 > + fi
283 > +
284 > + if grep -q "option(\'maintainer-mode\'" "${EMESON_SOURCE}"/meson_options.txt ; then
285 > + gst_conf+=( -Dmaintainer-mode=disabled )
286 > + fi
287 > +
288 > + if grep -q "option(\'schemas-compile\'" "${EMESON_SOURCE}"/meson_options.txt ; then
289 > + gst_conf+=( -Dschemas-compile=disabled )
290 > + fi
291 > +
292 > + if [[ ${PN} == ${GST_ORG_MODULE} ]]; then
293 > + gst_conf+=(
294 > + $(meson_feature nls)
295 > + $(meson_feature test tests)
296 > + )
297 > + fi
298 > +
299 > + einfo "Configuring to build ${GST_PLUGINS_ENABLED} plugin(s) ..."
300 > + gst_conf+=(
301 > + -Dexamples=disabled
302 > + -Dpackage-name="Gentoo GStreamer ebuild"
303 > + -Dpackage-origin="https://www.gentoo.org"
304 > + -Dgst_debug=false
305 > + "${@}"
306 > + )
307 > + meson_src_configure "${gst_conf[@]}"
308 > +}
309 > +
310 > +
311 > +# @FUNCTION: _gstreamer_get_target_filename
312 > +# @INTERNAL
313 > +# @DESCRIPTION:
314 > +# Looks for first argument being present as a substring in install targets
315 > +# Got ported from python to perl for greater language-stability
316 > +_gstreamer_get_target_filename() {
317 > + cat >"${WORKDIR}/_gstreamer_get_target_filename.pl" <<"EOF"
318 > +#!/usr/bin/env perl
319 > +use strict;
320 > +use utf8;
321 > +use JSON::PP;
322 > +
323 > +open(my $targets_file, '<:encoding(UTF-8)', 'meson-info/intro-targets.json') || die $!;
324 > +my $data = decode_json <$targets_file>;
325 > +close($targets_file) || die $!;
326 > +
327 > +if(!$ARGV[0]) {
328 > + die "Requires a target as argument";
329 > +}
330 > +
331 > +foreach my $target (@{$data}) {
332 > + if($target->{'installed'}
333 > + and (index($target->{'filename'}[0], $ARGV[0]) != -1)
334 > + ) {
335 > + printf "%s:%s\n", $target->{'filename'}[0], $target->{'install_filename'}[0];
336 > + }
337 > +}
338 > +EOF
339 > +
340 > + chmod +x "${WORKDIR}/_gstreamer_get_target_filename.pl" || die
341 > +
342 > + perl "${WORKDIR}/_gstreamer_get_target_filename.pl" $@ \
343 > + || die "Failed to extract target filenames from meson-info"
344 > +}
345 > +
346 > +# @FUNCTION: gstreamer_multilib_src_compile
347 > +# @DESCRIPTION:
348 > +# Compiles requested gstreamer plugin.
349 > +gstreamer_multilib_src_compile() {
350 > + local plugin_dir plugin
351 > +
352 > + for plugin_dir in ${GST_PLUGINS_BUILD_DIR} ; do
353 > + plugin=$(_gstreamer_get_target_filename $(gstreamer_get_plugin_dir ${plugin_dir}))
354 > + plugin_path="${plugin%%:*}"
355 > + eninja "${plugin_path/"${BUILD_DIR}/"}"
356 > + done
357 > +}
358 > +
359 > +# @FUNCTION: gstreamer_multilib_src_test
360 > +# @DESCRIPTION:
361 > +# Tests the gstreamer plugin (non-split)
362 > +gstreamer_multilib_src_test() {
363 > + GST_GL_WINDOW=x11 virtx eninja test;
364
365 Stray semicolon.
366
367 > +}
368 > +
369 > +# @FUNCTION: gstreamer_multilib_src_install
370 > +# @DESCRIPTION:
371 > +# Installs requested gstreamer plugin.
372 > +gstreamer_multilib_src_install() {
373 > + local plugin_dir plugin
374 > +
375 > + for plugin_dir in ${GST_PLUGINS_BUILD_DIR} ; do
376 > + for plugin in $(_gstreamer_get_target_filename $(gstreamer_get_plugin_dir ${plugin_dir})); do
377 > + local install_filename="${plugin##*:}"
378 > + insinto "${install_filename%/*}"
379 > + doins "${plugin%%:*}"
380 > + done
381 > + done
382 > +}
383 > +
384 > +# @FUNCTION: gstreamer_multilib_src_install_all
385 > +# @DESCRIPTION:
386 > +# Installs documentation for requested gstreamer plugin
387 > +gstreamer_multilib_src_install_all() {
388 > + local plugin_dir
389 > +
390 > + for plugin_dir in ${GST_PLUGINS_BUILD_DIR} ; do
391 > + local dir=$(gstreamer_get_plugin_dir ${plugin_dir})
392 > + [[ -e ${dir}/README ]] && dodoc "${dir}"/README
393 > + done
394 > +}
395
396 --
397 Best regards,
398 Michał Górny