meson: Define gst_plugins with list of dependencies

This is needed to link gst-full with Rust plugins. The script requires
either python11 or the tomli module.
This commit is contained in:
Xavier Claessens 2022-08-30 15:59:17 -04:00 committed by Sebastian Dröge
parent ad48d5e8f2
commit 4ac60165a8
3 changed files with 119 additions and 10 deletions

View file

@ -43,7 +43,7 @@ stages:
.debian:11-stable: .debian:11-stable:
extends: .debian:11 extends: .debian:11
variables: variables:
FDO_DISTRIBUTION_TAG: '$GST_RS_STABLE-${GST_RS_IMG_TAG}_2022-07-19.0' FDO_DISTRIBUTION_TAG: '$GST_RS_STABLE-${GST_RS_IMG_TAG}_2022-08-31.1'
FDO_BASE_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bullseye-slim:$GST_RS_STABLE-$GST_RS_IMG_TAG" FDO_BASE_IMAGE: "registry.freedesktop.org/gstreamer/gstreamer-rs/debian/bullseye-slim:$GST_RS_STABLE-$GST_RS_IMG_TAG"
.debian:11-msrv: .debian:11-msrv:
@ -63,11 +63,12 @@ stages:
- .fdo.container-build@debian - .fdo.container-build@debian
stage: prep stage: prep
variables: variables:
FDO_DISTRIBUTION_PACKAGES: "libcsound64-dev llvm clang nasm libsodium-dev" FDO_DISTRIBUTION_PACKAGES: "libcsound64-dev llvm clang nasm libsodium-dev libwebp-dev python3-pip"
FDO_DISTRIBUTION_EXEC: >- FDO_DISTRIBUTION_EXEC: >-
bash ci/install-dav1d.sh && bash ci/install-dav1d.sh &&
apt clean && apt clean &&
bash ./ci/install-rust-ext.sh bash ./ci/install-rust-ext.sh &&
pip install tomli
rules: rules:
- if: '$UPDATE_IMG == null' - if: '$UPDATE_IMG == null'
@ -216,6 +217,22 @@ gst-build:
- if: $CI_PIPELINE_SOURCE == "merge_request_event" - if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: 'manual' when: 'manual'
allow_failure: true allow_failure: true
variables:
MESON_ARGS: >
-Domx=disabled
-Dpython=disabled
-Dlibav=disabled
-Dlibnice=disabled
-Dugly=disabled
-Dbad=disabled
-Ddevtools=disabled
-Dges=disabled
-Drtsp_server=disabled
-Dvaapi=disabled
-Dsharp=disabled
-Dgst-examples=disabled
-Drs=enabled
-Dgst-plugins-rs:sodium=system
script: script:
- P=$(pwd) - P=$(pwd)
- cd .. - cd ..
@ -223,13 +240,18 @@ gst-build:
- git clone --depth 1 https://gitlab.freedesktop.org/gstreamer/gstreamer.git --branch main - git clone --depth 1 https://gitlab.freedesktop.org/gstreamer/gstreamer.git --branch main
- cd gstreamer - cd gstreamer
- ln -s $P subprojects/gst-plugins-rs - ln -s $P subprojects/gst-plugins-rs
- meson build -Domx=disabled -Dpython=disabled -Dlibav=disabled -Dlibnice=disabled -Dugly=disabled -Dbad=disabled -Ddevtools=disabled -Dges=disabled -Drtsp_server=disabled -Dvaapi=disabled -Dsharp=disabled -Dgst-examples=disabled -Drs=enabled -Dgst-plugins-rs:sodium=system - meson build $MESON_ARGS
- ninja -C build - ninja -C build
# Check static Rust plugins can be linked into gst-full
- meson build-gst-full --default-library=static $MESON_ARGS
- ninja -C build-gst-full
- meson devenv -C build-gst-full gst-inspect-1.0 rsaudiofx
artifacts: artifacts:
expire_in: '7 days' expire_in: '7 days'
when: always when: always
paths: paths:
- 'build/meson-logs/' - 'build/meson-logs/'
- 'build-gst-full/meson-logs/'
rustfmt: rustfmt:
extends: .img-stable extends: .img-stable

