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

Is there a way to override {name} and target name {name}::{name} for cmake_find_package #4430

Closed
nesc1 opened this issue Jan 31, 2019 · 14 comments

Comments

@nesc1
Copy link

nesc1 commented Jan 31, 2019

Hi, I'm removing all the CONAN_PKG::{name} from my project in order to only depend on find_package (this is usuful for easily change depenendencies locations depending on machine state, sometimes i want to find only libraries generated by conan other times i want to only find the installed system ones)

So when I depend only on conan library paths I need to ensure that what I'm linking is the right conan libraries, for this i only see two ways that are certain to give me the right paths, conan_basic_setup(TARGETS) and use CONAN_PKG::{name} or cmake_find_package (cmake_paths can find both libraries, conan and system libraries all together).

Now I'm using the second one, but I got a problem, the find_package names of the conan packages does not match the ones from system, example: libjpeg conan package generates a Findlibjpeg.cmake but the system one is FindJPEG.cmake, so I can not use the find_package(JPEG) because the conan generated one is expecting find_package(libjpeg)...

My question, can we override this name without renaming the conan package?
And can we rename the target name also (is that sometimes the target name is not {name}::{name})?

Thanks

@uilianries
Copy link
Member

Hi @nesc1 !

You can't change it directly by Conan, like an attribute, but you have two options I think. You could rename the cmake file by file(RENAME <oldname> <newname>) or you could create an alias or something related.

@nesc1
Copy link
Author

nesc1 commented Jan 31, 2019

Hi @uilianries I was hoping for a more automated thing... with alias I need to change my CMakeLists.txt in order to know if I'm linking with conan or not... and I wanted to avoid that... the file(RENAME ..) might be a solution... but on an outside script (because I have an shell script to start the cmake...) and rename the files and targets... not the best solution in the world.. but might work if we can not change this in conan then proably is one way to go...

@uilianries
Copy link
Member

I understand your point, but unfortunately there is nothing that Conan could do for now. When you use cmake_find_package, Conan provides a cmake file based on package name. We have had many user problems with case-sensitive names, so we decided to use lower case to keep it standardized.

However, we could think in a feature for renaming the cmake file generated when using cmake_find_package. WDYT @memsharded ?

@Johnnyxy
Copy link

Johnnyxy commented Jan 31, 2019

@nesc1 You could circumvent this in CMake by using something like a "proxy"-target.
This is certainly not a real conan solution but a flexible workaround that implies no changes to the conan code and keeps you flexible (also for debugging scenarios).

find_package (libjpeg)
if (NOT TARGET libjpeg::libjpeg)
    find_package (JPEG REQUIRED)
    add_library (libjpeg::libjpeg INTERFACE IMPORTED)
    target_link_libraries (libjpeg::libjpeg PUBLIC JPEG::JPEG)
    message (STATUS "using system provided JPEG library")
else()
    message (STATUS "using conan provided JPEG library")
endif()

...
...
...

target_link_libraries (your_project_target PRIVATE libjpeg::libjpeg)

@nesc1
Copy link
Author

nesc1 commented Jan 31, 2019

@Johnnyxy yap probably the best way and with minimal work.. the other is not so easy to do... thanks

@alcroito
Copy link

alcroito commented May 1, 2019

I have encountered the same issue while working on building Qt with CMake. For acquring dependencies we are considering between vcpkg and Conan.

The problem is that CMake native Find modules as well as vcpkg, generate mostly upper case and mixed-case target names.

For instance FindZLIB.cmake add_library(ZLIB::ZLIB), FindPNG.cmake add_library(PNG::PNG), FindBZip2.cmake add_library(BZip2::BZip2), etc.

Whereas Conan generates all lower case targets.

If I use the cmake_find_package and cmake_paths generators to consume a conan built
pcre2 package, in my project find_package(pcre2) will implicitly do a find_dependency(zlib), which will use the CMake native FindZLIB module, it will set ZLIB_FOUND to true, but then the Conan FindPCRE2.cmake checks for zlib_FOUND (notice the case), and cmake variables are case sensitive, which means that the PCRE2 find_package() call will ultimately fail.

Note swapping the cmake_find_package generator for cmake_find_package_multi does help for finding the proper pcre2 and zlib config files, but it still won't be compatible with projects that would like to support more than Conan provided packages.

Adding custom proxy Find modules is a solution of course, but it gets unwieldy and error-prone pretty fast when you have to wrap more than a few packages (which is the case for Qt).

Would you consider reopening the issue and perhaps brainstorm on a solution on how to handle customization of file, package and target names?

@nesc1
Copy link
Author

nesc1 commented May 3, 2019

Hi @alcroito i understand and know your problems because i also face the same problems.

Just to let you know that my final solution was not to use any of the conan generated targets, I only use the 'cmake_paths' generator and give to cmake all the available library paths doing -DCMAKE_PROJECT_${PROJECTNAME}_INCLUDE=${BUILDDIR}/conan_paths.cmake.

On cmake side I only use the find_package() functionality.

For the libraries that does not supply find_package functionality I manually add these findxxx.cmake files and I think is the best aproach, not completely 100% ok, but good enought and better than any other that you and I mention and tried.

@lasote lasote reopened this May 3, 2019
@alcroito
Copy link

alcroito commented May 3, 2019

Hi,

How is manually adding findxxx.cmake files different from what was previously mentioned?

You either provide your own findxxx.cmake files for project that don't have them, or you use the cmake_find_package generator, and still need something like findWrapxxx.cmake which will then use either the conan generated findxxx.cmake file, or the one that is included in upstream CMake or upstream package.

Either way, if you have 50+ libraries, you need to maintain a bunch of findxxx.cmake files, and that's a maintenance burden that could be avoided if Conan allowed configuration for the generator.

@nesc1
Copy link
Author

nesc1 commented May 3, 2019

Hi

Is managed diferently... at least I prefer, most of the libraries already support cmake so few of them do not.
Using the cmake_find_package generator will do that for all, or you manually remove the ones that you do not want or you copy manually the ones that you want... i personally don't like this step. For example Qt or boost are not managed correctly by cmake_find_package generator, I normally do not want all the components in both libraries, and cmake_find_package generator does not offer you this choice (as far as I know).

Like I said @alcroito, our prefered choice was that, because in the cmake code I only do one way, that is using find_package() functionality, and is the same for all libraries, the only thing that change is the way I call cmake to generate/compile my project. Note that this way you can use or not conan libraries, if you do not use the -DCMAKE_PROJECT_${PROJECTNAME}_INCLUDE then cmake will try to find them on the system (that was one requirement from us also).

So @alcroito I was only telling you what solution was best for us, for you it might be diferent and not the best one, each project as it own details and requirements, but yes neither is 100% ok. The one that I refer was a bit better for us in the end :)

@memsharded
Copy link
Member

This issue has been re-opened, because in #5090, they are proposing to add this names in the cpp_info in recipes. Not exactly a way to override from downstream, but some recipes might be able to define the "cmake" expected name in their components.

@alcroito
Copy link

alcroito commented May 3, 2019

@nesc1 Ok cool, thanks for the info. I just wanted some clarifications.

@memsharded That's great news! It's a step in the direction to perhaps someday allowing to override downstream as well : )

@jgsogo
Copy link
Contributor

jgsogo commented Aug 5, 2020

This is already possible (Conan v1.28) with:

  • cpp_info.names["cmake_find_package"] = "AAA"
  • cpp_info.filename["cmake_find_package"] = "BBB"
  • cpp_info.components["cmp1"].names["cmake_find_package"] = "CCC"

Conan will generate file FindBBB.cmake with target AAA::CCC.


Overriding from consumers is not considered ATM (is there a strong use-case for this?), it is the recipe providing the package the one that declares the targets it is providing.

@alcroito
Copy link

alcroito commented Aug 5, 2020

As I mentioned in the comment, overriding from consumer side would useful to avoid maintaining multiple package and target names for the same library in a custom FindFoo.cmake file, if the names differ between package managers.

One could argue that moves the maintenance of hardcoding the names from the FindFoo.cmake file to conanfile.py, but at least it keeps the cmake files cleaner (when supporting multiple package managers that provide the same library under different names).

@jgsogo
Copy link
Contributor

jgsogo commented Aug 5, 2020

I understand that pain, but I would always try to reconcile the naming proposing the required changes to one or the other package manager. I think C++ ecosystem needs this kind of effort from all of us.

Right now, from the consumer, you cannot override the names, filename and components.names for your requirements but you can easily modify the files generated by Conan to match your requirements, you can rename them or replace their contents.

jellespijker added a commit to Ultimaker/libnest2d that referenced this issue Aug 6, 2021
@nesc1 nesc1 closed this as completed Aug 11, 2022
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

8 participants