[PATCH RFC 1/2] meson: Pass objects to declare_dependency()

Akihiko Odaki posted 2 patches 6 months ago
Maintainers: Kevin Wolf <kwolf@redhat.com>, Hanna Reitz <hreitz@redhat.com>, "Daniel P. Berrangé" <berrange@redhat.com>, "Alex Bennée" <alex.bennee@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Paolo Bonzini <pbonzini@redhat.com>, "Marc-André Lureau" <marcandre.lureau@redhat.com>, Thomas Huth <thuth@redhat.com>, "Michael S. Tsirkin" <mst@redhat.com>, Laurent Vivier <lvivier@redhat.com>, Gerd Hoffmann <kraxel@redhat.com>
There is a newer version of this series
[PATCH RFC 1/2] meson: Pass objects to declare_dependency()
Posted by Akihiko Odaki 6 months ago
We used to request declare_dependency() to link_whole static libraries.
If a static library is a thin archive, GNU ld needs to open all object
files referenced by the archieve, and sometimes reaches to the open
file limit.

Another problem with link_whole is that it does not propagate
dependencies. In particular, gnutls, a dependency of crypto, is not
propagated to its users, and we currently workaround the issue by
declaring gnutls as a dependency for each crypto user.

Instead of using link_whole, extract objects included in static
libraries and pass them to declare_dependency(). This requires Meson
1.1.0 or later.

Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
---
 docs/devel/build-system.rst           |  2 +-
 meson.build                           | 27 ++++++++++++++-------------
 gdbstub/meson.build                   |  4 ++--
 subprojects/libvhost-user/meson.build |  2 +-
 tests/qtest/libqos/meson.build        |  2 +-
 5 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/docs/devel/build-system.rst b/docs/devel/build-system.rst
index 5baf027b7614..36ad40c76d2a 100644
--- a/docs/devel/build-system.rst
+++ b/docs/devel/build-system.rst
@@ -238,7 +238,7 @@ Subsystem sourcesets:
     libchardev = static_library('chardev', chardev_ss.sources(),
                                 build_by_default: false)
 
-    chardev = declare_dependency(link_whole: libchardev)
+    chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false))
 
 Target-independent emulator sourcesets:
   Various general purpose helper code is compiled only once and
diff --git a/meson.build b/meson.build
index d6549722b50d..0e6fa2e4b777 100644
--- a/meson.build
+++ b/meson.build
@@ -1,4 +1,4 @@
-project('qemu', ['c'], meson_version: '>=0.63.0',
+project('qemu', ['c'], meson_version: '>=1.1.0',
         default_options: ['warning_level=1', 'c_std=gnu11', 'cpp_std=gnu++11', 'b_colorout=auto',
                           'b_staticpic=false', 'stdsplit=false', 'optimization=2', 'b_pie=true'],
         version: files('VERSION'))
@@ -3456,20 +3456,20 @@ subdir('gdbstub')
 
 if enable_modules
   libmodulecommon = static_library('module-common', files('module-common.c') + genh, pic: true, c_args: '-DBUILD_DSO')
-  modulecommon = declare_dependency(link_whole: libmodulecommon, compile_args: '-DBUILD_DSO')
+  modulecommon = declare_dependency(objects: libmodulecommon.extract_all_objects(recursive: false), compile_args: '-DBUILD_DSO')
 endif
 
 qom_ss = qom_ss.apply({})
 libqom = static_library('qom', qom_ss.sources() + genh,
                         dependencies: [qom_ss.dependencies()],
                         build_by_default: false)
-qom = declare_dependency(link_whole: libqom)
+qom = declare_dependency(objects: libqom.extract_all_objects(recursive: false))
 
 event_loop_base = files('event-loop-base.c')
 event_loop_base = static_library('event-loop-base',
                                  sources: event_loop_base + genh,
                                  build_by_default: false)
-event_loop_base = declare_dependency(link_whole: event_loop_base,
+event_loop_base = declare_dependency(objects: event_loop_base.extract_all_objects(recursive: false),
                                      dependencies: [qom])
 
 stub_ss = stub_ss.apply({})
@@ -3703,7 +3703,7 @@ libauthz = static_library('authz', authz_ss.sources() + genh,
                           dependencies: [authz_ss.dependencies()],
                           build_by_default: false)
 
-authz = declare_dependency(link_whole: libauthz,
+authz = declare_dependency(objects: libauthz.extract_all_objects(recursive: false),
                            dependencies: qom)
 
 crypto_ss = crypto_ss.apply({})
@@ -3711,7 +3711,7 @@ libcrypto = static_library('crypto', crypto_ss.sources() + genh,
                            dependencies: [crypto_ss.dependencies()],
                            build_by_default: false)
 
-crypto = declare_dependency(link_whole: libcrypto,
+crypto = declare_dependency(objects: libcrypto.extract_all_objects(recursive: false),
                             dependencies: [authz, qom])
 
 io_ss = io_ss.apply({})
@@ -3720,7 +3720,8 @@ libio = static_library('io', io_ss.sources() + genh,
                        link_with: libqemuutil,
                        build_by_default: false)
 
-io = declare_dependency(link_whole: libio, dependencies: [crypto, qom])
+io = declare_dependency(objects: libio.extract_all_objects(recursive: false),
+                        dependencies: [crypto, qom])
 
 libmigration = static_library('migration', sources: migration_files + genh,
                               build_by_default: false)
@@ -3734,7 +3735,7 @@ libblock = static_library('block', block_ss.sources() + genh,
                           link_depends: block_syms,
                           build_by_default: false)
 
-block = declare_dependency(link_whole: [libblock],
+block = declare_dependency(objects: libblock.extract_all_objects(recursive: false),
                            link_args: '@block.syms',
                            dependencies: [crypto, io])
 
@@ -3743,7 +3744,7 @@ libblockdev = static_library('blockdev', blockdev_ss.sources() + genh,
                              dependencies: blockdev_ss.dependencies(),
                              build_by_default: false)
 
-blockdev = declare_dependency(link_whole: [libblockdev],
+blockdev = declare_dependency(objects: libblockdev.extract_all_objects(recursive: false),
                               dependencies: [block, event_loop_base])
 
 qmp_ss = qmp_ss.apply({})
@@ -3751,18 +3752,18 @@ libqmp = static_library('qmp', qmp_ss.sources() + genh,
                         dependencies: qmp_ss.dependencies(),
                         build_by_default: false)
 
-qmp = declare_dependency(link_whole: [libqmp])
+qmp = declare_dependency(objects: libqmp.extract_all_objects(recursive: false))
 
 libchardev = static_library('chardev', chardev_ss.sources() + genh,
                             dependencies: chardev_ss.dependencies(),
                             build_by_default: false)
 
-chardev = declare_dependency(link_whole: libchardev)
+chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false))
 
 hwcore_ss = hwcore_ss.apply({})
 libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh,
                            build_by_default: false)
-hwcore = declare_dependency(link_whole: libhwcore)
+hwcore = declare_dependency(objects: libhwcore.extract_all_objects(recursive: false))
 common_ss.add(hwcore)
 
 ###########
@@ -3774,7 +3775,7 @@ foreach m : block_mods + system_mods
   emulator_modules += shared_module(m.name(),
                 build_by_default: true,
                 name_prefix: '',
-                link_whole: m,
+                objects: m.extract_all_objects(recursive: false),
                 install: true,
                 install_dir: qemu_moddir)
 endforeach
diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index c91e398ae726..dff741ddd4d7 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -26,9 +26,9 @@ libgdb_system = static_library('gdb_system',
                                 gdb_system_ss.sources() + genh,
                                 build_by_default: false)
 
-gdb_user = declare_dependency(link_whole: libgdb_user)
+gdb_user = declare_dependency(objects: libgdb_user.extract_all_objects(recursive: false))
 user_ss.add(gdb_user)
-gdb_system = declare_dependency(link_whole: libgdb_system)
+gdb_system = declare_dependency(objects: libgdb_system.extract_all_objects(recursive: false))
 system_ss.add(gdb_system)
 
 common_ss.add(files('syscalls.c'))
diff --git a/subprojects/libvhost-user/meson.build b/subprojects/libvhost-user/meson.build
index a18014e7f26f..b3a2a3abf6be 100644
--- a/subprojects/libvhost-user/meson.build
+++ b/subprojects/libvhost-user/meson.build
@@ -17,7 +17,7 @@ vhost_user = static_library('vhost-user',
                             c_args: '-D_GNU_SOURCE')
 
 executable('link-test', files('link-test.c'),
-           link_whole: vhost_user)
+           objects: vhost_user.extract_all_objects(recursive: false))
 
 vhost_user_glib = static_library('vhost-user-glib',
                                  files('libvhost-user-glib.c'),
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 45b81c83ade3..5b18aa4eaeb9 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -70,4 +70,4 @@ endif
 libqos = static_library('qos', libqos_srcs + genh,
                         build_by_default: false)
 
-qos = declare_dependency(link_whole: libqos)
+qos = declare_dependency(objects: libqos.extract_all_objects(recursive: false))

-- 
2.45.1
Re: [PATCH RFC 1/2] meson: Pass objects to declare_dependency()
Posted by Philippe Mathieu-Daudé 6 months ago
On 24/5/24 10:00, Akihiko Odaki wrote:
> We used to request declare_dependency() to link_whole static libraries.
> If a static library is a thin archive, GNU ld needs to open all object
> files referenced by the archieve, and sometimes reaches to the open

"archive"

> file limit.
> 
> Another problem with link_whole is that it does not propagate
> dependencies. In particular, gnutls, a dependency of crypto, is not
> propagated to its users, and we currently workaround the issue by
> declaring gnutls as a dependency for each crypto user.
> 
> Instead of using link_whole, extract objects included in static
> libraries and pass them to declare_dependency(). This requires Meson
> 1.1.0 or later.
> 
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>
> ---
>   docs/devel/build-system.rst           |  2 +-
>   meson.build                           | 27 ++++++++++++++-------------
>   gdbstub/meson.build                   |  4 ++--
>   subprojects/libvhost-user/meson.build |  2 +-
>   tests/qtest/libqos/meson.build        |  2 +-
>   5 files changed, 19 insertions(+), 18 deletions(-)