Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkg-config dep.get_variable() returns value with unexpected prefix #14058

Open
Oruthh opened this issue Dec 30, 2024 · 10 comments
Open

pkg-config dep.get_variable() returns value with unexpected prefix #14058

Oruthh opened this issue Dec 30, 2024 · 10 comments
Labels

Comments

@Oruthh
Copy link

Oruthh commented Dec 30, 2024

Describe the bug
When attempting to retrieve a variable from the dbus-1.pc file using the dep.get_variable() function, the result includes an unexpected prefix. For example:

  • Expected result: /usr/share
  • Actual result: /workdir/build/rootfs/usr/share

In contrast, running the equivalent command directly with pkg-config produces the correct value:
/usr/bin/pkg-config --variable=datadir dbus-1

Output: /usr/share

To Reproduce

meson.build:

project('bugTest')

libdbus = dependency('dbus-1', version : '>= 1.3.2', required : true)
dbusdatadir = libdbus.get_variable(pkgconfig: 'datadir')
message(dbusdatadir)

cross-compile.txt:

[binaries]
c = 'aarch64-rpi4-linux-gnu-gcc'
cpp = 'aarch64-rpi4-linux-gnu-g++'
ar = 'aarch64-rpi4-linux-gnu-ar'
strip = 'aarch64-rpi4-linux-gnu-strip'
pkg-config = '/usr/bin/pkg-config'

