From ade1369db0837354c8619b82c77215f96532f4a1 Mon Sep 17 00:00:00 2001 From: Doug Nazar Date: Tue, 1 Apr 2025 14:50:38 -0400 Subject: [PATCH] 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: --- dependencies.py | 40 ++++++++++++++++++++++--- meson.build | 79 ++++++++++++++++++++++++++++++------------------- 2 files changed, 85 insertions(+), 34 deletions(-) diff --git a/dependencies.py b/dependencies.py index 4d5f43ef9..3f9eb7978 100755 --- a/dependencies.py +++ b/dependencies.py @@ -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())) diff --git a/meson.build b/meson.build index c892e3de7..70fdfa0b8 100644 --- a/meson.build +++ b/meson.build @@ -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]