Conan

How to get dependency include & library directories in Conanfile.py

Within conanfile.py , this is how you can obtain a list of include & library directories for each of the dependencies:

class MyProject(Conanfile):
    # ...
    def build(self):
        # Check dependencies
        for dependency in self.dependencies.values():
            cppinfo = dependency.cpp_info.aggregated_components()
            print("libdirs", cppinfo.libdirs)
            print("includedirs", cppinfo.includedirs)
        # ...

 

Posted by Uli Köhler in Conan

How to use ‘conan download’ to download a package from conancenter

When you try to download a package from conancenter using conan download, the right syntax to use is:

conan download libcurl/8.1.1 -r conancenter

If you forget to specify -r conancenter, you will see the following error message:

usage: conan download [-h] [-v [V]] [--only-recipe] [-p PACKAGE_QUERY] -r REMOTE reference
conan download: error: the following arguments are required: -r/--remote
ERROR: Exiting with code: 2

 

Posted by Uli Köhler in Conan

How to fix conan ERROR: The default build profile doesn’t exist.

Problem:

You want to install or build a conan project using a command such as

conan install .

but you see an error message such as

ERROR: The default build profile '/home/uli/.conan2/profiles/default' doesn't exist.
You need to create a default profile (type 'conan profile detect' command)
or specify your own profile with '--profile:build=<myprofile>'

Solution:

Typically you just want to create the default build profile using

conan profile detect

detect means to detect the compiler.

Posted by Uli Köhler in Conan

List of conan 2.x pre-defined templates

The following list of templates is predefined for conan 2.0.6:

  • basic
  • cmake_lib
  • cmake_exe
  • meson_lib
  • meson_exe
  • msbuild_lib
  • msbuild_exe
  • bazel_lib
  • bazel_exe
  • autotools_lib
  • autotools_exe

You can check for yourself using

conan new --help

In the output from this command, look for positional arguments -> template. In the help text, you’ll find a list of possible templates.

Posted by Uli Köhler in Conan

How to fix conan new ERROR: Missing definitions for the template. Required definitions are: ‘name’, ‘version’

Problem:

You want to initialize your conan project using a command such as

conan new cmake_exe

but you see the following error message:

ERROR: Missing definitions for the template. Required definitions are: 'name', 'version'

Solution:

Conan wants you to specify the name and version of your package using -d name=myproject -d version=1.0.0.

Full example:

conan new cmake_exe -d name=MyPkg -d version=1.0.0

 

Posted by Uli Köhler in Conan

How to fix conan ERROR: Template doesn’t exist or not a folder

Problem:

You want to initialize a conan project using a command such as

conan new myproject/1.0.0

However, once you run it, you see an error message like

ERROR: Template doesn't exist or not a folder: myproject/1.0.0

Solution:

The way you have to use conan new changed with Conan version 2.0.

Now you don’t specify the project name but a template! Templates are names such as cmake_exe but the easiest template to start with is basic as it doesn’t require any parameters:

conan new basic

You can also initialize it using a predefined template such as cmake_exe:

conan new cmake_exe -d name=MyProject -d version=1.0.0

 

Posted by Uli Köhler in Conan

How to initialize C++ project using conan 2.x

The simplest way of starting is by running the following command in your project directory:

conan new basic

This will create conanfile.py from the basic template.

Alternatively, you can initialize it from a predefined template such as cmake_exe:

conan new cmake_exe -d name=myproject -d version=1.0.0

 

Posted by Uli Köhler in C/C++, Conan

Conan .gitignore for executable projects

This is the .gitignore I use for most of my conan-built executable projects:

CMakeCache.txt
CMakeFiles/
Makefile
bin/
cmake_install.cmake
conan.lock
conanbuildinfo.cmake
conanbuildinfo.txt
conaninfo.txt
graph_info.json

It is debatable whether you should include lock files such as conan.lock. My opinion is that in the development phase they should be ignored but reconsidered when entering into production service.

Posted by Uli Köhler in Conan, git

How to initialize new C++ executable project using conan 1.x

