Closed marvin-the-mathematician closed 1 day ago
Hi @marvin-the-mathematician
Thanks for your question.
The package_info
contains the cpp_info
to model different aspects of the C/C++ build of the consumer: https://docs.conan.io/2/reference/conanfile/methods/package_info.html#cpp-info-library-and-build-information
The one that you want is defines
, so something like:
def package_info(self):
"""Add package metadata."""
self.cpp_info.libs = ["pkg"]
if not self.options.shared:
self.cpp_info.defines = ["PKG_API_STATIC_DEFINE=1"]
Should work. Please not that I have reversed the condition to if not self.options.shared
it seems you were using the opposite logic based on your description of the preprocessor definition above.
Please check that and let us know.
Thanks for the prompt answer (as always); much appreciated. Indeed, I did copy over the code incorrectly (apologies); luckily I have the correct logic in the real code ;-) I'll give your suggestion a go and let you know how that works out.
I have also just realised that I almost certainly need to map the propagated PKG_API_STATIC_DEFINE environment variable from the environment into a CMake compile definition. So I'll try doing that too. Or perhaps using the self.cpp_info.defines
field solves that problem for me.
Yep. That worked. Thank you so much! You have saved me another day of trying to figure that one out for myself :-) I now have my shared and static library packaging working across Windows 10, macOS Sonoma, Ubuntu Jammy and manylinux2014 in CI with minimal changes needed between the different pipeline scripts for each platform! Perfect.
As a follow up question, if I do currently export a pkgConfig.cmake file, etc. from within the CMakeLists.txt file for a library package will it be ignored by consumers of that package if those consumers are using Conan to manage their dependencies? In other words, if I commit to using Conan throughout the dependency graph can I stop exporting pkgConfig.cmake files, etc.?
Yep. That worked. Thank you so much! You have saved me another day of trying to figure that one out for myself :-) I now have my shared and static library packaging working across Windows 10, macOS Sonoma, Ubuntu Jammy and manylinux2014 in CI with minimal changes needed between the different pipeline scripts for each platform! Perfect.
Very happy to help :) Don't hesitate to create new tickets as necessary for any further question, if that helps.
Glad to know that Conan is helping with maintaining those different binaries too, thanks for the feedback.
As a follow up question, if I do currently export a pkgConfig.cmake file, etc. from within the CMakeLists.txt file for a library package will it be ignored by consumers of that package if those consumers are using Conan to manage their dependencies? In other words, if I commit to using Conan throughout the dependency graph can I stop exporting pkgConfig.cmake files, etc.?
You can do both. By default, the generated files from CMakeDeps
will have higher priority and will be used to locate and use dependencies. But it is also possible to use the packaged xxx-config.cmake
files if that makes sense, check https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/use_package_config_cmake.html (it might have some limitations, check them in the docs page). You can control if CMakeDeps
generate files for dependencies or not with the:
def generate(self):
deps = CMakeDeps(self)
deps.set_property("mydep", "cmake_find_mode", "none")
deps.generate()
In general, I find the effort of create a working xxx-config.cmake
file higher, specially when the package has dependencies, so I indeed prefer to leverage the Conan generated files with CMakeDeps
, but I understand there might be some exceptional cases, specially when a package is very complicated, with tons of components and lots of CMake logic like CMake macros that the consumer needs to execute, where using the in-package xxx-config.cmake
might be a bit more convenient. I suggest dropping them, use the generated ones with CMakeDeps
, and if there are some complicated situation, re-evaluate that single one.
What is your question?
For a Conan library package defined by the conanfile.py something like:
that includes an export header, say api.h, containing a PKG_API_STATIC_DEFINE preprocessor macro in something like the following way:
and a conanfile.py in the test_package folder as follows:
How should I set the
package_info
of the library package to ensure that in thetest_package
project the PKG_API_STATIC_DEFINE macro is defined when--options:all='pkg/*:shared=False'
is set and not defined when--options:all='pkg/*:shared=True'
is set?For example, I am using the following conan invocations to configure, build, test and package the project:
The final conan invocation will fail most notably on the Windows operating system with linker errors (undefined reference to symbol,etc.) because the wrong attribute ends up being used to decorate the public interfaces of the package. This is due to the fact that the PKG_API_STATIC_DEFINE macro is not defined (it should be) and so the PKG_API_EXPORT macro ends up being defined as
__declspec(dllimport)
when it should not be (when using static linkage to library package).I thought that using something like:
(in the conanfile for the library package) would work (having read the docs here (https://docs.conan.io/2/tutorial/creating_packages/define_package_information.html#propagating-environment-or-configuration-information-to-consumers) - I am using Conan 2.4.1 and Python 3.12.2). But it doesn't seem to. Could you indicate what the correct approach would be please?
Have you read the CONTRIBUTING guide?