[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8-a'
endian = 'little'

[target_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8-a'
endian = 'little'

[properties]
sys_root='/workdir/build/rootfs'
pkg_config_libdir=['/workdir/build/rootfs/lib/pkgconfig', '/workdir/build/rootfs/usr/lib/pkgconfig', '/workdir/build/rootfs/usr/local/lib/pkgconfig', '/workdir/build/rootfs/usr/share/pkgconfig', '/workdir/build/rootfs/usr/local/share/pkgconfig', '/workdir/build/rootfs/usr/local/lib/pkgconfig']

/workdir/build/rootfs/usr/lib/pkgconfig/dbus-1.pc:

original_prefix=/usr
prefix=${original_prefix}
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
libdir=${exec_prefix}/lib
includedir=${prefix}/include
system_bus_default_address=unix:path=/run/dbus/system_bus_socket
datarootdir=${prefix}/share
datadir=${datarootdir}
sysconfdir=/etc
session_bus_services_dir=${datadir}/dbus-1/services
system_bus_services_dir=${datadir}/dbus-1/system-services
interfaces_dir=${datadir}/dbus-1/interfaces
daemondir=${bindir}

Name: dbus
Description: Free desktop message bus
Version: 1.14.4
Libs: -L${libdir} -ldbus-1
Libs.private:
Cflags: -I${includedir}/dbus-1.0 -I${libdir}/dbus-1.0/include

command:
meson setup --cross-file=/workdir/src/meson-setups/cross-compile.txt build/

system parameters

  • This is cross build
  • Ubuntu 24.04
  • Python 3.12.3
  • Meson 1.6.1
  • Ninja 1.11.1
  • Pkg-config 1.8.1
@Oruthh Oruthh changed the title pkg-config dep.get_variable() returns value with prefix pkg-config dep.get_variable() returns value with unexpected prefix Dec 30, 2024
@bonzini
Copy link
Collaborator

bonzini commented Dec 30, 2024

Please attach the log from meson-logs/meson-log.txt

@Oruthh
Copy link
Author

Oruthh commented Dec 30, 2024

Here are the relevant logs:
meson-log.txt

@Oruthh
Copy link
Author

Oruthh commented Dec 30, 2024

I have double-checked that the PKG_CONFIG_LIBDIR variable is correctly set when using the pkg-config command, and I can confirm with certainty that it has the correct value.

To verify this, I edited the /workdir/build/rootfs/usr/lib/pkgconfig/dbus-1.pc file for testing purposes. The modified file now looks as follows:

original_prefix=/usr
prefix=${original_prefix}
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
libdir=${exec_prefix}/lib
includedir=${prefix}/include
system_bus_default_address=unix:path=/run/dbus/system_bus_socket
datarootdir=${prefix}/share
datadir=${datarootdir}/test
sysconfdir=/etc
session_bus_services_dir=${datadir}/dbus-1/services
system_bus_services_dir=${datadir}/dbus-1/system-services
interfaces_dir=${datadir}/dbus-1/interfaces
daemondir=${bindir}

Name: dbus
Description: Free desktop message bus
Version: 1.14.4
Libs: -L${libdir} -ldbus-1
Libs.private:    
Cflags: -I${includedir}/dbus-1.0 -I${libdir}/dbus-1.0/include

I added /test to the datadir variable

pkg-config --variable=datadir dbus-1 returns /usr/share/test

meson returns /workdir/build/rootfs/usr/share/test

New meson-log.txt file

@bonzini
Copy link
Collaborator

bonzini commented Dec 30, 2024

Why do you need the directory without the sysroot prefix?

You should be able to reproduce Meson's output by setting PKG_CONFIG_SYSROOT_DIR=/workdir/build/rootfs when you invoke pkg-config --variable=datadir dbus-1

@Oruthh
Copy link
Author

Oruthh commented Dec 30, 2024

For instance, when building systemd, Meson installs the D-Bus files into ${DESTDIR}/workdir/build/rootfs/usr/share/dbus-1/services. After deploying these files to the Raspberry Pi, D-Bus is unable to use them because, from D-Bus's perspective, they are in the wrong location, because they should be in /usr/share/dbus-1/services but they are in /workdir/build/rootfs/usr/share/dbus-1/services

Is there a way to set the sysroot for the linker without affecting pkg-config, similar to how it's done in autotool using --sysroot=${SYSROOT} -L${SYSROOT}/usr/lib in LDFLAGS?

@Oruthh
Copy link
Author

Oruthh commented Dec 31, 2024

I removed sys_root from cross-compile.txt and set the necessary variables (CFLAGS, CXXFLAGS, LDFLAGS, C_INCLUDE_PATH, and CPLUS_INCLUDE_PATH). It seems to be working now.

However, I’m wondering if this is the correct approach or if there’s a better way to handle this. Specifically, I now have to manually update C_INCLUDE_PATH when header files are located in different directories (e.g., /usr/include/libfdisk instead of /usr/include). Is there a more efficient solution to manage this?

@bonzini
Copy link
Collaborator

bonzini commented Dec 31, 2024

sys_root certainly feels like a half-baked feature, see also #7722 and #13217.

Probably get_variable should have an extra keyword argument sys_root: true / false.

I now have to manually update C_INCLUDE_PATH when header files are located in different directories

Can you explain this better? I don't understand how it's related to the sysroot.

@Oruthh
Copy link
Author

Oruthh commented Dec 31, 2024

I was using sys_root to help Meson locate the correct headers and .so files during package builds. After removing sys_root from my cross file, the paths provided by pkg-config became correct, but the compiler was unable to find the necessary headers.

To address this, I introduced the C_INCLUDE_PATH variable, which includes paths to header files, such as ${SYSROOT}/usr/include. However, not all packages place their headers there. For instance, libfdisk stores its headers in ${SYSROOT}/usr/include/libfdisk. In these cases, the compiler couldn’t locate the headers unless I manually added the directory to C_INCLUDE_PATH, resulting in:
${SYSROOT}/usr/include:${SYSROOT}/usr/include/libfdisk

After reading related issues, I tried to set c_args, c_link_args, cpp_args, and cpp_link_args in my cross file. Now, the file looks like this:

[binaries]
c = 'aarch64-rpi4-linux-gnu-gcc'
cpp = 'aarch64-rpi4-linux-gnu-g++'
ar = 'aarch64-rpi4-linux-gnu-ar'
strip = 'aarch64-rpi4-linux-gnu-strip'
pkg-config = '/usr/bin/pkg-config'

[host_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8-a'
endian = 'little'

[target_machine]
system = 'linux'
cpu_family = 'aarch64'
cpu = 'armv8-a'
endian = 'little'

[properties]
c_args = ['--sysroot=/workdir/build/rootfs']
c_link_args = ['--sysroot=/workdir/build/rootfs', '-L${SYSROOT}/usr/lib']
cpp_args = ['--sysroot=/workdir/build/rootfs']
cpp_link_args = ['--sysroot=/workdir/build/rootfs', '-L${SYSROOT}/usr/lib']
pkg_config_libdir=['/workdir/build/rootfs/lib/pkgconfig', '/workdir/build/rootfs/usr/lib/pkgconfig', '/workdir/build/rootfs/usr/local/lib/pkgconfig', '/workdir/build/rootfs/usr/share/pkgconfig', '/workdir/build/rootfs/usr/local/share/pkgconfig', '/workdir/build/rootfs/usr/local/lib/pkgconfig']
needs_exe_wrapper=true

Now GCC fails to locate the header files, and Ninja terminates while executing following command:
aarch64-rpi4-linux-gnu-gcc -Isrc/shared/libshared-fdisk.a.p -Isrc/shared -I../src/shared -Isrc/basic -I../src/basic -Isrc/fundamental -I../src/fundamental -Isrc/systemd -I../src/systemd -I. -I.. -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-journal -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -I/usr/include/libfdisk -I/usr/include/uuid -I/usr/include/blkid -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu11 -O3 -Wno-missing-field-initializers -Wno-unused-parameter -Wno-nonnull-compare -Warray-bounds -Warray-bounds=2 -Wdate-time -Wendif-labels -Werror=format=2 -Werror=format-signedness -Werror=implicit-function-declaration -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Werror=missing-declarations -Werror=missing-prototypes -Werror=overflow -Werror=override-init -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=strict-flex-arrays -Werror=undef -Wfloat-equal -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-aliasing=2 -Wstrict-prototypes -Wsuggest-attribute=noreturn -Wunused-function -Wwrite-strings -Wzero-length-bounds -fdiagnostics-show-option -fno-common -fstack-protector -fstack-protector-strong -fstrict-flex-arrays=3 --param=ssp-buffer-size=4 -Wno-maybe-uninitialized -Wno-unused-result -Werror=shadow --sysroot=/workdir/build/rootfs -fPIC -fno-strict-aliasing -fstrict-flex-arrays=1 -fvisibility=hidden -ffunction-sections -fdata-sections -fno-omit-frame-pointer -include config.h -fvisibility=default -MD -MQ src/shared/libshared-fdisk.a.p/fdisk-util.c.o -MF src/shared/libshared-fdisk.a.p/fdisk-util.c.o.d -o src/shared/libshared-fdisk.a.p/fdisk-util.c.o -c ../src/shared/fdisk-util.c

This results in the following error:
../src/shared/fdisk-util.h:6:10: fatal error: libfdisk.h: No such file or directory

I have verified that the libfdisk.h file exists in /workdir/build/rootfs/usr/include/libfdisk. When I manually modify the command by changing the -I/usr/... arguments to -I=/usr/.., like this:
aarch64-rpi4-linux-gnu-gcc -Isrc/shared/libshared-fdisk.a.p -Isrc/shared -I../src/shared -Isrc/basic -I../src/basic -Isrc/fundamental -I../src/fundamental -Isrc/systemd -I../src/systemd -I. -I.. -I../src/libsystemd/sd-bus -I../src/libsystemd/sd-device -I../src/libsystemd/sd-event -I../src/libsystemd/sd-hwdb -I../src/libsystemd/sd-id128 -I../src/libsystemd/sd-journal -I../src/libsystemd/sd-netlink -I../src/libsystemd/sd-network -I../src/libsystemd/sd-resolve -I=/usr/include/libfdisk -I=/usr/include/uuid -I=/usr/include/blkid -fdiagnostics-color=always -D_FILE_OFFSET_BITS=64 -Wall -Winvalid-pch -Wextra -std=gnu11 -O3 -Wno-missing-field-initializers -Wno-unused-parameter -Wno-nonnull-compare -Warray-bounds -Warray-bounds=2 -Wdate-time -Wendif-labels -Werror=format=2 -Werror=format-signedness -Werror=implicit-function-declaration -Werror=implicit-int -Werror=incompatible-pointer-types -Werror=int-conversion -Werror=missing-declarations -Werror=missing-prototypes -Werror=overflow -Werror=override-init -Werror=return-type -Werror=shift-count-overflow -Werror=shift-overflow=2 -Werror=strict-flex-arrays -Werror=undef -Wfloat-equal -Wimplicit-fallthrough=5 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wmissing-noreturn -Wnested-externs -Wold-style-definition -Wpointer-arith -Wredundant-decls -Wshadow -Wstrict-aliasing=2 -Wstrict-prototypes -Wsuggest-attribute=noreturn -Wunused-function -Wwrite-strings -Wzero-length-bounds -fdiagnostics-show-option -fno-common -fstack-protector -fstack-protector-strong -fstrict-flex-arrays=3 --param=ssp-buffer-size=4 -Wno-maybe-uninitialized -Wno-unused-result -Werror=shadow --sysroot=/workdir/build/rootfs -fPIC -fno-strict-aliasing -fstrict-flex-arrays=1 -fvisibility=hidden -ffunction-sections -fdata-sections -fno-omit-frame-pointer -include config.h -fvisibility=default -MD -MQ src/shared/libshared-fdisk.a.p/fdisk-util.c.o -MF src/shared/libshared-fdisk.a.p/fdisk-util.c.o.d -o src/shared/libshared-fdisk.a.p/fdisk-util.c.o -c ../src/shared/fdisk-util.c

The object file compiles successfully. According to the GCC documentation about -I argument:

Add the directory dir to the list of directories to be searched for header files during preprocessing. If dir begins with ‘=’ or $SYSROOT, then the ‘=’ or $SYSROOT is replaced by the sysroot prefix; see --sysroot and -isysroot.

After replacing every -I/usr/ with -I=/usr/ in the build.ninja file, the package compiles successfully.

I believe that sys_root should continue to affect PKG_CONFIG_SYSROOT_DIR as it currently does, but there should be an additional parameter, such as ccld_sys_root. This parameter could automatically add --sysroot=${SYSROOT} to both the linker and compiler, and change the -I flag from -Idir to -I=dir for packages from pkg-config

What do you think about this proposal?
If there are any aspects I might have overlooked, please let me know.

@bonzini
Copy link
Collaborator

bonzini commented Dec 31, 2024

No, I think there's no one good way to do get_variable when a sysroot is involved. Typically you want the "naked" directory, but not always. So the solution to your problem passes through extending get_variable.

@Oruthh
Copy link
Author

Oruthh commented Dec 31, 2024

To proceed with my project, I will continue using the C_INCLUDE_PATH variable and manually adjusting it as necessary.

Thank you for your time. Please feel free to inform me of any updates on this matter. I would greatly appreciate it.

@bonzini bonzini added the cross label Dec 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants