Skip to content

[question] meson generated pkgconfigs in conan2 #19378

@Eugene-Alexeev

Description

@Eugene-Alexeev

What is your question?

I have a libA that's defined like usual in meson:

# Create the library
lib_a = shared_library(
  'LibA',
  src_files,
  include_directories: include_directories(public_include_dirs + private_include_dirs),
  cpp_args: compile_args + common_args,
  objc_args: compile_args + common_args,
  install: true,
)

and then wrapped in a conan package ProjA (in reality contains multiple components):

    
class ProjA(ConanFile):
    name = "ProjA"

    def package_info(self):
        inc = ["include/"]
        self.cpp_info.components["libA"].libs = ["LibA"]
        self.cpp_info.components["libA"].includedirs = inc
        self.cpp_info.components["libA"].libdirs = [os.path.join(self.package_folder, "lib")]

it's then pushed to a repo and used in another ProjB. That one has hundreds of components with distinct include directories and dependencies, so defining them in conan the same way is a path I'd like to avoid. I tried to use meson's pkgconfig generation and that works, but how then pick up the generated files properly when dealing with package_info()?

this works:

deps = [ dependency('ProjA-LibA') ]

libB = static_library('LibB',
  sources,
  install: true,
  include_directories: include_directories,
  dependencies: deps,
)

# generate pkg-config file
pkg.generate(
  libB,
  name: 'LibB',
  version: meson.project_version(),
  filebase: 'libB',
)

this doesn't:

class ProjB(ConanFile):
    name = "ProjB"

    def requirements(self):
        self.requires("ProjA/1.0.0", visible=True, transitive_libs=True, transitive_headers=True)

    def package(self):
        meson = Meson(self)
        meson.install()

    def package_info(self):
        inc = ["include"]

        # meson puts them there
        pc_path = os.path.join(self.package_folder, "lib", "pkgconfig")

        # automatically discover all .pc files. is there a better way?
        if os.path.exists(pc_path):
            pc_files = glob.glob(os.path.join(pc_path, "*.pc"))

            for pc_file in pc_files:
                lib_name = os.path.splitext(os.path.basename(pc_file))[0]

                try:
                    pkg_config = PkgConfig(self, lib_name, pkg_config_path=pc_path)
                    pkg_config.fill_cpp_info(
                        self.cpp_info.components[lib_name],
                        is_system=False
                    )
                    self.cpp_info.components[lib_name].set_property(
                        "cmake_target_name",
                        f"{self.name}::{lib_name}"
                    )
                    self.output.info(f"loaded component: {lib_name}")
                except Exception as e:
                    self.output.warning(f"could not load .pc file for {lib_name}: {e}")

the part that doesn't work is connecting that conan dependency with a dependency that meson sees and generates in pkgconfig. its output looks something like this:

➜  pkgconfig cat libB.pc 
prefix=/
includedir=${prefix}/include
libdir=${prefix}/lib

Name: LibB
Description: blabla
Version: 1.0.0
Requires: ProjA-LibA
Libs: -L${libdir} -llibB
Cflags: -I${includedir}

so when I do "conan create" or "conan export-pkg" I get:

ProjA/1.0.0 Already installed! 
ProjB/1.0.0: Loaded component: export-txt
ProjB/1.0.0: WARN: Could not load .pc file for libB: PkgConfig failed. Command: pkg-config --print-provides barcodes-common --print-errors
stderr:
    Package ProjA-LibA was not found in the pkg-config search path.
    Perhaps you should add the directory containing `ProjA-LibA.pc'
    to the PKG_CONFIG_PATH environment variable

which is strange because it looks like conan should provide that since it's stated in self.requires(..) and installed

the question is - how to make conan pick up meson's generated .pc files so it fixes the connection between Conan's 'ProjA' dependency that contains 'LibA' components and meson's 'ProjA-LibA'?

Have you read the CONTRIBUTING guide?

  • I've read the CONTRIBUTING guide

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions