Skip to content

[bug] conan does not set env variables from profile [buildenv] in package_info, which leads to pkg-config issues #18128

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

Closed
qwertzui11 opened this issue Apr 15, 2025 · 7 comments · May be fixed by #18130

Comments

@qwertzui11
Copy link

qwertzui11 commented Apr 15, 2025

Describe the bug

Hi! Let me start of by saying thanks for your great work with conan.

My current goal is to setup a hello-world qt project for arm64v8.
The OS-Team gave me a nice toolchain to compile for the arm64v8 platform.

BuildOS: ubuntu24.04
conan-version: 2.15.0

How to reproduce it

I got the following conanfile.py created by conan new cmake_exe -d name=foo -d version=1.0

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout, CMakeDeps


class fooRecipe(ConanFile):
    name = "foo"
    version = "1.0"
    package_type = "application"

    # Optional metadata
    license = "<Put the package license here>"
    author = "<Put your name here> <And your email here>"
    url = "<Package recipe repository url here, for issues about the package>"
    description = "<Description of foo package here>"
    topics = ("<Put some tag here>", "<here>", "<and here>")

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"

    # Sources are located in the same place as this recipe, copy them to the recipe
    exports_sources = "CMakeLists.txt", "src/*"

    def requirements(self):
        # the goal is to use qt
        # self.requires("qt/6.7.3")
        # the problem arises with
        self.requires("opengl/system")

    def layout(self):
        cmake_layout(self)

    def generate(self):
        deps = CMakeDeps(self)
        deps.generate()
        tc = CMakeToolchain(self)
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

Using conan install

conan install \
  --profile:build default \
  --profile:host ./tools/conan-profiles/arm64v8-toolchain \
  --remote conancenter \
  --build missing \
  -s build_type=Release \
  .

with the host profile

{% set sysroots_path = os.getenv("SYSROOTS_PATH") %}

[settings]
os=Linux
arch=armv8
compiler=gcc
build_type=Release
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11

[buildenv]
#CC={{ sysroots_path }}/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-gcc
#CXX={{ sysroots_path }}/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g++
#LD={{ sysroots_path }}/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-ld

PKG_CONFIG_PATH+=(path){{ sysroots_path }}/armv8a-poky-linux/usr/lib/pkgconfig
PKG_CONFIG_PATH+=(path){{ sysroots_path }}/armv8a-poky-linux/usr/share/pkgconfig
PKG_CONFIG_SYSROOT_DIR=(path){{ sysroots_path }}/armv8a-poky-linux
CMAKE_CROSSCOMPILING_EMULATOR={{ sysroots_path }}/x86_64-pokysdk-linux/usr/bin/qemu-aarch64;-L;{{ sysroots_path }}/armv8a-poky-linux/

[conf]
tools.build:sysroot={{ sysroots_path }}/armv8a-poky-linux/
tools.build:compiler_executables={"c":"{{ sysroots_path }}/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-gcc","cpp":"{{ sysroots_path }}/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g++"}
tools.gnu:pkg_config={{ sysroots_path }}/x86_64-pokysdk-linux/usr/bin/pkg-config
tools.system.package_manager:mode=report-installed

tools.cmake.cmaketoolchain:system_name="Linux"
tools.cmake.cmaketoolchain:system_processor="aarch64"

Results in the following error log

======== Input profiles ========
Profile host:
[settings]
arch=armv8
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=11
os=Linux
[replace_requires]
libmount/2.39.2: libmount/2.40.2
[conf]
core.cache:storage_path=/mnt/work/conan
tools.build:compiler_executables={'c': '/mnt/work/Development/conan-fun/toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g
cc', 'cpp': '/mnt/work/Development/conan-fun/toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/aarch64-poky-linux/aarch64-poky-linux-g++'}
tools.build:sysroot=/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/
tools.cmake.cmaketoolchain:system_name="Linux"
tools.cmake.cmaketoolchain:system_processor="aarch64"
tools.gnu:pkg_config=/mnt/work/Development/conan-fun/toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/pkg-config
tools.system.package_manager:mode=report-installed
[buildenv]
PKG_CONFIG_PATH+=(path)/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/lib/pkgconfig
PKG_CONFIG_PATH+=(path)/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/share/pkgconfig
PKG_CONFIG_SYSROOT_DIR=(path)/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux
CMAKE_CROSSCOMPILING_EMULATOR=/mnt/work/Development/conan-fun/toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/qemu-aarch64;-L;/mnt/work/Development/conan-fun/
toolchain/sysroots/armv8a-poky-linux/

Profile build:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu17
compiler.libcxx=libstdc++11
compiler.version=13
os=Linux
[conf]
core.cache:storage_path=/mnt/work/conan
tools.system.package_manager:mode=install
tools.system.package_manager:sudo=True


======== Computing dependency graph ========
Graph root
    conanfile.py (foo/1.0): /mnt/work/Development/conan-fun/conanfile.py
Requirements
    opengl/system#7c02ea6ef926fd04844af53622a30541 - Cache

======== Computing necessary packages ========
Requirements
    opengl/system#7c02ea6ef926fd04844af53622a30541:da39a3ee5e6b4b0d3255bfef95601890afd80709#0ba8627bd47edc3a501e8f0eb9a79e5e - Cache
dpkg-query: no packages found matching libgl-dev:arm64

======== Installing packages ========
opengl/system: Already installed! (1 of 1)
ERROR: opengl/system: Error in package_info() method, line 68
        pkg_config.fill_cpp_info(self.cpp_info, is_system=self.settings.os != "FreeBSD")
        ConanException: PkgConfig failed. Command: /mnt/work/Development/conan-fun/toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/pkg-config --print-provides 
gl --print-errors
    stdout:

    stderr:
    Package gl was not found in the pkg-config search path.
    Perhaps you should add the directory containing `gl.pc'
    to the PKG_CONFIG_PATH environment variable
    No package 'gl' found

The thing is, that /mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/lib/pkgconfig contains the gl.pc.

I can verify it by using all the values from the conan logs:

export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/lib/pkgconfig"
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/share/pkgconfig"
/mnt/work/Development/conan-fun/toolchain/sysroots/x86_64-pokysdk-linux/usr/bin/pkg-config --print-provides gl --print-errors

gives gl = 1.2. Without the environment variables PKG_CONFIG_PATH I get the same error like conan.

So I assume there is an issue with conan in package_info not setting the environment variables given by the [buildenv] profile.
The PKG_CONFIG_PATH works nicely in other contexts with conan.
What do you think?

Thanks for your time! :)
Cheers

@memsharded memsharded self-assigned this Apr 15, 2025
@memsharded
Copy link
Member

Hi @qwertzui11

Hi! Let me start of by saying thanks for your great work with conan.

Thanks for your report, and thanks for your kind words!

I think there is a limitation in the opengl/system recipe, and running the pkg_config.fill_cpp_info() that runs on the package_info() method do not get the environment variables from the profiles.

I'll run a quick check.

@memsharded
Copy link
Member

I have reproduced in test in PR #18130

Indeed, it is a limitation of the current opengl/system recipe in ConanCenter.
This might be a bit challenging to fix, because it is very complicated to pass that information to the package_info() method, as in theory the package_info() shouldn't be running executables with information that depends on the profiles.

I'll bring it to discuss with the team for ConanCenter potential solutions.

What capacity do you have for customizing recipes? are you already using the flow documented in https://docs.conan.io/2/devops/using_conancenter.html to create your own binaries from a fork of conan-center-index instead of directly from ConanCenter? If that is the case, I might be able to suggest some changes to the recipe that could help.

@qwertzui11
Copy link
Author

Thats great news! Thanks a lot for your fast reply!

What capacity do you have for customizing recipes?

The client I'm working for has a Jfrog Artifactory instance, so I'm able to add patched recipes.
However I am currently able to work around the issue by setting PKG_CONFIG_PATH before using conan install. It's not a clean solution, but works for my current use-case.

Aka:

export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/lib/pkgconfig"
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/share/pkgconfig"

conan install \
  --profile:build default \
  --profile:host ./tools/conan-profiles/arm64v8-toolchain \
  --remote conancenter \
  --build missing \
  -s build_type=Release \
  .

I'm looking forward to the outcome of the discussion and I'd be happy to test or contribute in some other way 😃

Thanks again! 🎉
Cheers

@jcar87
Copy link
Contributor

jcar87 commented Apr 15, 2025

Hi @qwertzui11 - thanks for opening this issue.

What we typically expect from a toolchain that provides a pkg-config, is that pkg-config is already configured to work with that sysroot - so it's a bit unusual to even have to define PKG_CONFIG_PATH, but also it tends to not be enough, pkg-config is typically configured to to emit system/toolchain paths in -I and -L flags when the packages are inside the pre-determined sysroot.

Is there any documentation from yocto/poky as to how to use pkg-config when cross-compiling?

@LadyzRoman
Copy link

We also had this issue, and managed to workaround it by changing the "system" recipes as described here #13962

@qwertzui11
Copy link
Author

What we typically expect from a toolchain that provides a pkg-config, is that pkg-config is already configured to work with that sysroot - so it's a bit unusual to even have to define PKG_CONFIG_PATH, but also it tends to not be enough, pkg-config is typically configured to to emit system/toolchain paths in -I and -L flags when the packages are inside the pre-determined sysroot.

That's very good to know, thanks for the clarification.

Is there any documentation from yocto/poky as to how to use pkg-config when cross-compiling?

No, not really. One resource recommends to use PKG_CONFIG_PATH. But I did a bunch of tests, and it actually seems to be adapted, it simply does not put out ANY paths. My solution is to wrap /mnt/work/Development/conan-fun/toolchain/sysroots/armv8a-poky-linux/usr/lib/pkgconfig in a shell script called pkg-config-adaped and set PKG_CONFIG_PATH in it. then delegate the call.

Let me vent a bit: cross-compilation iiiisss such a terrible experience with C++ and its eco-system. eg, pkg-config gets heavily used by meson. But pkg-config likes (correctly) to prepend the sysroot, which gives invalid paths for conan dependencies. So this needs another hack.

Back to the topic. In conclusion I used pkg-config wrong. pkg-config has to put out the correct paths for the sysroot and PKG_CONFIG_PATH should simply not be necessary. As a workaround I got a script that wraps the faulty pkg-config and sets its env vars correctly.

@memsharded
Copy link
Member

Thanks for the feedback @qwertzui11!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants