build/pkg-config: output drivers first for static build
authorBruce Richardson <bruce.richardson@intel.com>
Tue, 30 Jun 2020 14:14:31 +0000 (15:14 +0100)
committerThomas Monjalon <thomas@monjalon.net>
Wed, 1 Jul 2020 17:30:52 +0000 (19:30 +0200)
When calling pkg-config --static --libs, pkg-config will always output the
regular libs first, and then the extra libs from Libs.private field,
since the assumption is that those are additional dependencies for building
statically that the .a files depend upon.

However, for DPDK, we only link the driver files for static builds, and
those need to come *before* the regular libraries. To get this result, we
need two pkgconfig files for DPDK, one for the shared libs, and a second
for the static libs and drivers, which depends upon the first. Using a
dependency means that the shared libs are printed only after the
Libs.private field rather than before.

Without this patch, the linking works in DPDK because in all cases we
specify the libraries after the drivers in the Libs.private line, ensuring
that the references to the libs from the drivers can be resolved. The
current output is therefore of the form, "(shared)libs, drivers,
(static)libs", while after this patch the output is, "drivers,
(static)libs, (shared)libs". The former case will not work if we use the
--whole-archive flag on the static libs as it will lead to duplicate
definitions due to some references having been previously resolved from the
shared libraries. By ensuring the shared libraries come last in the link
link, this issue does not occur, as duplicate references when linking the
shared libs will be ignored.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
Acked-by: Luca Boccassi <bluca@debian.org>
Acked-by: Sunil Pai G <sunil.pai.g@intel.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
buildtools/pkg-config/meson.build

index 85d5997..f663b1c 100644 (file)
@@ -10,17 +10,37 @@ pkg_extra_cflags = ['-include', 'rte_config.h'] + machine_args
 if is_freebsd
        pkg_extra_cflags += ['-D__BSD_VISIBLE']
 endif
-pkg.generate(name: meson.project_name(),
-       filebase: 'lib' + meson.project_name().to_lower(),
+
+# When calling pkg-config --static --libs, pkg-config will always output the
+# regular libs first, and then the extra libs from Libs.private field,
+# since the assumption is that those are additional dependencies for building
+# statically that the .a files depend upon. The output order of .pc fields is:
+#   Libs   Libs.private   Requires   Requires.private
+# The fields Requires* are for package names.
+# The flags of the DPDK libraries must be defined in Libs* fields.
+# However, the DPDK drivers are linked only in static builds (Libs.private),
+# and those need to come *before* the regular libraries (Libs field).
+# This requirement is satisfied by moving the regular libs in a separate file
+# included in the field Requires (after Libs.private).
+
+pkg.generate(name: 'dpdk-libs',
+       filebase: 'libdpdk-libs',
+       description: '''Internal-only DPDK pkgconfig file. Not for direct use.
+Use libdpdk.pc instead of this file to query DPDK compile/link arguments''',
        version: meson.project_version(),
+       subdirs: [get_option('include_subdir_arch'), '.'],
+       extra_cflags: pkg_extra_cflags,
        libraries: dpdk_libraries,
-       libraries_private: dpdk_drivers + dpdk_static_libraries +
-                       ['-Wl,-Bdynamic'] + dpdk_extra_ldflags,
-       requires: libbsd, # apps using rte_string_fns.h may need this if enabled
-                         # if libbsd is not enabled, then this is blank
+       libraries_private: dpdk_extra_ldflags)
+
+pkg.generate(name: 'DPDK', # main DPDK pkgconfig file
+       filebase: 'libdpdk',
+       version: meson.project_version(),
        description: '''The Data Plane Development Kit (DPDK).
 Note that CFLAGS might contain an -march flag higher than typical baseline.
 This is required for a number of static inline functions in the public headers.''',
-       subdirs: [get_option('include_subdir_arch'), '.'],
-       extra_cflags: pkg_extra_cflags
+       requires: ['libdpdk-libs', libbsd], # may need libbsd for string funcs
+                         # if libbsd is not enabled, then this is blank
+       libraries_private: dpdk_drivers + dpdk_static_libraries +
+                       ['-Wl,-Bdynamic']
 )