meson: Only add glib/gio/gtk features if required by enabled packages

If those features are requested, however no package has those as a
dependency, the compile will fail with error unable to find feature.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-rs/-/merge_requests/2166>
This commit is contained in:
Doug Nazar 2025-04-01 14:50:38 -04:00 committed by GStreamer Marge Bot
parent 1ea767ac2a
commit ade1369db0
2 changed files with 85 additions and 34 deletions

View file

@ -21,6 +21,7 @@ PARSER.add_argument('src_dir', type=Path)
PARSER.add_argument('plugins', nargs='*')
PARSER.add_argument('--features', action="store_true", help="Get list of features to activate")
PARSER.add_argument('--gst-version', help="GStreamer version used")
PARSER.add_argument('--feature-deps', action="store_true", help="Get list of feature dependencies per plugin")
# Map plugin name to directory name, for those that does not match.
@ -49,6 +50,30 @@ class CargoAnalyzer:
self.plugins = None
self.features = False
self.gst_version = "1.18"
self.feature_deps = False
self.crates = None
def load_crates(self):
with (self.src_dir / 'Cargo.toml').open('rb') as f:
self.crates = tomllib.load(f)['workspace']['members']
def get_feature_deps(self):
res = dict()
for crate in self.crates:
crate_path = opts.src_dir / crate / 'Cargo.toml'
with crate_path.open('rb') as f:
data = tomllib.load(f)
if 'lib' not in data or 'dependencies' not in data:
continue
name = data['lib']['name']
deps = set()
for dep_name, dep_info in data['dependencies'].items():
if not dep_name.startswith('gst') and 'workspace' in dep_info and dep_info['workspace']:
deps.add(dep_name)
if (len(deps)):
res[name] = deps
return res
def extract_version(self, feature_name):
if feature_name.startswith('v'):
@ -88,8 +113,6 @@ class CargoAnalyzer:
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'):
@ -97,7 +120,7 @@ class CargoAnalyzer:
name = RENAMES.get(name, name)
crate_path = None
for crate in crates:
for crate in self.crates:
if Path(crate).name == name:
crate_path = opts.src_dir / crate / 'Cargo.toml'
assert crate_path
@ -117,4 +140,13 @@ if __name__ == "__main__":
analyzer = CargoAnalyzer()
opts = PARSER.parse_args(namespace=analyzer)
print(','.join(analyzer.run()))
if opts.feature_deps and (opts.features or opts.plugins):
sys.exit('error: --feature-deps must not be used with --features or plugins')
analyzer.load_crates()
if opts.feature_deps:
for name, deps in analyzer.get_feature_deps().items():
print('{}: {}'.format(name, ','.join(deps)))
else:
print(','.join(analyzer.run()))

View file

@ -309,16 +309,6 @@ if get_option('gtk4').allowed()
gtk4_features += 'dmabuf'
endif
if gtk_dep.version().version_compare('>=4.16')
gtk4_features += 'gtk_v4_16'
elif gtk_dep.version().version_compare('>=4.14')
gtk4_features += 'gtk_v4_14'
elif gtk_dep.version().version_compare('>=4.12')
gtk4_features += 'gtk_v4_12'
elif gtk_dep.version().version_compare('>=4.10')
gtk4_features += 'gtk_v4_10'
endif
plugins += {
'gtk4': {
'library': 'libgstgtk4',
@ -380,29 +370,41 @@ features = []
examples = []
# Add the plugin library files as output
output = []
# List of features from meson dependencies
found_features = {}
# List of dependencies for each plugin from Cargo.toml
feature_deps = {}
# List of dependencies that are actually enabled
required_feature_deps = []
if get_option('gtk4').allowed()
if glib_dep.version().version_compare('>=2.74')
features += ['glib/v2_74', 'gio/v2_74']
elif glib_dep.version().version_compare('>=2.72')
features += ['glib/v2_72', 'gio/v2_72']
elif glib_dep.version().version_compare('>=2.70')
features += ['glib/v2_70', 'gio/v2_70']
elif glib_dep.version().version_compare('>=2.68')
features += ['glib/v2_68', 'gio/v2_68']
elif glib_dep.version().version_compare('>=2.66')
features += ['glib/v2_66', 'gio/v2_66']
elif glib_dep.version().version_compare('>=2.64')
features += ['glib/v2_64', 'gio/v2_64']
elif glib_dep.version().version_compare('>=2.62')
features += ['glib/v2_62', 'gio/v2_62']
elif glib_dep.version().version_compare('>=2.60')
features += ['glib/v2_60', 'gio/v2_60']
elif glib_dep.version().version_compare('>=2.58')
features += ['glib/v2_58', 'gio/v2_58']
glib_versions = ['2.74','2.72','2.70','2.68','2.66','2.64','2.62','2.60','2.58']
foreach glib_version : glib_versions
if glib_dep.version().version_compare(f'>=@glib_version@')
found_features += {'glib': 'glib/v' + glib_version.underscorify()}
found_features += {'gio': 'gio/v' + glib_version.underscorify()}
break
endif
endforeach
if get_option('gtk4').allowed() and gtk_dep.found()
gtk4_versions = ['4.16','4.14','4.12','4.10']
foreach gtk4_version : gtk4_versions
if gtk_dep.version().version_compare(f'>=@gtk4_version@')
found_features += {'gtk': 'gtk_v' + gtk4_version.underscorify()}
break
endif
endforeach
endif
p = run_command('dependencies.py', meson.current_source_dir(), '--feature-deps', capture: true, check: true)
foreach line : p.stdout().split('\n')
if ':' in line
tmp = line.split(':')
library_name = 'lib' + tmp[0].strip()
feature_deps += {library_name: tmp[1].strip().split(',')}
endif
endforeach
if get_option('rav1e').allowed()
nasm = find_program('nasm', required: false)
if nasm.found()
@ -451,6 +453,16 @@ foreach plugin_name, details: plugins
continue
endif
# Build list of required features
library_name = details.get('library', [])
if feature_deps.has_key(library_name)
foreach d : feature_deps.get(library_name)
if d not in required_feature_deps
required_feature_deps += d
endif
endforeach
endif
# Validate gst-plugin features
plugin_features = details.get('features', [])
foreach feature: plugin_features
@ -516,7 +528,7 @@ foreach plugin_name, details: plugins
packages += f'gst-plugin-@plugin_name@'
features += plugin_features
extra_features = run_command('dependencies.py', meson.current_source_dir(), plugin_name,
'--feature', '--gst-version', gst_dep.version(), capture: true, check: true).stdout().strip()
'--features', '--gst-version', gst_dep.version(), capture: true, check: true).stdout().strip()
if extra_features != ''
features += extra_features.split(',')
endif
@ -534,6 +546,13 @@ foreach plugin_name, details: plugins
endif
endforeach
# Add required features
foreach feat : required_feature_deps
if found_features.has_key(feat)
features += found_features[feat]
endif
endforeach
feature_args = []
if features.length() > 0
feature_args += ['--features', features]