2022-08-30 19:59:17 +00:00
|
|
|
#!/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
|
2022-09-17 14:33:34 +00:00
|
|
|
import sys
|
|
|
|
|
2022-08-30 19:59:17 +00:00
|
|
|
|
|
|
|
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='*')
|
2023-03-10 21:41:50 +00:00
|
|
|
PARSER.add_argument('--features', action="store_true", help="Get list of features to activate")
|
|
|
|
PARSER.add_argument('--gst-version', help="Get list of features to activate")
|
2022-08-30 19:59:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Map plugin name to directory name, for those that does not match.
|
|
|
|
RENAMES = {
|
|
|
|
'rsaudiofx': 'audiofx',
|
|
|
|
'rsfile': 'file',
|
|
|
|
'rsflv': 'flavors',
|
2022-10-23 09:13:23 +00:00
|
|
|
'rsrtp': 'rtp',
|
2024-01-10 10:10:19 +00:00
|
|
|
'rsrtsp': 'rtsp',
|
2022-08-30 19:59:17 +00:00
|
|
|
'rswebp': 'webp',
|
|
|
|
'rsonvif': 'onvif',
|
|
|
|
'rstracers': 'tracers',
|
|
|
|
'rsclosedcaption': 'closedcaption',
|
2022-08-16 14:44:41 +00:00
|
|
|
'rswebrtc': 'webrtc',
|
2022-10-23 09:13:23 +00:00
|
|
|
'rspng': 'png',
|
|
|
|
'rsvideofx': 'videofx',
|
2023-06-21 17:55:27 +00:00
|
|
|
'rsinter': 'inter',
|
2022-10-23 15:42:58 +00:00
|
|
|
'textahead': 'ahead',
|
|
|
|
'textwrap': 'wrap',
|
2022-08-30 19:59:17 +00:00
|
|
|
}
|
|
|
|
|
2023-03-10 21:41:50 +00:00
|
|
|
class CargoAnalyzer:
|
|
|
|
def __init__(self):
|
|
|
|
self.src_dir = None
|
|
|
|
self.plugins = None
|
|
|
|
self.features = False
|
|
|
|
self.gst_version = "1.18"
|
2022-08-30 19:59:17 +00:00
|
|
|
|
2023-03-10 21:41:50 +00:00
|
|
|
def extract_version(self, feature_name):
|
|
|
|
if feature_name.startswith('v'):
|
|
|
|
verindex = 1
|
|
|
|
elif feature_name.startswith('gst'):
|
|
|
|
verindex = 3
|
|
|
|
else:
|
|
|
|
return None
|
|
|
|
|
|
|
|
(majver, minver) = feature_name[verindex:].split("_")
|
|
|
|
return (int(majver), int(minver))
|
|
|
|
|
|
|
|
def extract_features(self, cargo_data):
|
|
|
|
features = cargo_data['features']
|
|
|
|
wanted_features = set()
|
|
|
|
gst_version_major = int(self.gst_version.split('.')[0])
|
|
|
|
gst_version_minor = int(self.gst_version.split('.')[1])
|
|
|
|
for (name, value) in features.items():
|
|
|
|
version = self.extract_version(name)
|
|
|
|
|
|
|
|
if version is None:
|
|
|
|
continue
|
|
|
|
(majver, minver) = version
|
|
|
|
|
|
|
|
if gst_version_major < majver or gst_version_minor < minver:
|
2022-08-30 19:59:17 +00:00
|
|
|
continue
|
2023-03-10 21:41:50 +00:00
|
|
|
wanted_features |= set(value)
|
|
|
|
if name.startswith("gst"):
|
|
|
|
# Required for some reason for rswebrtc which has a specific feature
|
|
|
|
wanted_features |= {f"{cargo_data['package']['name']}/{name}"}
|
|
|
|
|
|
|
|
return wanted_features
|
|
|
|
|
|
|
|
def run(self):
|
|
|
|
with (opts.src_dir / 'Cargo.toml').open('rb') as f:
|
|
|
|
crates = tomllib.load(f)['workspace']['members']
|
|
|
|
res = set()
|
|
|
|
for name in opts.plugins:
|
|
|
|
if name.startswith('gst'):
|
|
|
|
name = name[3:]
|
|
|
|
|
|
|
|
name = RENAMES.get(name, name)
|
|
|
|
crate_path = None
|
|
|
|
for crate in crates:
|
|
|
|
if Path(crate).name == name:
|
|
|
|
crate_path = opts.src_dir / crate / 'Cargo.toml'
|
|
|
|
assert crate_path
|
|
|
|
with crate_path.open('rb') as f:
|
|
|
|
data = tomllib.load(f)
|
|
|
|
if opts.features:
|
|
|
|
res |= self.extract_features(data)
|
|
|
|
else:
|
|
|
|
try:
|
|
|
|
requires = data['package']['metadata']['capi']['pkg_config']['requires_private']
|
|
|
|
except KeyError:
|
|
|
|
continue
|
|
|
|
res.update([i.strip().replace('>', "|>").replace('<', "|<").replace("==", "|==") for i in requires.split(',')])
|
|
|
|
return res
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
analyzer = CargoAnalyzer()
|
|
|
|
opts = PARSER.parse_args(namespace=analyzer)
|
|
|
|
|
|
|
|
print(','.join(analyzer.run()))
|