Important note: This post is for Conan 1.x and is not compatible with the current version conan 2.x! See How to initialize C++ project using conan 2.x for an updated version of this post!

In the directory where you want to create the project, run (obviously, replace mypackageby the name of everywhere in our code!)

conan new mypackage/1.0.0 -s

-s is important here. It tells conan that the source is available in the project directory and it should not be pulled using git etc.

This will initialize a shared library project, which we will now modify to build an executable.

First, open src/CMakeLists.txt and change add_library() to add_executable(), for example

add_library(mypackage mypackage.cpp)

to

add_executable(mypackage mypackage.cpp)

Now we shall modify conanfile.py to properly build & install the executable:

    def package(self):
        self.copy("*.h", dst="include", src="src")
        self.copy("*.lib", dst="lib", keep_path=False)
        self.copy("*.dll", dst="bin", keep_path=False)
        self.copy("*.dylib*", dst="lib", keep_path=False)
        self.copy("*.so", dst="lib", keep_path=False)
        self.copy("*.a", dst="lib", keep_path=False)
    def package_info(self):
        self.cpp_info.libs = ["NoxecoDB"]

with

    def package(self):
        self.copy("mypackage", src="bin", dst="bin", keep_path=False)

    def package_info(self):
        self.env_info.PATH = os.path.join(self.package_folder, "bin")

    def deploy(self):
        self.copy("mypackage", dst="bin", src="bin")

and add

import os.path

to the top of the file

Now let’s add a main() function to  src/mypackage.cpp. Replace the file’s content with

#include <iostream>

int main(int argc, char** argv) {
    std::cout << "Hello World!" <<std::endl;
}

Now it’s time to install the dependencies & build the project using

conan install . && conan build .

The executable will be in

bin/mypackage

You can run it using

./bin/mypackage

which will print

Hello World!

I also recommend to add this .gitignore:

CMakeCache.txt
CMakeFiles/
Makefile
bin/
cmake_install.cmake
conan.lock
conanbuildinfo.cmake
conanbuildinfo.txt
conaninfo.txt
graph_info.json

 

Posted by Uli Köhler in C/C++, Conan

How to fix conan install ERROR: Missing binary

Problem:

When running

conan install .

you see  ERROR: Missing binary error messages like this:

Installing (downloading, building) binaries...
ERROR: Missing binary: cpr/1.6.2:76fe60a9d5c829a2384b0f578695b5a6357b8acc
ERROR: Missing binary: gtest/cci.20210126:c37dc23725d84483088a68c29e2dd7122c328359
ERROR: Missing binary: jsoncpp/1.9.4:718278bac9f92b77a9a44bfbe1aa00d1c8344d51
ERROR: Missing binary: libcurl/7.78.0:d287dc966931230205222ceabf47400733e72fa3
ERROR: Missing binary: openssl/1.1.1l:c3baf9fae083edda2e0c5ef3337b6a111016a898
ERROR: Missing binary: zlib/1.2.11:c3baf9fae083edda2e0c5ef3337b6a111016a898

Solution:

Use the --build=missing flag for conan install to enable building the dependencies for which no binaries are available:

conan install . --build=missing

Complete error log example

Configuration:
[settings]
arch=armv8
arch_build=armv8
build_type=Release
compiler=gcc
compiler.libcxx=libstdc++
compiler.version=9
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

