conan
conan copied to clipboard
[question] find_package and non-standard structure of package content
Dear Conan Folks,
We have a legacy system where every script cannot be adapated to not disturb a running system. The contents of the package are : tools, includes . While using find_package from CMake the package is found but since it has not the standard structure , certain variables are not set example: <PKG-NAME>_INCLUDE_DIRS as in https://docs.conan.io/en/latest/reference/generators/cmake_find_package.html#cmake-cmake-find-package-generator-reference . What is the way to get to the package root in that case?Is there any variable set that will give the absolute path to the package? Thanks for your reply.
- [ ] I've read the CONTRIBUTING guide.
Hi @maitrey
It is necessary to define in the package recipe the structure:
def package_info(self):
self.cpp_info.includedirs = ["includes"]
self.cpp_info.bindirs = ["tools"]
Otherwise the default include
and bin
folder is used
Also, recall that the cmake_find_package
generator is deprecated and removed in 2.0. You should be upgrading to CMakeDeps
(and CMakeToolchain
)
Thanks @memsharded . I inspected the cmakefiles and started to use: <PKG_NAME>_PACKAGE_FOLDER_RELEASE. Is this allowed? Also, what if I have more folders and not only one tool? How can one define that in package_info method?
The <PKG_NAME>_PACKAGE_FOLDER_RELEASE
variables are implementation details of the CMakeDeps
generator, not intended to be used directly that way, but instead via the created targets via target_link_libraries(.... mypkg::mypkg)
or something similar. Why the targets are not good for your case?
It is not that the generated xxxx-data.cmake
files will change, but they are not documented, if not documented, then they are subject to change. You can always write your own file in generate()
method collecting the self.dependencies["dep"].package_folder
, if you want 100% stability.
For multiple folders:
def package_info(self):
self.cpp_info.includedirs = ["includes"]
self.cpp_info.bindirs = ["tool_folder1", "tool_folder2"]
Hi @memsharded , This works and then I can also access the paths from : self.deps_cpp_info["Package].bin_paths but how to access it from CMakeLists.txt. Can I use this Package_INCLUDE_DIRS or is this not allowed?Is there any other way to use it from CMakeLists.txt?
Please note that self.deps_cpp_info["Package].bin_paths
is a deprecated way to access information dependencies. self.dependencies
is the way to go now: https://docs.conan.io/en/latest/reference/conanfile/dependencies.html
In theory, the variables created by CMakeDeps
are an internal implementation detail, and the created targets are the way to go. That variable might be defined (actually one different for each config, with _RELEASE, _DEBUG, etc). Note that I am talking about CMakeDeps
and not cmake_find_package
or other legacy generators. Why aren't the created targets good for your use case? They are the CMake standard and recommended way to use libraries and dependencies.
While waiting for your reply , I also tried like this: tc.variables["Package"] = self.deps_cpp_info["Package"].bin_paths[0] . Targets are a good way just that I would have to change all the packages as many have include dirs. For creating targets in the creator package in cmake , I need to use add_library and access them with namespace from consumer package. For include headers , I am not sure exactly how to use them. May be you can help with an example.
Sorry, I am not sure what you mean. The include_dirs are already defined in the targets, no need to handle them separately.
The conan new hello/0.1 -m=cmake_lib
is a fully working functional example of creating a package and consuming it with find_package()
and target_link_libraries(.... targetname::targetname)
, without needing to use include_dirs
in CMakeLists.txt or anything like that.
hello example has not the use case that we have. We have packages that are include headers only package.
Can I use the dependencies like this: Package = self.dependencies["Package"] tc.variables["Package_BINDIR0"] = Package.cpp_info.bindirs[0].replace('\', '/')
hello example has not the use case that we have. We have packages that are include headers only package.
That is perfectly fine. A CMake target can also work with only headers, and it is still recommended practice and not using a Something_INCLUDE_DIR variable. Modern CMake is all about targets.
Package = self.dependencies["Package"] tc.variables["Package_BINDIR0"] = Package.cpp_info.bindirs[0].replace('', '/')
Yes, this should be possible. But for bindirs
specifically for dependencies it might not be necessary at all. The bindirs
of tool_requires
will be automatically added to the PATH env-var when the VirtualBuildEnv
generator is declared (which will be automatic in 2.0, or in 1.X if the conf
tools.env.virtualenv:auto_use=True
is defined).
Hi @memsharded , I was on holidays and therefore didnot work on this topic. So I have a package that is an interface package. This contains mainly header files and no source file. In the CMake implementation I have used:
add_library(A INTERFACE) target_include_directories(A INTERFACE ${CMAKE_SOURCE_DIR}/include/extras/additional_includes) target_include_directories(A INTERFACE ${CMAKE_SOURCE_DIR}/include/extras)
I have a package B that is consuming A, B is generating object files. Therefore I donot use, target_link_libraries.
If I use, from toplevel CMakeLists of B then it works:
include_directories(${A_INCLUDE_DIRS}/extras/additional_includes) include_directories(${A_INCLUDE_DIRS}/extras)
If I use,
target_include_directories(B PUBLIC A::A)
then it simply doesnot work, meaning it cannot find header files in additional_includes.
Could you please help me ?
The last comment on this issue is fixed as of now. Was a cmake and not a conan issue. Hence closing this issue.