diff --git a/gstinitstaticplugins.h b/gstinitstaticplugins.h new file mode 100644 index 0000000000..bd6245e3b1 --- /dev/null +++ b/gstinitstaticplugins.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 2019 Collabora Ltd. + * Author: Xavier Claessens + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation + * version 2.1 of the License. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#pragma once + +#include + +G_BEGIN_DECLS + +void gst_init_static_plugins (void); + +G_END_DECLS diff --git a/meson.build b/meson.build index 382eb42724..1209c8b148 100644 --- a/meson.build +++ b/meson.build @@ -9,6 +9,7 @@ gst_branch = 'master' build_system = build_machine.system() cc = meson.get_compiler('c') +pkgconfig = import('pkgconfig') python3 = import('python').find_installation() # Ensure that we're not being run from inside the gst-uninstalled env # because that will confuse meson, and it might find the already-built @@ -178,6 +179,89 @@ configure_file( all_plugins_paths] ) +# FIXME: Create a 'libraries' list in each subproject like we do for 'plugins' +libraries_map = { + # name: [subproject_name, variable_name] + 'gstreamer': ['gstreamer', 'libgst'], + 'base': ['gstreamer', 'gst_base'], + 'check': ['gstreamer', 'gst_check'], + 'controller': ['gstreamer', 'gst_controller'], + 'net': ['gstreamer', 'gst_net'], + + 'allocators': ['gst-plugins-base', 'gstallocators'], + 'app': ['gst-plugins-base', 'gstapp'], + 'audio': ['gst-plugins-base', 'gstaudio'], + 'fft': ['gst-plugins-base', 'gstfft'], + 'pbutils': ['gst-plugins-base', 'pbutils'], + 'riff': ['gst-plugins-base', 'gstriff'], + 'rtp': ['gst-plugins-base', 'gst_rtp'], + 'rtsp': ['gst-plugins-base', 'gst_rtsp'], + 'sdp': ['gst-plugins-base', 'gstsdp'], + 'tag': ['gst-plugins-base', 'gsttag'], + 'video': ['gst-plugins-base', 'gstvideo'], + 'gl': ['gst-plugins-base', 'gstgl'], + + 'bad-audio': ['gst-plugins-bad', 'gstbadaudio'], + 'bad-transcoder': ['gst-plugins-bad', 'gst_transcoder'], + 'codecparsers': ['gst-plugins-bad', 'gstcodecparsers'], + 'insertbin': ['gst-plugins-bad', 'gstinsertbin'], + 'mpegts': ['gst-plugins-bad', 'gstmpegts'], + 'player': ['gst-plugins-bad', 'gstplayer'], + 'sctp': ['gst-plugins-bad', 'libgstsctp'], + 'webrtc': ['gst-plugins-bad', 'gstwebrtc'], + 'vulkan': ['gst-plugins-bad', 'gstvulkan'], + + 'rtsp-server': ['gst-rtsp-server', 'gst_rtsp_server'], +} + +if get_option('default_library') == 'static' + # Generate a .c file which declare and register all built plugins + generate_init_static_plugins = find_program('scripts/generate_init_static_plugins.py') + init_static_plugins_c = configure_file( + output: 'gstinitstaticplugins.c', + command : [generate_init_static_plugins, + '@OUTPUT@', + all_plugins_paths] + ) + install_headers('gstinitstaticplugins.h', subdir : 'gstreamer-1.0/gst') + + # Get include paths in source tree + gst_dep = subproject('gstreamer').get_variable('gst_dep') + gst_includes = gst_dep.partial_dependency(includes: true, compile_args: true) + + # Get a list of libraries that needs to be exposed in the ABI. + exposed_libs = [] + foreach name : get_option('gst-full-libraries') + ['gstreamer'] + info = libraries_map[name] + exposed_libs += subproject(info[0]).get_variable(info[1]) + endforeach + + # glib and gobject are part of our public API. If we are using glib from the + # system then our pkg-config file must require it. If we built it as + # subproject then we need to link_whole it. + requires = [] + gobject_dep = dependency('gobject-2.0', fallback: ['glib', 'libgobject_dep']) + if gobject_dep.type_name() == 'internal' + glib_subproject = subproject('glib') + exposed_libs += glib_subproject.get_variable('libglib') + exposed_libs += glib_subproject.get_variable('libgobject') + else + requires = ['glib-2.0', 'gobject-2.0'] + endif + + # Build both shared and static library + gstfull = both_libraries('gstreamer-full-1.0', + init_static_plugins_c, + link_with : all_plugins, + link_whole : exposed_libs, + dependencies : gst_includes, + install : true, + ) + pkgconfig.generate(gstfull, + requires: requires, + subdirs : 'gstreamer-1.0') +endif + message('Building subprojects: ' + ', '.join(subprojects_names)) setenv = find_program('gst-env.py') diff --git a/meson_options.txt b/meson_options.txt index 47b9c596d5..8b7487685b 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -12,6 +12,8 @@ option('sharp', type : 'feature', value : 'disabled') option('custom_subprojects', type : 'string', value : '', description : 'Comma-separated project names') option('gst-examples', type : 'feature', value : 'auto', description : 'Build gst-examples') option('rs', type : 'feature', value : 'disabled') +option('gst-full-libraries', type : 'array', value : [], + description : '''List of libraries to expose in gstreamer-full's ABI. gstreamer, glib and gobject are always included.''') # Common options, automatically inherited by subprojects option('examples', type : 'feature', value : 'auto', description : 'Build examples') diff --git a/scripts/generate_init_static_plugins.py b/scripts/generate_init_static_plugins.py new file mode 100644 index 0000000000..d7a13e28ee --- /dev/null +++ b/scripts/generate_init_static_plugins.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 + +import argparse +import os +from string import Template + +TEMPLATE = Template(''' +#include + +$plugins_declaration + +void +gst_init_static_plugins (void) +{ + $plugins_registration +} +''') + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument(dest="output", help="Output file") + parser.add_argument(dest="plugins", nargs=argparse.REMAINDER, help="The list of plugins") + + options = parser.parse_args() + + names = set() + for plugin in options.plugins: + filename = os.path.basename(plugin) + if filename.startswith('libgst') and filename.endswith('.a'): + names.add(filename[len('libgst'):-len('.a')]) + + registration = ['GST_PLUGIN_STATIC_REGISTER(%s);' % name for name in names] + declaration = ['GST_PLUGIN_STATIC_DECLARE(%s);' % name for name in names] + + with open(options.output, "w") as f: + f.write(TEMPLATE.substitute({ + 'plugins_declaration': '\n'.join(declaration), + 'plugins_registration': '\n '.join(registration), + }))