[question] find_program with Conan 2 not working as expected
What is your question?
Conan 2.5.0 Given a very simple program with a CMake file like:
project(myprog)
include(GNUInstallDirs)
add_executable(myprog myprog.c)
install(TARGETS myprog DESTINATION ${CMAKE_INSTALL_BINDIR})
And a Conan file like:
def layout(self):
cmake_layout(self, src_folder=Foo._source_dir())
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure(build_script_folder=Foo._source_dir())
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.set_property("cmake_file_name", "myprog")
self.cpp_info.set_property("cmake_target_name", "myprog::myprog")
self.cpp_info.set_property("pkg_config_name", "myprog")
self.cpp_info.names["cmake_find_package"] = "myprog"
self.cpp_info.names["cmake_find_package_multi"] = "myprog"
I can see my "myprog" being built and put in the bin folder of the package, just like in Conan 1.63. However when I try to consume the binary with
find_program(MYPROG myprog)
I cannot find it, opposed to with Conan 1 where it did find the file. I see that the BINDIRS variable is not set in the generated XXX-config files (even though docs says it should default to "bin"). What have I done wrong? Using generators CMakeToolchain, CMakeDeps.
Have you read the CONTRIBUTING guide?
- [X] I've read the CONTRIBUTING guide
Hi @rollebolle
thanks for your question.
I am missing some part of your conanfile.py that would be the most important, the requirements.
Probably this is related to the fact that the dependency must be a tool_requires, not a regular requires.
If the consumer is finding a program to execute this, necessarily this program must belong to the "build" context, not to the "host" context. An example of this is cross-building, in which the executables in the host context won't run in the current build machine. You can read more about the build and host contexts here: https://docs.conan.io/2/tutorial/consuming_packages/cross_building_with_conan.html
Are you using tool_requires for this dependency? If not, can you please change it and try again?
Sorry - the full conanfile.py for my package is supplied below. For consuming the package in my app I use the simpler declarative conanfile.txt, with the package under the [requires] section. Moving it to [tool_requires] did not work. Also, in this specfic case, the "myprog" is not a build tool but simply forwarded as an install file in my app.
I am (again) assuming the difference between the Conan 1 and 2 case is the FindXXX vs XXX-config way of finding the package.
Just to make sure I didn't do anything wrong on the consumer end, I also tried it in the cmake-conan example, with cross-compilation etc, and got the same problem. Here is the rest of the conanfile.py (stripped away source section as it is not very interesting and long):
class Foo(ConanFile):
name = "myprog"
license = "Commercial"
author = ""
description = ""
exports_sources = "CMakeLists.txt"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
}
I am not sure what could be failing, there might be some detail missing.
I have just tried:
-
$ conan new cmake_exe -d name=tool -d version=0.1 -
$ conan create . -
$ rm -rf . -
$ conan new cmake_lib -d name=pkg -d version=0.1 - Edit the
conanfile.pyand addtool_requires = "tool/0.1" - Edit the
CMakeLists.txtand add:find_program(MYTOOL tool REQUIRED) message(STATUS "Found MYTOOL executable: ${MYTOOL}") -
$ conan install . -
$ cmake --preset conan-default(Windows)
And it worked. So there might be something missing somewhere. If you could please try to put together a reproducible full example, that would help.
Yes. Using the cmake-conan repo example again, I have modified the conanfile.txt like so:
[requires]
exe2/0.1
[layout]
cmake_layout
[generators]
CMakeToolchain
CMakeDeps
The CMakeFile in the example folder:
cmake_minimum_required(VERSION 3.24)
project(FormatOutput LANGUAGES CXX C)
set(CMAKE_CXX_STANDARD 14)
find_package(ex2 REQUIRED)
find_program(ex2_EXEC ex2 NO_SYSTEM_ENVIRONMENT_PATH REQUIRED)
The package conanfile.py
class InventoryConan(ConanFile):
name = "exe2"
license = "Commercial"
author = ""
exports_sources = "*"
settings = "os", "arch", "compiler", "build_type"
options = {
"shared": [True, False],
"fPIC": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
}
@staticmethod
def _source_dir():
return "."
def layout(self):
cmake_layout(self, src_folder=InventoryConan._source_dir())
def generate(self):
tc = CMakeToolchain(self)
tc.generate()
def build(self):
cmake = CMake(self)
cmake.configure(build_script_folder=InventoryConan._source_dir())
cmake.build()
def package(self):
cmake = CMake(self)
cmake.install()
def package_info(self):
self.cpp_info.set_property("cmake_file_name", "ex2")
self.cpp_info.set_property("cmake_target_name", "ex2::ex2")
self.cpp_info.set_property("pkg_config_name", "ex2")
self.cpp_info.bindirs.append("bin")
self.cpp_info.components["ex2"].bindirs = ["bin"]
self.cpp_info.names["cmake_find_package"] = "ex2"
self.cpp_info.names["cmake_find_package_multi"] = "ex2"
self.cpp_info.set_property("cmake_find_mode", "both")
The package CMakeLists file:
cmake_minimum_required(VERSION 3.10)
project(ex2)
add_executable(ex2 main.cpp)
include(GNUInstallDirs)
install(TARGETS ex2 DESTINATION ${CMAKE_INSTALL_BINDIR})
The commands I run. First in the folder containing the exe2 package:
conan create . --version 0.1
I can confirm the package is created and contains a binary called ex2
Then the cmake command in the example folder:
cmake -B build -S . DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=../conan_provider.cmake -DCMAKE_BUILD_TYPE=Release
The error (note that the package itself is found correctly):
CMake Error at CMakeLists.txt:9 (find_program):
Could not find ex2_EXEC using the following names: ex2
Thanks for the feedback and the details.
This is because the new cmake-conan integration in Conan 2 uses the transparent CMake dependency providers, but that means in practice they do not inject the conan_toolchain.cmake, and some information that is injected that way might not be available. For example, tool_requires environment information like env-vars cannot be injected in the same way.
You can see if it works with the "normal" flow in the consumer:
-
conan install . -
conanbuild.bat(in Windows) orsource conanbuild.sh(in Linux/Mac) -
cmake --preset conan-default(Windows)cmake --preset conan-release( Windows) -
cmake --build --preset conan-release
Can you please try that and let me know? If it works, then this would be a question to move to the cmake-conan repo, (still it is possible that it is an intrinsic limitation of the cmake-conan flow, we will see)
I tried the above commands almost exactly (conan ../../.. --preset conan-release) but with the same error as above
I don't know where the difference could be, I am using the default templates like from conan new cmake_exe, not sure what else to suggest. I think it will be necessary to have a full repro case: if you can please put complete source code in a Github repo, together with a script (like a build.py script) with exact commands that can be executed and reproduce the issue, that would help a lot, we could reproduce that and check what would be the issue.
I invited you to look in a repository I have created, with instructions on how to get the error in Conan 2 (and succeed in Conan 1)
Following up on this. Conan latest versions already got the new "incubating CMakeDeps", see https://docs.conan.io/2/incubating.html.
This new generator creates a new file that will be able to be used by the cmake-conan integration to do find_program()
This ticket should now be fixed with the new CMakeConfigDeps generator: https://docs.conan.io/2/incubating.html, available in Conan 2.12. Please open a new ticket for any further issue with the CMakeConfigDeps generator if necessary.
To get the new CMakeConfigDeps out of "incubating", please test it and report your positive feedback in https://github.com/conan-io/conan/issues/18211 (for issues/questions, better open new tickets)
For cmake-conan integration, it will need a couple of adjustements, I already have them in a branch, but necessary to get CMakeConfigDeps out of incubating first.
Many thanks!