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

[package] cereal/1.3.0: cereal cannot be found when using the cmake_paths generator #2151

Closed
xphade opened this issue Jul 7, 2020 · 19 comments
Labels
duplicate This issue or pull request already exists question Further information is requested

Comments

@xphade
Copy link

xphade commented Jul 7, 2020

Package and Environment Details (include every applicable attribute)

  • Package Name/Version: cereal/1.3.0
  • Operating System+version: Linux Ubuntu 18.04
  • Compiler+version: GCC 8
  • Conan version: conan 1.27.0

Conan profile (output of conan profile show default or conan profile show <profile> if custom profile is in use)

[settings]
os=Linux
os_build=Linux
arch=x86_64
arch_build=x86_64
compiler=gcc
compiler.version=8
compiler.libcxx=libstdc++
build_type=Release
[options]
[build_requires]
[env]

Description

When installing the cereal package, the project gets installed but cereal-config.cmake subsequently removed, see here:

tools.rmdir(os.path.join(self.package_folder, "share"))

However, without this file, CMake cannot find the cereal package when using the conan_paths.cmake toolchain file. Everything works as expected if the line above is removed.

@stilgarpl actually already noted the issue in this comment in PR #881 but it seems like they did not yet open an issue to discuss about it.

Steps to reproduce (Include if Applicable)

  • conanfile.txt requires cereal/1.3.0 and sets cmake_paths as generator
  • CMakeLists.txt calls find_package(cereal REQUIRED)
  • cd build/
  • conan install ..
  • cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_paths.cmake

Logs (Include/Attach if Applicable)

Click to expand log

CMake error at find_package(cereal REQUIRED):

CMake Error at CMakeLists.txt:52 (find_package):
  By not providing "Findcereal.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "cereal", but
  CMake did not find one.

  Could not find a package configuration file provided by "cereal" with any
  of the following names:

    cerealConfig.cmake
    cereal-config.cmake

  Add the installation prefix of "cereal" to CMAKE_PREFIX_PATH or set
  "cereal_DIR" to a directory containing one of the above files.  If "cereal"
  provides a separate development package or SDK, be sure it has been
  installed.
@xphade xphade added the bug Something isn't working label Jul 7, 2020
@uilianries uilianries added question Further information is requested duplicate This issue or pull request already exists and removed bug Something isn't working labels Jul 7, 2020
@uilianries
Copy link
Member

@xphade please, read #1970

@xphade
Copy link
Author

xphade commented Jul 7, 2020

Hey @uilianries, thanks for the quick answer!

For the project I'm having this issue with, we want to recommend users to get the dependencies via Conan but design the CMakeLists.txt as generic as possible so that they are free to provide them in a different way. Probably the way to go in our case is then to use cmake_paths together with the cmake_find_package generator, right? Then they would just need to do cmake .. -DCMAKE_TOOLCHAIN_FILE=conan_paths.cmake in case they are using Conan.

I only have one additional problem with this approach: For some dependencies, e.g. Eigen3, the target provided with the conan-generated CMake find file is named differently then the original target. In the Eigen case: Eigen3::Eigen3 (conan) vs Eigen3::Eigen for the original Eigen-generated CMake files.

Is there some solution for that? I guess it's related to this issue.

Thanks again for the help!

@uilianries
Copy link
Member

Indeed it's related to components. Now we can create target for find cmake, so if you find a wrong target, according the upstream, please, open an issue describing the case, including this one for Eigen.

Regards

@SpaceIm
Copy link
Contributor

SpaceIm commented Jul 8, 2020

I would say fixing CMake imported targets created by conan recipes is a work in progress in conan-center-index, since components mechanism in conan has been added recently. It should be more reliable in few weeks.

Anyway for Eigen3, #2155 should fix both cmake and pkgconfig.

@xphade
Copy link
Author

xphade commented Jul 8, 2020

Ha, just wanted to open an issue. Thanks @SpaceIm, that should fix our problems!

Closing this issue.

