Package (net-snmp) installed by conan can not be found by cmake

137 views Asked by At

I have created a simple conan project and want to include the 'net-snmp' package from conancenter in my c++ project. The problem is that I cannot find net-snmp when I try to build the project with cmake.

To reproduce the error, here is what I have done. Create simple project from template:

conan new hello/0.1 --template=cmake_exe

After that I included the the def requirements(self): in the newly generated conanfile.py:

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout


class HelloConan(ConanFile):
    name = "hello"
    version = "0.1"

    # Optional metadata
    license = "<Put the package license here>"
    author = "<Put your name here> <And your email here>"
    url = "<Package recipe repository url here, for issues about the package>"
    description = "<Description of Hello here>"
    topics = ("<Put some tag here>", "<here>", "<and here>")

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}

    # Sources are located in the same place as this recipe, copy them to the recipe
    exports_sources = "CMakeLists.txt", "src/*", "include/*"

    def requirements(self):                # i have only added 
        self.requires("net-snmp/5.9.1")    # these two lines

    def config_options(self):
        if self.settings.os == "Windows":
            del self.options.fPIC

    def layout(self):
        cmake_layout(self)

    def generate(self):
        tc = CMakeToolchain(self)
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        self.cpp_info.libs = ["hello"]

And in the CMakeLists.txt:

find_package(net-snmp 5.9.1 REQUIRED)

To build it I use:

mkdir build && cd build
conan install ..
cmake ..

This results in the following error:

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

  Could not find a package configuration file provided by "net-snmp"
  (requested version 5.9.1) with any of the following names:

    net-snmpConfig.cmake
    net-snmp-config.cmake

  Add the installation prefix of "net-snmp" to CMAKE_PREFIX_PATH or set
  "net-snmp_DIR" to a directory containing one of the above files.  If
  "net-snmp" provides a separate development package or SDK, be sure it has
  been installed.

I use:

  • Ubuntu 22.04.3
  • Conan 1.60.2 (I can't use 2.X because of CI restrictions)
  • CMake 3.27.2
1

There are 1 answers

8
uilianries On

First, I see you are using Conan 1.x for your tutorial. Please, consider moving to Conan 2.x. For more information about Conan 2.x: https://docs.conan.io/2/whatsnew.html

Back to your problem:

You declared a new dependency, but didn't tell Conan to generate its cmake files. So your conanfile.py should look more or less:

from conan import ConanFile
from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout


class HelloConan(ConanFile):
    name = "hello"
    version = "0.1"
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False]}
    default_options = {"shared": False, "fPIC": True}
    exports_sources = "CMakeLists.txt", "src/*", "include/*"

    def config_options(self):
        if self.settings.os == "Windows":
            del self.options.fPIC

    def layout(self):
        cmake_layout(self)

    def requirements(self):
        self.requires("net-snmp/5.9.1")

    def generate(self):
        tc = CMakeToolchain(self)
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        self.cpp_info.libs = ["hello"]

Now you need to update your generate method:

from conan.tools.cmake import CMakeDeps

...

def generate(self):
    tc = CMakeToolchain(self)
    tc.generate()
    tc = CMakeDeps(self)
    tc.generate()

The CMakeDeps generator will generate the net-snmp cmake files needed to find its headers, libraries, ...

But it's not enough, your commands need to be update as well, you are following the command to install your dependencies, and then, running cmake manually. There is a cost doing that, because you would need to tell cmake the toolchain file to match with your Conan profile.

Thus, as you want to build a library (based on conan new command with library template), you could run:

conan create .

The conan create command will export your recipe, than build it in your conan cache.


However, if you just want to consume a library directly to your already existent C++ project, you should follow another approach, following this tutorial. But to simplify:

Only add a new conanfile.txt in the root folder of your C++ project, with the follow content:

[requires]
net-snmp/5.9.1

[generators]
CMakeToolchain
CMakeDeps

Then, you should install your requirements and generate cmake files:

# in your project root folder
mkdir build && cd build
conan install ..
cmake .. -DCMAKE_TOOLCHAIN_FILE=Release/generators/conan_toolchain.cmake
cmake --build .

Using the build will avoid mixing build cached files with your sources. Plus, you need to pass the toolchain file to cmake, otherwise, it won't be able to match your Conan profile, neither find your installed dependencies.

This explanation is part of the Conan 2.x tutorial. So again, strongly recommend you moving to 2.x if you are trying Conan for the first time.