56
dependencies.py Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env python3
# Parse Cargo.toml files for each plugin to collect their external dependencies.
# Meson will lookup those dependencies using pkg-config to be able to link
# static Rust plugins into gst-full.
from argparse import ArgumentParser
from pathlib import Path
try:
# Python11 stdlib
import tomllib
except ImportError:
import tomli as tomllib
PARSER = ArgumentParser()
PARSER.add_argument('src_dir', type=Path)
PARSER.add_argument('plugins', nargs='*')
# Map plugin name to directory name, for those that does not match.
RENAMES = {
'rsaudiofx': 'audiofx',
'rsfile': 'file',
'rsflv': 'flavors',
'rstextwrap': 'wrap',
'rsjson': 'json',
'rsregex': 'regex',
'rswebp': 'webp',
'textahead': 'ahead',
'rsonvif': 'onvif',
'rstracers': 'tracers',
'rsclosedcaption': 'closedcaption',
'rsdav1d': 'dav1d',
}
if __name__ == "__main__":
opts = PARSER.parse_args()
deps = set()
for p in opts.plugins:
assert p.startswith('gst')
name = p[3:]
name = RENAMES.get(name, name)
files = list(opts.src_dir.glob(f'**/{name}/Cargo.toml'))
assert len(files) == 1
with files[0].open('rb') as f:
data = tomllib.load(f)
try:
requires = data['package']['metadata']['capi']['pkg_config']['requires_private']
except KeyError:
continue
deps.update([i.strip() for i in requires.split(',')])
print(','.join(deps))

View file

@ -5,6 +5,7 @@ project('gst-plugins-rs',
meson_version : '>= 0.60') meson_version : '>= 0.60')
python = import('python').find_installation() python = import('python').find_installation()
fs = import('fs')
if get_option('debug') if get_option('debug')
target = 'debug' target = 'debug'
@ -137,12 +138,6 @@ if static_build or get_option('default_library') == 'both'
endforeach endforeach
endif endif
pc_files = []
foreach p, lib : plugins
# skip the 'lib' prefix in plugin name
pc_files += [lib.substring(3) + '.pc']
endforeach
# Need to depends on all gstreamer-rs deps to ensure they are built # Need to depends on all gstreamer-rs deps to ensure they are built
# before gstreamer-rs when building with gst-build. # before gstreamer-rs when building with gst-build.
# Custom targets can't depend on dependency() objects so we have to depend # Custom targets can't depend on dependency() objects so we have to depend
@ -164,10 +159,14 @@ deps = [
['gstreamer-webrtc-1.0', 'gst-plugins-bad', 'gstwebrtc_dep', 'gstwebrtc_dep'], ['gstreamer-webrtc-1.0', 'gst-plugins-bad', 'gstwebrtc_dep', 'gstwebrtc_dep'],
] ]
# Used to not lookup the same dependency multiple times which clutters logs
deps_cache = {}
foreach d: deps foreach d: deps
dep = dependency(d[0], version : gst_req, dep = dependency(d[0], version : gst_req,
fallback : [d[1], d[2]]) fallback : [d[1], d[2]])
set_variable(d[2], dep) set_variable(d[2], dep)
deps_cache += {d[0]: dep}
if dep.type_name() == 'internal' if dep.type_name() == 'internal'
lib = subproject(d[1]).get_variable(d[3]) lib = subproject(d[1]).get_variable(d[3])
depends += lib depends += lib
@ -216,6 +215,38 @@ rs_plugins = custom_target('gst-plugins-rs',
plugins = rs_plugins.to_list() plugins = rs_plugins.to_list()
# This is used by GStreamer to static link Rust plugins into gst-full
gst_plugins = []
pc_files = []
foreach plugin : plugins
# skip the 'lib' prefix and extension from plugin path
plugin_name = fs.stem(plugin.full_path()).substring(3)
# Extract plugin dependencies from their Cargo.toml file
plugin_deps = []
p = run_command('dependencies.py', meson.current_source_dir(), plugin_name,
capture: true,
check: true)
foreach dep_name : p.stdout().strip().split(',')
if deps_cache.has_key(dep_name)
plugin_deps += deps_cache[dep_name]
else
dep = dependency(dep_name, required: false)
plugin_deps += dep
deps_cache += {dep_name: dep}
endif
endforeach
dep = declare_dependency(
link_with: plugin,
dependencies: plugin_deps,
variables: {'full_path': plugin.full_path()},
)
meson.override_dependency(plugin_name, dep)
gst_plugins += dep
pc_files += [plugin_name + '.pc']
endforeach
subdir('docs') subdir('docs')
# We don't need to pass a command as we depends on the target above # We don't need to pass a command as we depends on the target above