@xphade xphade closed this as completed Jul 8, 2020
@xphade
Copy link
Author

xphade commented Jul 9, 2020

Actually, I'm not sure if it is properly solved yet.

After #2155, Eigen3 works like a charm now. When linking to cereal, however, it's not behaving like with the original cereal-config.cmake. With the original cereal config file, the target is simply called cereal. With the conan find file it is called cereal::cereal.

So basically, it is necessary to write target_link_libraries(xxx INTERFACE cereal::cereal) when using conan vs. target_link_libraries(xxx INTERFACE cereal) when using the original config file.

@uilianries What do you think? This shouldn't be the case, right?

@xphade xphade reopened this Jul 9, 2020
@SpaceIm
Copy link
Contributor

SpaceIm commented Jul 9, 2020

Yes, several libraries don't define namespace, I've pointed some issues with current behaviour in conan: #2144 (comment)

@NikolausDemmel
Copy link

While yes, upstream packages should ideally adhere to cmake conventions, IMHO Conan should first of all follow the upstream cmake config, such that usage with different package managers or manual installation of the dependencies is transparent for the consuming CMakeLists.txt. Otherwise users have to do things like:

if(TARGET cereal)
  target_link_libraries(${PROJECT_NAME} INTERFACE cereal)
elseif(TARGET cereal::cereal)
  target_link_libraries(${PROJECT_NAME} INTERFACE cereal::cereal)
...

It may of course also provide the "proper" targets with namespace in addition.

Do the generated find modules support specifying such alias targets? Then I think we need another PR for the cereal recipe.

NikolausDemmel referenced this issue in ceres-solver/ceres-solver Jul 9, 2020
Since version 3.3 Eigen provides Eigen3Config.cmake with the imported
target Eigen3::Eigen. [1]
Use this imported target as descibed in Eigen-Wiki [2]

In the CeresConfig file improve relocatability by removing absolute
paths to the compiled dependencies. Instead find the used Eigen3::Eigen.
Furthermore use the find_dependency() [4] CMake function instead of the
find_package() call in CeresConfig.

This commit relies on all targets to be explicitly linked private or
public as done in the the change [3]

[1] https://bitbucket.org/eigen/eigen/pull-requests/257/cmake-imported-target-take-2/diff
[2] https://eigen.tuxfamily.org/dox/TopicCMakeGuide.html
[3] https://ceres-solver-review.googlesource.com/c/ceres-solver/+/16220
[4] https://cmake.org/cmake/help/latest/module/CMakeFindDependencyMacro.html

Change-Id: I44f44a089083f7169bcf430b59775242e4eb72d1
@SpaceIm
Copy link
Contributor

SpaceIm commented Jul 9, 2020

cereal is not the only recipe affected: glfw, freetype in CONFIG mode, fcl, libccd, tinyobjloader, and probably others.

@NikolausDemmel
Copy link

I understand. I'm just not sure what is the "official" opinion on how it should be addressed. Providing alias targets? Is that supported by the generator?

Would a PR that fixes cereal be welcome, or is there a systematic effort ongoing?

@SpaceIm
Copy link
Contributor

SpaceIm commented Jul 9, 2020

It can't be fixed in recipes right now, because AFAIK currently conan always creates namespaced targets with cmake_find_package and cmake_find_package_multi generators.

EDIT: I misunderstood, you suggested to submit a PR to cereal? Yes it would be welcome.

@NikolausDemmel
Copy link

It can't be fixed in recipes right now, because AFAIK currently conan always creates namespaced targets with cmake_find_package and cmake_find_package_multi generators.

Ok. Is there any place where we should voice our support for getting this changed? I'm new to Conan, but it seems a bit strange to discourage installing the working cmake config files (together with cmake_paths generator) while at the same time the workflow with the cmake_find_package generator doesn't really support all use cases (yet).

EDIT: I misunderstood, you suggested to submit a PR to cereal? Yes it would be welcome.

No, I meant a PR to the recipe. Fixing upstream cereal would of course be good and should be done as well, but I don't think that will result in a very quick solution, since the project is not terribly active, and we'd probably have to then wait for the next release...

please, read #1970

Actually, coming back to your original reply. I understand that conan(-center?) prefers the cmake_find_package generator over the cmake_paths together with the packages own cmake modules (if it defines them). In can sympathise with some of the arguments in the FAQ

https://github.com/conan-io/conan-center-index/wiki/FAQ#why-are-cmake-findconfig-files-and-pkg-config-files-not-packaged

and I understand that sometimes the upstream cmake config files are not working great. However, nowhere else does it say that using the packages' own cmake config files or find modules (where they are properly set up) is discouraged. E.g. if you check the conan documentation, it is described as a valid approach (and actually before cmake_find_package):

https://docs.conan.io/en/latest/integrations/build_system/cmake.html

So can't we just have both? Install the project's own cmake config, as well as making the cmake_find_package generators behave in a compatible way?

IMHO one thing that the FAQ at https://github.com/conan-io/conan-center-index/wiki/FAQ#why-are-cmake-findconfig-files-and-pkg-config-files-not-packaged doesn't really discuss is that Conan should not force the consuming CMakeLists.txt to be written in a conan specific way. If I write a library that depends on say Cereal, it should be up to the users of my library how they wanna fulfill that dependency. They might use conan, they might use vcpkg, or a system package manager like apt or homebrew. My libraries CMakeLists.txt should just call find_package(cereal) in all those cases. There is an interesting talk on this topic that emphasises this approach. From that FAQ entry, I read between the lines that Conan (Center?) wants to encourage (enforce?) a Conan-centric workflow only (maybe I'm wrong). While this can be very useful for specific cases, IMHO the package-manager agnostic workflow is equally important in the heterogeneous C++ world.

Am I wrong in my assessment of the situation at Conan (Center)? Where would be the right place to voice my opinion about this?

@uilianries
Copy link
Member

@NikolausDemmel Interesting case about Cereal. I used it in the past, but I didn't remember about the namespace absence. Anyway, we know the recommend way is using namespace, but unfortunately only Cereal doesn't follow it, but also other projects. So, I suggest filing a new issue to Conan, asking to support such case.

As Conan forces to use its generators, they should provide something close to the upstream behavior, but at same time valid.

@jgsogo
Copy link
Contributor

jgsogo commented Jul 14, 2020

I've open a feature request to Conan: conan-io/conan#7352 I think these are details that cannot be added to cpp_info model, but we can workaround them using build_modules, wdyt?

@NikolausDemmel
Copy link

but we can workaround them using build_modules, wdyt?

Sounds like a good solution.

So can't we just have both? Install the project's own cmake config, as well as making the cmake_find_package generators behave in a compatible way?

What about this one? Is there objection to still installing the packages own cmake config files? Even if the recommended way is using the cmake_find_package generator (which can be fixed once it's enabled by conan upstream)?

@SpaceIm
Copy link
Contributor

SpaceIm commented Jul 15, 2020

Do CCI hooks allow files (or parent folder of those files) included in cpp_info.build_modules but forbidden if not?

@uilianries
Copy link
Member

Yes, if not listed in build_modules it won't be allowed by hooks. You can use

self.cpp_info.build_modules.append(os.path.join("lib", "cmake", "Corrade", "UseCorrade.cmake"))
as reference

@SpaceIm SpaceIm mentioned this issue Jul 16, 2020
4 tasks
@ericLemanissier

This comment has been minimized.

@SpaceIm
Copy link
Contributor

SpaceIm commented Sep 2, 2021

This issue can be closed. cereal imported target has been fixed in #4257

@jgsogo jgsogo closed this as completed Oct 11, 2021
SvenRoederer pushed a commit to ColVisTec/conan-center-index that referenced this issue Sep 5, 2024
SvenRoederer pushed a commit to ColVisTec/conan-center-index that referenced this issue Oct 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
duplicate This issue or pull request already exists question Further information is requested
Projects
None yet
Development

No branches or pull requests

6 participants