[question] meson generated pkgconfigs in conan2
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?
- [x] I've read the CONTRIBUTING guide
Hi @Eugene-Alexeev
Thanks for your question.
I think the problem is that those .pc files have a dependency to an external ProjA-LibA.pc file that doesn't exist.
Note that such a file doesn't necessarily exist, because the ProjA package is not creating it? The package_info() method of ProjB did package its own xxxx.pc files, but it doesn't have any ProjA-LibA.pc file, it simply doesn't exist.
Maybe you could try calling the PkgConfigDeps generator in the ProjB generate() method, and then also package those files in the package() method so they are available at package_info() time.
In general the pkg_config.fill_cpp_info() flow is intended for packages that do not have any other Conan dependencies, like some of the system package wrappers. But it might not be suitable out of the box for this use case, you can try the above idea, but maybe there is something that make it unfeasible.
yes PkgConfigDeps is already called in ProjB's generate(), and it's executing successfully, I just omitted it. I can see both ProjA.pc and ProjA-LibA.pc, hence my expectation that conan will pick them up somehow. I'll try to connect them
yes PkgConfigDeps is already called in ProjB's generate(), and it's executing successfully, I just omitted it. I can see both ProjA.pc and ProjA-LibA.pc, hence my expectation that conan will pick them up somehow. I'll try to connect them
They can be generated in the temporary build folder in the generate() method, somewhere like build/generators. But these files are typically not packaged in the package() method, only the package projB ones, are you sure they are being packaged?