[vlc-commits] [Git][videolan/vlc][master] 23 commits: .gitignore: remove .orig and .symbollist files

Felix Paul Kühne (@fkuehne) gitlab at videolan.org
Sat May 30 14:31:58 UTC 2026



Felix Paul Kühne pushed to branch master at VideoLAN / VLC


Commits:
22c0f25f by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
.gitignore: remove .orig and .symbollist files

- - - - -
66a33e08 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
bin: Makefile.am: fix CPPFLAGS for vlc-osx-static

vlc-osx-static didn't inherit from AM_CPPFLAGS.

- - - - -
168b30dd by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
preparser: disable out-of-process when building statically

- - - - -
cad6b29a by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
vlc_plugin: define DLL_SYMBOL for partial linking

The partial linking code must be filtering the publicly exposed symbols
to only allow (_)?vlc_entry* symbols, as nothing more should be exposed
post the plugin ABI. It's mimicking what's been done on vlc_entry for
dynamic builds since it makes it similar.

However, to be exposed, the filtering needs the symbol to be visible
from the start, and thus DLL_SYMBOL needs to actually set the
visibility. We don't need to specifically ensure that only vlc_entry
symbols are visible since the filtering is done afterwards, but then
this is only enabled when partial linking is configured.

- - - - -
22110112 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
tools: patch libtool for old libraries

When libtool builds a static archive that depends on another static
archive, ie. an "old library" in libtool terminology, it archives the
dependency as a nested .a inside the target .a. Linkers cannot handle
nested archives and fail with errors such as:

    /usr/bin/ld: .libs/libfoo.a: member .libs/libfoo.a(libbar.a)
    in archive is not an object

The patch defers old_deplibs until the final executable or shared-library
link, recording them in dependency_libs so they propagate correctly
through the .la dependency chain.

This is required for VLC partial-linking support: we will read
old_library= from each plugin .la, resolves transitive static
dependencies via buildsystem/dependencies.sh, and partially links them
with `ld -r`. Without this patch the dependency_libs field is wrong and
nested archives break the partial linker.

The patch was sent to libtool-patches at gnu.org on 2021-04-06 but but was
not upstreamed yet. It was re-sent on 2026-04-28.

- - - - -
7b92c9cf by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
buildsystem: add a dependency extractor script

This should probably be done by libtool but libtool support for partial
linking is really lacking. I'll be adding support there when possible.

- - - - -
a131d2cb by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: add partial linking option

The option is disabled for now but will some day be enabled by default
since this is the only way to "support" static linking properly. It is
introduced here so that the option is used by following patches, but it
will really be useful only once we add supported platforms by the end of
the branch.

- - - - -
97805652 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
modules: scope vlc_module_name to prevent multiple definitions

Companions libraries like libvlc_pulse.so are still built when
configuring with the partial linking support. The guarantees expected by
those libraries are that:

  - They should be able to provide a global state across the plugins
    linking against it.

  - They should be usable from out-of-tree plugins.

They also happen to define a state scoped to the library itself given
that they link a vlc_module_name into the library itself, which needs to
leak back to libvlccore inline functions used across the library somehow.

Since in static builds, we cannot have multiple of those module names,
they will conflict with each other and with libvlccore core module at the
final link stage.

The "proper" solution to completely comply with this contract and
provide the proper vlc_module_name locally is to partially link those
libraries and localize the vlc_module_name as well, which is deferred to
later work for now.

- - - - -
8c9cfa89 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure: fetch --force-group-allocation to fix COMDAT

Detect and use the linker flag --force-group-allocation during partial
linking. This flag resolves COMDAT section groups and removes group
metadata from the output, preventing cross-plugin deduplication at
final link time that causes "defined in discarded section" errors with
C++ plugins.

- - - - -
f4fcae3f by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: test COMDAT resolution during partial linking

Compile two TUs with the same C++ template, partially link them, and
verify the COMDAT symbol appears only once. This tests the actual linker
behavior rather than checking for specific flags: GNU ld resolves COMDAT
with --force-group-allocation, LLD resolves it natively.

Also rework the --force-group-allocation check: set the flag when accepted
instead of erroring when absent. The COMDAT test is the actual gate.

- - - - -
cdb55f0a by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: move check for objcopy

Objcopy will be used by the partial linking compilation mode in the
build system to properly setup the ABI of each plugin's single object,
ensuring which symbols are exposed and which symbols are refused to
cross the object visibility.

This is needed in particular because linkers like ld won't change
anything regarding the object symbol visibility until the link to the
final artifact is done.

This is using either the host-prefixed objcopy or llvm-objcopy on
cross compilation builds or any of the prefixed/non-prefixed binaries
on native builds, in particular because objcopy will fail if it's not
compiled for the right target.

Mixing lld/llvm with objcopy or gcc with llvm-objcopy doesn't have
any impact because we're only modifying the visibility in the ELF
output, and don't touch LTO/linking with objcopy. However, the partial
linking procedure does prevent LTO because of this.

In the LTO case, we should link with LTO until the object is made,
and then drop the LTO sections for the partially linked plugin.

- - - - -
561977f8 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: error out when objcopy is missing for partial linking

On ELF, objcopy is required to localize symbols after partial linking.
On Darwin, ld64 -exported_symbol handles visibility so objcopy is not
needed. Error out early when partial linking is enabled on ELF but no
objcopy was found.

- - - - -
75c53ab9 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: add -fno-gnu-unique for partial linking

- - - - -
1709022c by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
modules: add -fno-gnu-unique for partial linking

- - - - -
632b9b69 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
modules: static.mk: add partial linking procedures

This commit uses the previously merged automake plugin indirection to
actually replace them by their partially linked version.

For each plugin, partial linking merges the multiple objects built from
the plugin's sources and their static dependencies into a single object
file, so as to resolve internal dependencies, and then forward the
dynamically linked dependencies through the libtool archive file.

As a notable point, we actually need dedicated code to be able to
forward the frameworks on Darwin platforms since automake won't forward
-framework Foo and libtool won't forward -Wl,framework,Foo.

- - - - -
761b8693 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
static: use --force-group-allocation for C++

Detect and use the linker flag --force-group-allocation during partial
linking. This flag resolves COMDAT section groups and removes group
metadata from the output, preventing cross-plugin deduplication at
final link time that causes "defined in discarded section" errors with
C++ plugins.

- - - - -
a1838127 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
static.mk: handle partial link for darwin

The change is separated from the other static.mk commit to highlight the
difference in linker between linux and darwin systems. Indeed,
(llvm-)objcopy from Darwin systems is not supporting any way to process
the binaries like we did for Linux (in particular localize-hidden
command) and only ld64 handle this kind of step at partial link time.

- - - - -
ff3fa3fd by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
modules: static.mk: generate vlc_module_manifest.h

