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

[question] Editable packages and public linked libraries #15468

Open
1 task
johannes-wolf opened this issue Jan 17, 2024 · 7 comments
Open
1 task

[question] Editable packages and public linked libraries #15468

johannes-wolf opened this issue Jan 17, 2024 · 7 comments
Assignees

Comments

@johannes-wolf
Copy link

johannes-wolf commented Jan 17, 2024

What is your question?

Following problem: I've got a project that pulls in some packages via Conan 2 and one single private package added via editable add, that also uses some packages. The reason for that private package being a Conan package is, that it seems to be the only option to have multiple conanfile.txt/conanfile.py files (FetchContent + conanfile.txt in the fetched project seems to be not an option).

I export multiple components from that package via:

def package_info(self):
    self.cpp_info.components["c1"].includedirs = ["libs/service/include"]
    self.cpp_info.components["c1"].set_property("cmake_target_name", "mypkg::c1")
    ...

The mypkg has some target_link_library(c1 PUBLIC lib-abc)

Now, if I link to mypkg::c1, it seems the INCLUDE_DIRECTORIES property is not set correctly.
The consumer of mypkg::c1 is unable to see where the public header files of lib-abc should come from. Am I doing something completely wrong? Are the target imported via find_package(mypgk REQUIRED c1) not the “real” CMake targets, but some targets generated by Conan? I already had to set the includedirs property, because the CMake's target properties were set to the Conan default of include.

How is it possible to have nested non-Conan projects/libs that each have their own conanfile.txt? A hack would be to scan for each conanfile.txt pre-build and merge them, but that won't work with FetchContent either… this is really frustrating, any ideas?

Note: I have no install(...) instructions in my mypkg's CMake. Are they strictly needed?

Have you read the CONTRIBUTING guide?

  • I've read the CONTRIBUTING guide
@memsharded memsharded self-assigned this Jan 17, 2024
@memsharded
Copy link
Member

memsharded commented Jan 17, 2024

Hi @johannes-wolf

Thanks for your question

The reason for that private package being a Conan package is, that it seems to be the only option to have multiple conanfile.txt/conanfile.py files (FetchContent + conanfile.txt in the fetched project seems to be not an option).

It is not very clear what you mean. It is possible to have multiple conanfiles even in the same folder, like conanfile1.py, conanfile2.py, conanfile3.txt and then reference them by name like conan install conanfile2.py for example.

Now, if I link to mypkg::c1, it seems the INCLUDE_DIRECTORIES property is not set correctly.

I think this is the default visibility of headers. When app -> pkgb -> pkga, then the headers of pkga are not directly visible by app, they are assumed to be private to pkgb by default. There are 2 cases here:

  • The headers of pkga are included in the public headers in pkgb, then the way to express this is in pkgb define self.requires("pkga/version", transitive_headers=True). The app code shouldn't have any direct #include to pkga headers, just need them to build
  • If app really directly need and #include pkga headers, then the solution is that app declares a direct dependency to pkga

Please let me know if this helps

@johannes-wolf
Copy link
Author

johannes-wolf commented Jan 17, 2024

Thank you for your reply.

It is not very clear what you mean. It is possible to have multiple conanfiles even in the same folder, like conanfile1.py, conanfile2.py, conanfile3.txt and then reference them by name like conan install conanfile2.py for example.

I meant pulling dependencies via FetchContent and processing their Conan dependencies, without having to redeclare all dependencies int the consuming conanfile. I guess this is not possible, because all dependencies must be known pre-build.

In my case, pkga is not a Conan package, but some dependency pulled via CMakes FetchContent. The whole project is a mix of Conan 2 packages and FetchContent dependencies, and the goal is to have the dependencies declare their Conan packages by themselves without having to put everything in the consumer (app).

@memsharded
Copy link
Member

I meant pulling dependencies via FetchContent

Yes, FetchContent is an internal thing in the build system, Conan is not even aware of it.

Conan packages by themselves without having to put everything in the consumer (app).

Yes, definitely it shouldn't be necessary to put everything in the consumer. But yes, the way to achieve this would be to drop the FetchContent and use regular Conan requires to resolve the relations between packages. FetchContent is basically an "air-gap" for Conan, does not exist and cannot propagate dependencies through it.

@johannes-wolf
Copy link
Author

Any plans on allowing Conan to pull directly from git?

But are the targets (generated?) by conan the same targets from the CMakeFiles.txt from my packages? Because why do I have to specify the includedirs even though, CMake should already know them?

@memsharded
Copy link
Member

Any plans on allowing Conan to pull directly from git?

Not directly pulling, but we are trying to be able to use a local folder with recipes (like conan-center-index) to be usable as remote here, please track this issue: #13930

But are the targets (generated?) by conan the same targets from the CMakeFiles.txt from my packages? Because why do I have to specify the includedirs even though, CMake should already know them?

Because parsing CMake files is almost impossible to do it reliably and work for all cases. Plus there are many other build systems supported by Conan like Meson, Autotools, MSBuild... automatically deducing the includedirs from all of them is impossible, and at the end of the day 99% of times it is just adding a line self.cpp_info.includedirs = ["include"], which is not necessary to specify because it is defaulted, so only in packages that don't put the headers in the an include folder is necessary. In any case we are working together with other vendors like CMake in the Common Package Specification (CPS) initiative to standardize the package interfaces to avoid this issue

@johannes-wolf
Copy link
Author

Ok, thank you for your explanation. I'll guess Conan won't work for my use case then.
I'll try running conan install as one FetchContent/ExternalProject Step, maybe that works?

@memsharded
Copy link
Member

I think the FetchContent/ExternalProject will also be not working for other possible package/dependency management solutions, as it is mostly a black box for tools. If you plan to use package managers, probably it makes sense to reconsider the strategy, either use FetchContent/ExternalProject or use the approach of the tool, but trying to mix both will probably be challenging with most tools.

For the "running conan install", we also have the cmake-conan integration that makes CMake to automatically call conan install ... for the dependencies: https://github.com/conan-io/cmake-conan, using the new CMake providers. So maybe you can use that, bring the conan_provider.cmake file, and pass it like -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=../conan_provider.cmake

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

No branches or pull requests

2 participants