openssl/1.1.1l: Not found in local cache, looking in remotes...
openssl/1.1.1l: Trying with 'conancenter'...
Downloading conanmanifest.txt completed [0.26k]                                          
Downloading conanfile.py completed [40.47k]                                              
Downloading conan_export.tgz completed [0.25k]                                           
Decompressing conan_export.tgz completed [0.00k]                                         
openssl/1.1.1l: Downloaded recipe revision 0
cpr/1.6.2: Not found in local cache, looking in remotes...
cpr/1.6.2: Trying with 'conancenter'...
Downloading conanmanifest.txt completed [0.25k]                                          
Downloading conanfile.py completed [9.62k]                                               
Downloading conan_export.tgz completed [0.30k]                                           
Decompressing conan_export.tgz completed [0.00k]                                         
cpr/1.6.2: Downloaded recipe revision 0
WARN: cpr/1.6.2: requirement libcurl/7.80.0 overridden by elasticlient/0.2 to libcurl/7.78.0 
libcurl/7.78.0: Not found in local cache, looking in remotes...
libcurl/7.78.0: Trying with 'conancenter'...
Downloading conanmanifest.txt completed [0.70k]                                          
Downloading conanfile.py completed [27.11k]                                              
Downloading conan_export.tgz completed [0.23k]                                           
Decompressing conan_export.tgz completed [0.00k]                                         
libcurl/7.78.0: Downloaded recipe revision 0
jsoncpp/1.9.4: Not found in local cache, looking in remotes...
jsoncpp/1.9.4: Trying with 'conancenter'...
Downloading conanmanifest.txt completed [0.65k]                                          
Downloading conanfile.py completed [4.90k]                                               
Downloading conan_export.tgz completed [0.25k]                                           
Decompressing conan_export.tgz completed [0.00k]                                         
jsoncpp/1.9.4: Downloaded recipe revision 0
gtest/cci.20210126: Not found in local cache, looking in remotes...
gtest/cci.20210126: Trying with 'conancenter'...
Downloading conanmanifest.txt completed [0.39k]                                          
Downloading conanfile.py completed [8.14k]                                               
Downloading conan_export.tgz completed [0.32k]                                           
Decompressing conan_export.tgz completed [0.00k]                                         
gtest/cci.20210126: Downloaded recipe revision 0
conanfile.py (elasticlient/0.2): Installing package
Requirements
    cpr/1.6.2 from 'conancenter' - Downloaded
    jsoncpp/1.9.4 from 'conancenter' - Downloaded
    libcurl/7.78.0 from 'conancenter' - Downloaded
    openssl/1.1.1l from 'conancenter' - Downloaded
    zlib/1.2.11 from 'conancenter' - Cache
Packages
    cpr/1.6.2:76fe60a9d5c829a2384b0f578695b5a6357b8acc - Missing
    jsoncpp/1.9.4:718278bac9f92b77a9a44bfbe1aa00d1c8344d51 - Missing
    libcurl/7.78.0:d287dc966931230205222ceabf47400733e72fa3 - Missing
    openssl/1.1.1l:c3baf9fae083edda2e0c5ef3337b6a111016a898 - Missing
    zlib/1.2.11:c3baf9fae083edda2e0c5ef3337b6a111016a898 - Missing
Build requirements
    gtest/cci.20210126 from 'conancenter' - Downloaded
Build requirements packages
    gtest/cci.20210126:c37dc23725d84483088a68c29e2dd7122c328359 - Missing

Installing (downloading, building) binaries...
ERROR: Missing binary: cpr/1.6.2:76fe60a9d5c829a2384b0f578695b5a6357b8acc
ERROR: Missing binary: gtest/cci.20210126:c37dc23725d84483088a68c29e2dd7122c328359
ERROR: Missing binary: jsoncpp/1.9.4:718278bac9f92b77a9a44bfbe1aa00d1c8344d51
ERROR: Missing binary: libcurl/7.78.0:d287dc966931230205222ceabf47400733e72fa3
ERROR: Missing binary: openssl/1.1.1l:c3baf9fae083edda2e0c5ef3337b6a111016a898
ERROR: Missing binary: zlib/1.2.11:c3baf9fae083edda2e0c5ef3337b6a111016a898

 

Posted by Uli Köhler in Conan

How to create conan debug profile

Run this command to create a debug profile from your default profile:

cp ~/.conan/profiles/default ~/.conan/profiles/debug && sed -i -e 's/Release/Debug/g' ~/.conan/profiles/debug

Example output from conan profile show debug:

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

 

Posted by Uli Köhler in C/C++, Conan

How to list local conan packages

In order to list local conan packages, run

conan search

Example output:

$ conan search
Existing package recipes:

cpr/1.6.2
elasticlient/0.2
elasticlient/0.2@demo/testing
gtest/cci.20210126
jsoncpp/1.9.4
libcurl/7.69.1
libcurl/7.78.0
openssl/1.1.1l
zlib/1.2.11

 

Posted by Uli Köhler in Conan

How to fix Conan CMake “Could NOT find OpenSSL”

Problem:

When building your conan package, you see this CMake error:

CMake Error at /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:146 (message):
  Could NOT find OpenSSL, try to set the path to OpenSSL root folder in the
  system variable OPENSSL_ROOT_DIR (missing: OPENSSL_CRYPTO_LIBRARY
  OPENSSL_INCLUDE_DIR)
Call Stack (most recent call first):
  /usr/share/cmake-3.16/Modules/FindPackageHandleStandardArgs.cmake:393 (_FPHSA_FAILURE_MESSAGE)
  /usr/share/cmake-3.16/Modules/FindOpenSSL.cmake:447 (find_package_handle_standard_args)
  ../_deps/curl-src/CMakeLists.txt:365 (find_package)

even though your conanfile.py declares OpenSSL as a dependency:

class MyPackageConan(ConanFile):
    # ...
    requires = ("openssl/1.1.1l", )

Solution:

Make sure that the project’s CMakeLists.txt contains these lines:

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

Typically, the way to do this is to use this code which is automatically generated by conan new:

        # This small hack might be useful to guarantee proper /MT /MD linkage
        # in MSVC if the packaged project doesn't have variables to set it
        # properly
        tools.replace_in_file("hello/CMakeLists.txt", "PROJECT(HelloWorld)",
                              '''PROJECT(HelloWorld)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()''')

in source() like this:

    def source(self):
        self.run("git clone https://github.com/conan-io/hello.git")
        # This small hack might be useful to guarantee proper /MT /MD linkage
        # in MSVC if the packaged project doesn't have variables to set it
        # properly
        tools.replace_in_file("hello/CMakeLists.txt", "PROJECT(HelloWorld)",
                              '''PROJECT(HelloWorld)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()''')

Note that you need to replace both hello/CMakeLists.txt with the correct filename (typically, just replace hello by). Also, you need to replace both instances PROJECT(HelloWorld) by the actual line from your CMakeLists.txt in order for the replace command to work.

Posted by Uli Köhler in C/C++, CMake, Conan

How to add build-only dependencies in Conan recipe

Just add build_requires = ('dep1/version1', 'dep1/version2') to your conanfile.py:

class MyPackageConan(ConanFile):
    # ...
    requires = ("openssl/1.1.1l", )
    build_requires = ("jsoncpp/1.9.4", )

 

Posted by Uli Köhler in C/C++, Conan

How to run ‘git submodule update’ in Conan recipe

If you want to run git submodule update in your conanfile.py, you can simple add a self.run() command after the git clone command:

self.run("git clone https://github.com/conan-io/hello.git")
self.run("cd hello && git submodule update --init --recursive")

Full example:

self.run("git clone https://github.com/seznam/elasticlient.git -b version-0.2")
self.run("cd elasticlient && git submodule update --init --recursive")

Note that you need to cd <directory> && git submodule update

Posted by Uli Köhler in C/C++, Conan

How to generate new Conan recipe for pre-existing package

If you want to create a new conan build recipe for a package that already exists, use

Without tests:

conan new hello/0.1

With tests:

conan new hello/0.1 -t

More info: See packaging docs

Posted by Uli Köhler in C/C++, Conan

How to add conan CMake build definition

When building a library using conan, this is the default conanfile.py definition for building using CMake

cmake = CMake(self)
cmake.configure(source_folder="hello")
cmake.build()

You can easily add definitions like this:

cmake.definitions["MY_FLAG"] = "1"

This will generate -DMY_FLAG=1 when calling CMake

Full example:

cmake = CMake(self)
cmake.definitions["USE_SYSTEM_CPR"] = "1
cmake.configure(source_folder="elasticlient")"
cmake.build()

Note that you need to add all cmake.definitions calls before calling cmake.configure()

Posted by Uli Köhler in C/C++, Conan