The manifest header declares the list of plugins as an X-macro and
allows integrating this list into other cases, including external
application and static module bank generation in the project.

- - - - -
f97c9783 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
modules/static.mk: add libvlc_static_modules bundle target

The target is used in the project when needing to build the static
module bank so as to convey the inherited flags (frameworks for Darwin)
and dependencies (those that are not linked into the plugins and instead
forwarded, like system libraries on Android) and avoid requiring a list
of all the plugins for next steps.

- - - - -
0f7cccb9 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
bin: vlc: add support for static partially linked plugin

This is the final test for the partial linking situation since we really
end up with a final binary that should have the static module bank
initialized correctly.

In the commit, we add the vlc_static_modules.c source file that contains
the standard definition for the static module bank and can be reused
against any binary being built to bundle the static module bank.

- - - - -
2fa33aa8 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: enable partial linking for supported targets

- - - - -
7f2ecc55 by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: allow building VLC statically

Now that partial linking is available, static linking can be done safely
and natively.

- - - - -
ecadeffe by Alexandre Janniaux at 2026-05-30T15:55:47+02:00
configure.ac: enable partial linking on supported platforms

Only enable partial linking on ELF platforms (Linux, Android) and
Apple platform.

Windows is excluded as partial linking is not supported there (there's
no way to enforce COMDAT groups to be allocated at ld -r time and it
really needs the final link to happen).

It's possible for emscripten platform but it needs some hacks that will
come later.

Fix #25156

- - - - -


22 changed files:

- .gitignore
- bin/Makefile.am
- bin/preparser/Makefile.am
- + bin/vlc_static_modules.c
- + buildsystem/dependencies.sh
- config.h.meson
- configure.ac
- + extras/tools/libtool-2.5.4-unarchive-old-libraries.patch
- extras/tools/tools.mak
- include/vlc_plugin.h
- modules/Makefile.am
- modules/audio_output/vlc_pipewire.c
- modules/audio_output/vlcpulse.c
- modules/common.am
- modules/misc/medialibrary/MetadataExtractor.cpp
- modules/misc/medialibrary/Thumbnailer.cpp
- modules/misc/medialibrary/fs/fs.cpp
- + modules/static.mk
- modules/video_output/xcb/events.c
- src/meson.build
- src/playlist/playlist.c
- src/preparser/preparser.c


Changes:

=====================================
.gitignore
=====================================
@@ -14,6 +14,8 @@
 *.class
 *.dmg
 *.qmlc
+*.orig
+*.symbollist
 .DS_Store
 .deps
 .libs


=====================================
bin/Makefile.am
=====================================
@@ -16,6 +16,7 @@ SUFFIXES = .rc.in .rc
 
 AM_CPPFLAGS = $(CPPFLAGS_vlc)
 AM_CFLAGS = $(CFLAGS_vlc)
+noinst_LTLIBRARIES =
 if HAVE_DBUS
 AM_CPPFLAGS += -DHAVE_DBUS
 endif
@@ -41,7 +42,7 @@ libbreakpad_wrapper_la_LIBADD = $(BREAKPAD_LIBS)
 libbreakpad_wrapper_la_LDFLAGS = -static
 libbreakpad_wrapper_la_CXXFLAGS = $(AM_CXXFLAGS) $(BREAKPAD_CFLAGS) -DBREAKPAD_URL=\"@BREAKPAD_URL@\"
 if HAVE_BREAKPAD
-noinst_LTLIBRARIES = libbreakpad_wrapper.la
+noinst_LTLIBRARIES += libbreakpad_wrapper.la
 vlc_LDADD += libbreakpad_wrapper.la -lstdc++ -lwininet
 EXTRA_vlc_DEPENDENCIES += libbreakpad_wrapper.la
 vlc_CPPFLAGS += -DHAVE_BREAKPAD
@@ -49,16 +50,18 @@ endif
 endif
 
 vlc_osx_SOURCES = darwinvlc.m
+vlc_osx_CPPFLAGS = $(AM_CPPFLAGS)
 vlc_osx_LDFLAGS = $(LDFLAGS_vlc) -Wl,-framework,CoreFoundation,-framework,Cocoa
 vlc_osx_LDFLAGS += -Xlinker -rpath -Xlinker "$(libdir)"
 if HAVE_BREAKPAD
 vlc_osx_LDFLAGS += -Wl,-framework,Breakpad
 vlc_osx_OBJCFLAGS = -F$(CONTRIB_DIR)/Frameworks
-vlc_osx_CPPFLAGS = -DHAVE_BREAKPAD
+vlc_osx_CPPFLAGS += -DHAVE_BREAKPAD
 endif
 vlc_osx_LDADD = ../lib/libvlc.la
 
 vlc_osx_static_SOURCES = $(vlc_osx_SOURCES)
+vlc_osx_static_CPPFLAGS = $(vlc_osx_CPPFLAGS)
 vlc_osx_static_OBJCFLAGS = $(AM_OBJCFLAGS) \
 	-DTOP_BUILDDIR=\"$(abs_top_builddir)\" \
 	-DTOP_SRCDIR=\"$(abs_top_srcdir)\" \
@@ -71,7 +74,6 @@ vlc_osx_static_LDADD = $(vlc_osx_LDADD)
 if HAVE_BREAKPAD
 vlc_osx_static_LDFLAGS += -Wl,-framework,Breakpad
 vlc_osx_static_OBJCFLAGS += -F$(CONTRIB_DIR)/Frameworks
-vlc_osx_static_CPPFLAGS = -DHAVE_BREAKPAD
 endif
 
 
@@ -125,6 +127,16 @@ vlc_cache_gen_LDFLAGS = -Wc,-static
 EXTRA_vlc_cache_gen_DEPENDENCIES = vlc_win32_rc.$(OBJEXT)
 endif
 
+if HAVE_PARTIAL_LINKING
+AM_CPPFLAGS += -DVLC_PARTIAL_LINKING -I $(builddir)/../modules/
+if !HAVE_WIN32
+vlc_SOURCES += vlc_static_modules.c
+endif
+vlc_osx_SOURCES += vlc_static_modules.c
+vlc_LDADD += ../modules/libvlc_static_modules.la
+vlc_osx_LDADD += ../modules/libvlc_static_modules.la
+endif
+
 #
 # Plug-ins cache
 #


=====================================
bin/preparser/Makefile.am
=====================================
@@ -4,6 +4,7 @@ AUTOMAKE_OPTIONS = subdir-objects
 # Preparser executable
 #
 if BUILD_VLC
+if HAVE_EXTERNAL_PREPARSER
 if HAVE_DYNAMIC_PLUGINS
 pkglibexec_PROGRAMS += vlc-preparser
 else
@@ -11,6 +12,7 @@ pkglibexec_PROGRAMS = vlc-preparser
 endif
 noinst_PROGRAMS += vlc-preparser-static
 endif
+endif
 
 vlc_preparser_SOURCES = \
 		../src/config/getopt.c \


=====================================
bin/vlc_static_modules.c
=====================================
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * Copyright (C) 2021-2026 Alexandre Janniaux <ajanni at videolabs.io>
+ *
+ * This program 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; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <vlc_modules_manifest.h>
+
+typedef int (*vlc_set_cb)(void*, void*, int, ...);
+typedef int (*vlc_plugin_cb)(vlc_set_cb, void*);
+
+#define DECLARE_PLUGIN(NAME) int vlc_entry__ ## NAME(vlc_set_cb, void*);
+#define LIST_PLUGIN(NAME) vlc_entry__ ## NAME,
+
+VLC_MODULE_LIST(DECLARE_PLUGIN)
+
+__attribute__((visibility("default")))
+vlc_plugin_cb vlc_static_modules[] = {
+    VLC_MODULE_LIST(LIST_PLUGIN)
+    NULL,
+};


=====================================
buildsystem/dependencies.sh
=====================================
@@ -0,0 +1,138 @@
+#!/bin/sh
+# SPDX-License-Identifier: LGPL-2.1-or-later
+# Copyright (C) 2021-2026 Alexandre Janniaux <ajanni at videolabs.io>
+#
+# Extract static or forwarded dependencies from a libtool .la archive.
+#
+# Usage: dependencies.sh <mode> <file.la>
+#
+# Modes:
+#   static    print static archive paths (.a) needed for partial linking
+#   forward   print flags (-l, .la deps) to defer to the final link stage
+set -eu
+
+MODE=$1
+LTFILE=$2
+
+# Parse a field value from a libtool .la archive, stripping quotes.
+# Usage: parse_la_field <file.la> <field_name>
+parse_la_field()
+{
+    _value=$(grep "$2=" "$1" | cut -d= -f2-)
+    _value="${_value%\'}"; _value="${_value#\'}"
+    echo "$_value"
+}
+
+# Collect -L directory paths from a dependency string.
+# Usage: collect_library_path <deps>
+collect_library_path()
+{
+    _lp=""
+    for _dep in $1; do
+        case "$_dep" in -L*)
+            _lp="$_lp ${_dep#-L}" ;;
+        esac
+    done
+    echo "$_lp"
+}
+
+# Resolve a -l flag to a static archive using LIBRARY_PATH search.
+# Prints resolved path(s) to stdout. Returns 1 if unresolvable.
+# Usage: resolve_lflag <-lfoo> <library_path>
+resolve_lflag()
+{
+    _libname="${1#-l}"
+    for _rpath in $2; do
+        _base="$_rpath/lib${_libname}"
+        if [ -f "${_base}.a" ]; then
+            echo "${_base}.a"
+            return 0
+        elif [ -f "${_base}.la" ]; then
+            if grep -q installed=yes "${_base}.la"; then
+                extract_dependencies "${_base}.la"
+                return 0
+            fi
+        fi
+    done
+    return 1
+}
+
+# Process a .la dependency: resolve its static archive path and recurse.
+# Sets _STATIC and _FORWARD for the caller to append.
+# Usage: process_la_dep <file.la>
+process_la_dep()
+{
+    _STATIC="" ; _FORWARD=""
+    _ladep="$1"
+
+    # Only installed static archives (contribs) should be
+    # merged. Build-tree libraries (installed=no with a
+    # libdir) like libvlccore.la, libvlc_pulse.la will be
+    # available at final link so that the lib global state
+    # is preserved for in-tree and out-of-tree plugins.
+    _installed=$(parse_la_field "$_ladep" installed)
+    _libdir_field=$(parse_la_field "$_ladep" libdir)
+    if [ "$_installed" = "no" ] && [ -n "$_libdir_field" ]; then
+        _FORWARD="$_ladep"
+        return
+    fi
+
+    _old_lib=$(parse_la_field "$_ladep" old_library)
+
+    if [ -n "$_old_lib" ]; then
+        _libdir=$(dirname "$_ladep")
+        # Check if the archive is in .libs, which could signal
+        # a non-installed library
+        if [ -f "$_libdir/.libs/$_old_lib" ]; then
+            _libdir="$_libdir/.libs"
+        fi
+        case "$MODE" in
+            static)  _STATIC="$_libdir/$_old_lib $(extract_dependencies "$_ladep")" ;;
+            forward) _FORWARD="$(extract_dependencies "$_ladep")" ;;
+        esac
+    else
+        # Shared-only library (no static archive): forward -l flag
+        _ln=$(basename "$_ladep" .la)
+        _ln="${_ln#lib}"
+        _FORWARD="-l$_ln"
+    fi
+}
+
+# Recursively extract dependencies from a .la file.
+# Prints the resolved dependency list for the current MODE.
+extract_dependencies()
+{
+    _deps=$(parse_la_field "$1" dependency_libs)
+    _lib_path=$(collect_library_path "$_deps")
+
+    STATIC_DEPENDENCIES=""
+    FORWARD_DEPENDENCIES=""
+
+    for _dep in $_deps; do
+        case "$_dep" in
+            -L*) ;; # already handled by collect_library_path
+            -l*)
+                if _resolved=$(resolve_lflag "$_dep" "$_lib_path"); then
+                    STATIC_DEPENDENCIES="$STATIC_DEPENDENCIES $_resolved"
+                else
+                    FORWARD_DEPENDENCIES="$FORWARD_DEPENDENCIES $_dep"
+                fi
+                ;;
+            *.a)
+                STATIC_DEPENDENCIES="$STATIC_DEPENDENCIES $_dep"
+                ;;
+            *.la)
+                process_la_dep "$_dep"
+                STATIC_DEPENDENCIES="$STATIC_DEPENDENCIES $_STATIC"
+                FORWARD_DEPENDENCIES="$FORWARD_DEPENDENCIES $_FORWARD"
+                ;;
+        esac
+    done
+
+    case "$MODE" in
+        forward) echo $FORWARD_DEPENDENCIES ;;
+        static)  echo $STATIC_DEPENDENCIES ;;
+    esac
+}
+
+extract_dependencies "$LTFILE"


=====================================
config.h.meson
=====================================
@@ -443,6 +443,9 @@
 /* Define to 1 if vlc_process_Spawn() is usable. */
 #mesondefine HAVE_VLC_PROCESS_SPAWN
 
+/* Define to 1 if the out-of-process preparser is supported. */
+#mesondefine HAVE_VLC_EXTERNAL_PREPARSER
+
 /* Define to 1 if you have the `vmsplice' function. */
 #mesondefine HAVE_VMSPLICE
 


=====================================
configure.ac
=====================================
@@ -82,6 +82,10 @@ AC_ARG_VAR([DESKTOP_FILE_VALIDATE], [Validator for desktop entry files])
 AC_CHECK_PROGS([DESKTOP_FILE_VALIDATE], [${DESKTOP_FILE_VALIDATE} desktop-file-validate], :)
 AC_ARG_VAR([BUILDCC], [Build system C11 or C99 compiler command])
 AC_CHECK_PROGS([BUILDCC], [c17-gcc c17 c11-gcc c11 c99-gcc c99], [false])
+dnl When cross-compiling, only accept $host-prefixed objcopy or llvm-objcopy.
+dnl Bare objcopy from the build system cannot handle cross-target objects.
+dnl llvm-objcopy is target-agnostic (reads the ELF header) so it is safe.
+AC_CHECK_PROGS(OBJCOPY, [${ac_tool_prefix}objcopy llvm-objcopy], :)
 AS_IF([test "$BUILDCC" = "false"], [
   AC_MSG_ERROR([Cannot find native C99 compiler: please define BUILDCC.])
 ])
@@ -325,7 +329,6 @@ int foo() { return my_array[0]; }
     AX_APPEND_COMPILE_FLAGS([-static-libgcc], [CXXFLAGS], [-Werror])
     AC_LANG_POP(C++)
     AC_CHECK_TOOL(WINDRES, windres, :)
-    AC_CHECK_TOOL(OBJCOPY, objcopy, :)
     AC_PREPROC_IFELSE([AC_LANG_PROGRAM(
       [[#ifdef _WIN32_WINNT
        # error _WIN32_WINNT already defined
@@ -551,6 +554,16 @@ AM_COND_IF([HAVE_PROCESS_SPAWN], [
   AC_DEFINE([HAVE_VLC_PROCESS_SPAWN], [1], [Define to 1 if vlc_process_Spawn() is usable.])
 ])
 
+dnl External (out-of-process) preparser requires both process spawn support
+dnl and dynamic linking: in static builds libvlc.a and the preparser binary
+dnl both define vlc_module_name, causing a multiple-definition link error.
+AM_CONDITIONAL([HAVE_EXTERNAL_PREPARSER],
+    [test "${HAVE_PROCESS_SPAWN}" = "1" -a "${enable_shared}" != "no"])
+AM_COND_IF([HAVE_EXTERNAL_PREPARSER], [
+  AC_DEFINE([HAVE_VLC_EXTERNAL_PREPARSER], [1],
+            [Define to 1 if the out-of-process preparser is supported.])
+])
+
 AM_CONDITIONAL([HAVE_WIN32],   [test "${SYS}" = "mingw32"])
 AM_CONDITIONAL([HAVE_WIN64],   [test "${HAVE_WIN64}" = "1"]) dnl Only used for the packaging
 AM_CONDITIONAL([HAVE_WINSTORE], [test "$vlc_winstore_app" = "1"])
@@ -694,9 +707,6 @@ DOLT
 
 lt_cv_deplibs_check_method=pass_all
 
-AS_IF([test "${enable_shared}" = "no" -a "${enable_vlc}" != "no"], [
-  AC_MSG_ERROR([VLC is based on plugins. Shared libraries cannot be disabled.])
-])
 
 dnl
 dnl Gettext stuff
@@ -1023,7 +1033,119 @@ AS_IF([test "${enable_shared}" = "no"], [
   have_dynamic_objects=no
 ])
 AM_CONDITIONAL([HAVE_DYNAMIC_PLUGINS], [test "${have_dynamic_objects}" != "no"])
-AM_CONDITIONAL([HAVE_PARTIAL_LINKING], [false])
+
+dnl Partial linking merges each plugin and its static dependencies into a
+dnl single relocatable object, enabling fully-static VLC builds.
+dnl Disabled by default for now; this will become the default in the future.
+AC_ARG_ENABLE([partial-linking],
+  AS_HELP_STRING([--enable-partial-linking],
+    [use partial linking for static plugin builds (default disabled)]))
+
+dnl Partial linking is only supported on ELF platforms and Apple platforms
+have_partial_linking_support=no
+AS_IF([test "${SYS}" = "linux" -o "${VENDOR}" = "android" -o "${SYS}" = "darwin"], [
+    have_partial_linking_support=yes
+])
+
+AS_IF([test "${enable_partial_linking}" = "yes" -a "${have_partial_linking_support}" != "yes"], [
+    AC_MSG_ERROR([Partial linking is not supported on this platform.])
+])
+
+have_partial_linking=no
+AS_IF([test "${enable_partial_linking}" = "yes" -a "${have_dynamic_objects}" = "no"], [
+    have_partial_linking=yes
+])
+
+AM_CONDITIONAL([HAVE_PARTIAL_LINKING], [test "${have_partial_linking}" = "yes"])
+AS_IF([test "${have_partial_linking}" = "yes"], [
+    AC_DEFINE([HAVE_PARTIAL_LINKING], 1, [Define if static plugins use partial linking])
+])
+AS_IF([test "${enable_shared}" = "no" -a "${have_partial_linking}" != "yes" -a "${enable_vlc}" != "no"], [
+    AC_MSG_ERROR([VLC requires partial linking to build with static plugins. Use --enable-partial-linking or --disable-vlc.])
+])
+
+dnl Check if the linker supports --force-group-allocation.
+dnl This flag resolves COMDAT section groups during partial linking, which are
+dnl generated when building C++ plugins. It proceed with intra-plugin
+dnl deduplication but will prevent cross-plugin deduplication since we don't
+dnl want the non-module ABI to be exposed out of the plugin object.
+FORCE_GROUP_ALLOCATION_LDFLAGS=""
+AS_IF([test "${have_partial_linking}" = "yes"], [
+    AC_CACHE_CHECK([whether the linker supports --force-group-allocation],
+        [vlc_cv_ld_force_group_allocation], [
+        VLC_SAVE_FLAGS
+        LDFLAGS="${LDFLAGS} -Wl,--force-group-allocation"
+        AC_LINK_IFELSE([AC_LANG_PROGRAM()],
+            [vlc_cv_ld_force_group_allocation=yes],
+            [vlc_cv_ld_force_group_allocation=no])
+        VLC_RESTORE_FLAGS
+    ])
+    AS_IF([test "${vlc_cv_ld_force_group_allocation}" = "yes"], [
+        FORCE_GROUP_ALLOCATION_LDFLAGS="-Wl,--force-group-allocation"
+    ])
+])
+
+dnl Test whether partial linking resolves COMDAT section groups.
+dnl C++ template instantiations produce COMDAT groups; if the linker does
+dnl not deduplicate them during -r, duplicate symbols will leak across
+dnl plugins at the final link.
+dnl
+dnl We test the behavior directly: compile two TUs with the same
+dnl template, partially link them, and check that the symbol appears
+dnl only once in the result.
+AS_IF([test "${have_partial_linking}" = "yes"], [
+    AC_CACHE_CHECK([whether partial linking resolves COMDAT groups],
+        [vlc_cv_ld_partial_link_comdat], [
+        vlc_cv_ld_partial_link_comdat=no
+        cat > conftest1.cpp <<EOF
+template<typename T> __attribute__((noinline)) T vlc_comdat_test(T x) { return x; }
+int vlc_comdat_a() { return vlc_comdat_test(1); }
+EOF
+        cat > conftest2.cpp <<EOF
+template<typename T> __attribute__((noinline)) T vlc_comdat_test(T x) { return x; }
+int vlc_comdat_b() { return vlc_comdat_test(2); }
+EOF
+        AS_IF([$CXX $CXXFLAGS $CPPFLAGS -c conftest1.cpp -o conftest1.o 2>/dev/null \
+            && $CXX $CXXFLAGS $CPPFLAGS -c conftest2.cpp -o conftest2.o 2>/dev/null \
+            && $CXX $CXXFLAGS $CPPFLAGS $LDFLAGS $FORCE_GROUP_ALLOCATION_LDFLAGS \
+                    -r -o conftest_partial.o conftest1.o conftest2.o 2>/dev/null],
+        [
+            comdat_count=`$NM conftest_partial.o 2>/dev/null \
+                | grep -c '[[TWV]].*vlc_comdat_test'`
+            AS_IF([test "$comdat_count" = "1"], [
+                vlc_cv_ld_partial_link_comdat=yes
+            ])
+        ])
+        rm -f conftest1.cpp conftest2.cpp conftest1.o conftest2.o conftest_partial.o
+    ])
+    AS_IF([test "${vlc_cv_ld_partial_link_comdat}" != "yes"], [
+        AS_IF([test "${have_dynamic_objects}" = "no" -a "${SYS}" != "darwin"], [
+            AC_MSG_ERROR([Partial linking does not resolve COMDAT groups. COMDAT deduplication is required for C++ static plugins.])
+        ])
+    ])
+])
+dnl On ELF, objcopy is required to localize symbols after partial linking.
+dnl The early detection (above) already ensures a target-compatible objcopy:
+dnl host-prefixed GNU objcopy or llvm-objcopy when cross-compiling.
+dnl On Darwin, ld64 -exported_symbol handles visibility so objcopy is not needed.
+AS_IF([test "${have_partial_linking}" = "yes" -a "${SYS}" != "darwin" -a "$OBJCOPY" = ":"], [
+    AC_MSG_ERROR([Partial linking on ELF requires objcopy or llvm-objcopy to localize symbols.])
+])
+AC_SUBST([FORCE_GROUP_ALLOCATION_LDFLAGS])
+
+dnl Check if the C++ compiler supports -fno-gnu-unique. GCC emits STB_GNU_UNIQUE
+dnl binding for some C++ symbols, which objcopy -G cannot localize. Emitting
+dnl WEAK instead lets partial-linked static module objects be combined without
+dnl multiple-definition errors and is also clang behavior.
+NO_GNU_UNIQUE_CXXFLAGS=""
+AS_IF([test "${have_partial_linking}" = "yes"], [
+    AC_LANG_PUSH([C++])
+    AX_CHECK_COMPILE_FLAG([-fno-gnu-unique], [
+        NO_GNU_UNIQUE_CXXFLAGS="-fno-gnu-unique"
+    ], [], [-Werror])
+    AC_LANG_POP([C++])
+])
+AC_SUBST([NO_GNU_UNIQUE_CXXFLAGS])
 
 AC_SUBST([LIBDL])
 
@@ -5067,6 +5189,7 @@ AC_SUBST([RCC])
 AC_SUBST([UIC])
 AC_SUBST([QSB])
 AC_SUBST([WINDRES])
+AC_SUBST([OBJCOPY])
 AC_SUBST([LIBEXT])
 AC_SUBST([AM_CPPFLAGS])
 AC_SUBST([MACOSX_DEPLOYMENT_TARGET])


=====================================
extras/tools/libtool-2.5.4-unarchive-old-libraries.patch
=====================================
@@ -0,0 +1,128 @@
+From 0c845d7b9039050d5794f6493ea405e2f83afb70 Mon Sep 17 00:00:00 2001
+From: Alexandre Janniaux <ajanni at videolabs.io>
+Date: Tue, 6 Apr 2021 10:22:14 +0200
+Subject: [PATCH 1/3] ltmain.in: ensure old libraries are not archived
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Previously, adding a static archive library, aka. old library, as a
+dependency of a new libtool library compiled as a static archive (be it
+a convenience library or an installed static library) resulted in the
+dependency archive being added into the target archive as-is.
+
+However, linkers are usually not able to use nested archive as-is. It
+results in errors like these on Linux and Darwin at least:
+
+    /usr/bin/ld: ./.libs/libfoo.a: member ./.libs/libfoo.a(libbar.a) in
+    archive is not an object
+
+or
+
+    /usr/bin/nm: libbar.a: file format not recognized
+
+With libfoo.a being the static libtool target and libbar.a being the
+nested/linked static library.
+
+Libtool has a quite close behaviour with convenience libraries, where
+the content (objects) of the convenience library are extracted and added
+back into the new target, but that´s mostly a libtool creation.
+
+The static dependencies should not be "linked" into other static
+libraries as there should not be linking involved, and we don´t want to
+potentially duplicate symbols like done for the convenience libraries.
+
+Instead, keep them in the dependency_libs of the new libtool archive
+created and forward them until we link a shared library or an
+executable.
+
+The test was marked XFAIL since 2010 because the fix for the
+nested-archive bug was incomplete. Now that ltmain.in properly
+forwards old library dependencies instead of archiving them,
+the test passes: remove the AT_XFAIL_IF and correct the
+foo.$OBJEXT assertion (objects from the dependency must NOT
+appear in the target archive).
+---
+ build-aux/ltmain.in         | 11 ++++++++---
+ tests/archive-in-archive.at |  8 ++++----
+ 2 files changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/build-aux/ltmain.in b/build-aux/ltmain.in
+index 70d0e111..b32478c9 100644
+--- a/build-aux/ltmain.in
++++ b/build-aux/ltmain.in
+@@ -5816,7 +5816,6 @@ func_mode_link ()
+       *.$libext|*.so)
+ 	# An archive or an explicit shared library.
+ 	func_append deplibs " $arg"
+-	func_append old_deplibs " $arg"
+ 	continue
+ 	;;
+ 
+@@ -6215,6 +6214,8 @@ func_mode_link ()
+ 	  if test conv = "$pass"; then
+ 	    deplibs="$deplib $deplibs"
+ 	    continue
++	  else
++	    func_append old_deplibs " $deplib"
+ 	  fi
+ 	  case $linkmode in
+ 	  lib)
+@@ -7184,7 +7185,6 @@ func_mode_link ()
+       # Now set the variables for building old libraries.
+       build_libtool_libs=no
+       oldlibs=$output
+-      func_append objs "$old_deplibs"
+       ;;
+ 
+     lib)
+@@ -8952,7 +8952,11 @@ func_mode_link ()
+ 	  build_libtool_libs=no
+           ;;
+ 	*)
+-	  oldobjs="$old_deplibs $non_pic_objects"
++	  oldobjs="$non_pic_objects"
++	  # This is not correct to add old_deplibs creating an archive
++	  # so append them only when creating an executable or a shared
++	  # library.
++	  test yes != "$build_old_libs" && oldobjs="$oldobjs $old_deplibs"
+ 	  $preload && test -f "$symfileobj" \
+ 	    && func_append oldobjs " $symfileobj"
+ 	  addlibs=$old_convenience
+@@ -9213,6 +9217,7 @@ func_mode_link ()
+ 	    done
+ 	    dlprefiles=$newdlprefiles
+ 	  fi
++	  func_append dependency_libs " $old_deplibs"
+ 	  $RM $output
+ 	  # place dlname in correct position for cygwin
+ 	  # In fact, it would be nice if we could use this code for all target
+diff --git a/tests/archive-in-archive.at b/tests/archive-in-archive.at
+index d081f57d..b48579ae 100644
+--- a/tests/archive-in-archive.at
++++ b/tests/archive-in-archive.at
+@@ -24,9 +24,6 @@
+ AT_SETUP([static library contains static library])
+ AT_KEYWORDS([libtool])
+ 
+-# This test passes with MS lib.
+-AT_XFAIL_IF([case $AR in ar-lib\ * | *[[/\\]]ar-lib\ *) false;; *) :;; esac])
+-
+ AT_DATA([foo.c],
+ [
+ int foo() { return 1;}
+@@ -51,7 +48,10 @@ AT_CHECK([$LIBTOOL --mode=link --tag=CC --tag=disable-shared $CC $CFLAGS $LDFLAG
+ AT_CHECK([$LIBTOOL --mode=install cp libbar.la $thisdir], [], [ignore], [ignore])
+ eval `$EGREP '^(old_library)=' < libbar.la`
+ libbar=$old_library
++# The old library (libfoo.a) must NOT be nested inside libbar.a.
+ AT_CHECK([$AR -t $libbar | $GREP $libfoo],[1],[ignore],[ignore])
+-AT_CHECK([$AR -t $libbar | $GREP foo.$OBJEXT],[],[ignore],[ignore])
++# Objects from libfoo must NOT be extracted into libbar.a either.
++AT_CHECK([$AR -t $libbar | $GREP foo.$OBJEXT],[1],[ignore],[ignore])
++# bar's own object must still be present.
+ AT_CHECK([$AR -t $libbar | $GREP bar.$OBJEXT],[],[ignore],[ignore])
+ AT_CLEANUP
+-- 
+2.53.0
+


=====================================
extras/tools/tools.mak
=====================================
@@ -125,6 +125,8 @@ libtool: libtool-$(LIBTOOL_VERSION).tar.gz
 	$(APPLY) $(TOOLS)/libtool-2.5.4-clang-libs.patch
 	$(APPLY) $(TOOLS)/libtool-2.4.7-lpthread.patch
 	$(APPLY) $(TOOLS)/libtool-2.5.4-embed-bitcode.patch
+
+	$(APPLY) $(TOOLS)/libtool-2.5.4-unarchive-old-libraries.patch
 	$(MOVE)
 
 .buildlibtool: libtool .automake .help2man


=====================================
include/vlc_plugin.h
=====================================
@@ -285,6 +285,14 @@ enum vlc_config_subcat
 # else
 #  define DLL_SYMBOL
 # endif
+#elif defined (VLC_PARTIAL_LINKING) && defined (__GNUC__)
+/* Static / partial-linking build: the entry symbols are still part of the
+ * plugin/host export interface (they are resolved by the host at static
+ * link time via per-module suffixed names). Under -fvisibility=hidden they
+ * would otherwise be emitted as private_external and subsequently demoted
+ * to local by `ld -r` during partial linking on Mach-O, breaking the final
+ * link. */
+# define DLL_SYMBOL                __attribute__((visibility("default")))
 #else
 # define DLL_SYMBOL
 #endif


=====================================
modules/Makefile.am
=====================================
@@ -133,3 +133,7 @@ noinst_LTLIBRARIES += $(noinst_PLUGINS)
 # Generate vlc_modules_list (local plugins + SUBDIRS)
 include modulelist.mk
 SUBDIRS += .
+
+# Extract plugins and convenience libraries from the libtool libraries
+# being built, excluding the ones using them.
+include static.mk


=====================================
modules/audio_output/vlc_pipewire.c
=====================================
@@ -34,7 +34,9 @@
 #include <vlc_tick.h>
 #include "vlc_pipewire.h"
 
+#ifndef HAVE_PARTIAL_LINKING
 const char vlc_module_name[] = "vlcpipewire";
+#endif
 
 struct vlc_pw_context {
     struct pw_thread_loop *loop;


=====================================
modules/audio_output/vlcpulse.c
=====================================
@@ -34,7 +34,9 @@
 #include <unistd.h>
 #include <pwd.h>
 
+#ifndef HAVE_PARTIAL_LINKING
 const char vlc_module_name[] = "vlcpulse";
+#endif
 
 #undef vlc_pa_error
 void vlc_pa_error (vlc_object_t *obj, const char *msg, pa_context *ctx)


=====================================
modules/common.am
=====================================
@@ -27,6 +27,10 @@ endif
 AM_CFLAGS =
 AM_CXXFLAGS =
 AM_OBJCFLAGS =
+if HAVE_PARTIAL_LINKING
+AM_CPPFLAGS += -DVLC_PARTIAL_LINKING
+AM_CXXFLAGS += $(NO_GNU_UNIQUE_CXXFLAGS)
+endif
 AM_LDFLAGS = \
 	-avoid-version -module \
 	-export-symbols-regex ^vlc_entry \


=====================================
modules/misc/medialibrary/MetadataExtractor.cpp
=====================================
@@ -93,7 +93,7 @@ MetadataExtractor::MetadataExtractor( vlc_object_t* parent )
         .max_parser_threads = 1,
         .max_thumbnailer_threads = 0,
         .timeout = VLC_TICK_FROM_SEC(5),
-#if !defined(HAVE_VLC_PROCESS_SPAWN)
+#if !defined(HAVE_VLC_EXTERNAL_PREPARSER)
         .external_process = false,
 #else
         .external_process = true,


=====================================
modules/misc/medialibrary/Thumbnailer.cpp
=====================================
@@ -40,7 +40,7 @@ Thumbnailer::Thumbnailer( vlc_medialibrary_module_t* ml )
         .max_parser_threads = 0,
         .max_thumbnailer_threads = 1,
         .timeout = VLC_TICK_FROM_SEC( 3 ),
-#if !defined(HAVE_VLC_PROCESS_SPAWN)
+#if !defined(HAVE_VLC_EXTERNAL_PREPARSER)
         .external_process = false,
 #else
         .external_process = true,


=====================================
modules/misc/medialibrary/fs/fs.cpp
=====================================
@@ -48,7 +48,7 @@ SDFileSystemFactory::SDFileSystemFactory(vlc_object_t *parent,
         .max_parser_threads = 1,
         .max_thumbnailer_threads = 0,
         .timeout = VLC_TICK_FROM_SEC(15),
-#if !defined(HAVE_VLC_PROCESS_SPAWN)
+#if !defined(HAVE_VLC_EXTERNAL_PREPARSER)
         .external_process = false,
 #else
         .external_process = true,


=====================================
modules/static.mk
=====================================
@@ -0,0 +1,142 @@
+# Extract plugins and convenience libraries from the libtool libraries
+# being built, excluding the ones using them.
+
+PLUGINS = $(VLC_PLUGINS:%=lib%.la)
+PARTIAL_PLUGINS = $(PLUGINS:_plugin.la=_plugin.partial.la)
+
+# With Mach-O, ld64's -exported_symbol promotes the listed pattern to
+# the only globally visible symbols in the relocatable output and
+# demotes everything else. On ELF this is handled by the
+# `objcopy -G 'vlc_entry*'` step below because it only works at the
+# final link otherwise.
+PARTIAL_LINK_EXPORT_FLAGS =
+if HAVE_DARWIN
+PARTIAL_LINK_EXPORT_FLAGS += -Wl,-exported_symbol,_vlc_entry*
+endif
+
+.PRECIOUS: $(PARTIAL_PLUGINS) $(PLUGINS:.la=.la.symbollist) $(PARTIAL_PLUGINS:=.symbollist) \
+	$(PARTIAL_PLUGINS:%.partial.la=.deps/%.partial.la.o)
+
+# Given the list of symbols from the original plugin, and the original
+# plugin itself with its libtool archive, we'll build the actual partial
+# plugin _object_. At this step, we also need to fetch the static
+# dependencies from the source plugin since we'll actually merge them
+# into the object. The -Wl,-u flag forces the linker to pull the entry
+# symbol from the archive, replacing the former module_expose.c approach.
+#
+# NOTE: After this step, the partial plugin object exists but it's not
+#       yet wrapped in a libtool archive the rest of the project can
+#       use.
+.deps/%_plugin.partial.la.o: %_plugin.la %_plugin.la.symbollist
+	$(AM_V_at)$(MKDIR_P) $(@D)
+	$(AM_V_at)$(AM_V_P) && set -x; \
+	libpath=`grep old_library= "$<" | cut -d"'" -f 2`; \
+	vlc_entrypoint=`$(NM) ".libs/$${libpath}" | \
+		awk '$$2 == "T" && $$3 ~ /^_?vlc_entry__[A-Za-z0-9_]+$$/ { print $$3; exit }'`; \
+	static_dependencies=`$(top_srcdir)/buildsystem/dependencies.sh static $<`; \
+	$(CXX) $(CXXFLAGS) $(LDFLAGS) \
+		-r -o $@ -fPIC \
+		$(FORCE_GROUP_ALLOCATION_LDFLAGS) \
+		$(PARTIAL_LINK_EXPORT_FLAGS) \
+		-Wl,-u,$${vlc_entrypoint} \
+		".libs/$${libpath}" \
+		$${static_dependencies}
+	@# Resolve COMDAT groups so they don't cause cross-plugin dedup at final link
+	@# Then localize ALL symbols except VLC entry points.
+	@# On Darwin, ld64 -exported_symbol already handles this (see PARTIAL_LINK_EXPORT_FLAGS).
+if !HAVE_DARWIN
+	$(AM_V_at)$(OBJCOPY) --wildcard \
+		-G 'vlc_entry*' \
+		$@ || rm -f $@
+endif
+# Unfortunately libtool checks that the following comment is there to check that
+# libtool object is correct, so provide it
+	$(AM_V_at)echo "# .deps/$*_plugin.partial.la.lo - a libtool object file" > $*_plugin.partial.la.lo
+	$(AM_V_at)echo "# Generated by doltcompile, not libtool" >> $*_plugin.partial.la.lo
+	$(AM_V_at)echo "non_pic_object=none" >> $*_plugin.partial.la.lo
+	$(AM_V_at)echo "pic_object=$(abs_builddir)/$@" >> $*_plugin.partial.la.lo
+
+# Generate a libtool archive the built partially linked object
+# constructed from the source plugin and its dependencies. At this
+# point, we also need to provide the dependencies that we could not or
+# didn't want to link.
+%_plugin.partial.la: %_plugin.la %_plugin.la.symbollist .deps/%_plugin.partial.la.o
+	$(AM_V_at)$(LIBTOOL) $(AM_V_lt) --mode=link --tag=CXX c++ -Wl,-Ur -fPIC -o $@ "$@.lo" \
+		-export-symbols-regex "^vlc_entry__"
+	$(AM_V_GEN)dependencies=`$(top_srcdir)/buildsystem/dependencies.sh forward $<`; \
+	frameworks=`echo "$($*_plugin_la_LDFLAGS)" \
+		| grep -oE '\-(framework|weak_framework),[A-Za-z][A-Za-z0-9_]*' \
+		| sort -u \
+		| sed 's/^/-Wl,/' \
+		| tr '\n' ' '`; \
+	sed -i.orig "s,dependency_libs=.*\$$,dependency_libs=' $${dependencies}'," $@ \
+		|| (rm $@ && exit 1); \
+	sed -i.orig "s|inherited_linker_flags='\(.*\)'|inherited_linker_flags='\1 $${frameworks}'|" $@ \
+		|| (rm $@ && exit 1); \
+	echo "" >> $@;
+
+if HAVE_PARTIAL_LINKING
+# Symbollist from original plugin .la file
+%_plugin.la.symbollist: %_plugin.la
+	$(AM_V_GEN)libpath=`grep old_library= "$<" | cut -d"'" -f 2`; \
+	entrypoint=`$(NM) ".libs/$${libpath}" | \
+	    awk '$$2 == "T" && $$3 ~ /^_?vlc_entry__[A-Za-z0-9_]+$$/ { s=$$3; sub(/^_/,"",s); print s; exit }'`; \
+	echo $${entrypoint} > $@
+
+# Symbollist from partial-linked .partial.la file (needed by manifest)
+# On macOS/Mach-O, objcopy -G applied during partial-linking can
+# localize the entry symbol but it remains the only vlc_entry__ name
+# defined in the archive.
+%_plugin.partial.la.symbollist: %_plugin.partial.la
+	$(AM_V_GEN)libpath=`grep old_library= "$<" | cut -d"'" -f 2`; \
+	entrypoint=`$(NM) ".libs/$${libpath}" | \
+	    awk 'tolower($$2) == "t" && $$3 ~ /^_?vlc_entry__[A-Za-z0-9_]+$$/ { s=$$3; sub(/^_/,"",s); print s; exit }'`; \
+	echo $${entrypoint} > $@
+
+# Generate a manifest file that allows linking against all the plugins
+# we've built, by providing an X-macro which reference each plugin.
+# It it particularily userful when building tests or binaries, but also
+# for downstream projects that might want to pick all those plugins.
+vlc_modules_manifest.h: $(PARTIAL_PLUGINS) $(PARTIAL_PLUGINS:=.symbollist) Makefile
+	## Collect paths of all static libraries needed (plugins and contribs)
+	$(AM_V_at)echo "#define VLC_MODULE_LIST(F) \\" > $@.tmp
+	## Note: $(NULL) here is to fix syntax interpretation of \\ in the string
+	$(AM_V_GEN)for ltlib in $(PARTIAL_PLUGINS); do \
+		module_name=`cat $${ltlib}.symbollist | sed s/.*vlc_entry__//`; \
+		if [ -z "$${module_name}" ]; then \
+			echo "Cannot parse $${ltlib} symbol"; \
+			exit 1; \
+		fi; \
+		echo "F($${module_name}) \\$(NULL)" >> $@.tmp; \
+	done
+	$(AM_V_at)echo "" >> $@.tmp
+	$(AM_V_at)mv $@.tmp $@
+
+BUILT_SOURCES += vlc_modules_manifest.h
+CLEANFILES += \
+	$(PLUGINS:=.symbollist) \
+	$(PARTIAL_PLUGINS) \
+	$(PARTIAL_PLUGINS:%.partial.la=.deps/%.partial.la.o) \
+	$(PARTIAL_PLUGINS:=.symbollist) \
+	vlc_modules_manifest.h
+endif
+
+# Static modules bundle gathering all plugins into a single
+# non-installed archive library, that can be used by downstream projects
+# or executables in the project to link against the static module bank.
+libvlc_static_modules_la_SOURCES =
+libvlc_static_modules_la_LDFLAGS = \
+	-static -export-symbols-regex ^vlc_entry \
+	$(top_builddir)/compat/libcompat.la $(LTLIBVLCCORE)
+libvlc_static_modules_la_LIBADD = $(PARTIAL_PLUGINS)
+
+# NOTE: It's easier to define libvlc_static_modules_la_DEPENDENCIES since
+# dependencies on POSIX2024 Make percent substitution is not properly
+# parsed by automake, and it would then depends upon pkglib_LTLIBRARIES,
+# which creates a circular dependency.
+libvlc_static_modules_la_DEPENDENCIES = $(PARTIAL_PLUGINS)
+EXTRA_libvlc_static_modules_la_DEPENDENCIES = vlc_modules_manifest.h
+
+if HAVE_PARTIAL_LINKING
+pkglib_LTLIBRARIES += libvlc_static_modules.la
+endif


=====================================
modules/video_output/xcb/events.c
=====================================
@@ -34,7 +34,9 @@
 
 #include "events.h"
 
+#ifndef HAVE_PARTIAL_LINKING
 const char vlc_module_name[] = "xcb";
+#endif
 
 #pragma GCC visibility push(default)
 


=====================================
src/meson.build
=====================================
@@ -335,6 +335,7 @@ if host_system == 'darwin'
     ]
     if have_osx
         cdata.set('HAVE_VLC_PROCESS_SPAWN', 1)
+        cdata.set('HAVE_VLC_EXTERNAL_PREPARSER', 1)
         libvlccore_sources += [
             'posix/spawn.c',
             'posix/process.c',
@@ -342,6 +343,7 @@ if host_system == 'darwin'
     endif
 elif host_system == 'windows'
     cdata.set('HAVE_VLC_PROCESS_SPAWN', 1)
+    cdata.set('HAVE_VLC_EXTERNAL_PREPARSER', 1)
     libvlccore_sources += [
         'win32/dirs-common.c',
         'win32/error.c',
@@ -388,6 +390,7 @@ else
 
     if host_system != 'android'
         cdata.set('HAVE_VLC_PROCESS_SPAWN', 1)
+        cdata.set('HAVE_VLC_EXTERNAL_PREPARSER', 1)
         libvlccore_sources += [
             'posix/dirs.c',
             'posix/error.c',


=====================================
src/playlist/playlist.c
=====================================
@@ -45,7 +45,7 @@ vlc_playlist_New(vlc_object_t *parent, enum vlc_playlist_preparsing rec,
             .types = VLC_PREPARSER_TYPE_PARSE | VLC_PREPARSER_TYPE_FETCHMETA_LOCAL,
             .max_parser_threads = preparse_max_threads,
             .timeout = preparse_timeout,
-#if !defined(HAVE_VLC_PROCESS_SPAWN)
+#if !defined(HAVE_VLC_EXTERNAL_PREPARSER)
         .external_process = false,
 #else
         .external_process = true,


=====================================
src/preparser/preparser.c
=====================================
@@ -40,7 +40,7 @@ vlc_preparser_t *vlc_preparser_New(vlc_object_t *obj,
     if (preparser == NULL) {
         return NULL;
     }
-#if defined(HAVE_VLC_PROCESS_SPAWN)
+#if defined(HAVE_VLC_EXTERNAL_PREPARSER)
     /* Must reflect cfg->external_process: forcing this to true would cause
      * vlc-preparser child processes to spawn further children, resulting in
      * an infinite fork bomb. */



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/abad2972122fff89b3964c2fbdefb55d34efa9dc...ecadeffefefd5f9a33bfa06c1d49dca48adf6dc4

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/abad2972122fff89b3964c2fbdefb55d34efa9dc...ecadeffefefd5f9a33bfa06c1d49dca48adf6dc4
You're receiving this email because of your account on code.videolan.org. Manage all notifications: https://code.videolan.org/-/profile/notifications | Help: https://code.videolan.org/help




More information about the vlc-commits mailing list