--- https://docs.conan.io/2/examples.html.md --- # Examples * [ConanFile methods examples](https://docs.conan.io/2//examples/conanfile.html.md) * [ConanFile package_info() examples](https://docs.conan.io/2//examples/conanfile/package_info.html.md) * [ConanFile layout() examples](https://docs.conan.io/2//examples/conanfile/layout.html.md) * [Conan extensions examples](https://docs.conan.io/2//examples/extensions.html.md) * [Custom commands](https://docs.conan.io/2//examples/extensions/commands/custom_commands.html.md) * [Builtin deployers](https://docs.conan.io/2//examples/extensions/deployers/builtin_deployers.html.md) * [Custom deployers](https://docs.conan.io/2//examples/extensions/deployers/custom_deployers.html.md) * [Package Signing Plugin](https://docs.conan.io/2//examples/extensions/package_signing/package_signing.html.md) * [Python build backend](https://docs.conan.io/2//examples/extensions/python/build_backend.html.md) * [Conan recipe tools examples](https://docs.conan.io/2//examples/tools.html.md) * [CMake](https://docs.conan.io/2//examples/tools/cmake/cmake.html.md) * [File interaction](https://docs.conan.io/2//examples/tools/files/files.html.md) * [Meson](https://docs.conan.io/2//examples/tools/meson/meson.html.md) * [Bazel](https://docs.conan.io/2//examples/tools/google/bazel.html.md) * [Autotools](https://docs.conan.io/2//examples/tools/autotools/autotools.html.md) * [GNU](https://docs.conan.io/2//examples/tools/gnu/gnu.html.md) * [Capturing Git scm information](https://docs.conan.io/2//examples/tools/scm/git/capture_scm/git_capture_scm.html.md) * [MSBuild](https://docs.conan.io/2//examples/tools/microsoft/msbuild.html.md) * [System Packages](https://docs.conan.io/2//examples/tools/system/system.html.md) * [Cross-building examples](https://docs.conan.io/2//examples/cross_build.html.md) * [Creating a Conan package for a toolchain](https://docs.conan.io/2//examples/cross_build/toolchain_packages.html.md) * [Cross building to Android with the NDK](https://docs.conan.io/2//examples/cross_build/android/ndk.html.md) * [Integrating Conan in Android Studio](https://docs.conan.io/2//examples/cross_build/android/android_studio.html.md) * [Cross-building with Emscripten - WebAssembly and asm.js](https://docs.conan.io/2//examples/cross_build/emscripten.html.md) * [Building packages for TriCore](https://docs.conan.io/2//examples/cross_build/tricore.html.md) * [Cross-compiling from Linux to Windows with MinGW](https://docs.conan.io/2//examples/cross_build/linux_to_windows_mingw.html.md) * [Configuration files examples](https://docs.conan.io/2//examples/config_files.html.md) * [Customize your settings: create your settings_user.yml](https://docs.conan.io/2//examples/config_files/settings/settings_user.html.md) * [Graph examples](https://docs.conan.io/2//examples/graph.html.md) * [Use a CMake macro packaged in a dependency](https://docs.conan.io/2//examples/graph/requires/consume_cmake_macro.html.md) * [Use cmake modules inside a `tool_requires` transparently](https://docs.conan.io/2//examples/graph/tool_requires/use_cmake_modules.html.md) * [Depending on different versions of the same tool-require](https://docs.conan.io/2//examples/graph/tool_requires/different_versions.html.md) * [Depending on same version of a tool-require with different options](https://docs.conan.io/2//examples/graph/tool_requires/different_options.html.md) * [Using the same requirement as a requires and as a tool_requires](https://docs.conan.io/2//examples/graph/tool_requires/using_protobuf.html.md) * [Developer tools and flows](https://docs.conan.io/2//examples/dev_flow.html.md) * [Debugging and stepping into dependencies](https://docs.conan.io/2//examples/dev_flow/debug/step_into_dependencies.html.md) * [Debugging shared libraries with Visual Studio](https://docs.conan.io/2//examples/dev_flow/debug/debugging_visual.html.md) * [Using a MinGW as tool_requires to build with gcc in Windows](https://docs.conan.io/2//examples/dev_flow/tool_requires/mingw.html.md) * [Conan commands examples](https://docs.conan.io/2//examples/commands.html.md) * [Using packages-lists](https://docs.conan.io/2//examples/commands/pkglists.html.md) * [Conan runners examples](https://docs.conan.io/2//examples/runners.html.md) * [Creating a Conan package using a Docker runner](https://docs.conan.io/2//examples/runners/docker/basic.html.md) * [Using a docker runner configfile to parameterize a Dockerfile](https://docs.conan.io/2//examples/runners/docker/configfile_build_args.html.md) * [Conan security examples](https://docs.conan.io/2//examples/security.html.md) * [Using Compiler Sanitizers with Conan](https://docs.conan.io/2//examples/security/sanitizers.html.md) --- https://docs.conan.io/2/incubating.html.md --- # Incubating features This section is dedicated to new features that are under development, looking for user testing and feedback. They are generally behind a flag to enable them to be explicitly opted-in at this testing stage. They require the very latest Conan version (sometimes recommended running from the `develop2` source branch), and explicitly setting those flags. ## New CMakeConfigDeps generator This generator is not incubating anymore, but already generally available. See [CMakeConfigDeps generator](https://docs.conan.io/2//reference/tools/cmake/cmakeconfigdeps.html.md#conan-tools-cmakeconfigdeps) ## Workspaces Workspaces are not incubating anymore, but generally available as experimental. Moved to [Workspaces](https://docs.conan.io/2//tutorial/developing_packages/workspaces.html.md#tutorial-workspaces) ### Workspace files syntax Moved to [Workspace](https://docs.conan.io/2//reference/workspace.html.md#reference-workspace) ### Workspace commands Moved to [conan workspace](https://docs.conan.io/2//reference/commands/workspace.html.md#reference-commands-workspace) ### Workspace monolithic builds Moved to [Monolithic build](https://docs.conan.io/2//tutorial/developing_packages/workspaces.html.md#tutorial-workspaces-monolithic) For any feedback, please open new tickets in [https://github.com/conan-io/conan/issues](https://github.com/conan-io/conan/issues). --- https://docs.conan.io/2/index.html.md --- # Conan 2 - C and C++ Package Manager Documentation Welcome! This is the user documentation for Conan, an open source, decentralized C/C++ package manager that works in all platforms and with all build systems and compilers. Other relevant resources: - [Conan home page](https://conan.io). Entry point to the project, with links to docs, blog, social, downloads, release mailing list, etc. - [Github project and issue tracker](https://github.com/conan-io/conan). The main support channel, file issues here for questions, bug reports and feature requests. Table of contents: * [Introduction](https://docs.conan.io/2//introduction.html.md) * [Installation](https://docs.conan.io/2//installation.html.md) * [Tutorial](https://docs.conan.io/2//tutorial.html.md) * [Consuming packages](https://docs.conan.io/2//tutorial/consuming_packages.html.md) * [Creating packages](https://docs.conan.io/2//tutorial/creating_packages.html.md) * [Working with Conan repositories](https://docs.conan.io/2//tutorial/conan_repositories.html.md) * [Developing packages locally](https://docs.conan.io/2//tutorial/developing_packages.html.md) * [Versioning](https://docs.conan.io/2//tutorial/versioning.html.md) * [Other important Conan features](https://docs.conan.io/2//tutorial/other_features.html.md) * [CI Tutorial](https://docs.conan.io/2//ci_tutorial/tutorial.html.md) * [Project setup](https://docs.conan.io/2//ci_tutorial/project_setup.html.md) * [Packages pipeline](https://docs.conan.io/2//ci_tutorial/packages_pipeline.html.md) * [Products pipeline](https://docs.conan.io/2//ci_tutorial/products_pipeline.html.md) * [Devops guide](https://docs.conan.io/2//devops/devops.html.md) * [Using ConanCenter packages in production environments](https://docs.conan.io/2//devops/using_conancenter.html.md) * [Local Recipes Index Repository](https://docs.conan.io/2//devops/devops_local_recipes_index.html.md) * [Backing up third-party sources with Conan](https://docs.conan.io/2//devops/backup_sources/sources_backup.html.md) * [Managing package metadata files](https://docs.conan.io/2//devops/metadata.html.md) * [Versioning](https://docs.conan.io/2//devops/versioning/versioning.html.md) * [Save and restore packages from/to the cache](https://docs.conan.io/2//devops/save_restore.html.md) * [Vendoring dependencies in Conan packages](https://docs.conan.io/2//devops/vendoring.html.md) * [Package promotions](https://docs.conan.io/2//devops/package_promotions.html.md) * [Checking package vulnerabilities](https://docs.conan.io/2//devops/audit.html.md) * [Package compression format](https://docs.conan.io/2//devops/compression.html.md) * [Security](https://docs.conan.io/2//security/security.html.md) * [Scanning dependencies with `conan audit`](https://docs.conan.io/2//security/audit.html.md) * [Software Bills of Materials (SBOM)](https://docs.conan.io/2//security/sboms.html.md) * [Security guidelines](https://docs.conan.io/2//security/guidelines.html.md) * [C, C++ Compiler Sanitizers](https://docs.conan.io/2//security/sanitizers.html.md) * [Integrations](https://docs.conan.io/2//integrations.html.md) * [CMake](https://docs.conan.io/2//integrations/cmake.html.md) * [CLion](https://docs.conan.io/2//integrations/clion.html.md) * [Visual Studio](https://docs.conan.io/2//integrations/visual_studio.html.md) * [Autotools](https://docs.conan.io/2//integrations/autotools.html.md) * [Bazel](https://docs.conan.io/2//integrations/bazel.html.md) * [Makefile](https://docs.conan.io/2//integrations/makefile.html.md) * [Xcode](https://docs.conan.io/2//integrations/xcode.html.md) * [Meson](https://docs.conan.io/2//integrations/meson.html.md) * [Emscripten](https://docs.conan.io/2//integrations/emscripten.html.md) * [Premake](https://docs.conan.io/2//integrations/premake.html.md) * [Android](https://docs.conan.io/2//integrations/android.html.md) * [JFrog](https://docs.conan.io/2//integrations/jfrog.html.md) * [ROS](https://docs.conan.io/2//integrations/ros.html.md) * [Python](https://docs.conan.io/2//integrations/python.html.md) * [GitHub](https://docs.conan.io/2//integrations/github.html.md) * [Community](https://docs.conan.io/2//integrations/community.html.md) * [Examples](https://docs.conan.io/2//examples.html.md) * [ConanFile methods examples](https://docs.conan.io/2//examples/conanfile.html.md) * [Conan extensions examples](https://docs.conan.io/2//examples/extensions.html.md) * [Conan recipe tools examples](https://docs.conan.io/2//examples/tools.html.md) * [Cross-building examples](https://docs.conan.io/2//examples/cross_build.html.md) * [Configuration files examples](https://docs.conan.io/2//examples/config_files.html.md) * [Graph examples](https://docs.conan.io/2//examples/graph.html.md) * [Developer tools and flows](https://docs.conan.io/2//examples/dev_flow.html.md) * [Conan commands examples](https://docs.conan.io/2//examples/commands.html.md) * [Conan runners examples](https://docs.conan.io/2//examples/runners.html.md) * [Conan security examples](https://docs.conan.io/2//examples/security.html.md) * [Reference](https://docs.conan.io/2//reference.html.md) * [Binary model](https://docs.conan.io/2//reference/binary_model.html.md) * [Commands](https://docs.conan.io/2//reference/commands.html.md) * [conanfile.py](https://docs.conan.io/2//reference/conanfile.html.md) * [conanfile.txt](https://docs.conan.io/2//reference/conanfile_txt.html.md) * [Conan Server](https://docs.conan.io/2//reference/conan_server.html.md) * [Configuration files](https://docs.conan.io/2//reference/config_files.html.md) * [Environment variables](https://docs.conan.io/2//reference/environment.html.md) * [Extensions](https://docs.conan.io/2//reference/extensions.html.md) * [Policies](https://docs.conan.io/2//reference/policies.html.md) * [Recipe tools](https://docs.conan.io/2//reference/tools.html.md) * [Runners](https://docs.conan.io/2//reference/runners.html.md) * [Workspace](https://docs.conan.io/2//reference/workspace.html.md) * [Knowledge](https://docs.conan.io/2//knowledge.html.md) * [Cheat sheet](https://docs.conan.io/2//knowledge/cheatsheet.html.md) * [Core guidelines](https://docs.conan.io/2//knowledge/guidelines.html.md) * [FAQ](https://docs.conan.io/2//knowledge/faq.html.md) * [Videos](https://docs.conan.io/2//knowledge/videos.html.md) * [JFrog Academy: Conan 2 Training](https://docs.conan.io/2//knowledge/academy.html.md) * [Community Resources](https://docs.conan.io/2//knowledge/community_resources.html.md) * [Incubating features](https://docs.conan.io/2//incubating.html.md) * [What’s new in Conan 2](https://docs.conan.io/2//whatsnew.html.md) * [Changelog](https://docs.conan.io/2//changelog.html.md) --- https://docs.conan.io/2/installation.html.md --- # Installation Conan can be installed on many operating systems. It has been extensively used and tested on Windows, Linux (different distros), macOS, and is also actively used in FreeBSD and Solaris SunOS. There are also several additional operating systems on which it has been reported to work. There are different ways to install Conan: 1. The preferred and **strongly recommended way to install Conan** is from PyPI, the Python Package Index, using the `pip` command. 2. Use a system installer, or create your own self-contained Conan executable, to not require Python on your system. 3. Running Conan from sources. ## Install with pip (recommended) To install latest Conan 2 version using `pip`, you need a Python >= 3.8 distribution installed on your machine. Modern Python distros come with pip pre-installed. However, if necessary you can install pip by following the instructions in [pip docs](https://pip.pypa.io/en/stable/installation/). Install Conan: ```bash $ pip install conan ``` #### IMPORTANT **Please READ carefully:** - Make sure that your **pip** installation matches your **Python (>= 3.8)** version. - On **Linux**, you may need **sudo** permissions to install Conan globally. - We strongly recommend using **virtualenvs** (virtualenvwrapper works great) for everything related to Python (check [https://virtualenvwrapper.readthedocs.io/en/stable/](https://virtualenvwrapper.readthedocs.io/en/stable/), or [https://pypi.org/project/virtualenvwrapper-win/](https://pypi.org/project/virtualenvwrapper-win/) on Windows). With Python 3, the built-in module `venv` can also be used instead (check [https://docs.python.org/3/library/venv.html](https://docs.python.org/3/library/venv.html)). If not using a **virtualenv** it is possible that conan dependencies will conflict with previously existing dependencies, especially if you are using Python for other purposes. - On **macOS**, especially the latest versions that may have **System Integrity Protection**, pip may fail. Try using virtualenvs, or install it to the Python user install directory with `$ pip install --user conan`. - Some Linux distros, such as Linux Mint, require a restart (shell restart, or logout/system if not enough) after installation, so Conan is found in the path. ### Known installation issues with pip When Conan is installed with **pip install --user conan**, a new directory is usually created for it. However, the directory is not appended automatically to the PATH and the **conan** commands do not work. This can usually be solved by restarting the session of the terminal or running the following command: > ```bash > $ source ~/.profile > ``` ### Update If installed via `pip`, your Conan version can be updated with: ```bash $ pip install conan --upgrade # Might need sudo or --user ``` The upgrade shouldn’t affect the installed packages or cache information. If the cache becomes inconsistent somehow, you may want to remove its content by deleting it (`/.conan2`). ## Install with pipx In certain scenarios, attempting to install with `pip` may yield the following error: ```bash error: externally-managed-environment x This environment is externally managed To install Python packages system-wide, try apt install python3-xyz, where xyz is the package you are trying to install. ... ``` This is because some modern Linux distributions have started marking their Python installations as “externally managed”, which means that the system’s package manager is responsible for managing Python packages. Installing packages globally or even in the user space can interfere with system operations and potentially break system tools (check [PEP-668](https://peps.python.org/pep-0668/) for more detailed information). For those cases, it’s recommended to use `pipx` to install Conan. `pipx` creates a virtual environment for each Python application, ensuring that dependencies do not conflict. The advantage is that it isolates Conan and its dependencies from the system Python and avoids potential conflicts with system packages while providing a clean environment for Conan to run. To install Conan with `pipx`: 1. Ensure `pipx` is installed on your system. If it isn’t, check the installation guidelines [in the pipx documentation](https://pipx.pypa.io/stable/installation/). For Debian-based distributions, you can install `pipx` using the system package manager: ```bash $ apt-get install pipx $ pipx ensurepath ``` (Note: The package name might vary depending on the distribution) 2. Restart your terminal and then install Conan using `pipx`: ```bash $ pipx install conan ``` 3. Now you can use Conan as you typically would. ## Use a system installer or create a self-contained executable There are a number of existing installers in [Conan downloads](https://conan.io/downloads) for macOS Homebrew, Debian, Windows, Arch Linux, that will not require a Python installation. We also distribute [Conan binaries](https://github.com/conan-io/conan/releases/latest) for Windows, Linux, and macOS in a compressed file that you can uncompress on your system and run directly. #### WARNING If you are using **macOS**, please be aware of the Gatekeeper feature that may quarantine the compressed binaries if downloaded directly using a web browser. To avoid this issue, download them using a tool such as curl, wget, or similar. If there is no installer for your platform, you can create your own Conan executable with the `pyinstaller.py` utility in the repo. This process is able to create a self-contained Conan executable that contains all it needs, including the Python interpreter, so it wouldn’t be necessary to have Python installed in the system. You can do it with: ```bash $ git clone https://github.com/conan-io/conan conan_src $ cd conan_src $ pip install -e . $ python pyinstaller.py ``` It is important to install the dependencies and the project first with `pip install -e .` which configures the project as “editable”, that is, to run from the current source folder. After creating the executable, it can be uninstalled with pip. This has to run on the same platform that will be using the executable, pyinstaller does not cross-build. The resulting executable can be just copied and put in the system PATH of the running machine to be able to run Conan. ## Install from source You can run Conan directly from source code. First, you need to install Python and pip. Then, clone (or download and unzip) the Conan git repository and install it. For the latest development version, checkout the develop2 branch of the repository: ```bash # clone folder name matters, to avoid imports issues $ git clone https://github.com/conan-io/conan.git conan_src $ cd conan_src $ python -m pip install -e . ``` Now test your `conan` installation by running: ```bash $ conan ``` You should see the Conan commands help. --- https://docs.conan.io/2/integrations.html.md --- # Integrations Conan provides seamless integration with several platforms, build systems, and IDEs. Conan brings off-the-shelf support for some of the most important operating systems, including Windows, Linux, macOS, Android, and iOS. Some of the most important build systems supported by Conan include CMake, MSBuild, Meson, Autotools and Make. In addition to build systems, Conan also provides integration with popular IDEs, such as Visual Studio and Xcode. * [CMake](https://docs.conan.io/2//integrations/cmake.html.md) * [CLion](https://docs.conan.io/2//integrations/clion.html.md) * [Introduction](https://docs.conan.io/2//integrations/clion.html.md#introduction) * [Installing the plugin](https://docs.conan.io/2//integrations/clion.html.md#installing-the-plugin) * [Configuring the plugin](https://docs.conan.io/2//integrations/clion.html.md#configuring-the-plugin) * [Using the plugin](https://docs.conan.io/2//integrations/clion.html.md#using-the-plugin) * [Visual Studio](https://docs.conan.io/2//integrations/visual_studio.html.md) * [Recipe tools for Visual Studio](https://docs.conan.io/2//integrations/visual_studio.html.md#recipe-tools-for-visual-studio) * [Conan extension for Visual Studio](https://docs.conan.io/2//integrations/visual_studio.html.md#conan-extension-for-visual-studio) * [Autotools](https://docs.conan.io/2//integrations/autotools.html.md) * [Bazel](https://docs.conan.io/2//integrations/bazel.html.md) * [Makefile](https://docs.conan.io/2//integrations/makefile.html.md) * [Xcode](https://docs.conan.io/2//integrations/xcode.html.md) * [Meson](https://docs.conan.io/2//integrations/meson.html.md) * [Emscripten](https://docs.conan.io/2//integrations/emscripten.html.md) * [Premake](https://docs.conan.io/2//integrations/premake.html.md) * [Android](https://docs.conan.io/2//integrations/android.html.md) * [JFrog](https://docs.conan.io/2//integrations/jfrog.html.md) * [Artifactory Build Info](https://docs.conan.io/2//integrations/jfrog.html.md#artifactory-build-info) * [ROS](https://docs.conan.io/2//integrations/ros.html.md) * [Consuming Conan packages using the ROSEnv generator](https://docs.conan.io/2//integrations/ros.html.md#consuming-conan-packages-using-the-rosenv-generator) * [Bridging the Conan-provided transitive dependencies to another ROS package](https://docs.conan.io/2//integrations/ros.html.md#bridging-the-conan-provided-transitive-dependencies-to-another-ros-package) * [Python](https://docs.conan.io/2//integrations/python.html.md) * [conan-py-build](https://docs.conan.io/2//integrations/python.html.md#conan-py-build) * [PyEnv](https://docs.conan.io/2//integrations/python.html.md#pyenv) * [GitHub](https://docs.conan.io/2//integrations/github.html.md) * [Examples](https://docs.conan.io/2//integrations/github.html.md#examples) * [Community](https://docs.conan.io/2//integrations/community.html.md) --- https://docs.conan.io/2/introduction.html.md --- # Introduction Conan is a dependency and package manager for C and C++ languages. It is [free and open-source](https://github.com/conan-io/conan), works in all platforms (Windows, Linux, macOS, FreeBSD, Solaris, etc.), and can be used to develop for all targets including embedded, mobile (iOS, Android), and bare metal. It also integrates with all build systems like CMake, Visual Studio (MSBuild), Makefiles, SCons, etc., including proprietary ones. It is specifically designed and optimized for accelerating the development and Continuous Integration of C and C++ projects. With full binary management, it can create and reuse any number of different binaries (for different configurations like architectures, compiler versions, etc.) for any number of different versions of a package, using exactly the same process in all platforms. As it is decentralized, it is easy to run your own server to host your own packages and binaries privately, without needing to share them. The free [JFrog Artifactory Community Edition (CE)](https://conan.io/downloads.html) is the recommended Conan server to host your own packages privately under your control. Conan is mature and stable, with a strong commitment to forward compatibility (non-breaking policy), and has a complete team dedicated full time to its improvement and support. It is backed and used by a great community, from open source contributors and package creators in [ConanCenter](https://conan.io/center) to thousands of teams and companies using it. ## Open Source Conan is Free and Open Source, with a permissive MIT license. Check out the source code and issue tracking (for questions and support, reporting bugs and suggesting feature requests and improvements) at [https://github.com/conan-io/conan](https://github.com/conan-io/conan) ## Decentralized package manager Conan is a decentralized package manager with a client-server architecture. This means that clients can fetch packages from, as well as upload packages to, different servers (“remotes”), similar to the “git” push-pull model to/from git remotes. At a high level, the servers are just storing packages. They do not build nor create the packages. The packages are created by the client, and if binaries are built from sources, that compilation is also done by the client application. ![image](images/conan-systems.png) The different applications in the image above are: - The Conan client: this is a console/terminal command-line application, containing the heavy logic for package creation and consumption. Conan client has a local cache for package storage, and so it allows you to fully create and test packages offline. You can also work offline as long as no new packages are needed from remote servers. - [JFrog Artifactory Community Edition (CE)](https://conan.io/downloads.html) is the recommended Conan server to host your own packages privately under your control. It is a free community edition of JFrog Artifactory for Conan packages, including a WebUI, multiple auth protocols (LDAP), Virtual and Remote repositories to create advanced topologies, a Rest API, and generic repositories to host any artifact. - The conan_server is a small server distributed together with the Conan client. It is a simple open-source implementation and provides basic functionality, but no WebUI or other advanced features. - [ConanCenter](https://conan.io/center) is a central public repository where the community contributes packages for popular open-source libraries like Boost, Zlib, OpenSSL, Poco, etc. ## Binary management One of the most powerful features of Conan is that it can create and manage pre-compiled binaries for any possible platform and configuration. By using pre-compiled binaries and avoiding repeated builds from source, it saves significant time for developers and Continuous Integration servers, while also improving the reproducibility and traceability of artifacts. A package is defined by a “conanfile.py”. This is a file that defines the package’s dependencies, sources, how to build the binaries from sources, etc. One package “conanfile.py” recipe can generate any arbitrary number of binaries, one for each different platform and configuration: operating system, architecture, compiler, build type, etc. These binaries can be created and uploaded to a server with the same commands in all platforms, having a single source of truth for all packages and not requiring a different solution for every different operating system. ![image](images/conan-binary_mgmt.png) Installation of packages from servers is also very efficient. Only the necessary binaries for the current platform and configuration are downloaded, not all of them. If the compatible binary is not available, the package can be built from sources in the client too. ## All platforms, all build systems and compilers Conan works on Windows, Linux (Ubuntu, Debian, Red Hat, ArchLinux, Raspbian), OSX, FreeBSD, and SunOS, and, as it is portable, it might work in any other platform that can run Python. It can target any existing platform: ranging from bare metal to desktop, mobile, embedded, servers, and cross-building. Conan works with any build system too. There are built-in integrations to support the most popular ones like CMake, Visual Studio (MSBuild), Autotools and Makefiles, Meson, SCons, etc., but it is not a requirement to use any of them. It is not even necessary that all packages use the same build system: each package can use their own build system, and depend on other packages using different build systems. It is also possible to integrate with any build system, including proprietary ones. Likewise, Conan can manage any compiler and any version. There are default definitions for the most popular ones: gcc, cl.exe, clang, apple-clang, intel, with different configurations of versions, runtimes, C++ standard library, etc. This model is also extensible to any custom configuration. ## Stable From Conan 2.0 and onwards, there is a commitment to stability, with the goal of not breaking user space while evolving the tool and the platform. This means: - Moving forward to following minor versions 2.1, 2.2, …, 2.X should never break existing recipes, packages or command line flows - If something is breaking, it will be considered a regression and reverted. - Bug fixes will not be considered breaking, recipes and packages relying on the incorrect behavior of such bugs will be considered already broken. - Only documented features in [https://docs.conan.io](https://docs.conan.io) are considered part of the public interface of Conan. Private implementation details, and everything not included in the documentation is subject to change. - The compatibility is always considered forward. New APIs, tools, methods, helpers can be added in following 2.X versions. Recipes and packages created with these features will be backwards incompatible with earlier Conan versions. - Only the latest released patch (major.minor.patch) of every minor version is supported and stable. There are some things that are not included in this commitment: - Public repositories, like **ConanCenter**, assume the use of the latest version of the Conan client, and using an older version may result in failure of packages and recipes created with a newer version of the client. It is recommended to use your own private repository to store your own copy of the packages for production, or as a secondary alternative, to use some locking mechanism to avoid possible disruption from packages in ConanCenter that are updated and require latest Conan version. - Configuration and automatic tools detection, like the detection of the default profile (`conan profile detect`) can and will change at any time. Users are encouraged to define their configurations in their own profiles files for repeatability. New versions of Conan might detect different default profiles. - Builtin default implementation of extension points as plugins or hooks can also change with every release. Users can provide their own ones for stability. - Output of packages templates with `conan new` can update at any time to use latest features. - The output streams stdout, stderr, i.e. the terminal output can change at any time. Do not parse the terminal output for automation. - Anything that is explicitly labeled as `experimental` or `preview` in the documentation, or in the Conan cli output. Read the section below for a detailed definition of these labels. - Anything that is labeled as `deprecated` in the documentation should not get new usages, as it will not get new fixes and it will be removed in the next major version. - Other tools and repositories outside of the Conan client Conan needs Python>=3.8 to run. Conan will deprecate support for Python versions 1 year after those versions have been declared End Of Life (EOL). If you have any question regarding Conan updates, stability, or any clarification about this definition of stability, please report in the documentation issue tracker: [https://github.com/conan-io/docs](https://github.com/conan-io/docs). ## Community Conan is being used in production by thousands of companies like TomTom, Audi, RTI, Continental, Plex, Electrolux and Mercedes-Benz and many thousands of developers around the world. But an essential part of Conan is that many of those users will contribute back, creating an amazing and helpful community: - The [https://github.com/conan-io/conan](https://github.com/conan-io/conan) project has around 8.6K stars in Github and counts with contributions from more than 400 different users (this is just the client tool). - Many other users contribute recipes for ConanCenter via the [https://github.com/conan-io/conan-center-index](https://github.com/conan-io/conan-center-index) repo, creating packages for popular Open Source libraries, contributing many thousands of Pull Requests per year. - More than two thousands Conan users hang around the [CppLang Slack #conan channel](https://cppalliance.org/slack/), and help responding to questions, discussing problems and approaches, making it one of the most active channels in the whole CppLang slack. - There is a Conan channel in [#include discord](https://www.includecpp.org/discord/). ## Navigating the documentation This documentation has very different sections: - The **tutorial** is an actual hands-on tutorial, with examples and real code, intended to be played sequentially from beginning to end, running the exercises in your own computer. There is a “narrative” to this section and the exercises might depend on some previous explanations and code - building on the previous example. This is the recommended approach for learning Conan. - The **examples** also contain hands-on, fully operational examples with code, aimed to explain some very specific feature, tool or behavior. They do not have a conducting thread, they should be navigated by topic. - The **reference** is the source of truth for the interfaces of every public command, class, method, helper, API and configuration file that can be used. It is not designed to be read fully, but to check for individual items when necessary. - The **knowledge** base contains things like the FAQ, a very important section about general guidelines, good practices and bad practices, videos from conference talks, etc. Features in this documentation might be labeled as: - **experimental**: This feature is released and can be used, but it is under active development and the interfaces, APIs or behavior might change as a result of evolution, and this will not be considered breaking. If you are interested in these features you are encouraged to try them and give feedback, because that is exactly what allows to stabilize them. - **preview**: When a feature is released in preview mode, this means it aims to be as final and stable as possible. Users are encouraged to use them, and the maintainers team will try not to break them unless necessary. But if necessary, they might change and break. - **deprecated**: This feature should no longer be used, and it will be fully removed in next major release. Other alternatives or approaches should be used instead of it, and if using it, migrating to the other alternatives should be done as soon as possible. They will not be maintained or get fixes. Everything else that is not labeled should be considered stable and won’t be broken, unless something that is declared a bugfix. Have any questions? Please check out our [FAQ section](https://docs.conan.io/2//knowledge/faq.html.md#faq) or write to us. --- https://docs.conan.io/2/knowledge.html.md --- # Knowledge * [Cheat sheet](https://docs.conan.io/2//knowledge/cheatsheet.html.md) * [Core guidelines](https://docs.conan.io/2//knowledge/guidelines.html.md) * [Good practices](https://docs.conan.io/2//knowledge/guidelines.html.md#good-practices) * [Forbidden practices](https://docs.conan.io/2//knowledge/guidelines.html.md#forbidden-practices) * [FAQ](https://docs.conan.io/2//knowledge/faq.html.md) * [ERROR: Missing prebuilt package](https://docs.conan.io/2//knowledge/faq.html.md#error-missing-prebuilt-package) * [ERROR: Invalid setting](https://docs.conan.io/2//knowledge/faq.html.md#error-invalid-setting) * [ERROR: AuthenticationException:](https://docs.conan.io/2//knowledge/faq.html.md#error-authenticationexception) * [ERROR: Obtaining different revisions in Linux and Windows](https://docs.conan.io/2//knowledge/faq.html.md#error-obtaining-different-revisions-in-linux-and-windows) * [Defining options for dependencies in conanfile.py recipes doesn’t work](https://docs.conan.io/2//knowledge/faq.html.md#defining-options-for-dependencies-in-conanfile-py-recipes-doesn-t-work) * [Getting version conflicts even when using version ranges](https://docs.conan.io/2//knowledge/faq.html.md#getting-version-conflicts-even-when-using-version-ranges) * [Conan is redirecting its output to stderr](https://docs.conan.io/2//knowledge/faq.html.md#conan-is-redirecting-its-output-to-stderr) * [Missing binary for a (tool) package that was just created with `conan create`](https://docs.conan.io/2//knowledge/faq.html.md#missing-binary-for-a-tool-package-that-was-just-created-with-conan-create) * [Using Conan with both corporate and public remotes (SSL certificates)](https://docs.conan.io/2//knowledge/faq.html.md#using-conan-with-both-corporate-and-public-remotes-ssl-certificates) * [Conan doesn’t skip failing remotes](https://docs.conan.io/2//knowledge/faq.html.md#conan-doesn-t-skip-failing-remotes) * [Videos](https://docs.conan.io/2//knowledge/videos.html.md) * [Using std::cpp 2026](https://docs.conan.io/2//knowledge/videos.html.md#using-std-cpp-2026) * [ACCU 2025](https://docs.conan.io/2//knowledge/videos.html.md#accu-2025) * [Using std::cpp 2025](https://docs.conan.io/2//knowledge/videos.html.md#using-std-cpp-2025) * [Using std::cpp 2024](https://docs.conan.io/2//knowledge/videos.html.md#using-std-cpp-2024) * [ACCU 2022](https://docs.conan.io/2//knowledge/videos.html.md#accu-2022) * [CppCon 2022](https://docs.conan.io/2//knowledge/videos.html.md#cppcon-2022) * [Meeting C++ 2023](https://docs.conan.io/2//knowledge/videos.html.md#meeting-c-2023) * [Using std::cpp 2021](https://docs.conan.io/2//knowledge/videos.html.md#using-std-cpp-2021) * [Meeting C++ online book & tool fair](https://docs.conan.io/2//knowledge/videos.html.md#meeting-c-online-book-tool-fair) * [JFrog Academy: Conan 2 Training](https://docs.conan.io/2//knowledge/academy.html.md) * [Conan 2 Essentials](https://docs.conan.io/2//knowledge/academy.html.md#conan-2-essentials) * [Conan 2 Advanced](https://docs.conan.io/2//knowledge/academy.html.md#conan-2-advanced) * [Community Resources](https://docs.conan.io/2//knowledge/community_resources.html.md) --- https://docs.conan.io/2/reference.html.md --- # Reference * [Binary model](https://docs.conan.io/2//reference/binary_model.html.md) * [How the `package_id` is computed](https://docs.conan.io/2//reference/binary_model/package_id.html.md) * [How settings and options of a recipe influence its package ID](https://docs.conan.io/2//reference/binary_model/settings_and_options.html.md) * [The effect of dependencies on `package_id`](https://docs.conan.io/2//reference/binary_model/dependencies.html.md) * [Extending the binary model](https://docs.conan.io/2//reference/binary_model/extending.html.md) * [Customizing the binary compatibility](https://docs.conan.io/2//reference/binary_model/custom_compatibility.html.md) * [Commands](https://docs.conan.io/2//reference/commands.html.md) * [conanfile.py](https://docs.conan.io/2//reference/conanfile.html.md) * [Attributes](https://docs.conan.io/2//reference/conanfile/attributes.html.md) * [Methods](https://docs.conan.io/2//reference/conanfile/methods.html.md) * [Running and output](https://docs.conan.io/2//reference/conanfile/running_and_output.html.md) * [conanfile.txt](https://docs.conan.io/2//reference/conanfile_txt.html.md) * [Conan Server](https://docs.conan.io/2//reference/conan_server.html.md) * [Configuration files](https://docs.conan.io/2//reference/config_files.html.md) * [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md) * [global_user.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#global-user-conf) * [Configuration precedence](https://docs.conan.io/2//reference/config_files/global_conf.html.md#configuration-precedence) * [Information about built-in confs](https://docs.conan.io/2//reference/config_files/global_conf.html.md#information-about-built-in-confs) * [profiles](https://docs.conan.io/2//reference/config_files/profiles.html.md) * [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md) * [remotes.json](https://docs.conan.io/2//reference/config_files/remotes.html.md) * [source_credentials.json](https://docs.conan.io/2//reference/config_files/source_credentials.html.md) * [credentials.json](https://docs.conan.io/2//reference/config_files/credentials.html.md) * [.conanrc](https://docs.conan.io/2//reference/config_files/conanrc.html.md) * [Environment variables](https://docs.conan.io/2//reference/environment.html.md) * [Extensions](https://docs.conan.io/2//reference/extensions.html.md) * [Python requires](https://docs.conan.io/2//reference/extensions/python_requires.html.md) * [Custom commands](https://docs.conan.io/2//reference/extensions/custom_commands.html.md) * [Custom Conan generators](https://docs.conan.io/2//reference/extensions/custom_generators.html.md) * [Python API](https://docs.conan.io/2//reference/extensions/python_api.html.md) * [Deployers](https://docs.conan.io/2//reference/extensions/deployers.html.md) * [Hooks](https://docs.conan.io/2//reference/extensions/hooks.html.md) * [Binary compatibility](https://docs.conan.io/2//reference/extensions/binary_compatibility.html.md) * [Profile plugin](https://docs.conan.io/2//reference/extensions/profile_plugin.html.md) * [Authorization plugins](https://docs.conan.io/2//reference/extensions/authorization_plugins.html.md) * [Command wrapper](https://docs.conan.io/2//reference/extensions/command_wrapper.html.md) * [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md) * [Compiler flags mapper plugin](https://docs.conan.io/2//reference/extensions/compiler_flags_plugin.html.md) * [Policies](https://docs.conan.io/2//reference/policies.html.md) * [Recipe tools](https://docs.conan.io/2//reference/tools.html.md) * [conan.tools.android](https://docs.conan.io/2//reference/tools/android.html.md) * [conan.tools.apple](https://docs.conan.io/2//reference/tools/apple.html.md) * [conan.tools.build](https://docs.conan.io/2//reference/tools/build.html.md) * [conan.tools.cmake](https://docs.conan.io/2//reference/tools/cmake.html.md) * [conan.tools.CppInfo](https://docs.conan.io/2//reference/tools/cpp_info.html.md) * [conan.tools.env](https://docs.conan.io/2//reference/tools/env.html.md) * [conan.tools.files](https://docs.conan.io/2//reference/tools/files.html.md) * [conan.tools.gnu](https://docs.conan.io/2//reference/tools/gnu.html.md) * [conan.tools.google](https://docs.conan.io/2//reference/tools/google.html.md) * [conan.tools.intel](https://docs.conan.io/2//reference/tools/intel.html.md) * [conan.tools.layout](https://docs.conan.io/2//reference/tools/layout.html.md) * [conan.tools.meson](https://docs.conan.io/2//reference/tools/meson.html.md) * [conan.tools.microsoft](https://docs.conan.io/2//reference/tools/microsoft.html.md) * [conan.tools.qbs](https://docs.conan.io/2//reference/tools/qbs.html.md) * [conan.tools.ros](https://docs.conan.io/2//reference/tools/ros.html.md) * [conan.tools.sbom](https://docs.conan.io/2//reference/tools/sbom.html.md) * [conan.tools.scm](https://docs.conan.io/2//reference/tools/scm.html.md) * [conan.tools.scons](https://docs.conan.io/2//reference/tools/scons.html.md) * [conan.tools.premake](https://docs.conan.io/2//reference/tools/premake.html.md) * [conan.tools.system](https://docs.conan.io/2//reference/tools/system.html.md) * [Runners](https://docs.conan.io/2//reference/runners.html.md) * [Docker runner](https://docs.conan.io/2//reference/runners/docker.html.md) * [Workspace](https://docs.conan.io/2//reference/workspace.html.md) --- https://docs.conan.io/2/tutorial.html.md --- # Tutorial The purpose of this section is to guide you through the most important Conan features with practical examples. From using libraries already packaged by Conan, to how to package your libraries and store them on a remote server alongside all the precompiled binaries. * [Consuming packages](https://docs.conan.io/2//tutorial/consuming_packages.html.md) * [Build a simple CMake project using Conan](https://docs.conan.io/2//tutorial/consuming_packages/build_simple_cmake_project.html.md) * [Using build tools as Conan packages](https://docs.conan.io/2//tutorial/consuming_packages/use_tools_as_conan_packages.html.md) * [Building for multiple configurations: Release, Debug, Static and Shared](https://docs.conan.io/2//tutorial/consuming_packages/different_configurations.html.md) * [Understanding the flexibility of using conanfile.py vs conanfile.txt](https://docs.conan.io/2//tutorial/consuming_packages/the_flexibility_of_conanfile_py.html.md) * [How to cross-compile your applications using Conan: host and build contexts](https://docs.conan.io/2//tutorial/consuming_packages/cross_building_with_conan.html.md) * [Introduction to versioning](https://docs.conan.io/2//tutorial/consuming_packages/intro_to_versioning.html.md) * [Creating packages](https://docs.conan.io/2//tutorial/creating_packages.html.md) * [Create your first Conan package](https://docs.conan.io/2//tutorial/creating_packages/create_your_first_package.html.md) * [Handle sources in packages](https://docs.conan.io/2//tutorial/creating_packages/handle_sources_in_packages.html.md) * [Add dependencies to packages](https://docs.conan.io/2//tutorial/creating_packages/add_dependencies_to_packages.html.md) * [Preparing the build](https://docs.conan.io/2//tutorial/creating_packages/preparing_the_build.html.md) * [Configure settings and options in recipes](https://docs.conan.io/2//tutorial/creating_packages/configure_options_settings.html.md) * [Build packages: the build() method](https://docs.conan.io/2//tutorial/creating_packages/build_packages.html.md) * [Package files: the package() method](https://docs.conan.io/2//tutorial/creating_packages/package_method.html.md) * [Define information for consumers: the package_info() method](https://docs.conan.io/2//tutorial/creating_packages/define_package_information.html.md) * [Testing Conan packages](https://docs.conan.io/2//tutorial/creating_packages/test_conan_packages.html.md) * [Other types of packages](https://docs.conan.io/2//tutorial/creating_packages/other_types_of_packages.html.md) * [Working with Conan repositories](https://docs.conan.io/2//tutorial/conan_repositories.html.md) * [Setting up a Conan remote](https://docs.conan.io/2//tutorial/conan_repositories/setting_up_conan_remotes.html.md) * [Uploading Packages](https://docs.conan.io/2//tutorial/conan_repositories/uploading_packages.html.md) * [Contributing to Conan Center](https://docs.conan.io/2//tutorial/conan_repositories/conan_center.html.md) * [Local Recipes Index Repository](https://docs.conan.io/2//tutorial/conan_repositories/setup_local_recipes_index.html.md) * [Developing packages locally](https://docs.conan.io/2//tutorial/developing_packages.html.md) * [Package Development Flow](https://docs.conan.io/2//tutorial/developing_packages/local_package_development_flow.html.md) * [Packages in editable mode](https://docs.conan.io/2//tutorial/developing_packages/editable_packages.html.md) * [Understanding the Conan Package layout](https://docs.conan.io/2//tutorial/developing_packages/package_layout.html.md) * [Workspaces](https://docs.conan.io/2//tutorial/developing_packages/workspaces.html.md) * [Versioning](https://docs.conan.io/2//tutorial/versioning.html.md) * [Versions](https://docs.conan.io/2//tutorial/versioning/versions.html.md) * [Version ranges](https://docs.conan.io/2//tutorial/versioning/version_ranges.html.md) * [Revisions](https://docs.conan.io/2//tutorial/versioning/revisions.html.md) * [Lockfiles](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md) * [Dependencies conflicts](https://docs.conan.io/2//tutorial/versioning/conflicts.html.md) * [Other important Conan features](https://docs.conan.io/2//tutorial/other_features.html.md) * [python_requires](https://docs.conan.io/2//tutorial/other_features.html.md#python-requires) * [Packages lists](https://docs.conan.io/2//tutorial/other_features.html.md#packages-lists) * [Removing unused packages from the cache](https://docs.conan.io/2//tutorial/other_features.html.md#removing-unused-packages-from-the-cache) #### NOTE The **Conan 2 Essentials** and **Conan 2 Advanced** training paths are available for free at the JFrog Academy. They cover the same topics as this documentation in a more interactive way. [Conan 2 Essentials](https://academy.jfrog.com/path/conan-cc-package-manager?utm_source=Conan+Docs) | [Conan 2 Advanced](https://academy.jfrog.com/path/conan-2-advanced?utm_source=Conan+Docs) | See [JFrog Academy: Conan 2 Training](https://docs.conan.io/2//knowledge/academy.html.md#academy) for the full course overview. --- https://docs.conan.io/2/whatsnew.html.md --- # What’s new in Conan 2 Conan 2 comes with many exciting improvements based on the lessons learned in the last years with Conan 1.X. Also, a lot of effort has been made to backport necessary things to Conan 1.X to make the upgrade easier: recipes using latest 1.X integrations will be compatible with Conan 2, and binaries for both versions will not collide and be able to live in the same server repositories. ## Conan 2 migration guide If you are using Conan 1.X, please read the [Conan 2 Migration guide](https://docs.conan.io/en/latest/conan_v2.html) to start preparing your package recipes for 2.0 and be aware of some changes while you still work in Conan 1.X. That guide summarizes the above mentioned backports to make the upgrade easier. ## New graph model Conan 2 defines new requirement traits (headers, libs, build, run, test, package_id_mode, options, transitive_headers, transitive_libs) and package types (static, shared, application, header-only) to better represent the relations that happen with C and C++ binaries, like executables or shared libraries linking static libraries or shared libraries. #### SEE ALSO - [https://www.youtube.com/watch?v=kKGglzm5ous](https://www.youtube.com/watch?v=kKGglzm5ous) - [https://github.com/conan-io/tribe/blob/main/design/026-requirements_traits.md](https://github.com/conan-io/tribe/blob/main/design/026-requirements_traits.md) - [https://github.com/conan-io/tribe/blob/main/design/027-package_types.md](https://github.com/conan-io/tribe/blob/main/design/027-package_types.md) ## New public Python API A new modular Python API is made available, public and documented. This is a real API, with building blocks that are already used to build the Conan built-in commands, but that will allow further extensions. There are sub-APIs for different functional groups, like `api.list`, `api.search`, `api.remove`, `api.profile`, `api.graph`, `api.upload`, `api.remotes`, etc. that will allow to implement advanced user flows, functionality and automation. #### SEE ALSO - [Python API reference](https://docs.conan.io/2//reference/extensions/python_api.html.md#reference-python-api) ## New build system integrations Introduced in latest Conan 1.X, Conan 2 will use modern build system integrations like `CMakeDeps` and `CMakeToolchain` that are fully transparent CMake integrations (i.e. the consuming `CMakeLists.txt` doesn’t need to be aware at all about Conan). These integrations can also achieve a better IDE integration, for example via CMakePresets.json. #### SEE ALSO - [Tools reference](https://docs.conan.io/2//reference/tools.html.md#conan-tools) ## New custom user commands Conan 2 allows extending Conan with custom user commands, written in Python that can be called as `conan xxxx`. These commands can be shared and installed with `conan config install`, and have layers of commands and subcommands. The custom user commands use the new 2.0 public Python API to implement their functionality. ## New CLI Conan 2 has redesigned the CLI for better consistency, removing ambiguities, and improving the user experience. The new CLI also sends all the information, warning, and error messages to stderr, while keeping the final result in stdout, allowing multiple output formats like `--format=html` or `--format=json` and using redirects to create files `--format=json > myfile.json`. The information provided by the CLI will be more structured and thorough so that it can be used more easily for automation, especially in CI/CD systems. #### SEE ALSO - [Commands reference](https://docs.conan.io/2//reference/commands.html.md#reference-commands) ## New deployers Conan 2 implements “deployers” which can be called on the command-line as `conan install …. --deployer=mydeploy`, typically to perform copy operations from the Conan cache to user folders. Such deployers can be built-in (“full_deploy”, “direct_deploy” and “runtime_deploy” are provided so far), or user-defined, which can be shared and managed with `conan config install`. Deployers run before generators, and they can change the target folders. For example, if the `--deployer=full_deploy` deployer runs before `CMakeDeps`, the files generated by `CMakeDeps` will point to the local copy in the user folder done by the `full_deploy` deployer, and not to the Conan cache. Deployers can be multi-configuration. Running `conan install . --deployer=full_deploy` repeatedly for different profiles, can achieve a fully self-contained project, including all the artifacts, binaries, and build files that is completely independent of Conan and no longer requires Conan at all to build. ## New package_id Conan 2 defines a new, dynamic `package_id` that is a great improvement over the limitations of Conan 1.X. This `package_id` will take into account the package types and types of requirements to implement a more meaningful strategy, depending on the scenario. For example, it is well known that when an application `myapp` is linking a static library `mylib`, any change in the binary of the static library `mylib` requires re-building the application `myapp`. So Conan will default to a mode like `full_mode` that will generate a new `myapp` `package_id`, for every change in the `mylib` recipe or binary. While a dependency between a static library `mylib_a` that is used by `mylib_b` in general does not imply that a change in `mylib_b` always needs a rebuild of `mylib_a`, and that relationship can default to a `minor_mode` mode. In Conan 2, the one doing modifications to `mylib_a` can better express whether the consumer `mylib_b` needs to rebuild or not, based on the version bump (patch version bump will not trigger a rebuild while a minor version bump will trigger it) Furthermore, the default versioning scheme in Conan has been generalized to any number of digits and letters, as opposed to the official “semver” that uses just 3 fields. ## compatibility.py Conan 2 features a new extension mechanism to define binary compatibility at a global level. A `compatibility.py` file in the Conan cache will be used to define which fallbacks of binaries should be used in case there is some missing binary for a given package. Conan will provide a default one to account for `cppstd` compatibility, and executables compatibility, but this extension is fully configurable by the user (and can also be shared and managed with `conan config install`). ## New lockfiles Lockfiles in Conan 2 have been greatly simplified and made way more flexible. Lockfiles are now modeled as lists of sorted references, which allow one single lockfile being used for multiple configurations, merging lockfiles, applying partially defined lockfiles, being strict or non-strict, adding user-defined constraints to lockfiles, and much more. #### SEE ALSO - [Tutorial introduction to lockfiles](https://docs.conan.io/2//tutorial/consuming_packages/intro_to_versioning.html.md#tutorial-consuming-packages-versioning-lockfiles) - [https://github.com/conan-io/tribe/blob/main/design/034-new_lockfiles.md](https://github.com/conan-io/tribe/blob/main/design/034-new_lockfiles.md) - [Tutorial about versioning and lockfiles](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles) ## New configuration and environment management The new configuration system called `[conf]` in profiles and command line, and introduced experimentally in Conan 1.X, is now the primary mechanism to configure and control Conan behavior. The idea is that the configuration system is used to transmit information from Conan (a Conan profile) to Conan (a Conan recipe, or a Conan build system integration like `CMakeToolchain`). This new configuration system can define strings, booleans, lists, and is cleaner and more structured and powerful than environment variables. A better, more explicit environment management, also introduced in Conan 1.X is now the way to pass information from Conan (profiles) to tools (like compilers, build systems). #### SEE ALSO - [Reference of environment tools](https://docs.conan.io/2//reference/tools/env.html.md#reference-tools-env) ## Multi-revision cache The Conan cache has been completely redesigned to allow storing more than one revision at a time. It has also shortened the paths, using hashes, removing the need to use `short_paths` in Windows. Note that the cache is still not concurrent, so parallel jobs or tasks should use independent caches. ## New extension plugins Several extension points, named “plugins” have been added, to provide advanced and typically orthogonal functionality to what the Conan recipes implement. These plugins can be shared, managed and installed via `conan config install` ### Profile checker A new `profile.py` extension point is provided that can be used to perform operations on the profile after it has been processed. A default implementation that checks that the given compiler version is capable of supporting the given compiler `cppstd` is provided, but this is fully customizable by the user. ### Command wrapper A new `cmd_wrapper.py` extension provides a way to wrap any `conanfile.py` command (i.e., anything that runs inside `self.run()` in a recipe), in a new command. This functionality can be useful for wrapping build commands in build optimization tools such as IncrediBuild or compile caches. ### Package signing A new `sign.py` extension has been added to implement signing and verifying of packages. With growing awareness about the importance of software supply chain security, the ability to sign and verify software packages is becoming more critical. This extension point will soon get a plugin implementation based on Sigstore. ## Package immutability optimizations The thorough use of `revisions` in Conan 2 (already introduced in Conan 1.X as opt-in in [https://docs.conan.io/en/latest/versioning/revisions.html](https://docs.conan.io/en/latest/versioning/revisions.html)), together with the declaration of artifacts **immutability** allows for improved processes when downloading, installing, updating and uploading dependencies. `Revisions` allow accurate traceability of artifacts, and thus allow better update flows. For example, it will be easier to get different binaries for different configurations from different repositories, as long as they were created from the same recipe revision. Package transfers, uploads and downloads will also be more efficient, based on `revisions`. As long as a given revision exists on the server or in the cache, Conan will not transfer artifacts at all for that package. ## Package lists Conan 2 allows bulk operations over multiple recipes and packages with the “Package Lists” feature. This feature allows to upload, download, remove and list multiple recipes and packages with one single command. Package lists can also be created from a dependency graph resulting from a `conan create` or `conan install` command, so it is possible to upload to a server all packages that belong to a given dependency graph by just chaining two commands. #### SEE ALSO - [Read the example usages](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists) - [Package lists blog post](https://blog.conan.io/2023/06/28/Conan-bulk-package-operations.html) ## Metadata files Conan 2 allows to store, upload, download and modify metadata files associated to recipes and packages. This feature can be very useful to manage build logs, test executables, test results, coverage data and various other files needed for traceability, compliance and business purposes. #### SEE ALSO - [Metadata files blog post](https://blog.conan.io/2023/10/24/Conan-launches-metadata-files.html) ## Third-party backup sources When building packages for third parties with sources in the internet, those sources can be removed or changed. The “backup sources” can automatically store a copy of those sources on your own server, so your builds are always fully reproducible, no matter what happens to the original internet sources. #### SEE ALSO - [Blog post about backup sources](https://blog.conan.io/2023/10/03/backup-sources-feature.html) ## Installing configuration from Conan packages From Conan 2.2, it is possible to install configuration not only from git repos and http servers, but also from Conan packages. Running `conan config install-pkg myconf/myversion` for a Conan package `myconf/myversion` stored on a Conan server, will install the configuration files inside that package. It also allows to use version ranges to update easily to the latest one within the range, and lockfiles to achieve reproducibility. #### SEE ALSO - [Read the conan config install-pkg command reference](https://docs.conan.io/2//reference/commands/config.html.md#reference-commands-conan-config-install-pkg) --- https://docs.conan.io/2/ci_tutorial/packages_pipeline.html.md --- # Packages pipeline The **packages pipeline** will build, create and upload the package binaries for the different configurations and platforms, when some developer is submitting some changes to one of the organization repositories source code. For example if a developer is doing some changes to the `ai` package, improving some of the library functionality, and bumping the version to `ai/1.1.0`. If the organization needs to support both Windows and Linux platforms, then the package pipeline will build the new `ai/1.1.0` both for Windows and Linux, before considering the changes are valid. If some of the configurations fail to build under a specific platform, it is common to consider the changes invalid and stop the processing of those changes, until the code is fixed. For the `package pipeline` we will start with a simple source code change in the `ai` recipe, simulating some improvements in the `ai` package, providing some better algorithms for our game. **Let’s do the following changes in the ai package**: - Let’s change the implementation of the `ai/src/ai.cpp` function and change the message from `Some Artificial` to `SUPER BETTER Artificial` - Let’s change the default `intelligence=0` value in `ai/include/ai.h` to a new `intelligence=50` default. - Finally, let’s bump the version. As we did some changes to the package public headers, it would be adviced to bump the `minor` version, so let\`s edit the `ai/conanfile.py` file and define `version = "1.1.0"` there (instead of the previous `1.0`). Note that if we did some breaking changes to the `ai` public API, the recommendation would be to change the major instead and create a new `2.0` version. The **packages pipeline** will take care of building the different packages binaries for the new `ai/1.1.0` and upload them to the `packages` binary repository to avoid disrupting or causing potential issues to other developers and CI jobs. If the pipeline succeed it will promote (copy) them to the `products` binary repository, and stop otherwise. There are different aspects that need to be taken into account when building these binary packages for `ai/1.1.0`. The following tutorial sections do the same job, but under different hypothesis. They are explained in increasing complexity. Note all of the commands can be found in the repository `run_example.py` file. This file is mostly intended for maintainers and testing, but it might be useful as a reference in case of issues. * [Package pipeline: single configuration](https://docs.conan.io/2//ci_tutorial/packages_pipeline/single_configuration.html.md) * [Package pipeline: multi configuration](https://docs.conan.io/2//ci_tutorial/packages_pipeline/multi_configuration.html.md) * [Package pipeline: multi configuration using lockfiles](https://docs.conan.io/2//ci_tutorial/packages_pipeline/multi_configuration_lockfile.html.md) --- https://docs.conan.io/2/ci_tutorial/products_pipeline.html.md --- # Products pipeline The **products pipeline** responds to a more challenging question: do my “products” build correctly with the new versions of the packages? to the packages and their dependencies? This is the real “Continuous Integration” part, in which changes in different packages are really tested against the organization important products to check if things integrate cleanly or break. Let’s continue with the example above, if we now have a new `ai/1.1.0` package, is it going to break the existing `game/1.0` and/or `mapviewer/1.0` applications? Is it necessary to re-build from source some of the existing packages that depend directly or indirectly on `ai` package? In this tutorial we use `game/1.0` and `mapviewer/1.0` as our “products”, but this concept will be further explained later, and specially why it is important to think in terms of “products” instead of trying to explicitly model the dependencies top-bottom in the CI. The essence of this **products pipeline** in our example is that the new `ai/1.1.0` version that was uploaded to the `products` repository automatically falls into the valid version ranges, and our versioning approach means that such a minor version increase will require building from source its consumers, in this case `engine/1.0` and `game/1.0` and in that specific sequential order, while all the other packages will remain the same. Knowing which packages need to be built from source and in which order, and executing that build to check if the main organization products keep working correctly with the new dependencies versions is the responsibility of the products pipeline. ## What are the **products** The **products** are the main software artifact that a organization (a company, a team, a project) is delivering as final result and provide some value for users of those artifacts. In this example we will consider `game/1.0` and `mapviewer/1.0` the “products”. Note that it is possible to define different versions of the same package as products, for example, if we had to maintain different versions of the `game` for different customers, we could have `game/1.0` and `game/2.3` as well as different versions of `mapviewer` as products. The “products” approach, besides the advantage of focusing on the business value, has another very important advantage: it avoids having to model the dependency graph at the CI layer. It is a frequent attempt trying to model the inverse dependency model, that is, representing at the CI level the dependants or consumers of a given package. In our example, if we had configured a job for building the `ai` package, we could have another job for the `engine` package, that is triggered after the `ai` one, configuring such topology somehow in the CI system. But this approach does not scale at all and have very important limitations: - The example above is relatively simple, but in practice dependency graphs can have many more packages, even several hundreds, making it very tedious and error prone to define all dependencies among packages in the CI - Dependencies evolve over time, and new versions are used, some dependencies are removed and newer dependencies are added. The simple relationship between repositories modeled at the CI level can result in a very inefficient, slow and time consuming CI, if not a fragile one that continuously breaks because some dependencies change. - The combinatorial nature that happens downstream a dependency graph, where a relatively stable top dependency, lets say `mathlib/1.0` might be used by multiple consumers such as `ai/1.0`, `ai/1.1`, `ai/1.2` which in turn each one might be used by multiple `engine` different versions and so on. Building only the latest version of the consumers would be insufficient in many cases and building all of them would be extremely costly. - The “inverse” dependency model, that is, asking what are the “dependants” of a given package is extremely challeging in practice, specially in a decentralized approach like Conan in which packages can be stored in different repositories, including different servers, and there isn’t a central database of all packages and their relations. Also, the “inverse” dependency model is, similar to the direct one, conditional. As a dependency can be conditional on any configuration (settings, options), the inverse is also conditioned to the same logic, and such logic also evolves and changes with every new revision and version. In C and C++ projects the “products” pipeline becomes more necessary and critical than in other languages due to the compilation model with headers textual inclusions becoming part of the consumers’ binary artifacts and due to the native artifacts linkage models. ## Building intermediate packages new binaries A frequently asked question is what would be the version of a consumer package when it builds against a new dependency version. Put it explicitly for our example, where we have defined that we need to build again the `engine/1.0` package because now it is depending on `ai/1.1.0` new version: - Should we create a new `engine/1.1` version to build against the new `ai/1.1.0`? - Or should we keep the `engine/1.0` version? The answer lies in the [binary model and how dependencies affect the package_id](https://docs.conan.io/2//reference/binary_model/dependencies.html.md#reference-binary-model-dependencies). Conan has a binary model that takes into account both the versions, revisions and `package_id` of the dependencies, as well as the different package types (`package_type` attribute). The recommendation is to keep the package versions aligned with the source code. If `engine/1.0` is building from a specific commit/tag of its source repository, and the source of that repository doesn’t change at all, then it becomes very confusing to have a changing package version that deviate from the source version. With the Conan binary model what we will have is 2 different binaries for `engine/1.0`, with 2 different `package_id`. One binary will be built against the `ai/1.0` version and the other binary will be built against the `ai/1.1.0`, something like: ```default $ conan list engine:* -r=develop engine/1.0 revisions fba6659c9dd04a4bbdc7a375f22143cb (2024-08-22 09:46:24 UTC) packages 2c5842e5aa3ed21b74ed7d8a0a637eb89068916e info settings ... requires ai/1.0.Z graphics/1.0.Z mathlib/1.0.Z de738ff5d09f0359b81da17c58256c619814a765 info settings ... requires ai/1.1.Z graphics/1.0.Z mathlib/1.0.Z ``` Let’s see how a product pipeline can build such `engine/1.0` and `game/1.0` new binaries using the new dependencies versions. In the following sections we will present a products pipeline in an incremental way, the same as the packages pipeline. * [Products pipeline: single configuration](https://docs.conan.io/2//ci_tutorial/products_pipeline/single_configuration.html.md) * [Products pipeline: the build-order](https://docs.conan.io/2//ci_tutorial/products_pipeline/build_order.html.md) * [Products pipeline: multi-product multi-configuration builds](https://docs.conan.io/2//ci_tutorial/products_pipeline/multi_product.html.md) * [Products pipeline: distributed full pipeline with lockfiles](https://docs.conan.io/2//ci_tutorial/products_pipeline/full_pipeline.html.md) --- https://docs.conan.io/2/ci_tutorial/project_setup.html.md --- # Project setup The code necessary for this tutorial is found in the `examples2` repo, clone it and move to the folder: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/ci/game ``` ## Server repositories setup We need 3 different repositories in the same server. Make sure to have an Artifactory running and available. You can download the free [Artifactory CE](https://docs.conan.io/2//tutorial/conan_repositories/setting_up_conan_remotes/artifactory/artifactory_ce_cpp.html.md#artifactory-ce-cpp) from the [downloads page](https://conan.io/downloads.html) and run it in your own computer, or you can use docker: ```bash $ docker run --name artifactory -d -p 8081:8081 -p 8082:8082 releases-docker.jfrog.io/jfrog/artifactory-cpp-ce:7.63.12 # Can be stopped with "docker stop artifactory" ``` When you launch it, you can go to [http://localhost:8082/](http://localhost:8082/) to check it (user: “admin”, password: “password”). If you have another available Artifactory, it can be used too if you can create new repositories there. As a first step, log into the web UI and **create 3 different local repositories** called `develop`, `packages` and `products`. Then according to the `project_setup.py` file, these are the necessary environment variables to configure the server. Please define `ARTIFACTORY_URL`, `ARTIFACTORY_USER` and/or `ARTIFACTORY_PASSWORD` if necessary to adapt to your setup: ```python # TODO: This must be configured by users SERVER_URL = os.environ.get("ARTIFACTORY_URL", "http://localhost:8081/artifactory/api/conan") USER = os.environ.get("ARTIFACTORY_USER", "admin") PASSWORD = os.environ.get("ARTIFACTORY_PASSWORD", "password") ``` ## Initial dependency graph #### WARNING - The initialization of the project will remove the contents of the 3 `develop`, `products` and `packages` repositories in the server. - The `examples2/ci/game` folder contains a `.conanrc` file that defines a local cache, so commands executed in this tutorial do not pollute or alter your main Conan cache. ```bash $ python project_setup.py ``` This will do several tasks, clean the server repos, create initial `Debug` and `Release` binaries for the dependency graph and upload them to the `develop` repo, then clean the local cache. Note in this example we are using `Debug` and `Release` as our different configurations for convenience, but in real cases these would be different configurations such as Windows/X86_64, Linux/x86_64, Linux/armv8, etc., running in different computers. After the setup, it can be checked that the 3 remotes are defined, but only `develop` remote is enabled, and there are no packages in the local cache: ```bash $ conan remote list products: http://localhost:8081/artifactory/api/conan/products [Verify SSL: True, Enabled: False] develop: http://localhost:8081/artifactory/api/conan/develop [Verify SSL: True, Enabled: True] packages: http://localhost:8081/artifactory/api/conan/packages [Verify SSL: True, Enabled: False] $ conan list * Found 0 pkg/version recipes matching * in local cache Local Cache WARN: There are no matching recipe references ``` #### IMPORTANT The order of the remotes is important. If the `products` repository is enabled, it will have higher priority than the `develop` one, so if it contains new versions, they will be picked from there. This dependency graph of packages in the `develop` repo is the starting point for our tutorial, assumed as a functional and stable “develop” state of the project that developers can `conan install` to work in any of the different packages. --- https://docs.conan.io/2/ci_tutorial/tutorial.html.md --- # Continuous Integration (CI) tutorial #### NOTE - This is an advanced topic, previous knowledge of Conan is necessary. Please [read and practice the user tutorial](https://docs.conan.io/2//tutorial.html.md#tutorial) first. - This section is intended for devops and build engineers designing and implementing a CI pipeline involving Conan packages, if it is not the case, you can skip this section. - There is a conference talk [Continuous Integration for Large Scale C/C++ Projects With Conan2 at ACCU-2025](https://docs.conan.io/2//knowledge/videos.html.md#accu2025) that is based in this tutorial, that might provide some extra information and some implementation details. Continuous Integration has different meanings for different users and organizations. In this tutorial we will cover the scenarios when users are doing changes to the source code of their packages and want to automatically build new binaries for those packages and also compute if those new package changes integrate cleanly or break the organization main products. In this tutorial we will use this small project that uses several packages (static libraries by default) to build a couple of applications, a video game and a map viewer utility. The `game` and `mapviewer` are our final “**products**”, what we distribute to our users: All of the packages in the dependency graph have a `requires` to its direct dependencies using version ranges, for example, `game` contains a `requires("engine/[>=1.0 <2]")` so new patch and minor versions of the dependencies will automatically be used without needing to modify the recipes. #### NOTE **Important notes** - This section is written as a hands-on tutorial. It is intended to be reproduced by copying the commands in your machine. - The tutorial presents some of the tools, good practices and common approaches to the CI problem. But there are no silver bullets. This tutorial is not the unique way that things should be done. Different organizations might have different needs and priorities, different build services power and budget, different sizes, etc. The principles and practices presented in the tutorial might need to be adapted. - If you have any questions or feedback, please submit a new issue in [https://github.com/conan-io/conan/issues](https://github.com/conan-io/conan/issues) - However some of the principles and best practices would be general for all approaches. Things like package immutability, using promotions between repositories and not using the `channel` for that purpose are good practices that should be followed. ## Packages and products pipelines When a developer is doing some changes to a package source code, we will consider 2 different parts or pipelines of the overall system CI: the **packages pipeline** and the **products pipeline** - The **packages pipeline** takes care of building one single package when its code is changed. If necessary it will build it for different configurations. - The **products pipeline** takes care of building the main organization “products” (the packages that implement the final applications or deliverables), and making sure that changes and new versions in dependencies integrate correctly, rebuilding any intermediate packages in the graph if necessary. The idea is that if some developer does changes to the `ai` package, producing a new `ai/1.1.0` version, the packages pipeline will first build this new version. But this new version might accidentally break or require rebuilding some consumer packages. If our organization main **products** are `game/1.0` and `mapviewer/1.0`, then the products pipeline can be triggered, in this case it would rebuild `engine/1.0` and `game/1.0` as they are affected by the change. ## Repositories and promotions The concept of multiple server side repositories is very important for CI. In this tutorial we will use 3 repositories: - `develop`: This repository is the main one that developers have configured in their machines to be able to `conan install` dependencies and work. As such it is expected to be quite stable, similar to a shared “develop” branch in git, and the repository should contain pre-compiled binaries for the organization’s pre-defined platforms, so developers and CI don’t need to do `--build=missing` and build again and again from source. - `packages`: This repository will be used to temporarily upload the packages built by the “packages pipeline”, to not upload them directly to the `develop` repo and avoid disruption until these packages are fully validated. - `products`: This repository will be used to temporarily upload the packages built by the “products pipeline”, while building and testing that new dependencies changes do not break the main “products”. Promotions are the mechanism used to make packages available from one pipeline to the other. Connecting the above packages and product pipelines with the repositories, there will be 2 promotions: - When all the different binaries for the different configurations have been built for a single package with the `packages pipeline`, and uploaded to the `packages` repository, the new version and changes to the package can be considered “correct” and promoted (copied) to the `products` repository. - When the `products pipeline` has built from source all the necessary packages that need a re-build because of the new package versions in the `products` repository and has checked that the organization “products” (such `game/1.0` and `mapviewer/1.0`) are not broken, then the packages can be promoted (copied) from the `products` repo to the `develop` repo, to make them available for all other developers and CI. #### NOTE - The concept of **immutability** is important in package management and devops. Modifying `channel` is strongly discouraged, see [Package promotions](https://docs.conan.io/2//devops/package_promotions.html.md#devops-package-promotions). - The versioning approach is important. This tutorial will be following [the default Conan versioning approach, see details here](https://docs.conan.io/2//devops/versioning/default.html.md#devops-versioning-default) This tutorial is just modeling the **development** flow. In production systems, there will be other repositories and promotions, like a `testing` repository for the QA team, and a final `release` repository for final users, such that packages can be promoted from `develop` to `testing` to `release` as they pass validation. Read more about promotions in [Package promotions](https://docs.conan.io/2//devops/package_promotions.html.md#devops-package-promotions). Let’s start with the tutorial, move to the next section to do the project setup: * [Project setup](https://docs.conan.io/2//ci_tutorial/project_setup.html.md) * [Server repositories setup](https://docs.conan.io/2//ci_tutorial/project_setup.html.md#server-repositories-setup) * [Initial dependency graph](https://docs.conan.io/2//ci_tutorial/project_setup.html.md#initial-dependency-graph) * [Packages pipeline](https://docs.conan.io/2//ci_tutorial/packages_pipeline.html.md) * [Package pipeline: single configuration](https://docs.conan.io/2//ci_tutorial/packages_pipeline/single_configuration.html.md) * [Package pipeline: multi configuration](https://docs.conan.io/2//ci_tutorial/packages_pipeline/multi_configuration.html.md) * [Package pipeline: multi configuration using lockfiles](https://docs.conan.io/2//ci_tutorial/packages_pipeline/multi_configuration_lockfile.html.md) * [Products pipeline](https://docs.conan.io/2//ci_tutorial/products_pipeline.html.md) * [What are the **products**](https://docs.conan.io/2//ci_tutorial/products_pipeline.html.md#what-are-the-products) * [Building intermediate packages new binaries](https://docs.conan.io/2//ci_tutorial/products_pipeline.html.md#building-intermediate-packages-new-binaries) --- https://docs.conan.io/2/ci_tutorial/packages_pipeline/multi_configuration.html.md --- # Package pipeline: multi configuration In the previous section we were building just 1 configuration. This section will cover the case in which we need to build more than 1 configuration. We will use the `Release` and `Debug` configurations here for convenience, as it is easier to follow, but in real case these configurations will be more like Windows, Linux, OSX, building for different architectures, cross building, etc. Let’s begin cleaning our cache: ```bash $ conan remove "*" -c # Make sure no packages from last run ``` We will create the packages for the 2 configurations sequentially in our computer, but note these will typically run in different computers, so it is typical for CI systems to launch the builds of different configurations in parallel. ```bash $ cd ai # If you were not inside "ai" folder already $ conan create . --build="missing:ai/*" -s build_type=Release --format=json > graph.json $ conan list --graph=graph.json --graph-binaries=build --format=json > built.json $ conan remote enable packages $ conan upload -l=built.json -r=packages -c --format=json > uploaded_release.json $ conan remote disable packages ``` We have done a few changes and extra steps: - First step is similar to the one in the previous section, a `conan create`, just making it explicit our configuration `-s build_type=Release` for clarity, and capturing the output of the `conan create` in a `graph.json` file. - The second step is create from the `graph.json` a `built.json` **package list** file, with the packages that needs to be uploaded, in this case, only the packages that have been built from source (`--graph-binaries=build`) will be uploaded. This is done for efficiency and faster uploads. - Third step is to enable the `packages` repository. It was not enabled to guarantee that all possible dependencies came from `develop` repo only. - Then, we will upload the `built.json` package list to the `packages` repository, creating the `uploaded_release.json` package list with the new location of the packages (the server repository). - Finally, we will disable again the `packages` repository Likewise, the Debug build will do the same steps: ```bash $ conan create . --build="missing:ai/*" -s build_type=Debug --format=json > graph.json $ conan list --graph=graph.json --graph-binaries=build --format=json > built.json $ conan remote enable packages $ conan upload -l=built.json -r=packages -c --format=json > uploaded_debug.json $ conan remote disable packages ``` When both Release and Debug configuration finish successfully, we would have these packages in the repositories: When all the different binaries for `ai/1.1.0` have been built correctly, the `package pipeline` can consider its job succesfull and decide to promote those binaries. But further package builds and checks are necessary, so instead of promoting them to the `develop` repository, the `package pipeline` can promote them to the `products` binary repository. As all other developers and CI use the `develop` repository, no one will be broken at this stage either: ```bash # aggregate the package list $ conan pkglist merge -l uploaded_release.json -l uploaded_debug.json --format=json > uploaded.json $ conan remote enable packages $ conan remote enable products # Promotion using Conan download/upload commands # (slow, can be improved with art:promote custom command) $ conan download --list=uploaded.json -r=packages --format=json > promote.json $ conan upload --list=promote.json -r=products -c $ conan remote disable packages $ conan remote disable products ``` The first step uses the `conan pkglist merge` command to merge the package lists from the “Release” and “Debug” configurations and merge it into a single `uploaded.json` package list. This list is the one that will be used to run the promotion. In this example we are using a slow `conan download` + `conan upload` promotion. This can be way more efficient with the `conan art:promote` extension command. After running the promotion we will have the following packages in the server: To summarize: - We built 2 different configurations, `Release` and `Debug` (could have been Windows/Linux or others), and uploaded them to the `packages` repository. - When all package binaries for all configurations were successfully built, we promoted them from the `packages` to the `products` repository, to make them available for the `products pipeline`. - **Package lists** were captured in the package creation process and merged into a single one to run the promotion. There is still an aspect that we haven’t considered yet, the possibility that the dependencies of `ai/1.1.0` change during the build. Move to the next section to see how to use lockfiles to achieve more consistent multi-configuration builds. --- https://docs.conan.io/2/ci_tutorial/packages_pipeline/multi_configuration_lockfile.html.md --- # Package pipeline: multi configuration using lockfiles In the previous example, we built both `Debug` and `Release` package binaries for `ai/1.1.0`. In real world scenarios the binaries to build would be different platforms (Windows, Linux, embedded), different architectures, and very often it will not be possible to build them in the same machine, requiring different computers. The previous example had an important assumption: the dependencies of `ai/1.1.0` do not change at all during the building process. In many scenarios, this assumption will not hold, for example if there are any other concurrent CI jobs, and one succesfull job publishes a new `mathlib/1.1` version in the `develop` repo. Then it is possible that one build of `ai/1.1.0`, for example, the one running in the Linux servers starts earlier and uses the previous `mathlib/1.0` version as dependency, while the Windows servers start a bit later, and then their build will use the recent `mathlib/1.1` version as dependency. This is a very undesirable situation, having binaries for the same `ai/1.1.0` version using different dependencies versions. This can lead in later graph resolution problems, or even worse, get to the release with different behavior for different platforms. The way to avoid this discrepancy in dependencies is to force the usage of the same dependencies versions and revisions, something that can be done with [lockfiles](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles). Creating and applying lockfiles is relatively straightforward. The process of creating and promoting the configurations will be identical to the previous section, but just applying the lockfiles. ## Creating the lockfile Let’s make sure as usual that we start from a clean state: ```bash $ conan remove "*" -c # Make sure no packages from last run ``` Then we can create the lockfile `conan.lock` file: ```bash # Capture a lockfile for the Release configuration $ conan lock create . -s build_type=Release --lockfile-out=conan.lock # extend the lockfile so it also covers the Debug configuration # in case there are Debug-specific dependencies $ conan lock create . -s build_type=Debug --lockfile=conan.lock --lockfile-out=conan.lock ``` Note that different configurations, using different profiles or settings could result in different dependency graphs. A lockfile file can be used to lock the different configurations, but it is important to iterate the different configurations/profiles and capture their information in the lockfile. #### NOTE The `conan.lock` is the default argument, and if a `conan.lock` file exists, it might be automatically used by `conan install/create` and other graph commands. This can simplify many of the commands, but this tutorial is showing the full explicit commands for clarity and didactical reasons. The `conan.lock` file can be inspected, it will be something like: ```json { "version": "0.5", "requires": [ "mathlib/1.0#f2b05681ed843bf50d8b7b7bdb5163ea%1724319985.398" ], "build_requires": [], "python_requires": [], "config_requires": [] } ``` As we can see, it is locking the `mathlib/1.0` dependency version and revision. With the lockfile, creating the different configurations is exactly the same, but providing the `--lockfile=conan.lock` argument to the `conan create` step, it will guarantee that `mathlib/1.0#f2b05681ed843bf50d8b7b7bdb5163ea` will always be the exact dependency used, irrespective if there exist new `mathlib/1.1` versions or new revisions available. The following builds could be launched in parallel but executed at different times, and still they will always use the same `mathlib/1.0` dependency: ```bash $ cd ai # If you were not inside "ai" folder already $ conan create . --build="missing:ai/*" --lockfile=conan.lock -s build_type=Release --format=json > graph.json $ conan list --graph=graph.json --graph-binaries=build --format=json > built.json $ conan remote enable packages $ conan upload -l=built.json -r=packages -c --format=json > uploaded_release.json $ conan remote disable packages ``` ```bash $ conan create . --build="missing:ai/*" --lockfile=conan.lock -s build_type=Debug --format=json > graph.json $ conan list --graph=graph.json --graph-binaries=build --format=json > built.json $ conan remote enable packages $ conan upload -l=built.json -r=packages -c --format=json > uploaded_debug.json $ conan remote disable packages ``` Note the only modification to the previous example is the addition of `--lockfile=conan.lock`. The promotion will also be identical to the previous one: ```bash # aggregate the package list $ conan pkglist merge -l uploaded_release.json -l uploaded_debug.json --format=json > uploaded.json $ conan remote enable packages $ conan remote enable products # Promotion using Conan download/upload commands # (slow, can be improved with art:promote custom command) $ conan download --list=uploaded.json -r=packages --format=json > promote.json $ conan upload --list=promote.json -r=products -c $ conan remote disable packages $ conan remote disable products ``` And the final result will be the same as in the previous section, but this time just with the guarantee that both `Debug` and `Release` binaries were built using exactly the same `mathlib` version: Now that we have the new `ai/1.1.0` binaries in the `products` repo, we can consider the `packages pipeline` finished and move to the next section, and build and check our products to see if this new `ai/1.1.0` version integrates correctly. --- https://docs.conan.io/2/ci_tutorial/packages_pipeline/single_configuration.html.md --- # Package pipeline: single configuration We will start with the most simple case, in which we only had to build 1 configuration, and that configuration can be built in the current CI machine. As we described before while presenting the different server binary repositories, the idea is that package builds will use by default the `develop` repo only, which is considered the stable one for developer and CI jobs. This pipeline starts from a clean state, with no packages in the cache, and only the `develop` repository enabled. With this configuration the CI job could just do: ```bash $ cd ai $ conan create . --build="missing:ai/*" ... ai/1.1.0: SUPER BETTER Artificial Intelligence for aliens (Release)! ai/1.1.0: Intelligence level=50 ``` Note the `--build="missing:ai/*"` might not be fully necessary in some cases, but it can save time in other situations. For example, if the developer did some changes just to the repo README, and didn’t bump the version at all, Conan will not generate a new `recipe revision`, and detect this as a no-op, avoiding having to unnecessarily rebuild binaries from source. If we are in a single-configuration scenario and it built correctly, for this simple case we don’t need a promotion, and just uploading directly the built packages to the `products` repository will be enough, where the `products pipeline` will pick it later. ```bash # We don't want to disrupt developers or CI, upload to products $ conan remote enable products $ conan upload "ai*" -r=products -c $ conan remote disable products ``` As the cache was initially clean, all `ai` packages would be the ones that were built in this pipeline. This was a very simple scenario, let’s move to a more realistic one: having to build more than one configuration. --- https://docs.conan.io/2/ci_tutorial/products_pipeline/build_order.html.md --- # Products pipeline: the build-order The previous section used `--build=missing` to build all the necessary packages in the same CI machine. This is not always desired, or even possible, and in many situations it is preferable to do a distributed build, to achieve faster builds and better usage the CI resources. The most natural distribution of the build load is to build different packages in different machines. Let’s see how this is possible with the `conan graph build-order` command. Let’s start as usual making sure we have a clean environment with the right repositories defined: ```bash # First clean the local "build" folder $ pwd # should be /examples2/ci/game $ rm -rf build # clean the temporary build folder $ mkdir build && cd build # To put temporary files $ conan remove "*" -c # Make sure no packages from last run # NOTE: The products repo is first, it will have higher priority. $ conan remote enable products ``` We will obviate by now the `mapviewer/1.0` product and focus this section in the `game/1.0` product. The first step is to compute the “build-order”, that is, the list of packages that need to be built, and in what order. This is done with the following `conan graph build-order` command: ```bash $ conan graph build-order --requires=game/1.0 --build=missing --order-by=recipe --reduce --format=json > game_build_order.json ``` Note a few important points: - It is necessary to use the `--build=missing`, in exactly the same way than in the previous section. Failing to provide the intended `--build` policy and argument will result in incomplete or erroneous build-orders. - The `--reduce` argument eliminates all elements in the resulting order that don’t have the `binary: Build` policy. This means that the resulting “build-order” cannot be merged with other build order files for aggregating them into a single one, which is important when there are multiple configurations and products. - The `--order-by` argument allows to define different orders, by “recipe” or by “configuration”. In this case, we are using `--order-by=recipe` which is intended to parallelize builds per recipe, that means, that all possible different binaries for a given package like `engine/1.0` should be built first before any consumer of `engine/1.0` can be built. The resulting `game_build_order.json` looks like: ```json { "order_by": "recipe", "reduced": true, "order": [ [ { "ref": "engine/1.0#fba6659c9dd04a4bbdc7a375f22143cb", "packages": [ [ { "package_id": "de738ff5d09f0359b81da17c58256c619814a765", "binary": "Build", "build_args": "--requires=engine/1.0 --build=engine/1.0", } ] ] } ], [ { "ref": "game/1.0#1715574045610faa2705017c71d0000e", "depends": [ "engine/1.0#fba6659c9dd04a4bbdc7a375f22143cb" ], "packages": [ [ { "package_id": "bac7cd2fe1592075ddc715563984bbe000059d4c", "binary": "Build", "build_args": "--requires=game/1.0 --build=game/1.0", } ] ] } ] ] } ``` For convenience, in the same way that `conan graph info ... --format=html > graph.html` can generate a file with an HTML interactive dependency graph, the `conan graph build-order ... --format=html > build_order.html` can generate an HTML visual representation of the above json file: ![image](ci_tutorial/products_pipeline/build_order_simple.png) The resulting json contains an `order` element which is a list of lists. This arrangement is important, every element in the top list is a set of packages that can be built in parallel because they do not have any relationship among them. You can view this list as a list of “levels”, in level 0, there are packages that have no dependencies to any other package being built, in level 1 there are packages that contain dependencies only to elements in level 0 and so on. Then, the order of the elements in the outermost list is important and must be respected. Until the build of all the packages in one list item has finished, it is not possible to start the build of the next “level”. Using the information in the `graph_build_order.json` file, it is possible to execute the build of the necessary packages, in the same way that the previous section’s `--build=missing` did, but not directly managed by us. Taking the arguments from the json, the commands to execute would be: ```bash $ conan install --requires=engine/1.0 --build=engine/1.0 $ conan install --requires=game/1.0 --build=game/1.0 ``` We are executing these commands manually, but in practice, it would be a `for` loop in CI executing over the json output. We will see some Python code later for this. At this point we wanted to focus on the `conan graph build-order` command, but we haven’t really explained how the build is distributed. Also note that inside every element there is an inner list of lists, the `"packages"` section, for all the binaries that must be built for a specific recipe for different configurations. Let’s move now to see how a multi-product, multi-configuration build order can be computed. --- https://docs.conan.io/2/ci_tutorial/products_pipeline/full_pipeline.html.md --- # Products pipeline: distributed full pipeline with lockfiles This section will present the full and complete implementation of a multi-product, multi-configuration distributed CI pipeline. It will cover important implementation details: - Using lockfiles to guarantee a consistent and fixed set of dependencies for all configurations. - Uploading built packages to the `products` repository. - Capturing “package lists” and using them to run the final promotion. - How to iterate the “build-order” programmatically Let’s start as usual cleaning the local cache and defining the correct repos: ```bash # First clean the local "build" folder $ pwd # should be /examples2/ci/game $ rm -rf build # clean the temporary build folder $ mkdir build && cd build # To put temporary files $ conan remove "*" -c # Make sure no packages from last run # NOTE: The products repo is first, it will have higher priority. $ conan remote enable products ``` Similarly to what we did in the `packages pipeline` when we wanted to ensure that the dependencies are exactly the same when building the different configurations and products, the first necessary step is to compute a `conan.lock` lockfile that we can pass to the different CI build agents to enforce the same set of dependencies everywhere. This can be done incrementally for the different `products` and configurations, aggregating it in the final single `conan.lock` lockfile. This approach assumes that both `game/1.0` and `mapviewer/1.0` will be using the same versions and revisions of the common dependencies. ```bash $ conan lock create --requires=game/1.0 --lockfile-out=conan.lock $ conan lock create --requires=game/1.0 -s build_type=Debug --lockfile=conan.lock --lockfile-out=conan.lock $ conan lock create --requires=mapviewer/1.0 --lockfile=conan.lock --lockfile-out=conan.lock $ conan lock create --requires=mapviewer/1.0 -s build_type=Debug --lockfile=conan.lock --lockfile-out=conan.lock ``` #### NOTE Recall that the `conan.lock` arguments are mostly optional, as that is the default lockfile name. The first command can be typed as `conan lock create --requires=game/1.0`. Also, all commands, including `conan install`, if they find a existing `conan.lock` file they will use it automatically, without an explicit `--lockfile=conan.lock`. The commands in this tutorial are shown explicitly complete for completeness and didactical reasons. Then, we can compute the build order for each product and configuration. These commands are identical to the ones in the previous section, with the only difference of adding a `--lockfile=conan.lock` argument: ```bash $ conan graph build-order --requires=game/1.0 --lockfile=conan.lock --build=missing --order-by=recipe --format=json > game_release.json $ conan graph build-order --requires=game/1.0 --lockfile=conan.lock --build=missing -s build_type=Debug --order-by=recipe --format=json > game_debug.json $ conan graph build-order --requires=mapviewer/1.0 --lockfile=conan.lock --build=missing --order-by=recipe --format=json > mapviewer_release.json $ conan graph build-order --requires=mapviewer/1.0 --lockfile=conan.lock --build=missing -s build_type=Debug --order-by=recipe --format=json > mapviewer_debug.json ``` Likewise the `build-order-merge` command will be identical to the previous one. In this case, as this command doesn’t really compute a dependency graph, a `conan.lock` argument is not necessary, dependencies are not being resolved: ```bash $ conan graph build-order-merge --file=game_release.json --file=game_debug.json --file=mapviewer_release.json --file=mapviewer_debug.json --reduce --format=json > build_order.json ``` So far, this process has been almost identical to the previous section one, just with the difference of capturing and using a lockfile. Now, we will explain the “core” of the `products` pipeline: iterating the build-order and distributing the build, and gathering the resulting built packages. This would be an example of some Python code that performs the iteration sequentially (a real CI system would distribute the builds to different agents in parallel): ```python build_order = open("build_order.json", "r").read() build_order = json.loads(build_order) to_build = build_order["order"] pkg_lists = [] # to aggregate the uploaded package-lists for level in to_build: for recipe in level: # This could be executed in parallel ref = recipe["ref"] # For every ref, multiple binary packages are being built. # This can be done in parallel too. Often it is for different platforms # they will need to be distributed to different build agents for packages_level in recipe["packages"]: # This could be executed in parallel too for package in packages_level: build_args = package["build_args"] filenames = package["filenames"] build_type = "-s build_type=Debug" if any("debug" in f for f in filenames) else "" run(f"conan install {build_args} {build_type} --lockfile=conan.lock --format=json", file_stdout="graph.json") run("conan list --graph=graph.json --format=json", file_stdout="built.json") filename = f"uploaded{len(pkg_lists)}.json" run(f"conan upload -l=built.json -r=products -c --format=json", file_stdout=filename) pkg_lists.append(filename) ``` #### NOTE - This code is specific for the `--order-by=recipe` build-order, if chosing the `--order-by=configuration`, the json is different and it would require a different iteration. These are the tasks that the above Python code is doing: - For every `package` in the build-order, a `conan install --require= --build=` is issued, and the result of this command is stored in a `graph.json` file - The `conan list` command transform this `graph.json` into a package list called `built.json`. Note that this package list actually stores both the built packages and the necessary transitive dependencies. This is done for simplicity, as later these package lists will be used for running a promotion, and we also want to promote the dependencies such as `ai/1.1.0` that were built in the `packages pipeline` and not by this job. - The `conan upload` command uploads the package list to the `products` repo. Note that the `upload` first checks what packages already exist in the repo, avoiding costly transfers if they already exist. - The result of the `conan upload` command is captured in a new package list called `uploaded.json`, that we will accumulate later, that will serve for the final promotion. In practice this translates to the following commands (that you can execute to continue the tutorial): ```bash # engine/1.0 release $ conan install --requires=engine/1.0 --build=engine/1.0 --lockfile=conan.lock --format=json > graph.json $ conan list --graph=graph.json --format=json > built.json $ conan upload -l=built.json -r=products -c --format=json > uploaded1.json # engine/1.0 debug $ conan install --requires=engine/1.0 --build=engine/1.0 --lockfile=conan.lock -s build_type=Debug --format=json > graph.json $ conan list --graph=graph.json --format=json > built.json $ conan upload -l=built.json -r=products -c --format=json > uploaded2.json # game/1.0 release $ conan install --requires=game/1.0 --build=game/1.0 --lockfile=conan.lock --format=json > graph.json $ conan list --graph=graph.json --format=json > built.json $ conan upload -l=built.json -r=products -c --format=json > uploaded3.json # game/1.0 debug $ conan install --requires=game/1.0 --build=game/1.0 --lockfile=conan.lock -s build_type=Debug --format=json > graph.json $ conan list --graph=graph.json --format=json > built.json $ conan upload -l=built.json -r=products -c --format=json > uploaded4.json ``` After this step the newly built packages will be in the `products` repo and we will have 4 `uploaded1.json` - `uploaded4.json` files. Simplifying the different release and debug configurations, the state of our repositories would be something like: We can now accumulate the different `uploadedX.json` files into a single package list `uploaded.json` that contains everything: ```bash $ conan pkglist merge -l uploaded0.json -l uploaded1.json -l uploaded2.json -l uploaded3.json --format=json > uploaded.json ``` And finally, if everything worked well, and we consider this new set of versions and new package binaries is ready to be used by developers and other CI jobs, then we can run the final promotion from the `products` to the `develop` repository: ```bash # Promotion using Conan download/upload commands # (slow, can be improved with art:promote custom command) $ conan download --list=uploaded.json -r=products --format=json > promote.json $ conan upload --list=promote.json -r=develop -c ``` And our final `develop` repository state will be: This state of the `develop` repository will have the following behavior: - Developers installing `game/1.0` or `engine/1.0` will by default resolve to latest `ai/1.1.0` and use it. They will find pre-compiled binaries for the dependencies too, and they can continue developing using the latest set of dependencies. - Developers and CI that were using a lockfile that was locking `ai/1.0` version, will still be able to keep working with that dependency without anything breaking, as the new versions and package binaries do not break or invalidate the previous existing binaries. At this point, the question of what to do with the lockfile used in the Ci could arise. Note that the `conan.lock` now contains the `ai/1.1.0` version locked. There could be different strategies, like storing this lockfile in the “products” git repositories, making it easily available when developers checkout those repos. Note, however, that this lockfile matches the latest state of the `develop` repo, so developers checking out one of the “products” git repositories and doing a `conan install` against the `develop` server repository will naturally resolve to the same dependencies stored in the lockfile. It is a good idea to at least store this lockfile in any release bundle, if the “products” are bundled somehow (a installer, a debian/rpm/choco/etc package), to include or attach to this bundled release for the final users of the software, the lockfile used to produce it, so no matter what changes in development repositories, those lockfiles can be recovered from the release information later in time. ## Final remarks As commented in this CI tutorial introduction, this doesn’t pretend to be a silver bullet, a CI system that you can deploy as-is in your organization. This tutorial so far presents a “happy path” of a Continuous Integration process for developers, and how their changes in packages that are part of larger products can be tested and validated as part of those products. The focus of this CI tutorial is to introduce some important concepts, good practices and tools such as: - The importance of defining the organization “products”, the main deliverables that need to be checked and built against new dependencies versions created by developers. - How new dependencies versions of developers shouldn’t be uploaded to the main development repositories until validated, to not break other developers and CI jobs. - How multiple repositories can be used to build a CI pipeline that isolate non validated changes and new versions. - How large dependency graphs can be built efficiently in CI with the `conan graph build-order`, and how build-orders for different configurations and products can be merged together. - Why `lockfiles` are necessary in CI when there are concurrent CI builds. - The importance of versioning, and the role of `package_id` to re-build only what is necessary in large dependency graphs. - Not using `user/channel` as variable and dynamic qualifiers of packages that change across the CI pipeline, but using instead different server repositories. - Running package promotions (copies) across server repositories when new package versions are validated. There are still many implementation details, strategies, use cases, and error scenarios that are not covered in this tutorial yet: - How to integrate breaking changes of a package that requires a new breaking major version. - Different versioning strategies, using pre-releases, using versions or relying on recipe revisions in certain cases. - How lockfiles can be stored and used across different builds, if it is good to persist them and where. - Different branching and merging strategies, nightly builds, releases flows. We plan to extend this CI tutorial, including more examples and use cases. If you have any question or feedback, please create a ticket in [https://github.com/conan-io/conan/issues](https://github.com/conan-io/conan/issues). --- https://docs.conan.io/2/ci_tutorial/products_pipeline/multi_product.html.md --- # Products pipeline: multi-product multi-configuration builds In the previous section we computed a `conan graph build-order` with several simplifications, we didn’t take the `mapviewer` product into account, and we processed only 1 configuration. In real scenarios, it will be necessary to manage more than one product and the most common case is that there is more than one configuration for every product. If we build these different cases sequentially it will be much slower and inefficient, and if we try to build them in parallel there will easily be many duplicated and unnecessary builds of the same packages, wasting resources and even producing issues as race conditions or traceability problems. To avoid this issue, it is possible to compute a single unified “build-order” that aggregates all the different build-orders that are computed for the different products and configurations. Let’s start as usual cleaning the local cache and defining the correct repos: ```bash # First clean the local "build" folder $ pwd # should be /examples2/ci/game $ rm -rf build # clean the temporary build folder $ mkdir build && cd build # To put temporary files $ conan remove "*" -c # Make sure no packages from last run # NOTE: The products repo is first, it will have higher priority. $ conan remote enable products ``` Now, we will start computing the build-order for `game/1.0` for the 2 different configurations that we are building in this tutorial, debug and release: ```bash $ conan graph build-order --requires=game/1.0 --build=missing --order-by=recipe --format=json > game_release.json $ conan graph build-order --requires=game/1.0 --build=missing --order-by=recipe -s build_type=Debug --format=json > game_debug.json ``` These commands are basically the same as in the previous section, each one with a different configuration and creating a different output file `game_release.json` and `game_debug.json`. These files will be similar to the previous ones, but as we haven’t used the `--reduce` argument (this is important!) they will actually contain a “build-order” of all elements in the graph, even if only some contain the `binary: Build` definition, and others will contain other `binary: Download|Cache|etc`. Now, let’s compute the build-order for `mapviewer/1.0`: ```bash $ conan graph build-order --requires=mapviewer/1.0 --build=missing --order-by=recipe --format=json > mapviewer_release.json $ conan graph build-order --requires=mapviewer/1.0 --build=missing --order-by=recipe -s build_type=Debug --format=json > mapviewer_debug.json ``` Note that in the generated `mapviewer_xxx.json` build-order files, there will be only 1 element for `mapviewer/1.0` that contains a `binary: Download`, because there is really no other package to be built, and as `mapviewer` is an application linked statically, Conan knows that it can “skip” its dependencies binaries. If we had used the `--reduce` argument we would have obtained an empty `order`. But this is not an issue, as the next final step will really compute what needs to be built. Let’s take all the 4 different “build-order” files (2 products x 2 configurations each), and merge them together: ```bash $ conan graph build-order-merge --file=game_release.json --file=game_debug.json --file=mapviewer_release.json --file=mapviewer_debug.json --reduce --format=json > build_order.json ``` Now we have applied the `--reduce` argument to produce a final `build_order.json` that is ready for distribution to the build agents and it only contains those specific packages that need to be built: ```json { "order_by": "recipe", "reduced": true, "order": [ [ { "ref": "engine/1.0#fba6659c9dd04a4bbdc7a375f22143cb", "packages": [ [ { "package_id": "de738ff5d09f0359b81da17c58256c619814a765", "filenames": ["game_release"], "build_args": "--requires=engine/1.0 --build=engine/1.0", }, { "package_id": "cbeb3ac76e3d890c630dae5c068bc178e538b090", "filenames": ["game_debug"], "build_args": "--requires=engine/1.0 --build=engine/1.0", } ] ] } ], [ { "ref": "game/1.0#1715574045610faa2705017c71d0000e", "packages": [ [ { "package_id": "bac7cd2fe1592075ddc715563984bbe000059d4c", "filenames": ["game_release"], "build_args": "--requires=game/1.0 --build=game/1.0", }, { "package_id": "01fbc27d2c156886244dafd0804eef1fff13440b", "filenames": ["game_debug"], "build_args": "--requires=game/1.0 --build=game/1.0", } ] ] } ] ], "profiles": { "game_release": {"args": ""}, "game_debug": {"args": "-s:h=\"build_type=Debug\""}, "mapviewer_release": {"args": ""}, "mapviewer_debug": {"args": "-s:h=\"build_type=Debug\""} } } ``` This build order summarizes the necessary builds. First it is necessary to build all different binaries for `engine/1.0`. This recipe contains 2 different binaries, one for Release and the other for Debug. These binaries belong to the same element in the `packages` list, which means they do not depend on each other and can be built in parallel. Each binary tracks its own original build-order file with `"filenames": ["game_release"],` so it is possible to deduce the necessary profiles to apply to it. The `build_order.json` file contains a `profiles` section that helps recovering the profile and settings command line arguments that were used to create the respective original build-order files. Then, after all binaries of `engine/1.0` have been built, it is possible to proceed to build the different binaries for `game/1.0`. It also contains 2 different binaries for its debug and release configurations, which can be built in parallel. In practice, this would mean something like: ```bash # This 2 could be executed in parallel # (in different machines, or different Conan caches) $ conan install --requires=engine/1.0 --build=engine/1.0 $ conan install --requires=engine/1.0 --build=engine/1.0 -s build_type=Debug # Once engine/1.0 builds finish, it is possible # to build these 2 binaries in parallel (in different machines or caches) $ conan install --requires=game/1.0 --build=game/1.0 $ conan install --requires=game/1.0 --build=game/1.0 -s build_type=Debug ``` In this section we have still omitted some important implementation details that will follow in next sections. The goal was to focus on the `conan graph build-order-merge` command and how different products and configurations can be merged in a single “build-order”. The next section will show with more details how this build-order can be really distributed in CI, using lockfiles to guarantee constant dependencies. --- https://docs.conan.io/2/ci_tutorial/products_pipeline/single_configuration.html.md --- # Products pipeline: single configuration In this section we will implement a very basic products pipeline, without distributing the build, without using lockfiles or building multiple configurations. The main idea is to illustrate the need to rebuild some packages because there is a new `ai/1.1.0` version that can be integrated by our main products. This new `ai` version is in the `products` repository, as it was already succesfully built by the “packages pipeline”. Let’s start by making sure we have a clean environment with the right repositories defined: ```bash # First clean the local "build" folder $ pwd # should be /examples2/ci/game $ rm -rf build # clean the temporary build folder $ mkdir build && cd build # To put temporary files # Now clean packages and define remotes $ conan remove "*" -c # Make sure no packages from last run # NOTE: The products repo is first, it will have higher priority. $ conan remote enable products ``` Recall that the `products` repo has higher priority than the `develop` repo. It means Conan will resolve first in the `products` repo, if it finds a valid version for the defined version ranges, it will stop there and return that version, without checking the `develop` repo (checking all repositories can be done with `--update`, but that would be slower and with the right repository ordering, it is not necessary). As we have already defined, our main products are `game/1.0` and `mapviewer/1.0`, let’s start by trying to install and use `mapviewer/1.0`: ```bash $ conan install --requires=mapviewer/1.0 ... Requirements graphics/1.0#24b395ba17da96288766cc83accc98f5 - Downloaded (develop) mapviewer/1.0#c4660fde083a1d581ac554e8a026d4ea - Downloaded (develop) mathlib/1.0#f2b05681ed843bf50d8b7b7bdb5163ea - Downloaded (develop) ... Install finished successfully # Activate the environment and run the executable # Use "conanbuild.bat && mapviewer" in Windows $ source conanrun.sh && mapviewer ... graphics/1.0: Checking if things collide (Release)! mapviewer/1.0:serving the game (Release)! ``` As we can see, `mapviewer/1.0` doesn’t really depend on `ai` package at all, not any version. So if we install it, we would already have a pre-compiled binary for it and everything works. But if we now try the same with `game/1.0`: ```bash $ conan install --requires=game/1.0 ... ======== Computing necessary packages ======== ... ERROR: Missing binary: game/1.0:bac7cd2fe1592075ddc715563984bbe000059d4c game/1.0: WARN: Cant find a game/1.0 package binary bac7cd2fe1592075ddc715563984bbe000059d4c for the configuration: ... [requires] ai/1.1.0#01a885b003190704f7617f8c13baa630 ``` It will fail, because it will get `ai/1.1.0` from the `products` repo, and there will be no pre-compiled binary for `game/1.0` against this new version of `ai`. This is correct, `ai` is a static library, so we need to re-build `game/1.0` against it, let’s do it using the `--build=missing` argument: ```bash $ conan install --requires=game/1.0 --build=missing ... ======== Computing necessary packages ======== Requirements ai/1.1.0:8b108997a4947ec6a0487a0b6bcbc0d1072e95f3 - Download (products) engine/1.0:de738ff5d09f0359b81da17c58256c619814a765 - Build game/1.0:bac7cd2fe1592075ddc715563984bbe000059d4c - Build graphics/1.0:8b108997a4947ec6a0487a0b6bcbc0d1072e95f3 - Download (develop) mathlib/1.0:4d8ab52ebb49f51e63d5193ed580b5a7672e23d5 - Download (develop) -------- Installing package engine/1.0 (4 of 5) -------- engine/1.0: Building from source ... engine/1.0: Package de738ff5d09f0359b81da17c58256c619814a765 created -------- Installing package game/1.0 (5 of 5) -------- game/1.0: Building from source ... game/1.0: Package bac7cd2fe1592075ddc715563984bbe000059d4c created Install finished successfully ``` Note the `--build=missing` knows that `engine/1.0` also needs a new binary as a result of its dependency to the new `ai/1.1.0` version. Then, Conan proceeds to build the packages in the right order, first `engine/1.0` has to be built, because `game/1.0` depends on it. After the build we can list the new built binaries and see how they depend on the new versions: ```bash $ conan list engine:* Local Cache engine engine/1.0 revisions fba6659c9dd04a4bbdc7a375f22143cb (2024-09-30 12:19:54 UTC) packages de738ff5d09f0359b81da17c58256c619814a765 info ... requires ai/1.1.Z graphics/1.0.Z mathlib/1.0.Z $ conan list game:* Local Cache game game/1.0 revisions 1715574045610faa2705017c71d0000e (2024-09-30 12:19:55 UTC) packages bac7cd2fe1592075ddc715563984bbe000059d4c info ... requires ai/1.1.0#01a885b003190704f7617f8c13baa630:8b108997a4947ec6a0487a0b6bcbc0d1072e95f3 engine/1.0#fba6659c9dd04a4bbdc7a375f22143cb:de738ff5d09f0359b81da17c58256c619814a765 graphics/1.0#24b395ba17da96288766cc83accc98f5:8b108997a4947ec6a0487a0b6bcbc0d1072e95f3 mathlib/1.0#f2b05681ed843bf50d8b7b7bdb5163ea:4d8ab52ebb49f51e63d5193ed580b5a7672e23d5 ``` The new `engine/1.0:de738ff5d09f0359b81da17c58256c619814a765` binary depends on `ai/1.1.Z`, because as it is a static library it will only require re-builds for changes in the minor version, but not patches. While the `game/1.0` new binary will depend on the full exact `ai/1.1.0#revision:package_id`, and also on the new `engine/1.0:de738ff5d09f0359b81da17c58256c619814a765` new binary that depends on `ai/1.1.Z`. Now the game can be executed: ```bash # Activate the environment and run the executable # Use "conanbuild.bat && game" in Windows $ source conanrun.sh && game mathlib/1.0: mathlib maths (Release)! ai/1.1.0: SUPER BETTER Artificial Intelligence for aliens (Release)! ai/1.1.0: Intelligence level=50 graphics/1.0: Checking if things collide (Release)! engine/1.0: Computing some game things (Release)! game/1.0:fun game (Release)! ``` We can see that the new `game/1.0` binary incorporates the improvements in `ai/1.1.0`, and links correctly with the new binary for `engine/1.0`. And this is a basic “products pipeline”, we manage to build and test our main products when necessary (recall that `mapviewer` wasn’t really affected, so no rebuilds were necessary at all). In general, a production “products pipeline” will finish uploading the built packages to the repository and running a new promotion to the `develop` repo. But as this was a very basic and simple pipeline, let’s wait a bit for that, and let’s continue with more advanced scenarios. --- https://docs.conan.io/2/devops/audit.html.md --- # Checking package vulnerabilities #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. The `conan audit` command (introduced in Conan 2.14.0) is used to check for known vulnerabilities in your Conan packages. By default, Conan provides access to a ConanCenter provider, which is a public provider that checks for vulnerabilities in ConanCenter packages, which uses JFrog Advanced Security to scan packages. ## Requesting a token To use the command, you will first need to register for the free service at [https://audit.conan.io/register](https://audit.conan.io/register). After registering, you will receive an email with an activation link. Clicking this link will take you to a page where your personal access token is displayed. Once you have your token, you can authenticate the `conancenter` provider with it: ```bash $ conan audit provider auth conancenter --token= ``` #### NOTE Using `--token` in the command line may expose your token in the shell history. To prevent this, set it as an environment variable named after the provider in uppercase. For example, for conancenter, use: `CONAN_AUDIT_PROVIDER_TOKEN_CONANCENTER=`. ## Scanning packages Once you have authenticated, you can check for vulnerabilities in your packages with the `conan audit scan` and `conan audit list` commands. > - `conan audit scan` will check for the vulnerabilities of the given package(s) and their dependencies. > - `conan audit list` will list the vulnerabilities of the given package(s) without checking their dependencies. ```bash $ conan audit list openssl/1.1.1w Requesting vulnerability info for: openssl/1.1.1w ****************** * openssl/1.1.1w * ****************** 2 vulnerabilities found: - CVE-2023-5678 (Severity: Medium, CVSS: 5.3) Issue summary: Generating excessively long X9.42 DH keys or checking excessively long X9.42 DH keys or parameters may be very slow. Impact summary: Applications that use the functions DH_generate_key() to generate an X9.42 DH key may exper... url: https://git.openssl.org/gitweb/?p=openssl.git;a=commitdiff;h=db925ae2e65d0d925adef429afc37f75bd1c2017 - CVE-2024-0727 (Severity: Medium, CVSS: 5.5) Issue summary: Processing a maliciously formatted PKCS12 file may lead OpenSSL to crash leading to a potential Denial of Service attack Impact summary: Applications loading files in the PKCS12 format from untrusted sources might terminate ... url: https://github.com/alexcrichton/openssl-src-rs/commit/add20f73b6b42be7451af2e1044d4e0e778992b2 Total vulnerabilities found: 2 Summary: - openssl/1.1.1w 2 vulnerabilities found Vulnerability information provided by JFrog. Please check https://jfrog.com/advanced-security/ for more information. You can send questions and report issues about the returned vulnerabilities to conan-research@jfrog.com. ``` To scan the entire dependency graph of a package, the simplest way is using the `conan audit scan` command and providing a path to your conanfile, just as you would do with other Conan commands such as `conan install`. For example, for a project with a conanfile.txt: ```ini [requires] libpng/1.5.30 openssl/1.1.1w ``` You can run: ```default $ conan audit scan . ``` Note that all of these commands support various output formats, such as JSON and HTML. ```default $ conan audit scan . -f=html > report.html ``` This generates an HTML report with the vulnerabilities found in the given package(s) and their dependencies, which will look something like: ![Conan audit report](images/devops/audit-report.png) The scan also has the threshold option `--severity-level`, which allows you to set a minimum severity level for the vulnerabilities. In case the threshold value is surpassed by any of the vulnerabilities found, the command will return a non-zero exit code. By default, it’s set to 9.0 (Critical), but you can set it to a lower value to include lower severity vulnerabilities in the report. To disable the threshold, set it to 100.0. ```default $ conan audit scan . --severity-level=5.0 ... The package openssl/1.1.1w has a CVSS score 5.3 and exceeded the threshold severity level 5.0. ``` ## Adding private providers You can add your own private providers to the list of providers used by the `conan audit` subcommands. For now, only JFrog Advanced Security providers are supported. #### NOTE To use these private providers, your Artifactory license should include a subscription to JFrog Curation To add a provider, the recommended way is to first create a specific user in Artifactory to use as the read-only user, which can be given no extra permissions. Then, after creating an access token for the user, you can add the provider with the following command: ```bash $ conan audit provider add myprovider --type=private --url=https://your.artifactory.url --token= ``` #### NOTE Instead of using the `--token` argument in the command line, which may expose your token in the shell history, you can authenticate with the provider using an environment variable. Set the `CONAN_AUDIT_PROVIDER_TOKEN_` environment variable with the token value, replacing with the provider name in uppercase and using underscores (\_) instead of hyphens (-). For example, for myprovider, use: `CONAN_AUDIT_PROVIDER_TOKEN_MYPROVIDER=`. Note the `--type=private` argument, which specifies that the provider is a private provider, and that the supplied URL should be the base URL of the Artifactory instance. You can now use the provider with the `conan audit scan` and `conan audit list` commands **without any limitation on the number of requests**, by specifying the provider name using the `-p` / `--provider` argument. ```default $ conan audit scan . -p=myprovider ``` #### SEE ALSO - For detailed reference documentation on all `conan audit` subcommands and their options, consult the [conan audit command reference](https://docs.conan.io/2//reference/commands/audit.html.md#reference-commands-audit). - Read more in the dedicated [blog post](https://blog.conan.io/introducing-conan-audit-command/). - Please check the [conan audit command reference](https://docs.conan.io/2//security/security.html.md#security) for other security related features. - Check out our [security conference in using std::cpp 2025](https://docs.conan.io/2//knowledge/videos.html.md#using-stdcpp2025-audit) for a deeper insight in package vulnerabilities. --- https://docs.conan.io/2/devops/compression.html.md --- # Package compression format Conan compresses different artifacts before uploading them to the servers for faster uploads and downloads, and lower storage needs. Specifically for C and C++ packages that could contain hundreds of different files, for example multiple header files, it is very inefficient to upload and store them one by one. For this reason Conan creates some compressed artifacts like `conan_export.tgz`, `conan_sources.tgz` and `conan_package.tgz`, for the recipe extra files, the exported sources and the final package binary respectively. These are the files that are uploaded to the servers, together with the `conanfile.py`, the `conanmanifest.txt` and the `conaninfo.txt` files. The compression happens when a locally created artifact is being uploaded with the `conan upload` command. If the recipe and package artifacts have been downloaded from the server, the compressed artifacts are cached and it is not necessary to compress them again. Furthermore, uploading them to a server that contains those artifacts will skip the actual upload transfer when the `revisions` match, or even avoid the transfer when uploading to a repository without the revision, but the file already exists in the server if the server has file de-duplication capabilities, like Artifactory. These artifacts are automatically extracted when a package is downloaded or installed. #### WARNING The different compressed artifacts are an internal implementation detail, and it is not allowed to manipulate, change, remove or alter them. Conan has traditionally used only the built-in `tgz` format to compress the artifacts, and allowed the `core.gzip:compresslevel` to select different compression levels (a tradeoff between speed and compression ratio). From Conan 2.25 it is possible to (experimentally) select other compression formats that might be more efficient. ## Using `xz` or `zstd` compression formats #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. From Conan 2.25 it is possible to choose between `gz`, `xz` and `zst` compression formats with the configuration: `core.upload:compression_format`. This configuration can be defined in the `global.conf` file. Recall that this file can also be distributed to all developers and CI machines easily with `conan config install/install-pkg`. The compressed artifacts will be named after the compression format, with extensions such as `conan_package.txz`, `conan_package.tzst` or `conan_package.tgz`. The `core:compresslevel` allows to select the compression level for the different algorithms. It supersedes the previous `core.gzip:compresslevel`. #### IMPORTANT The `zstd` compression is using Python>=3.14 built-in features. It requires then Python>=3.14, both for compressing and uploading, and for consuming recipes and packages that were compressed with `zstd`. Conan will fail with an error message in both cases if Python<3.14. Previous Conan versions (Conan<2.25), only understand `.tgz` artifacts and `gz` compression, and will fail to process artifacts compressed with other formats, Make sure that all your Conan clients have updated to >=2.25 before using this feature. --- https://docs.conan.io/2/devops/devops.html.md --- # Devops guide The previous [tutorial](https://docs.conan.io/2//tutorial.html.md#tutorial) section was aimed at users in general and developers. The [Continuous Integration tutorial](https://docs.conan.io/2//ci_tutorial/tutorial.html.md#ci-tutorial) explained the basics on how to implement Continuous Integration involving Conan packages. This section is intended for DevOps users, build and CI engineers, administrators, and architects adopting, designing and implementing Conan in production in their teams and organizations. If you plan to use Conan in production in your project, team, or organization, this section contains the necessary information. * [Using ConanCenter packages in production environments](https://docs.conan.io/2//devops/using_conancenter.html.md) * [Local Recipes Index Repository](https://docs.conan.io/2//devops/devops_local_recipes_index.html.md) * [Backing up third-party sources with Conan](https://docs.conan.io/2//devops/backup_sources/sources_backup.html.md) * [Managing package metadata files](https://docs.conan.io/2//devops/metadata.html.md) * [Versioning](https://docs.conan.io/2//devops/versioning/versioning.html.md) * [Save and restore packages from/to the cache](https://docs.conan.io/2//devops/save_restore.html.md) * [Vendoring dependencies in Conan packages](https://docs.conan.io/2//devops/vendoring.html.md) * [Package promotions](https://docs.conan.io/2//devops/package_promotions.html.md) * [Checking package vulnerabilities](https://docs.conan.io/2//devops/audit.html.md) * [Package compression format](https://docs.conan.io/2//devops/compression.html.md) --- https://docs.conan.io/2/devops/devops_local_recipes_index.html.md --- # Local Recipes Index Repository The **Local Recipes Index** is an **experimental** repository type introduced in Conan to enhance flexibility in managing C/C++ package recipes. This repository type allows users to use a local directory as a Conan remote, where the directory structure mirrors that of the conan-center-index GitHub repository. This setup is particularly useful for: - Building binaries from a private conan-center-index fork. - Sharing your own recipes for certain libraries or tools that, due to licensing restrictions or proprietary nature, are not suitable for ConanCenter. Check how you can use it for this purpose in the dedicated section of the documentation [Local Recipes Index Repository](https://docs.conan.io/2//tutorial/conan_repositories/setup_local_recipes_index.html.md#setup-local-recipes-index). ## Building Binaries from a private conan-center-index fork As we already introduced in the [previous section of the Conan DevOps Guide](https://docs.conan.io/2//devops/devops.html.md#devops) some organizations, particularly large enterprises, prefer not to use binaries downloaded from the internet. Instead, they build their own binaries in-house using the conan-center-index recipes. These organizations often need to customize these recipes to meet unique requirements that are not applicable to the broader community, making such contributions unsuitable for the upstream repository. The local-recipes-index allows users to maintain a local folder with the same structure as the conan-center-index GitHub repository, using it as a source for package recipes. This new type of repository is recipes-only, necessitating the construction of package binaries from source on each machine where the package is used. For sharing binaries across teams, we continue to recommend [using a Conan remote server like Artifactory](https://docs.conan.io/2//tutorial/conan_repositories/setting_up_conan_remotes/artifactory/artifactory_ce_cpp.html.md#artifactory-ce-cpp) for production purposes. ![image](images/devops/local-repo-general-flow-diagram.png) The local-recipes-index repository allows you to easily build binaries from a fork of conan-center-index, and then hosting them on a Conan remote repository like Artifactory. The main difference with the process explained in the [previous section](https://docs.conan.io/2//devops/devops.html.md#devops) is the ability to immediately test multiple local changes without the need to export each time a recipe is modified. Note that in this case, mixing binaries from ConanCenter with locally built binaries is not recommended for several reasons: - Binary compatibility: There may be small differences in setup between the ConanCenter CI and the user’s CI. Maintaining a consistent setup for all binaries can mitigate some issues. - Full control over builds: Building all binaries yourself ensures you have complete control over the compilation environment and dependency versions. Instead, it’s recommended to build all your direct and transitive dependencies from the fork. To begin, remove the upstream ConanCenter as it will not be used, everything will come from our own fork: ```bash $ conan remote remove conancenter ``` Then we will clone our fork (in this case, we are cloning directly the upstream for demo purposes, but you would be cloning your fork instead): ```bash $ git clone https://github.com/conan-io/conan-center-index ``` Add this as our mycenter remote: ```bash # Add the mycenter remote pointing to the local folder $ conan remote add mycenter ./conan-center-index ``` And that’s all! Now you’re set to list and use packages from your conan-center-index local folder: ```bash $ conan list "zlib/*" -r=mycenter mycenter zlib zlib/1.2.11 zlib/1.2.12 zlib/1.2.13 zlib/1.3 zlib/1.3.1 ``` We can also install packages from this repo, for example we can do: ```bash $ conan install --requires=zlib/1.3 ... ======== Computing dependency graph ======== zlib/1.3: Not found in local cache, looking in remotes... zlib/1.3: Checking remote: mycenter zlib/1.3: Downloaded recipe revision 5c0f3a1a222eebb6bff34980bcd3e024 Graph root cli Requirements zlib/1.3#5c0f3a1a222eebb6bff34980bcd3e024 - Downloaded (mycenter) ======== Computing necessary packages ======== Requirements zlib/1.3#5c0f3a1a222eebb6bff34980bcd3e024:72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a - Missing ERROR: Missing binary: zlib/1.3:72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a ``` As we can see, Conan managed to get the recipe for `zlib/1.3` from `mycenter`, but then it failed because there is no binary. This is expected, **the repository only contains the recipes, but not the binaries**. We can build the binary from source with `--build=missing` argument: ```bash $ conan install --requires=zlib/1.3 --build=missing ... zlib/1.3: package(): Packaged 2 '.h' files: zconf.h, zlib.h zlib/1.3: package(): Packaged 1 file: LICENSE zlib/1.3: package(): Packaged 1 '.a' file: libz.a zlib/1.3: Created package revision 0466b3475bcac5c2ce37bb5deda835c3 zlib/1.3: Package '72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a' created zlib/1.3: Full package reference: zlib/1.3#5c0f3a1a222eebb6bff34980bcd3e024:72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a#0466b3475bcac5c2ce37bb5deda835c3 zlib/1.3: Package folder /home/conan/.conan2/p/b/zlib1ed9fe13537a2/p WARN: deprecated: Usage of deprecated Conan 1.X features that will be removed in Conan 2.X: WARN: deprecated: 'cpp_info.names' used in: zlib/1.3 ======== Finalizing install (deploy, generators) ======== cli: Generating aggregated env files cli: Generated aggregated env files: ['conanbuild.sh', 'conanrun.sh'] Install finished successfully ``` We can see now the binary package in our local cache: ```bash $ conan list "zlib:*" Local Cache zlib zlib/1.3 revisions 5c0f3a1a222eebb6bff34980bcd3e024 (2024-04-10 11:50:34 UTC) packages 72c852c5f0ae27ca0b1741e5fd7c8b8be91a590a info settings arch: x86_64 build_type: Release compiler: gcc compiler.version: 9 os: Linux options fPIC: True shared: False ``` Finally, upload the binary package to our Artifactory repository to make it available for our organization, users and CI jobs: ```bash $ conan remote add myartifactoryrepo $ conan upload zlib* -r=myartifactoryrepo -c ``` This way, consumers of the packages will not only enjoy the pre-compiled binaries and avoid having to always re-build from source all dependencies, but that will also provide stronger guarantees that the dependencies build and work correctly, that all dependencies and transitive dependencies play well together, etc. Decoupling the binary creation process from the binary consumption process is the way to achieve faster and more reliable usage of dependencies. Remember, in a production setting, the conan upload command should be executed by CI, not developers, following the [Conan guidelines](https://docs.conan.io/2//knowledge/guidelines.html.md#guidelines). This approach ensures that package consumers enjoy pre-compiled binaries and consistency across dependencies. ## Modifying the local-recipes-index repository files One of the advantages of this approach is that all the changes that we do in every single recipe are automatically available for the Conan client. For example, changes to the recipes/zlib/config.yml file are immediately recognized by the Conan client. If you edit that file and remove all versions but the latest and then we list the recipes: ```bash $ conan list "zlib/*" -r=mycenter mycenter zlib zlib/1.3.1 ``` When some of the recipes change, then note that the current Conan home already contains a cached copy of the package, so it will not update it unless we explicitly use the `--update`, as any other Conan remote. So if we do a change in the `zlib` recipe in `recipes/zlib/all/conanfile.py` and repeat: ```bash $ conan install --requires=zlib/1.3.1 -r=mycenter --update --build=missing ``` We will immediately have the new package binary locally built from source from the new modified recipe in our Conan home. ## Using local-recipes-index Repositories in Production Several important points should be considered when using this new feature: - It is designed for **third-party packages**, where recipes in one repository are creating packages with sources located elsewhere. To package your own code, the standard practice of adding conanfile.py recipes along with the source code and using the standard conan create flow is recommended. - The local-recipes-index repositories point to **local folders in the filesystem**. While users may choose to sync that folder with a git repository or other version control mechanisms, Conan is agnostic to this, as it is only aware of the folder in the filesystem that points to the (current) state of the repository. Users may choose to run git commands directly to switch branches/commit/tags and Conan will automatically recognise the changes - This approach operates at the source level and does not generate package binaries. For deployment for development and production environments, the use of a remote package server such as Artifactory is crucial. It’s important to note that this feature is not a replacement for Conan’s remote package servers, which play a vital role in hosting packages for regular use. - Also, note that a server remote can retain a history of changes storing multiple recipe revisions. In contrast, a local-recipes-index remote can only represent a single snapshot at any given time. - ConanCenter does not use `python-requires`, as this is a mechanism more intended for first-party packages. Using `python-requires` in a `local-recipes-index` repository is possible (and experimental) at this moment, but only if the `python-requires` are also in the same index repository. It is not intended or planned to support having these `python-requires` in other repositories or in the user Conan cache. Furthermore, this feature does not support placing server URLs directly in recipes; remote repositories must be explicitly added with conan remote add. Decoupling abstract package requirements, such as “zlib/1.3.1”, from their specific origins is crucial to resolving dependencies correctly and leveraging Conan’s graph capabilities, including version conflict detection and resolution, version-ranges resolution, [opting into pre-releases](https://docs.conan.io/2//devops/versioning/resolve_prereleases.html.md#resolve-prereleases-summary), [platform_requires](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-platform-requires), [replace_requires](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-replace-requires), etc. This separation also facilitates the implementation of modern DevOps practices, such as package immutability, full relocatability and package promotions. #### SEE ALSO - [Using Local-Recipes-Index repositories to share your libraries](https://docs.conan.io/2//tutorial/conan_repositories/setup_local_recipes_index.html.md#setup-local-recipes-index) - [Introducing the Local-Recipes-Index Post](https://blog.conan.io/2024/04/23/Introducing-local-recipes-index-remote.html) --- https://docs.conan.io/2/devops/metadata.html.md --- # Managing package metadata files #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. A Conan package is typically composed by several C and C++ artifacts, headers, compiled libraries and executables. But there are other files that might not be necessary for the normal consumption of such a package, but which could be very important for compliance, technical or business reasons, for example: - Full build logs - The tests executables - The tests results from running the test suite - Debugging artifacts like heavy .pdb files - Coverage, sanitizers, or other source or binary analysis tools results - Context and metadata about the build, exact machine, environment, author, CI data - Other compliance and security related files There are several important reasons to store and track these files like regulations, compliance, security, reproducibility and traceability. The problem with these files is that they can be large/heavy, if we store them inside the package (just copying the artifacts in the `package()` method), this will make the packages much larger, and it will affect the speed of downloading, unzipping and using packages in general. And this typically happens a lot of times, both in developer machines but also in CI, and it can have an impact on the developer experience and infrastructure costs. Furthermore, packages are immutable, that is, once a package has been created, it shouldn’t be modified. This might be a problem if we want to add extra metadata files after the package has been created, or even after the package has been uploaded. The **metadata files** feature allows to create, upload, append and store metadata associated to packages in an integrated and unified way, while avoiding the impact on developers and CI speed and costs, because metadata files are not downloaded and unzipped by default when packages are used. It is important to highlight that there are two types of metadata: - Recipe metadata, associated to the `conanfile.py` recipe, the metadata should be common to all binaries created from this recipe (package name, version and recipe revision). This metadata will probably be less common, but for example results of some scanning of the source code, that would be common for all configurations and builds, can be recipe metadata. - Package binary metadata, associated to the package binary for a given specific configuration and represented by a `package_id`. Build logs, tests reports, etc, that are specific to a binary configuration will be package metadata. ## Creating metadata in recipes Recipes can directly define metadata in their methods. A common use case would be to store logs. Using the `self.recipe_metadata_folder` and `self.package_metadata_folder`, the recipe can store files in those locations. ```python import os from conan import ConanFile from conan.tools.files import save, copy class Pkg(ConanFile): name = "pkg" version = "0.1" def layout(self): # Or something else, like the "cmake_layout(self)" built-in layout self.folders.build = "mybuild" self.folders.generators = "mybuild/generators" def export(self): # logs that might be generated in the recipe folder at "export" time. # these would be associated with the recipe repo and original source of the recipe repo copy(self, "*.log", src=self.recipe_folder, dst=os.path.join(self.recipe_metadata_folder, "logs")) def source(self): # logs originated in the source() step, for example downloading files, patches or other stuff save(self, os.path.join(self.recipe_metadata_folder, "logs", "src.log"), "srclog!!") def build(self): # logs originated at build() step, the most common ones save(self, "mylogs.txt", "some logs!!!") copy(self, "mylogs.txt", src=self.build_folder, dst=os.path.join(self.package_metadata_folder, "logs")) ``` Note that “recipe” methods (those that are common for all binaries, like `export()` and `source()`) should use `self.recipe_metadata_folder`, while “package” specific methods (`build()`, `package()`) should use the `self.package_metadata_folder`. Doing a `conan create` over this recipe, will create “metadata” folders in the Conan cache. We can have a look at those folders with: ```bash $ conan create . $ conan cache path pkg/0.1 --folder=metadata # folder containing the recipe metadata $ conan cache path pkg/0.1:package_id --folder=metadata # folder containing the specific "package_id" binary metadata ``` It is also possible to use the “local flow” commands and get local “metadata” folders. If we want to do this, it is very recommended to use a `layout()` method like above to avoid cluttering the current folder. Then the local commands will allow to test and debug the functionality: ```bash $ conan source . # check local metadata/logs/src.log file $ conan build . # check local mybuild/metadata/logs/mylogs.txt file ``` **NOTE**: Note that the locally created metadata will not be exported to the Conan cache during the `conan export-pkg` command. Some metadata, as the one generated in `export()` method can be generated in the cache, as the `conan export-pkg` command calls that method, but the metadata inside the “build” folder will not be exported. If you want to add that metadata to the exported package, you can copy it after the `conan export-pkg` using the paths reported by `conan cache path`, as described below in the “Adding metadata with commands” section. ## Creating metadata with hooks If there is some common metadata across recipes, it is possible to capture it without modifying the recipes, using hooks. Let’s say that we have a simpler recipe: ```python import os from conan import ConanFile from conan.tools.files import save, copy class Pkg(ConanFile): name = "pkg" version = "0.1" no_copy_source = True def layout(self): self.folders.build = "mybuild" self.folders.generators = "mybuild/generators" def source(self): save(self, "logs/src.log", "srclog!!") def build(self): save(self, "logs/mylogs.txt", "some logs!!!") ``` As we can see, this is not using the metadata folders at all. Let’s define now the following hooks: ```python import os from conan.tools.files import copy def post_export(conanfile): conanfile.output.info("post_export") copy(conanfile, "*.log", src=conanfile.recipe_folder, dst=os.path.join(conanfile.recipe_metadata_folder, "logs")) def post_source(conanfile): conanfile.output.info("post_source") copy(conanfile, "*", src=os.path.join(conanfile.source_folder, "logs"), dst=os.path.join(conanfile.recipe_metadata_folder, "logs")) def post_build(conanfile): conanfile.output.info("post_build") copy(conanfile, "*", src=os.path.join(conanfile.build_folder, "logs"), dst=os.path.join(conanfile.package_metadata_folder, "logs")) ``` The usage of these hooks will have a very similar effect to the in-recipe approach: the metadata files will be created in the cache when `conan create` executes, and also locally for the `conan source` and `conan build` local flow. ## Adding metadata with commands Metadata files can be added or modified after the package has been created. To achieve this, using the `conan cache path` command will return the folders to do that operation, so copying, creating or modifying files in that location will achieve this. ```bash $ conan create . --name=pkg --version=0.1 $ conan cache path pkg/0.1 --folder=metadata # folder to put the metadata, initially empty if we didn't use hooks # and the recipe didn't store any metadata. We can copy and put files # in the folder $ conan cache path pkg/0.1:package_id --folder=metadata # same as above, for the package metadata, we can copy and put files in # the returned folder ``` This metadata is added locally, in the Conan cache. If you want to update the server metadata, uploading it from the cache is necessary. ## Uploading metadata So far the metadata has been created locally, stored in the Conan cache. Uploading the metadata to the server is integrated with the existing `conan upload` command: ```bash $ conan upload "*" -c -r=default # Uploads recipes, packages and metadata to the "default" remote ... pkg/0.1: Recipe metadata: 1 files pkg/0.1:da39a3ee5e6b4b0d3255bfef95601890afd80709: Package metadata: 1 files ``` By default, `conan upload` will upload recipes and packages metadata when a recipe or a package is uploaded to the server. But there are some situations that Conan will completely avoid this upload, if it detects that the revisions do already exist in the server, it will not upload the recipes or the packages. If the metadata has been locally modified or added new files, we can force the upload explicitly with: ```bash # We added some metadata to the packages in the cache # But those packages already exist in the server $ conan upload "*" -c -r=default --metadata="*" ... pkg/0.1: Recipe metadata: 1 files pkg/0.1:da39a3ee5e6b4b0d3255bfef95601890afd80709: Package metadata: 1 files ``` The `--metadata` argument allows to specify the metadata files that we are uploading. If we structure them in folders, we could specify `--metadata="logs*"` to upload only the logs metadata, but not other possible ones like `test` metadata. ```bash # Upload only the logs metadata of the zlib/1.2.13 binaries # This will upload the logs even if zlib/1.2.13 is already in the server $ conan upload "zlib/1.2.13:*" -r=remote -c --metadata="logs/*" # Multiple patterns are allowed: $ conan upload "*" -r=remote -c --metadata="logs/*" --metadata="tests/*" ``` Sometimes it might be useful to upload packages without uploading the metadata, even if the metadata cache folders contain files. To ignore uploading the metadata, use an empty argument as metadata pattern: ```bash # Upload only the packages, not the metadata $ conan upload "*" -r=remote -c --metadata="" ``` The case of mixing `--metadata=""` with `--metadata="*"` is not allowed, and it will raise an error. ```bash # Invalid command, it will raise an error $ conan upload "*" -r=remote -c --metadata="" --metadata="logs/*" ERROR: Empty string and patterns can not be mixed for metadata. ``` ## Downloading metadata As described above, metadata is not downloaded by default. When packages are downloaded with a `conan install` or `conan create` fetching dependencies from the servers, the metadata from those servers will not be downloaded. The way to recover the metadata from the server is to explicitly specify it with the `conan download` command: ```bash # Get the metadata of the "pkg/0.1" package $ conan download pkg/0.1 -r=default --metadata="*" ... $ conan cache path pkg/0.1 --folder=metadata # Inspect the recipe metadata in the returned folder $ conan cache path pkg/0.1:package_id --folder=metadata # Inspect the package metadata for binary "package_id" ``` The retrieval of the metadata is done with `download` per-package. If we want to download the metadata for a whole dependency graph, it is necessary to use “package-lists”: ```bash $ conan install . --format=json -r=remote > graph.json $ conan list --graph=graph.json --format=json > pkglist.json # the list will contain the "remote" origin of downloaded packages $ conan download --list=pkglist.json --metadata="*" -r=remote ``` Note that the “package-list” will only contain associated to the “remote” origin the packages that were downloaded. If they were previously in the cache, then, they will not be listed under the “remote” origin and the metadata will not be downloaded. If you want to collect the dependencies metadata, recall to download it when the package is installed from the server. There are other possibilities, like a custom command that can automatically collect and download dependencies metadata from the servers. ### Downloading metadata to an arbitrary folder #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. Since Conan 2.32, the Python API provides two methods to fetch only the metadata of a recipe or package revision into an arbitrary folder, bypassing the Conan cache. This is useful for custom commands and CI workflows that need to inspect metadata (build logs, test outputs…) without changing the local cache state: - [`DownloadAPI.recipe_metadata`](https://docs.conan.io/2//reference/extensions/python_api/DownloadAPI.html.md#conan.api.subapi.download.DownloadAPI.recipe_metadata) - [`DownloadAPI.package_metadata`](https://docs.conan.io/2//reference/extensions/python_api/DownloadAPI.html.md#conan.api.subapi.download.DownloadAPI.package_metadata) Both methods require a fully resolved reference (with recipe revision, and package revision for the package case), the target `Remote`, the metadata patterns to fetch, and the destination folder. The metadata files are written under `/metadata/`. This can be wrapped in a custom command as follows: ```python import os from conan.api.model import PkgReference, RecipeReference from conan.cli.command import conan_command @conan_command(group="custom commands") def metadata_download(conan_api, parser, *args): """Download the metadata of a recipe/package revision into cwd (no cache).""" parser.add_argument("reference") parser.add_argument("-r", "--remote", required=True) a = parser.parse_args(*args) remote = conan_api.remotes.get(a.remote) if ":" in a.reference: pref = PkgReference.loads(a.reference) if pref.ref.revision is None: pref.ref = conan_api.list.latest_recipe_revision(pref.ref, remote) if pref.revision is None: pref = conan_api.list.latest_package_revision(pref, remote) conan_api.download.package_metadata(pref, remote, ["*"], os.getcwd()) else: ref = RecipeReference.loads(a.reference) if ref.revision is None: ref = conan_api.list.latest_recipe_revision(ref, remote) conan_api.download.recipe_metadata(ref, remote, ["*"], os.getcwd()) ``` ## Removing metadata At the moment it is not possible to remove metadata from the server side using Conan, as the metadata are “additive”, it is possible to add new data, but not to remove it (otherwise it would not be possible to add new metadata without downloading first all the previous metadata, and that can be quite inefficient and more error prone, specially sensitive to possible race conditions). The recommendation to remove metadata from the server side would be to use the tools, web interface or APIs that the server might provide. #### NOTE > **Best practices** - Metadata shouldn’t be necessary for using packages. It should be possible to consume recipes and packages without downloading their metadata. If metadata is mandatory for a package to be used, then it is not metadata and should be packaged as headers and binaries. - Metadata reading access should not be a frequent operation, or something that developers have to do. Metadata read is intended for exceptional cases, when some build logs need to be recovered for compliance, or some test executables might be needed for debugging or re-checking a crash. - Conan does not do any compression or decompression of the metadata files. If there are a lot of metadata files, consider zipping them yourself, otherwise the upload of those many files can take a lot of time. If you need to handle different types of metadata (logs, tests, reports), zipping the files under each category might be better to be able to filter with the `--metadata=xxx` argument. ## test_package as metadata This is an illustrative example of usage of metadata, storing the full `test_package` folder as metadata to later recover it and execute it. Note that this is not necessarily intended for production. Let’s start with a hook that automatically stores as **recipe metadata** the `test_package` folder ```python import os from conan.tools.files import copy def post_export(conanfile): conanfile.output.info("Storing test_package") folder = os.path.join(conanfile.recipe_folder, "test_package") copy(conanfile, "*", src=folder, dst=os.path.join(conanfile.recipe_metadata_folder, "test_package")) ``` Note that this hook doesn’t take into account that `test_package` can be dirty with tons of temporary build objects (it should be cleaned before being added to metadata), and it doesn’t check that `test_package` might not exist at all and crash. When a package is created and uploaded, it will upload to the server the recipe metadata containing the `test_package`: ```bash $ conan create ... $ conan upload "*" -c -r=default # uploads metadata ... pkg/0.1: Recipe metadata: 1 files ``` Let’s remove the local copy, and assume that the package is installed, but the metadata is not: ```bash $ conan remove "*" -c # lets remove the local packages $ conan install --requires=pkg/0.1 -r=default # this will not download metadata ``` If at this stage the installed package is failing in our application, we could recover the `test_package`, downloading it, and copying it to our current folder: ```bash $ conan download pkg/0.1 -r=default --metadata="test_package*" $ conan cache path pkg/0.1 --folder=metadata # copy the test_package folder from the cache, to the current folder # like `cp -R ...` # Execute the test_package $ conan test metadata/test_package pkg/0.1 pkg/0.1 (test package): Running test() ``` #### SEE ALSO - TODO: Examples how to collect the metadata of a complete dependency graph with some custom deployer or command This is an **experimental** feature. We are looking forward to hearing your feedback, use cases and needs, to keep improving this feature. Please report it in [Github issues](https://github.com/conan-io/conan/issues) --- https://docs.conan.io/2/devops/package_promotions.html.md --- # Package promotions Package promotions are the recommended devops practice to handle quality, maturity or stages of packages in different technologies, and of course, also for Conan packages. The principle of package promotions is that there are multiple server package repositories defined and packages are uploaded and copied among repositories depending on the stage. For example we could have two different server package repositories called “testing” and “release”: #### NOTE **Best practices** - Using different `user/channel` to try to denote maturity is strongly discouraged. It was described in the early Conan 1 days years ago, before the possibility of having multiple repositories, but it shouldn’t be used anymore. - Packages should be completely immutable across pipelines and stages, a package cannot rename or change its `user/channel`, and re-building it from source to have a new `user/channel` is also a strongly discourage devops practice. Between those repositories there will be some quality gates. In our case, some packages will be put in the “testing” repository, for the QA team to test them, for example `zlib/1.3.1` and `openssl/3.2.2`: When the QA team tests and approves these packages, they can be promoted to the “release” repository. Basically, a promotion is a copy of the packages, including all the artifacts and metadata from the “testing” to the “release” repository. There are different ways to implement and execute a package promotion. Artifactory has some APIs that can be used to move individual files or folders. The [Conan extensions repository](https://github.com/conan-io/conan-extensions) contains the `conan art:promote` command that can be used to promote Conan “package lists” from one server repository to another repository. If we have a package list `pkglist.json` that contains the above `zlib/1.3.1` and `openssl/3.2.2` packages, then the command would look like: ```bash $ conan art:promote pkglist.json --from=testing --to=release --url=https:///artifactory --user= --password= ``` Note that the `conan art:promote` command doesn’t work with ArtifactoryCE, Pro editions of Artifactory are needed. The promote functionality can be implemented in these cases with a simple download+upload flow: ```bash # Promotion using Conan download/upload commands # (slow, can be improved with art:promote custom command) $ conan download --list=promote.json -r=testing --format=json > downloaded.json $ conan upload --list=downloaded.json -r=release -c ``` After the promotion from “testing” to “release” repository, the packages would be like: #### NOTE **Best practices** - In modern package servers such as Artifactory package artifacts are **deduplicated**, that is, they do not take any extra storage when they are copied in different locations, including different repositories. The **deduplication** is checksum based, so the system is also smart to avoid re-uploading existing artifacts. This is very important for the “promotions” mechanism: this mechanism is only copying some metadata, so it can be very fast and it is storage efficient. Pipelines can define as many repositories and promotions as necessary without concerns about storage costs. - Promotions can also be done in JFrog platform with `Release Bundles`. The [Conan extensions repository](https://github.com/conan-io/conan-extensions) also contains one command to generate a release bundle (that can be promoted using the Artifatory API). #### SEE ALSO - [Using package lists examples](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists) - [Promotions usage in CI](https://docs.conan.io/2//ci_tutorial/tutorial.html.md#ci-tutorial) --- https://docs.conan.io/2/devops/save_restore.html.md --- # Save and restore packages from/to the cache #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. With the `conan cache save` and `conan cache restore` commands, it is possible to create a .tgz from one or several packages from a Conan cache and later restore those packages into another Conan cache. There are some scenarios this can be useful: - In Continuous Integration, specially if doing distributed builds, it might be very convenient to be able to move temporary packages recently built. Most CI systems have the capability of transferring files between jobs for this purpose. The Conan cache is not concurrent, sometimes for parallel jobs different caches have to be used. - For air-gapped setups, in which packages can only be transferred via client side. - Developers directly sharing some packages with other developers for testing or inspection. The process of saving the packages is using the `conan cache save` command. It can use a pattern, like the `conan list` command, but it can also accept a package-list, like other commands like `remove, upload, download`. For example: ```bash $ conan cache save "pkg/*:*" Saving pkg/1.0: p/pkg1df6df1a3b33c Saving pkg/1.0:9a4eb3c8701508aa9458b1a73d0633783ecc2270: p/b/pkgd573962ec2c90/p Saving pkg/1.0:9a4eb3c8701508aa9458b1a73d0633783ecc2270 metadata: p/b/pkgd573962ec2c90/p ... # creates conan_cache_save.tgz ``` The `conan_cache_save.tgz` file contains the packages named `pkg` (any version), the last recipe revision, and the last package revision of all the package binaries. The name of the file can be changed with the optional `--file=xxxx` argument. Some important considerations: - The command saves the contents of the cache “recipe” folders, containing the subfolders “export”, “export_sources”, “source” and recipe “metadata”. - The “source” folder in the cache can be skipped with the `conan cache save --no-source` argument. That means that if the restored recipe needs to build a new binary in the restored cache, it will not have the sources and it will try to download them if the recipe `source()` method says so. - The command saves the contents of the “package” and the package “metadata” folders, but not the binary “build” or “download”, that are considered temporary folders. - If the user doesn’t want any of those folders to be saved, they can be cleaned before saving them with `conan cache clean` command - The command saves the cache files and artifacts as well as the metadata (revisions, package_id) to be able to restore those packages in another cache. But it doesn’t save any other cache state like `settings.yml`, `global.conf`, `remotes`, etc. If the saved packages require any other specific configuration, it should be managed with `conan config install`. The compression format can be defined by the file extension, supported formats are `.tgz`, `.txz` (experimental) and `.tzst` (experimental, requires Python>=3.14). The compression level can be defined via the `core:compresslevel` configuration. We can move this `conan_cache_save.tgz` file to another Conan cache and restore it as: ```bash $ conan cache restore conan_cache_save.tgz Restore: pkg/1.0 in p/pkg1df6df1a3b33c Restore: pkg/1.0:9a4eb3c8701508aa9458b1a73d0633783ecc2270 in p/b/pkg773791b8c97aa/p Restore: pkg/1.0:9a4eb3c8701508aa9458b1a73d0633783ecc2270 metadata in p/b/pkg773791b8c97aa/d/metadata ... ``` The restore process will overwrite existing packages if they already exist in the cache. #### NOTE **Best practices** - Saving and restoring packages is not a substitute for proper storage (upload) of packages in a Conan server repository. It is only intended as a transitory mechanism, in CI systems, to save an air-gap, etc., but not as a long-term storage and retrieval. - Saving and restoring packages is not a substitute for proper backup of server repositories. The recommended way to implement long term backup of Conan packages is using some server side backup strategy. - The storage format and serialization is not guaranteed at this moment to be future-proof and stable. It is expected to work in the same Conan version, but future Conan versions might break the storage format created with previous versions. (this is aligned with the above recommendation to not use it as a backup strategy) --- https://docs.conan.io/2/devops/using_conancenter.html.md --- # Using ConanCenter packages in production environments #### NOTE **Default Remote Update in Conan 2.9.2** Starting from **Conan version 2.9.2**, the default remote has been changed to https://center2.conan.io. The previous default remote https://center.conan.io is now frozen and will no longer receive updates. It is recommended to update your remote configuration to use the new default remote to ensure access to the latest recipes and package updates (for more information, please read this [post](https://blog.conan.io/2024/09/30/Conan-Center-will-stop-receiving-updates-for-Conan-1.html)). If you still have the deprecated remote configured as the default, please update using the following command: ```bash conan remote update conancenter --url="https://center2.conan.io" ``` ConanCenter is a fantastic resource that contains reference implementations of recipes for over 1500 libraries and applications contributed by the community. As such, it is a great knowledge base on how to create and build Conan packages for open source dependencies. ConanCenter also builds and provides binary packages for a wide range of configurations: multiple operating systems (Windows, Linux, macOS), compilers, compiler versions, and library variants (shared, static). On top of this, for a lot of libraries community contributors ensure that recipes are compatible for additional operating systems (Android, iOS, FreeBSD, QNX) and CPU architectures. The recipes in Conan Center are the greatest example of Conan’s universality promise. Unlike other package managers or repositories, ConanCenter does not maintain a fixed snapshot of versions. On the contrary, for a given library (e.g. OpenCV), multiple versions are actively maintained at the same time. This gives users greater control of which versions to use, rather than having to remain fixed to an older version, or pushing them to always be on the latest version. In order to support this ecosystem, ConanCenter recipes are updated very frequently. Recipes themselves may be updated to support a new platform, bug fixes, or to require newer versions of their dependencies. On the other hand, each user of ConanCenter may have a different combination of versions in their requirements. This means that given the same input list of requirements, Conan may resolve the graph differently at different points in time - resolving to different recipe revisions, versions, or packages. This is similar to the default behavior of package managers in other languages (pip/PyPi, npm, cargo, etc). In production environments where reproducibility is important, it is therefore discouraged to depend directly on Conan Center in an unconstrained manner. The following guidelines contain a series of recommendations to ensure repeatability, reliability, compliance and, where applicable, control to enable customization. As a summary, it is highly recommended to follow these approaches when using packages from ConanCenter: - Lock the versions and revisions you depend on using [lockfiles](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles) - Host your own copy of ConanCenter recipes and package binaries [in a server under your control](https://docs.conan.io/2//devops/conancenter/hosting_binaries.html.md#devops-conancenter-hosting-your-own-conancenter-fork) ## Repeatability and reproducibility As mentioned earlier - given a set of requirements, changes in ConanCenter can cause the Conan dependency solver to resolve different graphs over time. This does not only apply to the actual versions of libraries (e.g. `opencv/4.5.0` instead `opencv/4.2.1`) - but also the recipes themselves. That is, there may exist multiple revisions of the `opencv/4.5.0` recipe, which can have side effects for consumers. Changes in recipes typically address a problem (bugfixes), target functionality (e.g. adding a conditional option, support for a new platform), or change versions of dependencies. In order to ensure repeatability, the use of lockfiles on the consumer side is greatly encouraged: please check [the lockfile docs](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles) for more information. Lockfiles ensure that Conan will resolve the same graph in a repeatable and consistent manner - thus making sure the same versions are used across multiple systems (CI, developers, etc). Lockfiles are also used in other package managers like Python pip, Rust Cargo, npm - these recommendations are in line with the practices of these other technologies. Additionally, it is highly recommended to host your recipes and packages in your own server (see below). Both of these approaches help you achieve having control on when upstream changes from ConanCenter are propagated across your team and systems. ## Service reliability Consuming recipes and packages from the ConanCenter remote can be impacted during periods of downtime (scheduled or otherwise). While every effort is made to ensure that the ConanCenter is always available, and unscheduled downtime is rare and treated with urgency - this can impact users that depend on ConanCenter directly. Additionally, when building recipes from source, this requires retrieving the source packages (typically zip or tar files) from remote servers outside of the control of ConanCenter. Occasionally, these too can suffer from unscheduled downtime. In enterprise production environments with strong uptime is required, it is strongly recommended to host recipes and binary packages in a server under your control. - Read more: [creating and hosting your own Conan Center binaries](https://docs.conan.io/2//devops/conancenter/hosting_binaries.html.md#devops-conancenter-hosting-your-own-conancenter-fork) This can also protect against transient network issues, and issues caused by transfer of binary data from external sources. These recommendations also apply when consuming packages from external sources in any package manager. ## Compliance and security Some industries such as finance, robotics and embedded, have stronger requirements around change management, open source licenses and reproducibility. For example, changes in recipes could result in a new version being resolved for a dependency, in a way that the license for that version has changed and needs to be validated and audited by your organization. In some industries like medical or automotive, you may be required to ensure all your dependencies can be built from source in a repeatable way, and thus using binaries provided by Conan Center may not be advisable. In these instances, we recommend building your own binary packages from source: - Read more: [creating and hosting your own Conan Center binaries](https://docs.conan.io/2//devops/conancenter/hosting_binaries.html.md#devops-conancenter-hosting-your-own-conancenter-fork) If the `conancenter` remote is used directly, your organization might require that the binaries are built from source, and not downloaded directly from ConanCenter. This can exceptionally be achieved with the `recipes_only` field [in the remote configuration](https://docs.conan.io/2//reference/config_files/remotes.html.md#reference-config-files-remotes-json), but it is highly likely that you will also want to build the packages from source, and not depend on the recipes and binaries provided by ConanCenter. See the above link for more information. ## Control and customization It is very common for users of dependencies to require custom changes to external libraries - typically to support specific platform configurations not considered by either ConanCenter or the original library authors, backport bug fixes, etc. Some of these changes may not be suitable to be merged in ConanCenter, and it may not happen until this has been reviewed and validated by ConanCenter maintainers. For this reason, if you need tight control over the changes in recipes, it is highly recommended to host not only a Conan remote, but your own fork of the conan-center-index recipe repository. - Read more: [creating and hosting your own Conan Center binaries](https://docs.conan.io/2//devops/conancenter/hosting_binaries.html.md#devops-conancenter-hosting-your-own-conancenter-fork) The following subsections describe in more details the above strategies: * [Creating and hosting your own ConanCenter binaries](https://docs.conan.io/2//devops/conancenter/hosting_binaries.html.md) --- https://docs.conan.io/2/devops/vendoring.html.md --- # Vendoring dependencies in Conan packages #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. From Conan 2.4 it is possible to create and use Conan packages that completely vendor their dependencies, that is, they completely hide and isolate their dependencies from their consumers. This can be useful in some different cases: - When sharing Conan packages with other organizations which vendor (copy, embed or link) the dependencies, so it is not necessary for the consumers of their packages to have access to those dependencies and the intention is that they always use the shared precompiled binaries. - To introduce a hard decoupling between parts of a project. To make a package vendor its dependencies, define in its recipe the following attribute: ```bash class MyPkg(ConanFile): name = "mypkg" version = "0.1" vendor = True requires = "somedep/1.2" ``` When we have this recipe, we can create its binaries with a normal `conan create .`. But when we use this package as a requirement for other packages, its dependencies will be fully invisible. The graph will not even expand the `somedep/1.2` requirement. This dependency doesn’t even need to be available in the remotes for the consumers, it will not be checked. Some important notes: - A package that vendors its dependencies is intended to be consumed always in binary form. - The dependencies of a vendoring package always form a fully private and isolated dependency graph, decoupled from the rest of the dependency graph that uses this package. - It is the responsibility of the vendoring package and its users to guarantee that vendored dependencies do not collide. If a vendoring package vendors for example `libssl.a` as a static library doing a regular copy of it in its package, and there is another package in the graph that also provides `libssl`, there will be a conflict that Conan cannot detect as `libssl.a` is vendored as an internal implementation detail of the package, but not explicitly modeled. Mechanisms like `provides` can be used for this purpose, but it is the responsibility of the recipe authors to take it into account. - The `package_id` of a package that defines `vendor=True` is fully independent of its dependencies. The dependencies versions will never affect the `package_id` of the vendoring package, so it is important to note that the version of the vendoring package represents a full private dependency graph. - The regular `default_options` or options values definitions from consumer `conanfile.py` recipes do not propagate over vendoring packages, as they don’t even expand their dependencies. - If a vendoring package binary is missing and/or the user request to build such a package from sources, Conan will fail, raising an error that it is not possible to build it. - To allow the expansion of the private dependency the `tools.graph:vendor=build` configuration can be activated. If that is the case, the private dependency graph of the package will be computed and expanded and the package will be allowed to build. --- https://docs.conan.io/2/devops/backup_sources/sources_backup.html.md --- # Backing up third-party sources with Conan For recipes and build scripts for open source, publicly available libraries, it is common practice to download the sources from a canonical source, like Github releases, or project download web pages. Keeping a record of the origin of these files is useful for traceability purposes, however, it is often not guaranteed that the files will be available in the long term, and a user in the future building the same recipe from source may encounter a problem. Conan can thus be configured to transparently retrieve sources from a configured mirror, without modifying the recipes or conandata.yml. Additionally, these sources can be transparently uploaded alongside the packages via **conan upload**. The *sources backup* feature is intended for storing the downloaded recipe sources in a file server in your own infrastructure, allowing future reproducibility of your builds even in the case where the original download URLs are no longer accessible. The backup is triggered for calls to the [download](https://docs.conan.io/2//reference/tools/files/downloads.html.md#conan-tools-files-get) and [get](https://docs.conan.io/2//reference/tools/files/downloads.html.md#conan-tools-files-get) methods when a `sha256` file hash is provided. ## Configuration overview This feature is controlled by a few [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf) items: * `core.sources:download_cache`: Local path to store the sources backups to. *If not set, the default Conan home cache path will be used.* * `core.sources:download_urls`: Ordered list of URLs that Conan will try to download the sources from, where `origin` represents the original URL passed to `get`/`download` from conandata.yml. This allows to control the fetch order, either `["origin", "https://your.backup/remote/"]` to look into and fetch from your backup remote only if and when the original source is not present, or `["https://your.backup/remote/", "origin"]` to prefer your backup server ahead of the recipes’ canonical links. Being a list, multiple remotes are also possible. `["origin"]` *by default* * `core.sources:upload_url`: URL of the remote to upload the backups to when calling **conan upload**, which might or might not be different from any of the URLs defined for download. *Empty by default* * `core.sources:exclude_urls`: List of origins to skip backing up. If the URL passed to `get`/`download` starts with any of the origins included in this list, the source won’t be uploaded to the backup remote when calling **conan upload**. *Empty by default* #### NOTE When adding a backup source remote to `core.sources:download_urls`, if the server is not reachable, (or if it requires authentication and it is not provided), Conan will **NOT** skip it and continue to the next URL in the list, instead it will raise an error and the download will fail. If your remote backup server is down and you want to be able to continue downloading from the original URLs, remove the backup remote from the list temporarily. ## Usage Let’s overview how the feature works by providing an example usage from beginning to end: In summary, it looks something like: - A remote backup repository is set up. This should allow `PUT` and `GET` HTTP methods to modify and fetch its contents. If access credentials are desired (which is strongly recommended for uploading permissions), you can use the [source_credentials.json](https://docs.conan.io/2//reference/config_files/source_credentials.html.md#reference-config-files-source-credentials) feature. [See below](#backup-sources-setup-remote) if you are in need for configuring your own. - The remote’s URL can then be set in `core.sources:download_urls` and `core.sources:upload_url`. - In your recipe’s `source()` method, ensure the relevant `get`/`download` calls supply the `sha256` hash of the downloaded files. - Set `core.sources:download_cache` in your [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf) file if a custom location is desired, else the default cache folder will be used - Run Conan normally, creating packages etc. - Once some sources have been locally downloaded, the folder pointed to by `core.sources:download_cache` will contain, for each downloaded file: : - A blob file (no extensions) with the name of the `sha256` hash provided in `get`/`download`. - A `.json` file which will also have the name of the `sha256` hash, that will contain information about which references and which mirrors this blob belongs to. - Calling `conan upload` will now optionally upload the backups for the matching references if `core.sources:upload_url` is set. #### NOTE [See below](#backup-sources-setup-remote) for a guide on how to configure your own backup server ### Setting up the necessary configs The [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf) file should contain the `core.sources:download_urls` if downloading from a custom backup source remote is desired, and `core.sources:download_cache` if a custom local cache path to download the backups to is desired. ```text core.sources:download_urls=["https://myteam.myorg.com/artifactory/backup-sources/", "origin"] core.sources:download_cache=/path/to/backup/sources ``` #### NOTE Either `core.sources:download_urls` or `core.sources:download_cache` should be defined for the feature to be enabled. You might want to add extra confs based on your use case, as described [in the beginning of this document](#backup-sources-config). #### NOTE The recommended approach for dealing with the configuration of CI workers and developers in your organization is to install the configs using the `conan config install` command on a repository. Read more [here](https://docs.conan.io/2//reference/commands/config.html.md#reference-commands-conan-config-install) ### Run Conan as normal With the above steps completed, Conan can now be used as normal, and for every downloaded source, Conan will first look into the folder indicated in `core.sources:download_cache`, and if not found there, will traverse `core.sources:download_urls` until it find the file or fails, and store a local copy in the same `core.sources:download_cache` location. When the backup is fetched from the the backup remote, a message like what follows will be shown to the user: ```text $ conan create . --version=1.3 ... ======== Installing packages ======== zlib/1.3: Calling source() in /Users/ruben/.conan2/p/zlib0f4e45286ecd1/s/src zlib/1.3: Sources for ['https://zlib.net/fossils/zlib-1.3.tar.gz', 'https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz'] found in remote backup https://myteam.myorg.com/artifactory/backup-sources -------- Installing package zlib/1.3 (1 of 1) -------- ... ``` If we now again try to run this, we’ll find that no download is performed and the locally stored version of the files is used. ### Upload the packages Once a package has been created as shown above, when a call to `conan upload zlib/1.3 -c` is performed to upload the resulting binary to your Conan repository, it will also upload the source backups for that same reference to your backups remote if configured to do so, and future source downloads of this recipe will use the newly updated contents when necessary. #### NOTE See [the packages list feature](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists) for a way to only upload the packages that have been built In case there’s a need to upload backups for sources not linked to any package, or for packages that are already on the remote and would therefore be skipped during upload, the **conan cache backup-upload** command can be used to address this scenario. ### Creating the backup repository You can also set up your own remote backup repository instead of relying on an already available one. While an Artifactory generic repository (available for free with Artifactory CE) is recommend for this purpose, any simple server that allows `PUT` and `GET` HTTP methods to modify and fetch its contents is sufficient. Read the following section for instructions on how to create a generic Artifactory backup repo and how to give it public read permissions, while keeping write access only for authorized agents * [Creating an Artifactory backup repo for your sources](https://docs.conan.io/2//devops/backup_sources/repositories/artifactory/creating_backup_sources_repo.html.md) --- https://docs.conan.io/2/devops/backup_sources/repositories/artifactory/creating_backup_sources_repo.html.md --- # Creating an Artifactory backup repo for your sources For the backup repository, we’ll create a generic Artifactory repo using the free Community Edition version. For this, in the repositories section of the administration tab, we’ll create a new generic repository, and in this example we’ll imaginatively give it the name of *backup-sources*. The URL of the remote should now be added to the [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf) file’s `core.sources:upload_url` conf ```text core.sources:upload_url=https://myteam.myorg.com/artifactory/backup-sources/ ``` Next, as we want this to be a public read repo, we’ll allow anonymous read access to our repo. [See the official Artifactory documentation for a step-by-step guide on how to create one](https://jfrog.com/help/r/how-to-grant-an-anonymous-user-access-to-specific-repositories/artifactory-how-to-grant-an-anonymous-user-access-to-specific-repositories). Now, to be able to upload contents, we’ll also create a new user from the User Management section, called *backup uploader*, and from the Access Tokens section, we’ll generate a reference token associated with the user ![image](devops/backup_sources/repositories/artifactory/images/create_reference_token.png) The generated token should now live in the [source_credentials.json](https://docs.conan.io/2//reference/config_files/source_credentials.html.md#reference-config-files-source-credentials) file: ```json { "credentials": [ { "url": "https://myteam.myorg.com/artifactory/backup-sources/", "token": "cmVmdGtu1234567890abcdefghijklmnopqrstuvwxyz" } ] } ``` And last but not least, from the Permissions section we’ll give the user manage access to the new repository (which will automatically give it every other permission available, feel free to modify them according to your needs) ![image](devops/backup_sources/repositories/artifactory/images/permissions_add_backup_access.png) With this, access to our remote backup is now configured to allow anonymous read but authenticated upload. --- https://docs.conan.io/2/devops/conancenter/hosting_binaries.html.md --- # Creating and hosting your own ConanCenter binaries Hosting your own copy of the packages you need in your server could be done by just downloading binaries from ConanCenter and then uploading them to your own server. However, it is much better to fully own the complete supply chain and create the binaries in your own CI systems. So the recommended flow to use ConanCenter packages in production would be: - Create a fork of the ConanCenter Github repository: [https://github.com/conan-io/conan-center-index](https://github.com/conan-io/conan-center-index) - Create a list of the packages and versions you need for your projects. This list can be added to the fork too, and maintained there (packages can be added and removed with PRs when the teams need them). - Create a script that first `conan export` all the packages in your list, then `conan create --build=missing` them. - Upload your build packages to your own server, that you use in production, instead of ConanCenter. #### NOTE **Best practices** - Do not add `user/channel` to packages created from ConanCenter forks, it is way simpler to create and use them as `zlib/1.2.13` without user-channel. The `user/channel` part would be mostly recommended for your own proprietary packages, but not for open source ConanCenter packages. It adds more divergence from the upstream and consequently more maintenance with little added value. - Do not mix packages and recipes created from your fork of `conan-center-index` Github repo with the ones from ConanCenter central server. Once you create some binaries for third parties from your fork, it is strongly recommended to fully disconnect from ConanCenter (you can remove the `remote`, and you can add the `remotes.json` file with your own remotes to the configuration you can distribute and install with `conan config install/install-pkg`), and create all your third-party packages from your fork. This is the basic flow idea. We will be adding examples and tools to further automate this flow as soon as possible. This flow is relatively straightforward, and has many advantages that mitigate the risks described before: - No central repository outage can affect your builds. - No changes in the central repository can break your projects, you are in full control when and how those changes are updated in your packages (as explained below). - You can customize, adapt, fix and perfectly control what versions are used, and release fixes in minutes, not weeks. You can apply customizations that wouldn’t be accepted in the central repository. - You fully control the binaries supply chain, from the source (recipes) to the binaries, eliminating in practice the majority of potential supply chain attacks of central repositories. ## Updating from upstream Updating from the upstream `conan-center-index` Github repo is still possible, and it can be done in a fully controlled way: - Merge the latest changes in the upstream main fork of `conan-center-index` into your fork. - You can check and audit those changes if you want to, analyzing the diffs (some automation that trims the diffs of recipes that you don’t use could be useful) - Firing the above process will efficiently rebuild the new binaries that are needed. If your recipes are not affected by changes, the process will avoid rebuilding binaries (thanks to `--build=missing`). - You can upload the packages to a secondary “test” server repository. Then test your project against that test server, to check that your project is not broken by the new ConanCenter packages. - Once you verify that everything is good with the new packages, you can copy them from the secondary “test” repository to your main production repository to start using them. --- https://docs.conan.io/2/devops/versioning/default.html.md --- # Default versioning approach When doing changes to the source code of a package, and creating such a package, one good practice is to increase the version of the package to represent the scope and impact of those changes. The “semver” standard specification defines a `MAJOR.MINOR.PATCH` versioning approach with a specific meaning for changing each digit. Conan implements versioning based on the “semver” specification, but with some extended capabilities that were demanded by the C and C++ ecosystems: - Conan versions can have any number of digits, like `MAJOR.MINOR.PATCH.MICRO.SUBMICRO...` - Conan versions can contain also letters, not only digits, and they are also ordered in alphabetical order, so `1.a.2` is older tha `1.b.1` for example. - The version ranges can be equally defined for any number of digits, like `dependency/[>=1.0.0.0 <1.0.0.10]` Read the [introduction to versioning](https://docs.conan.io/2//tutorial/versioning.html.md#tutorial-versioning) in the tutorial. But one very different aspect of C and C++ building model compared to other languages is how the dependencies affect the binaries of the consumers requiring them. This is described in the [Conan binary model](https://docs.conan.io/2//reference/binary_model/dependencies.html.md#reference-binary-model-dependencies) reference. Basically, when some package changes its version, this can have different effects on the “consumers” of this package, requiring such “consumers” to do a rebuild from source or not to integrate the new dependency changes. This also depends on the package types, as the logic changes when linking a shared library or a static library. Conan binary model with `dependency traits`, `package_type`, and the `package_id` modes is able to represent this logic and compute efficiently what needs to be rebuilt from source. The default Conan behavior can give some hints of what version changes would be recommended when doing different changes to the packages source code: - Not modifying the version typically means that we want Conan automatic **recipe revisions** to handle that. A common use case is when the C/C++ source code is not modified at all, and only changes to the `conanfile.py` recipe are done. As the source code is the same, we might want to keep the same version number, and just have a new revision of that version. - **Patch**: Increasing the **patch** version of a package means that only internal changes were done, in practice it means change to files that are not public headers of the package. This “patch” version can avoid having to re-build consumers of this package, for example if the current package getting a new “patch” version is a static library, all other packages that implement static libraries that depend on this one do not need to be re-built from source, as depending on the same public interface headers guarantee the same binary. - **Minor**: If changes are done to package public headers, in an API source compatible way, then the recommendation would be to increase the **minor** verson of a package. That means that other packages that depend on it will be able to compile without issues, but as there were modifications in public headers (that could contain C++ templates or other things that could be inlined in the consumer packages), then those consumer packages need to be rebuilt from source to incorporate these changes. - **Major**: If API breaking changes are done to the package public headers, then increasing the **major** version is recommended. As the most common recommended version-range is something like `dependency/[>1.0 <2]`, where the next major is excluded, that means that publishing these new versions will not break existing consumers, because they will not be used at all by those consumers, because their version ranges will exclude them. It will be necessary to modify the consumers recipes and source code (to fix the API breaking changes) to be able to use the new major version. Note that while this is close to the standard “semver” definition of version and version ranges, the C/C++ compilation model needs to introduce a new side effect, that of “needing to rebuild the consumers”, following the logic explained above in the `embed` and `non_embed` cases. This is just the default recommended versioning approach, but Conan allows to change these defaults, as it implements an extension of the “semver” standard that allows any number of digits, letters, etc, and it also allows to change the `package_id` modes to define how different versions of the dependencies affect the consumers binaries. See [how to customize the dependencies package_id modes](https://docs.conan.io/2//reference/binary_model/custom_compatibility.html.md#reference-binary-model-custom-compatibility-dependencies). #### NOTE **Best practices** - It is not recommended to use other package reference fields, as the `user` and `channel` to represent changes in the source code, or other information like the git branch, as this becomes “viral” requiring changes in the `requires` of the consumers. Furthermore, they don’t implement any logic in the build model with respect to which consumers need to be rebuilt. - The recommended approach is to use versioning and multiple server repositories to host the different packages, so they don’t interfere with other builds, read [the Continuous Integration tutorial](https://docs.conan.io/2//ci_tutorial/tutorial.html.md#ci-tutorial) for more details. --- https://docs.conan.io/2/devops/versioning/resolve_prereleases.html.md --- # Handling version ranges and pre-releases When developing a package and using version ranges for defining our dependencies, there might come a time when a new version of a dependency gets a new pre-release version that we would like to test before it’s released to have a change to validate the new version ahead of time. At first glance, it could be expected that the new version matches our range if it intersect it, but [as described in the version ranges tutorial](https://docs.conan.io/2//tutorial/versioning/version_ranges.html.md#tutorial-version-ranges-expressions), by default Conan does not match pre-release versions to ranges that don’t specify it. Conan provides the [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf) `core.version_ranges:resolve_prereleases` conf, a tri-state configuration option that controls if version ranges should resolve to pre-releases. When \_not_ set, the default behavior is to listen to the version range expression, and only match if the version range explicitly allows pre-release versions, like for `[>=1 <2, include_prerelease]`. If the `include_prerelease` flag is not specified, pre-release versions are ignored in this case. When set to `False`, it will not match pre-release versions, even if the version range expression allows it. When set to `True`, it globally enables pre-release matching in version ranges, even if the version range expression does not explicitly allow it. This avoids having to modify and export the recipes of your dependency graph, which would become unfeasible for large ones. This conf has the added benefit of affecting the whole dependency graph, so that if any of our dependencies also define a requirement to our library of interest, the new version will also be picked up by it. Let’s see this in action. Imagine we have the following (summarized) dependency graph, in which we depend on `libpng` and `libmysqlclient`, both of which depend on `zlib` via the `[>1.2 <2]` version range: If `zlib/1.3-pre` is now published, using it is as easy as modifying your [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf) file and adding the line `core.version_ranges:resolve_prereleases=True` (or adding the `--core-conf core.version_ranges:resolve_prereleases=True` CLI argument to your command invocations), after which, running `conan create` will now output the expected prerelease version of `zlib` being used: ```text ... ======== Computing dependency graph ======== Graph root cli Requirements libmysqlclient/8.1.0#493d36bd9641e15993479706dea3c341 - Cache libpng/1.6.40#2ba025f1324ff820cf68c9e9c94b7772 - Cache lz4/1.9.4#b572cad582ca4d39c0fccb5185fbb691 - Cache openssl/3.1.2#f2eb8e67d3f5513e8a9b5e3b62d87ea1 - Cache zlib/1.3-pre#f2eb8e6ve24ff825bca32bea494b77dd - Cache zstd/1.5.5#54d99a44717a7ff82e9d37f9b6ff415c - Cache Build requirements cmake/3.27.1#de7930d308bf5edde100f2b1624841d9 - Cache Resolved version ranges cmake/[>=3.18 <4]: cmake/3.27.1 openssl/[>=1.1 <4]: openssl/3.1.2 zlib/[>1.2 <2]: zlib/1.3-pre ... ``` Now our package can be tested and validated against this new version, and the conf be afterwards removed once the testing is over to go back to the usual Conan behaviour. --- https://docs.conan.io/2/devops/versioning/versioning.html.md --- # Versioning This section deals with different versioning topics: * [Default versioning approach](https://docs.conan.io/2//devops/versioning/default.html.md) * [Handling version ranges and pre-releases](https://docs.conan.io/2//devops/versioning/resolve_prereleases.html.md) --- https://docs.conan.io/2/examples/commands.html.md --- # Conan commands examples * [Using packages-lists](https://docs.conan.io/2//examples/commands/pkglists.html.md) * [Listing packages and downloading them](https://docs.conan.io/2//examples/commands/pkglists.html.md#listing-packages-and-downloading-them) * [Downloading from one remote and uploading to a different remote](https://docs.conan.io/2//examples/commands/pkglists.html.md#downloading-from-one-remote-and-uploading-to-a-different-remote) * [Building and uploading packages](https://docs.conan.io/2//examples/commands/pkglists.html.md#building-and-uploading-packages) * [Removing packages lists](https://docs.conan.io/2//examples/commands/pkglists.html.md#removing-packages-lists) --- https://docs.conan.io/2/examples/conanfile.html.md --- # ConanFile methods examples * [ConanFile package_info() examples](https://docs.conan.io/2//examples/conanfile/package_info.html.md) * [Propagating environment or configuration information to consumers](https://docs.conan.io/2//examples/conanfile/package_info/package_info_conf_and_env.html.md) * [Define components for Conan packages that provide multiple libraries](https://docs.conan.io/2//examples/conanfile/package_info/components.html.md) * [ConanFile layout() examples](https://docs.conan.io/2//examples/conanfile/layout.html.md) * [Declaring the layout when the Conanfile is inside a subfolder](https://docs.conan.io/2//examples/conanfile/layout/conanfile_in_subfolder.html.md) * [Declaring the layout when creating packages for third-party libraries](https://docs.conan.io/2//examples/conanfile/layout/third_party_libraries.html.md) * [Declaring the layout when we have multiple subprojects](https://docs.conan.io/2//examples/conanfile/layout/multiple_subprojects.html.md) * [Using components and editable packages](https://docs.conan.io/2//examples/conanfile/layout/editable_components.html.md) --- https://docs.conan.io/2/examples/config_files.html.md --- # Configuration files examples * [Customize your settings: create your settings_user.yml](https://docs.conan.io/2//examples/config_files/settings/settings_user.html.md) * [Locate the settings_user.yml](https://docs.conan.io/2//examples/config_files/settings/settings_user.html.md#locate-the-settings-user-yml) * [Use your new settings](https://docs.conan.io/2//examples/config_files/settings/settings_user.html.md#use-your-new-settings) --- https://docs.conan.io/2/examples/cross_build.html.md --- # Cross-building examples * [Creating a Conan package for a toolchain](https://docs.conan.io/2//examples/cross_build/toolchain_packages.html.md) * [Cross building to Android with the NDK](https://docs.conan.io/2//examples/cross_build/android/ndk.html.md) * [Integrating Conan in Android Studio](https://docs.conan.io/2//examples/cross_build/android/android_studio.html.md) * [Cross-building with Emscripten - WebAssembly and asm.js](https://docs.conan.io/2//examples/cross_build/emscripten.html.md) * [Building packages for TriCore](https://docs.conan.io/2//examples/cross_build/tricore.html.md) * [Cross-compiling from Linux to Windows with MinGW](https://docs.conan.io/2//examples/cross_build/linux_to_windows_mingw.html.md) --- https://docs.conan.io/2/examples/dev_flow.html.md --- # Developer tools and flows * [Debugging and stepping into dependencies](https://docs.conan.io/2//examples/dev_flow/debug/step_into_dependencies.html.md) * [Building from source](https://docs.conan.io/2//examples/dev_flow/debug/step_into_dependencies.html.md#building-from-source) * [Step into a dependency with Visual Studio](https://docs.conan.io/2//examples/dev_flow/debug/step_into_dependencies.html.md#step-into-a-dependency-with-visual-studio) * [Debugging shared libraries with Visual Studio](https://docs.conan.io/2//examples/dev_flow/debug/debugging_visual.html.md) * [Creating a project and debugging as usual](https://docs.conan.io/2//examples/dev_flow/debug/debugging_visual.html.md#creating-a-project-and-debugging-as-usual) * [Removing build files from the Conan cache](https://docs.conan.io/2//examples/dev_flow/debug/debugging_visual.html.md#removing-build-files-from-the-conan-cache) * [Installing a hook to copy the PDBs to the package folder](https://docs.conan.io/2//examples/dev_flow/debug/debugging_visual.html.md#installing-a-hook-to-copy-the-pdbs-to-the-package-folder) * [Debugging without build files](https://docs.conan.io/2//examples/dev_flow/debug/debugging_visual.html.md#debugging-without-build-files) * [Locating the sources path for the debugger](https://docs.conan.io/2//examples/dev_flow/debug/debugging_visual.html.md#locating-the-sources-path-for-the-debugger) * [Using a MinGW as tool_requires to build with gcc in Windows](https://docs.conan.io/2//examples/dev_flow/tool_requires/mingw.html.md) --- https://docs.conan.io/2/examples/extensions.html.md --- # Conan extensions examples #### NOTE Check the [conan-extensions](https://github.com/conan-io/conan-extensions) repository, which hosts useful extensions ready to use or to take inspiration from for your custom ones * [Custom commands](https://docs.conan.io/2//examples/extensions/commands/custom_commands.html.md) * [Custom command: Clean old recipe and package revisions](https://docs.conan.io/2//examples/extensions/commands/clean/custom_command_clean_revisions.html.md) * [Builtin deployers](https://docs.conan.io/2//examples/extensions/deployers/builtin_deployers.html.md) * [Creating a Conan-agnostic deploy of dependencies for developer use](https://docs.conan.io/2//examples/extensions/deployers/dev/development_deploy.html.md) * [Custom deployers](https://docs.conan.io/2//examples/extensions/deployers/custom_deployers.html.md) * [Copy sources from all your dependencies](https://docs.conan.io/2//examples/extensions/deployers/sources/custom_deployer_sources.html.md) * [Package Signing Plugin](https://docs.conan.io/2//examples/extensions/package_signing/package_signing.html.md) * [Signing packages with OpenSSL](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_openssl.html.md) * [Signing packages with Sigstore (Cosign)](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_sigstore.html.md) * [Python build backend](https://docs.conan.io/2//examples/extensions/python/build_backend.html.md) * [Build a Python C/C++ extension using Conan and conan-py-build](https://docs.conan.io/2//examples/extensions/python/build_backend/build_python_extension_with_conan.html.md) --- https://docs.conan.io/2/examples/graph.html.md --- # Graph examples This section contains examples about different types of advanced graphs, using different types of `requires` and `tool_requires`, advanced usage of requirement traits, etc. * [Use a CMake macro packaged in a dependency](https://docs.conan.io/2//examples/graph/requires/consume_cmake_macro.html.md) * [Use cmake modules inside a `tool_requires` transparently](https://docs.conan.io/2//examples/graph/tool_requires/use_cmake_modules.html.md) * [Depending on different versions of the same tool-require](https://docs.conan.io/2//examples/graph/tool_requires/different_versions.html.md) * [Depending on same version of a tool-require with different options](https://docs.conan.io/2//examples/graph/tool_requires/different_options.html.md) * [Using the same requirement as a requires and as a tool_requires](https://docs.conan.io/2//examples/graph/tool_requires/using_protobuf.html.md) --- https://docs.conan.io/2/examples/runners.html.md --- # Conan runners examples #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. * [Creating a Conan package using a Docker runner](https://docs.conan.io/2//examples/runners/docker/basic.html.md) * [Using a docker runner configfile to parameterize a Dockerfile](https://docs.conan.io/2//examples/runners/docker/configfile_build_args.html.md) --- https://docs.conan.io/2/examples/security.html.md --- # Conan security examples * [Using Compiler Sanitizers with Conan](https://docs.conan.io/2//examples/security/sanitizers.html.md) * [AddressSanitizer: index out of bounds](https://docs.conan.io/2//examples/security/sanitizers.html.md#addresssanitizer-index-out-of-bounds) * [UndefinedBehaviorSanitizer: signed integer overflow](https://docs.conan.io/2//examples/security/sanitizers.html.md#undefinedbehaviorsanitizer-signed-integer-overflow) --- https://docs.conan.io/2/examples/tools.html.md --- # Conan recipe tools examples * [CMake](https://docs.conan.io/2//examples/tools/cmake/cmake.html.md) * [CMakeToolchain: Building your project using CMakePresets](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/build_project_cmake_presets.html.md) * [CMakeToolchain: Extending your CMakePresets with Conan generated ones](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/extend_own_cmake_presets.html.md) * [CMakeToolchain: Inject arbitrary CMake variables into dependencies](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/inject_cmake_variables.html.md) * [CMakeToolchain: Using xxx-config.cmake files inside packages](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/use_package_config_cmake.html.md) * [Using CMakeToolchain with different generators: Ninja example](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/use_different_toolchain_generator.html.md) * [CMakeToolchain: Using LLVM/Clang Windows compiler](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/llvm_clang.html.md) * [File interaction](https://docs.conan.io/2//examples/tools/files/files.html.md) * [Patching sources](https://docs.conan.io/2//examples/tools/files/patches/patch_sources.html.md) * [Meson](https://docs.conan.io/2//examples/tools/meson/meson.html.md) * [Build a simple Meson project using Conan](https://docs.conan.io/2//examples/tools/meson/build_simple_meson_project.html.md) * [Create your first Conan package with Meson](https://docs.conan.io/2//examples/tools/meson/create_your_first_package.html.md) * [Bazel](https://docs.conan.io/2//examples/tools/google/bazel.html.md) * [Build a simple Bazel project using Conan](https://docs.conan.io/2//examples/tools/google/bazeltoolchain/build_simple_bazel_project.html.md) * [Build a simple Bazel 7.x project using Conan](https://docs.conan.io/2//examples/tools/google/bazeltoolchain/build_simple_bazel_7x_project.html.md) * [Autotools](https://docs.conan.io/2//examples/tools/autotools/autotools.html.md) * [Build a simple Autotools project with Conan dependencies](https://docs.conan.io/2//examples/tools/autotools/build_project_autotools_toolchain.html.md) * [Create your first Conan package with Autotools](https://docs.conan.io/2//examples/tools/autotools/create_your_first_package.html.md) * [Create your first Conan package with Autotools in Windows (msys2)](https://docs.conan.io/2//examples/tools/autotools/create_your_first_package_windows.html.md) * [AutoTools: Using LLVM/Clang Windows compiler](https://docs.conan.io/2//examples/tools/autotools/llvm_clang.html.md) * [GNU](https://docs.conan.io/2//examples/tools/gnu/gnu.html.md) * [Using PkgConfig.fill_cpp_info with PKG_CONFIG_PATH from a profile](https://docs.conan.io/2//examples/tools/gnu/pkg_config_sysroot.html.md) * [Capturing Git scm information](https://docs.conan.io/2//examples/tools/scm/git/capture_scm/git_capture_scm.html.md) * [Credentials management](https://docs.conan.io/2//examples/tools/scm/git/capture_scm/git_capture_scm.html.md#credentials-management) * [MSBuild](https://docs.conan.io/2//examples/tools/microsoft/msbuild.html.md) * [Create your first Conan package with Visual Studio/MSBuild](https://docs.conan.io/2//examples/tools/microsoft/msbuild/create_your_first_package.html.md) * [System Packages](https://docs.conan.io/2//examples/tools/system/system.html.md) * [Wrapping system requirements in a Conan package](https://docs.conan.io/2//examples/tools/system/system_package/package_manager.html.md) * [Consuming system requirements only when building a package](https://docs.conan.io/2//examples/tools/system/system_package/consuming_system_packages.html.md) --- https://docs.conan.io/2/examples/commands/pkglists.html.md --- # Using packages-lists Packages lists are a powerful and convenient Conan feature that allows to automate and concatenate different Conan commands. Let’s see some common use cases: ## Listing packages and downloading them A first simple use case could be listing some recipes and/or binaries in a server, and then downloading them. We can do any `conan list`, for example, to list all `zlib` versions above `1.2.11`, the latest recipe revision, all Windows binaries for that latest recipe revision, and finally the latest package revision for every binary. #### NOTE If we want to actually download something later, it is necessary to specify a package revision in the `conan list` pattern, such as `latest`, otherwise only the recipes will be downloaded. ```bash $ conan list "zlib/[>1.2.11]#latest:*#latest" -p os=Windows --format=json -r=conancenter > pkglist.json ``` The output of the command is sent in `json` format to the file `pkglist.json` that looks like: ```json "conancenter": { "zlib/1.2.12": { "revisions": { "b1fd071d8a2234a488b3ff74a3526f81": { "timestamp": 1667396813.987, "packages": { "ae9eaf478e918e6470fe64a4d8d4d9552b0b3606": { "revisions": { "19808a47de859c2408ffcf8e5df1fdaf": { } }, "info": { "settings": { "arch": "x86_64", "os": "Windows" } } } } } }, "zlib/1.2.13": { } } ``` The first level in the `pkglist.json` is the “origin” remote or “Local Cache” if the list happens in the cache. In this case, as we listed the packages in `conancenter` remote, that will be the origin. We can now do a download of these recipes and binaries with a single `conan download` invocation: ```bash $ conan download --list=pkglist.json -r=conancenter # Download the recipes and binaries in pkglist.json # And displays a report of the downloaded things ``` ## Downloading from one remote and uploading to a different remote Let’s say that we create a new package list from the packages downloaded in the previous step: ```bash $ conan download --list=pkglist.json -r=conancenter --format=json > downloaded.json # Download the recipes and binaries in pkglist.json # And stores the result in "downloaded.json" ``` The resulting `downloaded.json` will be almost the same as the `pkglist.json` file, but in this case, the “origin” of those packages is the `"Local Cache"` (as the downloaded packages will be in the cache): ```json "Local Cache": { "zlib/1.2.12": { "revisions": { } } } ``` That means that we can now upload this same set of recipes and binaries to a different remote: ```bash $ conan upload --list=downloaded.json -r=myremote -c # Upload those artifacts to the same remote ``` #### NOTE **Best practices** This would be a **slow** mechanism to run promotions between different server repositories. Servers like Artifactory provide ways to directly copy packages from one repository to another without using a client, that are orders of magnitude faster because of file deduplication, so that would be the recommended approach. The presented approach in this section might be used for air-gapped environments and other situations in which it is not possible to do a server-to-server copy. ## Building and uploading packages One of the most interesting flows is the one when some packages are being built in the local cache, with a `conan create` or `conan install --build=xxx` command. Typically, we would like to upload the locally built packages to the server, so they don’t have to be re-built again by others. But we might want to upload only the built binaries, but not all others transitive dependencies, or other packages that we had previously in our local cache. It is possible to compute a package list from the output of a `conan install`, `conan create` and `conan graph info` commands. Then, that package list can be used for the upload. Step by step: First let’s say that we have our own package `mypkg/0.1` and we create it: ```bash $ conan new cmake_lib -d name=mypkg -d version=0.1 $ conan create . --format=json > create.json ``` This will create a json representation of the graph, with information of what packages have been built `"binary": "Build"`: ```json { "graph": { "nodes": { "0": { "ref": "conanfile", "id": "0", "recipe": "Cli", "context": "host", "test": false }, "1": { "ref": "mypkg/0.1#f57cc9a1824f47af2f52df0dbdd440f6", "id": "1", "recipe": "Cache", "package_id": "2401fa1d188d289bb25c37cfa3317e13e377a351", "prev": "75f44d989175c05bc4be2399edc63091", "build_id": null, "binary": "Build" } } } ``` We can compute a package list from this file, and then upload those artifacts to the server with: ```bash $ conan list --graph=create.json --graph-binaries=build --format=json > pkglist.json # Create a pkglist.json with the known list of recipes and binaries built from sources $ conan upload --list=pkglist.json -r=myremote -c ``` ## Removing packages lists It is also possible to first `conan list` and create a list of things to remove, and then remove them: ```bash # Removes everything from the cache $ conan list "*#*" --format=json > pkglist.json $ conan remove --list=pkglist.json -c ``` Note that in this case, the default patterns are different in `list` and `remove`, because of the destructive nature of `conan remove`: - When a recipe is passed to `remove` like `conan remove zlib/1.2.13`, it will remove the recipe of `zlib/1.2.13` and all of its binaries, because the binaries cannot live without the recipe. - When a `package_id` is passed, like `conan remove zlib/1.2.13:package_id`, then that specific `package_id` will be removed, but the recipe will not Then the pattern to remove everything will be different if we call directly `conan remove` or if we call first `conan list`, for example: ```bash # Removes everything from the cache $ conan remove "*" # OR via list, we need to explicitly include all revisions $ conan list "*#*" --format=json > pkglist.json $ conan remove --list=pkglist.json -c # Removes only the binaries from the cache (leave recipes) $ conan remove "*:*" # OR via list, we need to explicitly include all revisions $ conan list "*#*:*" --format=json > pkglist.json $ conan remove --list=pkglist.json -c ``` For more information see the [Reference commands section](https://docs.conan.io/2//reference/commands.html.md#reference-commands) --- https://docs.conan.io/2/examples/conanfile/layout.html.md --- # ConanFile layout() examples * [Declaring the layout when the Conanfile is inside a subfolder](https://docs.conan.io/2//examples/conanfile/layout/conanfile_in_subfolder.html.md) * [Declaring the layout when creating packages for third-party libraries](https://docs.conan.io/2//examples/conanfile/layout/third_party_libraries.html.md) * [Declaring the layout when we have multiple subprojects](https://docs.conan.io/2//examples/conanfile/layout/multiple_subprojects.html.md) * [Using components and editable packages](https://docs.conan.io/2//examples/conanfile/layout/editable_components.html.md) --- https://docs.conan.io/2/examples/conanfile/package_info.html.md --- # ConanFile package_info() examples * [Propagating environment or configuration information to consumers](https://docs.conan.io/2//examples/conanfile/package_info/package_info_conf_and_env.html.md) * [Define components for Conan packages that provide multiple libraries](https://docs.conan.io/2//examples/conanfile/package_info/components.html.md) --- https://docs.conan.io/2/examples/conanfile/layout/conanfile_in_subfolder.html.md --- # Declaring the layout when the Conanfile is inside a subfolder Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/conanfile/layout/conanfile_in_subfolder ``` If we have a project intended to package the code that is in the same repo as the `conanfile.py`, but the `conanfile.py` is not in the root of the project: ```text . ├── CMakeLists.txt ├── conan │ └── conanfile.py ├── include │ └── say.h └── src └── say.cpp ``` The `conanfile.py` would look like this: ```python import os from conan import ConanFile from conan.tools.files import load, copy from conan.tools.cmake import CMake class PkgSay(ConanFile): name = "say" version = "1.0" settings = "os", "compiler", "build_type", "arch" generators = "CMakeToolchain" def layout(self): # The root of the project is one level above self.folders.root = ".." # The source of the project (the root CMakeLists.txt) is the source folder self.folders.source = "." self.folders.build = "build" def export_sources(self): # The path of the CMakeLists.txt and sources we want to export are one level above folder = os.path.join(self.recipe_folder, "..") copy(self, "*.txt", folder, self.export_sources_folder) copy(self, "src/*.cpp", folder, self.export_sources_folder) copy(self, "include/*.h", folder, self.export_sources_folder) def source(self): # Check that we can see that the CMakeLists.txt is inside the source folder cmake_file = load(self, "CMakeLists.txt") def build(self): # Check that the build() method can also access the CMakeLists.txt in the source folder path = os.path.join(self.source_folder, "CMakeLists.txt") cmake_file = load(self, path) cmake = CMake(self) cmake.configure() cmake.build() def package(self): cmake = CMake(self) cmake.install() ``` You can try and create the `say` package: ```bash $ cd conan $ conan create . ``` #### SEE ALSO - [layout method](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md#reference-conanfile-methods-layout) - [how the package layout works](https://docs.conan.io/2//tutorial/developing_packages/package_layout.html.md#tutorial-package-layout). --- https://docs.conan.io/2/examples/conanfile/layout/editable_components.html.md --- # Using components and editable packages It is possible to define components in the `layout()` method, to support the case of `editable` packages. That is, if we want to put a package in `editable` mode, and that package defines `components`, it is necessary to define the components layout correctly in the `layout()` method. Let’s see it in a real example. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/conanfile/layout/editable_components ``` There we find a `greetings` subfolder and package, that contains 2 libraries, the `hello` library and the `bye` library. Each one is modeled as a `component` inside the package recipe: ```python class GreetingsConan(ConanFile): name = "greetings" version = "0.1" settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" exports_sources = "src/*" def build(self): cmake = CMake(self) cmake.configure() cmake.build() def layout(self): cmake_layout(self, src_folder="src") # This "includedirs" starts in the source folder, which is "src" # So the components include dirs is the "src" folder (includes are # intended to be included as ``#include "hello/hello.h"``) self.cpp.source.components["hello"].includedirs = ["."] self.cpp.source.components["bye"].includedirs = ["."] # compiled libraries "libdirs" will be inside the "build" folder, depending # on the platform they will be in "build/Release" or directly in "build" folder bt = "." if self.settings.os != "Windows" else str(self.settings.build_type) self.cpp.build.components["hello"].libdirs = [bt] self.cpp.build.components["bye"].libdirs = [bt] def package(self): copy(self, "*.h", src=self.source_folder, dst=join(self.package_folder, "include")) copy(self, "*.lib", src=self.build_folder, dst=join(self.package_folder, "lib"), keep_path=False) copy(self, "*.a", src=self.build_folder, dst=join(self.package_folder, "lib"), keep_path=False) def package_info(self): self.cpp_info.components["hello"].libs = ["hello"] self.cpp_info.components["bye"].libs = ["bye"] self.cpp_info.set_property("cmake_file_name", "MYG") self.cpp_info.set_property("cmake_target_name", "MyGreetings::MyGreetings") self.cpp_info.components["hello"].set_property("cmake_target_name", "MyGreetings::MyHello") self.cpp_info.components["bye"].set_property("cmake_target_name", "MyGreetings::MyBye") ``` While the location of the `hello` and `bye` libraries in the final package is in the final `lib` folder, then nothing special is needed in the `package_info()` method, beyond the definition of the components. In this case, the customization of the CMake generated filenames and targets is also included, but it is not necessary for this example. The important part is the `layout()` definition. Besides the common `cmake_layout`, it is necessary to define the location of the components headers (`self.cpp.source` as they are source code) and the location of the locally built libraries. As the location of the libraries depends on the platform, the final `self.cpp.build.components["component"].libdirs` depends on the platform. With this recipe we can put the package in editable mode and locally build it with: ```bash $ conan editable add greetings $ conan build greetings # we might want to also build the debug config ``` In the `app` folder we have a package recipe to build 2 executables, that link with the `greeting` package components. The `app/conanfile.py` recipe there is simple, the `build()` method builds and runs both `example` and `example2` executables that are built with `CMakeLists.txt`: ```cmake # Note the MYG file name, not matching the package name, # because the recipe defined "cmake_file_name" find_package(MYG) add_executable(example example.cpp) # Note the MyGreetings::MyGreetings target name, not matching the package name, # because the recipe defined "cmake_target_name" # "example" is linking with the whole package, both "hello" and "bye" components target_link_libraries(example MyGreetings::MyGreetings) add_executable(example2 example2.cpp) # "example2" is only using and linking "hello" component, but not "bye" target_link_libraries(example2 MyGreetings::MyHello) ``` ```bash $ conan build app hello: Release! bye: Release! ``` If you now go to the `bye.cpp` source file and modify the output message, then build `greetings` and `app` locally, the final output message for the “bye” component library should change: ```bash $ conan build greetings $ conan build app hello: Release! adios: Release! ``` --- https://docs.conan.io/2/examples/conanfile/layout/multiple_subprojects.html.md --- # Declaring the layout when we have multiple subprojects Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/conanfile/layout/multiple_subprojects ``` Let’s say that we have a project that contains two subprojects: *hello* and *bye*, that need to access some information that is at their same level (sibling folders). Each subproject would be a Conan package. The structure could be something similar to this: ```text . ├── bye │ ├── CMakeLists.txt │ ├── bye.cpp # contains an #include "../common/myheader.h" │ └── conanfile.py # contains include(../common/myutils.cmake) ├── common │ ├── myheader.h │ └── myutils.cmake └── hello ├── CMakeLists.txt # contains include(../common/myutils.cmake) ├── conanfile.py └── hello.cpp # contains an #include "../common/myheader.h" ``` Both *hello* and *bye* subprojects needs to use some of the files located inside the `common` folder (that might be used and shared by other subprojects too), and it references them by their relative location. Note that `common` is not intended to be a Conan package. It is just some common code that will be copied into the different subproject packages. We can use the `self.folders.root = ".."` layout specifier to locate the root of the project, then use the `self.folders.subproject = "subprojectfolder"` to relocate back most of the layout to the current subproject folder, as it would be the one containing the build scripts, sources code, etc., so other helpers like `cmake_layout()` keep working. Let’s see how the *conanfile.py* of *hello* could look like: ```python import os from conan import ConanFile from conan.tools.cmake import cmake_layout, CMake from conan.tools.files import copy class hello(ConanFile): name = "hello" version = "1.0" settings = "os", "compiler", "build_type", "arch" generators = "CMakeToolchain" def layout(self): self.folders.root = ".." self.folders.subproject = "hello" cmake_layout(self) def export_sources(self): source_folder = os.path.join(self.recipe_folder, "..") copy(self, "hello/conanfile.py", source_folder, self.export_sources_folder) copy(self, "hello/CMakeLists.txt", source_folder, self.export_sources_folder) copy(self, "hello/hello.cpp", source_folder, self.export_sources_folder) copy(self, "common*", source_folder, self.export_sources_folder) def build(self): cmake = CMake(self) cmake.configure() cmake.build() self.run(os.path.join(self.cpp.build.bindirs[0], "hello")) ``` Let’s build *hello* and check that it’s building correctly, using the contents of the common folder. ```bash $ conan install hello $ conan build hello ... [100%] Built target hello conanfile.py (hello/1.0): RUN: ./hello hello WORLD ``` You can also run a **conan create** and check that it works fine too: ```bash $ conan create hello ... [100%] Built target hello conanfile.py (hello/1.0): RUN: ./hello hello WORLD ``` #### NOTE Note the importance of the `export_sources()` method, which is able to maintain the same relative layout of the `hello` and `common` folders, both in the local developer flow in the current folder, but also when those sources are copied to the Conan cache, to be built there with `conan create` or `conan install --build=hello`. This is one of the design principles of the `layout()`, the relative location of things must be consistent in the user folder and in the cache. #### SEE ALSO - Read more about the [layout method](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md#reference-conanfile-methods-layout) and [how the package layout works](https://docs.conan.io/2//tutorial/developing_packages/package_layout.html.md#tutorial-package-layout). --- https://docs.conan.io/2/examples/conanfile/layout/third_party_libraries.html.md --- # Declaring the layout when creating packages for third-party libraries Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/conanfile/layout/third_party_libraries ``` If we have this project, intended to create a package for a third-party library whose code is located externally: ```text . ├── conanfile.py └── patches └── mypatch ``` The `conanfile.py` would look like this: ```python ... class Pkg(ConanFile): name = "hello" version = "1.0" exports_sources = "patches*" ... def layout(self): cmake_layout(self, src_folder="src") # if you are declaring your own layout, just declare: # self.folders.source = "src" def source(self): # we are inside a "src" subfolder, as defined by layout # the downloaded soures will be inside the "src" subfolder get(self, "https://github.com/conan-io/libhello/archive/refs/heads/main.zip", strip_root=True) # Please, be aware that using the head of the branch instead of an immutable tag # or commit is not a good practice in general as the branch may change the contents # patching, replacing, happens here patch(self, patch_file=os.path.join(self.export_sources_folder, "patches/mypatch")) def build(self): # If necessary, the build() method also has access to the export_sources_folder # for example if patching happens in build() instead of source() #patch(self, patch_file=os.path.join(self.export_sources_folder, "patches/mypatch")) cmake = CMake(self) cmake.configure() cmake.build() ... ``` We can see that the `ConanFile.export_sources_folder` attribute can provide access to the root folder of the sources: - Locally it will be the folder where the `conanfile.py` lives - In the cache it will be the “source” folder, that will contain a copy of `CMakeLists.txt` and `patches`, while the “source/src” folder will contain the actual downloaded sources. We can check that everything runs fine now: ```bash $ conan create . ... Downloading main.zip hello/1.0: Unzipping 3.7KB Unzipping 100 % ... [ 50%] Building CXX object CMakeFiles/hello.dir/src/hello.cpp.o [100%] Linking CXX static library libhello.a [100%] Built target hello ... $ conan list hello/1.0 Local Cache hello hello/1.0 ``` #### SEE ALSO - Read more about the [layout method](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md#reference-conanfile-methods-layout) and [how the package layout works](https://docs.conan.io/2//tutorial/developing_packages/package_layout.html.md#tutorial-package-layout). --- https://docs.conan.io/2/examples/conanfile/package_info/components.html.md --- # Define components for Conan packages that provide multiple libraries At the [section of the tutorial about the package_info() method](https://docs.conan.io/2//tutorial/creating_packages/define_package_information.html.md#tutorial-creating-define-package-info), we learned how to define information in a package for consumers, such as library names or include and library folders. In the tutorial, we created a package with only one library that consumers linked to. However, in some cases, libraries provide their functionalities separated into different *components*. These components can be consumed independently, and in some cases, they may require other components from the same library or others. For example, consider a library like OpenSSL that provides *libcrypto* and *libssl*, where *libssl* depends on *libcrypto*. Conan provides a way to abstract this information using the components attribute of the CppInfo object to define the information for each separate component of a Conan package. Consumers can also select specific components to link against but not the rest of the package. Let’s take a game-engine library as an example, which provides several components such as *algorithms*, *ai*, *rendering*, and *network*. Both *ai* and *rendering* depend on the *algorithms* component. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/conanfile/package_info/components ``` You can check the contents of the project: ```text . ├── CMakeLists.txt ├── conanfile.py ├── include │ ├── ai.h │ ├── algorithms.h │ ├── network.h │ └── rendering.h ├── src │ ├── ai.cpp │ ├── algorithms.cpp │ ├── network.cpp │ └── rendering.cpp └── test_package ├── CMakeLists.txt ├── CMakeUserPresets.json ├── conanfile.py └── src └── example.cpp ``` As you can see, there are sources for each of the components and a CMakeLists.txt file to build them. We also have a test_package that we are going to use to test the consumption of the separate components. First, let’s have a look at package_info() method in the *conanfile.py* and how we declared the information for each component that we want to provide to the consumers of the game-engine package: ```python ... def package_info(self): self.cpp_info.components["algorithms"].libs = ["algorithms"] self.cpp_info.components["algorithms"].set_property("cmake_target_name", "algorithms") self.cpp_info.components["network"].libs = ["network"] self.cpp_info.components["network"].set_property("cmake_target_name", "network") self.cpp_info.components["ai"].libs = ["ai"] self.cpp_info.components["ai"].requires = ["algorithms"] self.cpp_info.components["ai"].set_property("cmake_target_name", "ai") self.cpp_info.components["rendering"].libs = ["rendering"] self.cpp_info.components["rendering"].requires = ["algorithms"] self.cpp_info.components["rendering"].set_property("cmake_target_name", "rendering") ``` There are a couple of relevant things: - We declare the libraries generated by each of the components by setting information in the `cpp_info.components` attribute. You can set the same information for each of the components as you would for the `self.cpp_info` object. The `cpp_info` for components has some defaults defined, just like it does for [self.cpp_info](https://docs.conan.io/2//tutorial/creating_packages/define_package_information.html.md#tutorial-creating-define-package-info). For example, the `cpp_info.components` object provides the `.includedirs` and `.libdirs` properties to define those locations, but Conan sets their value as `["lib"]` and `["include"]` by default, so it’s not necessary to add them in this case. - We are also declaring the components’ dependencies using the `.requires` attribute. With this attribute, you can declare requirements at the component level, not only for components in the same recipe but also for components from other packages that are declared as requires of the Conan package. - We are changing the default target names for the components using the [properties model](https://docs.conan.io/2//tutorial/creating_packages/define_package_information.html.md#tutorial-creating-define-package-info-properties). By default, Conan sets a target name for components like ``, but for this tutorial we will set the component target names just with the component names omitting the `::`. - When `cpp_info` has global build information (e.g. `cpp_info.defines`), it does not inherit to the components. If you want to share this information with the components, you need to set it explicitly for each component. You can have a look at the consumer part by checking the *test_package* folder. First the *conanfile.py*: ```python ... def generate(self): deps = CMakeDeps(self) deps.check_components_exist = True deps.generate() ``` You can see that we are setting the [check_components_exist](https://docs.conan.io/2//reference/tools/cmake/cmakedeps.html.md#conan-tools-cmakedeps-check-components-exist) property for CMakeDeps. This is not needed, just to show how you can do if you want your consumers to fail if the component does not exist. So, the CMakeLists.txt could look like this: ```text cmake_minimum_required(VERSION 3.15) project(PackageTest CXX) find_package(game-engine REQUIRED COMPONENTS algorithms network ai rendering) add_executable(example src/example.cpp) target_link_libraries(example algorithms network ai rendering) ``` And the `find_package()` call would fail if any of the components targets do not exist. Let’s run the example: ```text $ conan create . ... game-engine/1.0: RUN: cmake --build "/Users/barbarian/.conan2/p/t/game-d6e361d329116/b/build/Release" -- -j16 [ 12%] Building CXX object CMakeFiles/algorithms.dir/src/algorithms.cpp.o [ 25%] Building CXX object CMakeFiles/network.dir/src/network.cpp.o [ 37%] Linking CXX static library libnetwork.a [ 50%] Linking CXX static library libalgorithms.a [ 50%] Built target network [ 50%] Built target algorithms [ 62%] Building CXX object CMakeFiles/ai.dir/src/ai.cpp.o [ 75%] Building CXX object CMakeFiles/rendering.dir/src/rendering.cpp.o [ 87%] Linking CXX static library libai.a [100%] Linking CXX static library librendering.a [100%] Built target ai [100%] Built target rendering ... ======== Launching test_package ======== ... -- Conan: Component target declared 'algorithms' -- Conan: Component target declared 'network' -- Conan: Component target declared 'ai' -- Conan: Component target declared 'rendering' ... [ 50%] Building CXX object CMakeFiles/example.dir/src/example.cpp.o [100%] Linking CXX executable example [100%] Built target example ======== Testing the package: Executing test ======== game-engine/1.0 (test package): Running test() game-engine/1.0 (test package): RUN: ./example I am the algorithms component! I am the network component! I am the ai component! └───> I am the algorithms component! I am the rendering component! └───> I am the algorithms component! ``` You could check that requiring a component that does not exist will raise an error. Add the *nonexistent* component to the find_package() call: ```text cmake_minimum_required(VERSION 3.15) project(PackageTest CXX) find_package(game-engine REQUIRED COMPONENTS nonexistent algorithms network ai rendering) add_executable(example src/example.cpp) target_link_libraries(example algorithms network ai rendering) ``` And test the package again: ```text $ conan test test_package game-engine/1.0 ... Conan: Component 'nonexistent' NOT found in package 'game-engine' Call Stack (most recent call first): CMakeLists.txt:4 (find_package) -- Configuring incomplete, errors occurred! ... ERROR: game-engine/1.0 (test package): Error in build() method, line 22 cmake.configure() ConanException: Error 1 while executing ``` #### SEE ALSO If you want to use recipes defining components in `editable` mode, check the example in [Using components and editable packages](https://docs.conan.io/2//examples/conanfile/layout/editable_components.html.md#examples-conanfile-layout-components-editables). --- https://docs.conan.io/2/examples/conanfile/package_info/package_info_conf_and_env.html.md --- # Propagating environment or configuration information to consumers TBD --- https://docs.conan.io/2/examples/config_files/settings/settings_user.html.md --- # Customize your settings: create your settings_user.yml Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/config_files/settings_user ``` In this example we are going to see how to customize your settings without overwriting the original **settings.yml** file. #### NOTE To understand better this example, it is highly recommended to read previously the reference about [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md#reference-config-files-settings-yml). ## Locate the settings_user.yml First of all, let’s have a look at the proposed `source/settings_user.yml`: ```yaml os: webOS: sdk_version: [null, "7.0.0", "6.0.1", "6.0.0"] arch: ["cortexa15t2hf"] compiler: gcc: version: ["13.0-rc"] ``` As you can see, we don’t have to rewrite all the settings because they will be merged with the already defined in **settings.yml**. Then, what are we adding through that `settings_user.yml` file? * New OS: `webOS`, and its sub-setting: `sdk_version`. * New `arch` available: `cortexa15t2hf`. * New gcc version: `13.0-rc`. Now, it’s time to copy the file `source/settings_user.yml` into your `[CONAN_HOME]/` folder: ```bash $ conan config install sources/settings_user.yml Copying file settings_user.yml to /Users/myuser/.conan2/. ``` ## Use your new settings After having copied the `settings_user.yml`, you should be able to use them for your recipes. Add this simple one into your local folder: ```python from conan import ConanFile class PkgConan(ConanFile): name = "pkg" version = "1.0" settings = "os", "compiler", "build_type", "arch" ``` Then, create several Conan packages (not binaries, as it does not have any source file for sure) to see that it’s working correctly: ```bash $ conan create . -s os=webOS -s os.sdk_version=7.0.0 ... Profile host: [settings] arch=x86_64 build_type=Release compiler=apple-clang compiler.cppstd=gnu98 compiler.libcxx=libc++ compiler.version=12.0 os=webOS os.sdk_version=7.0.0 Profile build: [settings] arch=x86_64 build_type=Release compiler=apple-clang compiler.cppstd=gnu98 compiler.libcxx=libc++ compiler.version=12.0 os=Macos ... -------- Installing (downloading, building) binaries... -------- pkg/1.0: Copying sources to build folder pkg/1.0: Building your package in /Users/myuser/.conan2/p/t/pkg929d53a5f06b1/b pkg/1.0: Generating aggregated env files pkg/1.0: Package 'a0d37d10fdb83a0414d7f4a1fb73da2c210211c6' built pkg/1.0: Build folder /Users/myuser/.conan2/p/t/pkg929d53a5f06b1/b pkg/1.0: Generated conaninfo.txt pkg/1.0: Generating the package pkg/1.0: Temporary package folder /Users/myuser/.conan2/p/t/pkg929d53a5f06b1/p pkg/1.0 package(): WARN: No files in this package! pkg/1.0: Package 'a0d37d10fdb83a0414d7f4a1fb73da2c210211c6' created pkg/1.0: Created package revision 6a947a7b5669d6fde1a35ce5ff987fc6 pkg/1.0: Full package reference: pkg/1.0#637fc1c7080faaa7e2cdccde1bcde118:a0d37d10fdb83a0414d7f4a1fb73da2c210211c6#6a947a7b5669d6fde1a35ce5ff987fc6 pkg/1.0: Package folder /Users/myuser/.conan2/p/pkgb3950b1043542/p ``` ```bash $ conan create . -s compiler=gcc -s compiler.version=13.0-rc -s compiler.libcxx=libstdc++11 ... Profile host: [settings] arch=x86_64 build_type=Release compiler=gcc compiler.libcxx=libstdc++11 compiler.version=13.0-rc os=Macos Profile build: [settings] arch=x86_64 build_type=Release compiler=apple-clang compiler.cppstd=gnu98 compiler.libcxx=libc++ compiler.version=12.0 os=Macos ... -------- Installing (downloading, building) binaries... -------- pkg/1.0: Copying sources to build folder pkg/1.0: Building your package in /Users/myuser/.conan2/p/t/pkg918904bbca9dc/b pkg/1.0: Generating aggregated env files pkg/1.0: Package '44a4588d3fe63ccc6e7480565d35be38d405718e' built pkg/1.0: Build folder /Users/myuser/.conan2/p/t/pkg918904bbca9dc/b pkg/1.0: Generated conaninfo.txt pkg/1.0: Generating the package pkg/1.0: Temporary package folder /Users/myuser/.conan2/p/t/pkg918904bbca9dc/p pkg/1.0 package(): WARN: No files in this package! pkg/1.0: Package '44a4588d3fe63ccc6e7480565d35be38d405718e' created pkg/1.0: Created package revision d913ec060e71cc56b10768afb9620094 pkg/1.0: Full package reference: pkg/1.0#637fc1c7080faaa7e2cdccde1bcde118:44a4588d3fe63ccc6e7480565d35be38d405718e#d913ec060e71cc56b10768afb9620094 pkg/1.0: Package folder /Users/myuser/.conan2/p/pkg789b624c93fc0/p ``` ```bash $ conan create . -s os=webOS -s arch=cortexa15t2hf ... Profile host: [settings] arch=cortexa15t2hf build_type=Release compiler=apple-clang compiler.cppstd=gnu98 compiler.libcxx=libc++ compiler.version=12.0 os=webOS Profile build: [settings] arch=x86_64 build_type=Release compiler=apple-clang compiler.cppstd=gnu98 compiler.libcxx=libc++ compiler.version=12.0 os=Macos ... -------- Installing (downloading, building) binaries... -------- pkg/1.0: Copying sources to build folder pkg/1.0: Building your package in /Users/myuser/.conan2/p/t/pkgde9b63a6bed0a/b pkg/1.0: Generating aggregated env files pkg/1.0: Package '19cf3cb5842b18dc78e5b0c574c1e71e7b0e17fc' built pkg/1.0: Build folder /Users/myuser/.conan2/p/t/pkgde9b63a6bed0a/b pkg/1.0: Generated conaninfo.txt pkg/1.0: Generating the package pkg/1.0: Temporary package folder /Users/myuser/.conan2/p/t/pkgde9b63a6bed0a/p pkg/1.0 package(): WARN: No files in this package! pkg/1.0: Package '19cf3cb5842b18dc78e5b0c574c1e71e7b0e17fc' created pkg/1.0: Created package revision f5739d5a25b3757254dead01b30d3af0 pkg/1.0: Full package reference: pkg/1.0#637fc1c7080faaa7e2cdccde1bcde118:19cf3cb5842b18dc78e5b0c574c1e71e7b0e17fc#f5739d5a25b3757254dead01b30d3af0 pkg/1.0: Package folder /Users/myuser/.conan2/p/pkgd154182aac59e/p ``` As you could observe, each command has created a different package. That was completely right because we were using different settings for each one. If you want to see all the packages created, you can use the [conan list](https://docs.conan.io/2//reference/commands/list.html.md#reference-commands-list) command: ```bash $ conan list pkg/1.0:* Local Cache pkg pkg/1.0 revisions 637fc1c7080faaa7e2cdccde1bcde118 (2023-02-16 06:42:10 UTC) packages 19cf3cb5842b18dc78e5b0c574c1e71e7b0e17fc info settings arch: cortexa15t2hf build_type: Release compiler: apple-clang compiler.cppstd: gnu98 compiler.libcxx: libc++ compiler.version: 12.0 os: webOS 44a4588d3fe63ccc6e7480565d35be38d405718e info settings arch: x86_64 build_type: Release compiler: gcc compiler.libcxx: libstdc++11 compiler.version: 13.0-rc os: Macos a0d37d10fdb83a0414d7f4a1fb73da2c210211c6 info settings arch: x86_64 build_type: Release compiler: apple-clang compiler.cppstd: gnu98 compiler.libcxx: libc++ compiler.version: 12.0 os: webOS os.sdk_version: 7.0.0 ``` Try any other custom setting! #### SEE ALSO - [profiles](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles). - [Conan packages binary compatibility: the package ID](https://docs.conan.io/2//tutorial/creating_packages/configure_options_settings.html.md#creating-packages-configure-options-settings) --- https://docs.conan.io/2/examples/cross_build/emscripten.html.md --- # Cross-building with Emscripten - WebAssembly and asm.js This example demonstrates how to cross-build a simple C++ project using Emscripten and Conan. Conan supports [WASM](https://webassembly.org) cross compilation, giving you the flexibility to target different JavaScript/WebAssembly runtimes in the browser. We recommend creating separate Conan profiles for each target. Below are recommended profiles and instructions on how to build with them. ## Setting up Conan profile for WebAssembly (WASM) ```text [settings] arch=wasm build_type=Release compiler=emcc compiler.cppstd=17 compiler.libcxx=libc++ # Optional settings to enable multithreading (see note below) # compiler.threads=posix compiler.version=4.0.10 os=Emscripten [tool_requires] emsdk/4.0.10 [conf] # Optional settings to enable memory allocation tools.build:exelinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] tools.build:sharedlinkflags=['-sALLOW_MEMORY_GROWTH=1', '-sMAXIMUM_MEMORY=4GB', '-sINITIAL_MEMORY=64MB'] ``` #### NOTE Conan also supports building for [asm.js](http://asmjs.org) targets, which is a nowadays considered deprecated. What’s the difference between asm.js and WASM? - **asm.js** is a subset of JavaScript optimized for speed. It is fully supported by all browsers (even older ones) and compiles to a large `.js` file. - **WebAssembly (WASM)** is a binary format that is smaller and faster to load and execute. Most modern browsers support it, and it is generally recommended for new projects. **WASM** is also easier to integrate with native browser APIs compared to **asm.js**. Even though Emscripten is not a true runtime environment (like Linux or Windows), it is part of a toolchain ecosystem that compiles C/C++ to WebAssembly (WASM) and asm.js. Conan uses `os=Emscripten` to: - Align with the toolchain: Emscripten integrates the compiler, runtime glue, and JavaScript environment, making it practical to treat as an “OS-like” target. - Support backward compatibility: Many recipes in Conan Center Index use `os=Emscripten` to enable or disable features and dependencies that specifically target Emscripten. - Maintain stability: Changing this setting would break recipes that rely on it, and would complicate compatibility with alternative WASM toolchains. #### NOTE `wasm` arch refers to `WASM 32-bit` target architecture, which is the default. If you wish to target `WASM64`, set `arch=wasm64` in your profile. **Note that WASM64 is still experimental** and requires Node.js v20+ and a browser that supports it. #### IMPORTANT According to [emscripten documentation](https://emscripten.org/docs/api_reference/wasm_workers.html) Emscripten supports two multithreading APIs: - POSIX Threads API (`posix` in conan profile) - Wasm Workers API (`wasm_workers` in conan profile) These two APIs are incompatible with each other and incompatibles with binaries compiled without threading support. This incompatibility necessitates the modeling of threading usage within the compiler’s binary model, allowing conan to distinguish between binaries compiled with threading and those compiled without it. Conan will automatically set compiler and linker flags to enable threading if configured in the profile. The profiles above use the `emsdk` package from [Conan Center Index repository](https://conan.io/center/recipes/emsdk), which provides the Emscripten SDK, including `emcc`, `em++`, and tools like `emrun` and `node`. If you prefer to use your system-installed Emscripten instead of the Conan-provided one, `tool_requires` could be replaced by custom `compiler_executables` and `buildenv`: ```text [conf] tools.build:compiler_executables={'c':'/path/to/emcc', 'cpp':'/path/to/em++'} [buildenv] CC=emcc CXX=em++ AR=emar NM=emnm RANLIB=emranlib STRIP=emstrip ``` This way conan could configure emsdk local installation to be used from CMake, Meson, Autotools or other build systems. In some cases, you might also need the `Emscripten.cmake` toolchain file for advanced scenarios. This toolchais is already added in our packaged emsdk but if you are using your own Emscripten installation, you can specify it in the profile by using [tools.cmake.cmaketoolchain:user_toolchain](https://docs.conan.io/2//reference/tools/cmake/cmaketoolchain.html.md#conan-cmake-user-toolchain) and providing the absolute path to your toolchain file. #### NOTE The `tools.build:exelinkflags` and `tools.build:sharedlinkflags` in previous profiles are recomendations but users can modify them or define their values in the CMakeLists.txt file using the `set_target_properties()` command. - By enabling `ALLOW_MEMORY_GROWTH` we allow the runtime to grow its memory dynamically at runtime by calling `emscripten_resize_heap()`. Without this flag, memory is allocated at startup and cannot grow. - The `MAXIMUM_MEMORY` and `INITIAL_MEMORY` values specifies the maximum and initial memory size for the Emscripten runtime. These values can be adjusted based on your application’s needs. Take into account that `arch=wasm64` has a theorical exabytes maximum memory size, but runtime currently limits it to 16GB, while `arch=wasm32` has a maximum memory size of 4GB and `arch=asm.js` has a maximum memory size of 2GB. #### IMPORTANT `emcc` compiler does not guarantee any ABI compatibility between different versions (patches included) To ensure a new `package_id` is generated when the Emscripten version changes, it is recommended to update the `compiler.version` setting in your profile accordingly. This will ensure that the package ID is generated based on the Emscripten version, allowing Conan to detect changes in the Emscripten toolchain and rebuild the project accordingly. --- https://docs.conan.io/2/examples/cross_build/linux_to_windows_mingw.html.md --- # Cross-compiling from Linux to Windows with MinGW It is possible to cross-build from Linux to Windows using the MinGW cross-compiler. Note that such a compiler won’t be using the MSVC runtime, but the MinGW one, which uses the `libstdc++6.dll` runtime. This [blog post about Clang in Windows](https://blog.conan.io/2022/10/13/Different-flavors-Clang-compiler-Windows.html) describes the different runtimes for the different Windows subsystems, which is equally applicable to MinGW. The first step would be to install the compiler. In Debian based systems: ```bash $ sudo apt install gcc-mingw-w64-x86-64-posix $ sudo apt install g++-mingw-w64-x86-64-posix ``` If the compiler is installed in the system path, then we could write a profile like: ```text [settings] os=Windows compiler=gcc compiler.version=10 compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 arch=x86_64 build_type=Release [buildenv] CC=x86_64-w64-mingw32-gcc-posix CXX=x86_64-w64-mingw32-g++-posix ``` Then, let’s say that we have a basic CMake project, which we can create with the `conan new`: ```bash $ conan new cmake_lib -d name=mypkg -d version=0.1 $ conan create . -pr=mingw ... -- Using Conan toolchain: .../conan_toolchain.cmake -- Conan toolchain: Defining architecture flag: -m64 -- Conan toolchain: C++ Standard 17 with extensions ON -- The CXX compiler identification is GNU 10.0.0 -- Check for working CXX compiler: /usr/bin/x86_64-w64-mingw32-g++-posix - skipped mypkg/0.1 (test package): Running CMake.build() mypkg/0.1 (test package): RUN: cmake --build ... gcc-10-x86_64-gnu17-release" -- -j8 [ 50%] Building CXX object CMakeFiles/example.dir/src/example.cpp.obj [100%] Linking CXX executable example.exe [100%] Built target example ``` The example.exe will not be executed in the Linux machine, because the `test_package` contains a `if can_run(self)` branch to not run it in cross-build scenarios. We can now take the `example.exe` and run it in a Windows machine: ```bash mypkg/0.1: Hello World Release! mypkg/0.1: _M_X64 defined mypkg/0.1: __x86_64__ defined mypkg/0.1: _GLIBCXX_USE_CXX11_ABI 1 mypkg/0.1: MSVC runtime: MultiThreadedDLL mypkg/0.1: __cplusplus201402 mypkg/0.1: __GNUC__10 mypkg/0.1: __MINGW32__1 mypkg/0.1: __MINGW64__1 ``` #### NOTE - It is very possible that some recipes in ConanCenter are not prepared to be cross-built from Linux to Windows. The recommended way to build ConanCenter recipes is to build them with MSVC in Windows, as there might be limitations for the specific build-systems of the recipes, and MinGW support is not guaranteed. - Trying to run the executables with some emulators like `wine` might require extra effort, because the runtime environment is intended to be Windows, and as such a `conanrun.bat` environment file will be created, but that cannot be executed in Linux. Using configurations like `-c tools.build.cross_building:can_run=True -c tools.microsoft.bash:subsystem=mingw -c tools.microsoft.bash:active=True` can allow to force the generation and execution of `conanrun.sh`. --- https://docs.conan.io/2/examples/cross_build/toolchain_packages.html.md --- # Creating a Conan package for a toolchain After learning how to create recipes for tool requires that package applications, we are going to show an example on how to create a recipe that packages a precompiled toolchain or compiler for building other packages. In the “[How to cross-compile your applications using Conan: host and build contexts](https://docs.conan.io/2//tutorial/consuming_packages/cross_building_with_conan.html.md#consuming-packages-cross-building-with-conan)” tutorial section, we discussed the basics of cross-compiling applications using Conan with a focus on the “build” and “host” contexts. We learned how to configure Conan to use different profiles for the build machine and the target host machine, enabling us to cross-compile applications for platforms like Raspberry Pi from an Ubuntu Linux machine. However, in that section, we assumed the existence of a cross-compiling toolchain or compiler as part of the build environment, set up through Conan profiles. Now, we will take a step further by demonstrating how to create a Conan package for such a toolchain. This package can then be used as a tool_require in other Conan recipes, simplifying the process of setting up the environment for cross-compilation. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/cross_build/toolchain_packages/toolchain ``` Here, you will find a Conan recipe (and the *test_package*) to package an ARM toolchain for cross-compiling to Linux ARM for both 32 and 64 bits. To simplify a bit, we are assuming that we can just cross-build from Linux x86_64 to Linux ARM, both 32 and 64 bits. If you’re looking for another example, you can explore an additional MacOs to Linux cross-build example right [here](https://github.com/conan-io/examples2/tree/main/examples/cross_build/toolchain_packages/toolchain_macos_linux_cross) . ```bash . ├── conanfile.py └── test_package ├── CMakeLists.txt ├── conanfile.py └── test_package.cpp ``` Let’s check the recipe and go through the most relevant parts: ```python import os from conan import ConanFile from conan.tools.files import get, copy, save from conan.errors import ConanInvalidConfiguration from conan.tools.scm import Version class ArmToolchainPackage(ConanFile): name = "arm-toolchain" version = "13.2" ... settings = "os", "arch" package_type = "application" def _archs32(self): return ["armv6", "armv7", "armv7hf"] def _archs64(self): return ["armv8", "armv8.3"] def _get_toolchain(self, target_arch): if target_arch in self._archs32(): return ("arm-none-linux-gnueabihf", "df0f4927a67d1fd366ff81e40bd8c385a9324fbdde60437a512d106215f257b3") else: return ("aarch64-none-linux-gnu", "12fcdf13a7430655229b20438a49e8566e26551ba08759922cdaf4695b0d4e23") def validate(self): if self.settings.arch != "x86_64" or self.settings.os != "Linux": raise ConanInvalidConfiguration(f"This toolchain is not compatible with {self.settings.os}-{self.settings.arch}. " "It can only run on Linux-x86_64.") valid_archs = self._archs32() + self._archs64() if self.settings_target.os != "Linux" or self.settings_target.arch not in valid_archs: raise ConanInvalidConfiguration(f"This toolchain only supports building for Linux-{valid_archs.join(',')}. " f"{self.settings_target.os}-{self.settings_target.arch} is not supported.") if self.settings_target.compiler != "gcc": raise ConanInvalidConfiguration(f"The compiler is set to '{self.settings_target.compiler}', but this " "toolchain only supports building with gcc.") if Version(self.settings_target.compiler.version) >= Version("14") or Version(self.settings_target.compiler.version) < Version("13"): raise ConanInvalidConfiguration(f"Invalid gcc version '{self.settings_target.compiler.version}'. " "Only 13.X versions are supported for the compiler.") def source(self): # The ARM toolchain is distributed under GPL-3.0-only license # Reference: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads save(self, "LICENSE", "ARM GNU Toolchain\n" "License: GNU General Public License v3.0 (GPL-3.0-only)\n" "https://www.gnu.org/licenses/gpl-3.0.html\n\n" "EULA: https://developer.arm.com/GetEula?Id=37988a7c-c40e-4b78-9fd1-62c20b507aa8\n") def build(self): toolchain, sha = self._get_toolchain(self.settings_target.arch) get(self, f"https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-{toolchain}.tar.xz", sha256=sha, strip_root=True) def package_id(self): self.info.settings_target = self.settings_target # We only want the ``arch`` setting self.info.settings_target.rm_safe("os") self.info.settings_target.rm_safe("compiler") self.info.settings_target.rm_safe("build_type") def package(self): toolchain, _ = self._get_toolchain(self.settings_target.arch) dirs_to_copy = [toolchain, "bin", "include", "lib", "libexec"] for dir_name in dirs_to_copy: copy(self, pattern=f"{dir_name}/*", src=self.build_folder, dst=self.package_folder, keep_path=True) copy(self, "LICENSE", src=self.build_folder, dst=os.path.join(self.package_folder, "licenses"), keep_path=False) def package_info(self): toolchain, _ = self._get_toolchain(self.settings_target.arch) self.cpp_info.bindirs.append(os.path.join(self.package_folder, toolchain, "bin")) self.conf_info.define("tools.build:compiler_executables", { "c": f"{toolchain}-gcc", "cpp": f"{toolchain}-g++", "asm": f"{toolchain}-as" }) ``` ## Validating the toolchain package: settings, settings_build and settings_target As you may recall, the [validate() method](https://docs.conan.io/2//reference/conanfile/methods/validate.html.md#reference-conanfile-methods-validate) is used to indicate that a package is not compatible with certain configurations. As mentioned earlier, we are limiting the usage of this package to a *Linux x86_64* platform for cross-compiling to a *Linux ARM* target, supporting both 32-bit and 64-bit architectures. Let’s check how we incorporate this information into the `validate()` method and discuss the various types of settings involved: **Validating the build platform** ```python ... settings = "os", "arch" ... def validate(self): if self.settings.arch != "x86_64" or self.settings.os != "Linux": raise ConanInvalidConfiguration(f"This toolchain is not compatible with {self.settings.os}-{self.settings.arch}. " "It can only run on Linux-x86_64.") ... ``` First, it’s important to acknowledge that only the `os` and `arch` settings are declared. These settings represent the machine that will compile the package for the toolchain, so we only need to verify that they correspond to `Linux` and `x86_64`, as these are the platforms for which the toolchain binaries are intended. It is important to note that for this package, which is to be used as a `tool_requires`, these settings do not relate to the `host` profile but to the `build` profile. This distinction is recognized by Conan when creating the package with the `--build-require` argument. This will make the `settings` and the `settings_build` to be equal within the context of package creation. **Validating the target platform** In scenarios involving cross-compilation, validations regarding the target platform, where the executable generated by the toolchain’s compilers will run, must refer to the `settings_target`. These settings come from the information in the `host` profile. For instance, if compiling for a Raspberry Pi, that will be the information stored in the `settings_target`. Again, Conan is aware that `settings_target` should be populated with the `host` profile information due to the use of the `--build-require` flag during package creation. ```python def validate(self): ... valid_archs = self._archs32() + self._archs64() if self.settings_target.os != "Linux" or self.settings_target.arch not in valid_archs: raise ConanInvalidConfiguration(f"This toolchain only supports building for Linux-{valid_archs.join(',')}. " f"{self.settings_target.os}-{self.settings_target.arch} is not supported.") if self.settings_target.compiler != "gcc": raise ConanInvalidConfiguration(f"The compiler is set to '{self.settings_target.compiler}', but this " "toolchain only supports building with gcc.") if Version(self.settings_target.compiler.version) >= Version("14") or Version(self.settings_target.compiler.version) < Version("13"): raise ConanInvalidConfiguration(f"Invalid gcc version '{self.settings_target.compiler.version}'. " "Only 13.X versions are supported for the compiler.") ``` As you can see, several verifications are made to ensure the validity of the operating system and architectures for the resulting binaries’ execution environment. Additionally, it verifies that the compiler’s name and version align with the expectations for the `host` context. Here, the diagram shows both profiles and which settings are picked for the **arm-toolchain** recipe that is in the *build* context. ## Downloading the binaries for the toolchain and packaging it ```python ... def _archs32(self): return ["armv6", "armv7", "armv7hf"] def _archs64(self): return ["armv8", "armv8.3"] def _get_toolchain(self, target_arch): if target_arch in self._archs32(): return ("arm-none-linux-gnueabihf", "df0f4927a67d1fd366ff81e40bd8c385a9324fbdde60437a512d106215f257b3") else: return ("aarch64-none-linux-gnu", "12fcdf13a7430655229b20438a49e8566e26551ba08759922cdaf4695b0d4e23") def source(self): # The ARM toolchain is distributed under GPL-3.0-only license # Reference: https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads save(self, "LICENSE", "ARM GNU Toolchain\n" "License: GNU General Public License v3.0 (GPL-3.0-only)\n" "https://www.gnu.org/licenses/gpl-3.0.html\n\n" "EULA: https://developer.arm.com/GetEula?Id=37988a7c-c40e-4b78-9fd1-62c20b507aa8\n") def build(self): toolchain, sha = self._get_toolchain(self.settings_target.arch) get(self, f"https://armkeil.blob.core.windows.net/developer/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x86_64-{toolchain}.tar.xz", sha256=sha, strip_root=True) def package(self): toolchain, _ = self._get_toolchain(self.settings_target.arch) dirs_to_copy = [toolchain, "bin", "include", "lib", "libexec"] for dir_name in dirs_to_copy: copy(self, pattern=f"{dir_name}/*", src=self.build_folder, dst=self.package_folder, keep_path=True) copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"), keep_path=False) ... ``` The source() method is used to download or reference the recipe license. In this case, we reference the ARM toolchain’s GPL-3.0 license and EULA. However, this is the only action performed there. The actual toolchain binaries are fetched in the build() method. This approach is necessary because the toolchain package is designed to support both 32-bit and 64-bit architectures, requiring us to download two distinct sets of toolchain binaries. Which binary the package ends up with depends on the settings_target architecture. This conditional downloading process can’t happen in the source() method, as it [caches the downloaded contents](https://docs.conan.io/2//reference/conanfile/methods/source.html.md#reference-conanfile-methods-source-caching). The package() method doesn’t have anything out of the ordinary; it simply copies the downloaded files into the package folder, license included. ## Adding `settings_target` to the Package ID information In recipes designed for cross-compiling scenarios, particularly those involving toolchains that target specific architectures or operating systems, and the binary package can be different based on the target platform we may need to modify the `package_id()` to ensure that Conan correctly identifies and differentiates between binaries based on the target platform they are intended for. In this case, we extend the `package_id()` method to include `settings_target`, which encapsulates the target platform’s configuration (in this case if it’s 32 or 64 bit): ```python def package_id(self): # Assign settings_target to the package ID to differentiate binaries by target platform. self.info.settings_target = self.settings_target # We only want the ``arch`` setting self.info.settings_target.rm_safe("os") self.info.settings_target.rm_safe("compiler") self.info.settings_target.rm_safe("build_type") ``` By specifying `self.info.settings_target = self.settings_target`, we explicitly instruct Conan to consider the target platform’s settings when generating the package ID. In this case we remove `os`, `compiler` and `build_type` settings as changing them will not be relevant for selecting the toolchain we will use for building and leave only the `arch` setting that will be used to decide if want to produce binaries for 32 or 64 bits. ## Define information for consumers In the `package_info()` method we define all the information that consumers need to have available when using the toolchain: ```python def package_info(self): toolchain, _ = self._get_toolchain(self.settings_target.arch) self.cpp_info.bindirs.append(os.path.join(self.package_folder, toolchain, "bin")) self.conf_info.define("tools.build:compiler_executables", { "c": f"{toolchain}-gcc", "cpp": f"{toolchain}-g++", "asm": f"{toolchain}-as" }) ``` In this case, we need to define the following information: - Add directories containing toolchain tools that may be required during compilation. The toolchain we download will store its tools in both `bin` and `/bin`. Since `self.cpp_info.bindirs` defaults to `bin`, we only need to add the directory specific to the triplet. Note that it’s not necessary to define environment information to add these directories to the `PATH`, as Conan will manage this through the [VirtualRunEnv](https://docs.conan.io/2//reference/tools/env/virtualrunenv.html.md#conan-tools-env-virtualrunenv). - We define the `tools.build:compiler_executables` configuration. This configuration will be considered in several generators, like [CMakeToolchain](https://docs.conan.io/2//reference/tools/cmake/cmaketoolchain.html.md#conan-tools-cmaketoolchain), [MesonToolchain](https://docs.conan.io/2//reference/tools/meson/mesontoolchain.html.md#conan-tools-meson-mesontoolchain), or [AutotoolsToolchain](https://docs.conan.io/2//reference/tools/gnu/autotoolstoolchain.html.md#conan-tools-gnu-autotoolstoolchain), to direct to the appropriate compiler binaries. ## Testing the Conan toolchain package We also added a simple *test_package* to test the toolchain: ```python import os from io import StringIO from conan import ConanFile from conan.tools.cmake import CMake, cmake_layout class TestPackageConan(ConanFile): settings = "os", "arch", "compiler", "build_type" generators = "CMakeToolchain", "VirtualBuildEnv" def build_requirements(self): self.tool_requires(self.tested_reference_str) def layout(self): cmake_layout(self) def build(self): cmake = CMake(self) cmake.configure() cmake.build() def test(self): if self.settings.arch in ["armv6", "armv7", "armv7hf"]: toolchain = "arm-none-linux-gnueabihf" else: toolchain = "aarch64-none-linux-gnu" self.run(f"{toolchain}-gcc --version") test_file = os.path.join(self.cpp.build.bindirs[0], "test_package") stdout = StringIO() self.run(f"file {test_file}", stdout=stdout) if toolchain == "aarch64-none-linux-gnu": assert "ELF 64-bit" in stdout.getvalue() else: assert "ELF 32-bit" in stdout.getvalue() ``` This test package ensures that the toolchain is functional, building a minimal *hello world* program and that binaries produced with it are correctly targeted for the specified architecture. ## Cross-build an application using the toolchain Having detailed the toolchain recipe, it’s time to proceed with package creation: ```bash $ conan create . -pr:b=default -pr:h=../profiles/raspberry-64 --build-require ======== Exporting recipe to the cache ======== ... ======== Input profiles ======== Profile host: [settings] arch=armv8 build_type=Release compiler=gcc compiler.cppstd=gnu14 compiler.libcxx=libstdc++11 compiler.version=13 os=Linux Profile build: [settings] arch=x86_64 build_type=Release compiler=gcc compiler.cppstd=gnu14 compiler.libcxx=libstdc++11 compiler.version=7 os=Linux ... ======== Testing the package: Executing test ======== arm-toolchain/13.2 (test package): Running test() arm-toolchain/13.2 (test package): RUN: aarch64-none-linux-gnu-gcc --version aarch64-none-linux-gnu-gcc (Arm GNU Toolchain 13.2.rel1 (Build arm-13.7)) 13.2.1 20231009 Copyright (C) 2023 Free Software Foundation, Inc. ... ``` #### IMPORTANT Use `--build-require` argument. The `conan create` command by default creates packages for the “host” context, using the “host” profile. But if the package we are creating is intended to be used as a tool with `tool_requires`, then it needs to be built for the “build” context instead. The `--build-require` argument specifies this. When this argument is provided, the current recipe binary will be built for the “build” context, in this case using the `default` profile, and it will receive the `raspberry-64` “host” profile settings as `settings_target`. The `arm-toolchain/13.2` package is a package which executables run in the current “build” machine, not in the RaspberryPI, but it is a tool that targets the RaspberryPI. The `--build-require` argument is necessary to build the `arm-toolchain` package correctly as a build tool. With the toolchain package prepared, we proceed to build an actual application. This will be the same application previously cross-compiled in the [How to cross-compile your applications using Conan: host and build contexts](https://docs.conan.io/2//tutorial/consuming_packages/cross_building_with_conan.html.md#consuming-packages-cross-building-with-conan) section. However, this time, we incorporate the toolchain package as a dependency within the host profile. This ensures the toolchain is used to build the application and all its dependencies ```bash $ cd .. && cd consumer $ conan install . -pr:b=default -pr:h=../profiles/raspberry-64 -pr:h=../profiles/arm-toolchain --build missing $ cmake --preset conan-release $ cmake --build --preset conan-release $ file ./build/Release/compressor compressor: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 3.7.0, with debug_info, not stripped ``` We composed the already existing profile with another profile called `arm-toolchain` that just has the `tool_requires` added: ```ini [tool_requires] arm-toolchain/13.2 ``` During this procedure, the zlib dependency will also be compiled for ARM 64-bit architecture if it hasn’t already been. Additionally, it’s important to verify the architecture of the resulting executable, confirming its alignment with the targeted 64-bit architecture. #### SEE ALSO - [More info on settings_target](https://docs.conan.io/2//reference/binary_model/extending.html.md#binary-model-extending-cross-build-target-settings) - [Cross-compile your applications using Conan](https://docs.conan.io/2//tutorial/consuming_packages/cross_building_with_conan.html.md#consuming-packages-cross-building-with-conan) - [Another example of cross-compilation from Macos to Linux](https://github.com/conan-io/examples2/tree/main/examples/cross_build/toolchain_packages/toolchain_macos_linux_cross) --- https://docs.conan.io/2/examples/cross_build/tricore.html.md --- # Building packages for TriCore #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. TriCore is an embedded microcontroller architecture used in multiple domains such as automotive. There are multiple compilers for TriCore, some of which can be found [here](https://www.infineon.com/cms/en/tools/aurix-tools/Compilers/). There are also `gcc` implementations for TriCore; this is what we will be using in the examples on this page. Since Conan 2.7 there is some built-in support for this architecture: - The default `settings.yml` contains architectures: `'tc131', 'tc16', 'tc161', 'tc162', 'tc18'` - `CMakeToolchain` defines `CMAKE_SYSTEM_NAME=Generic-ELF` and `CMAKE_SYSTEM_PROCESSOR=tricore` for these architectures - The compiler flags `-m"` are injected as compiler and linker flags in `CMakeToolchain` and `AutotoolsToolchain` That means that it is possible to define a profile like: ```default [settings] os=baremetal arch=tc162 compiler=gcc compiler.version=11 compiler.cppstd=20 compiler.libcxx=libstdc++11 [options] *:fPIC=False *:shared=False [conf] tools.build:compiler_executables={"c":"tricore-elf-gcc","cpp":"tricore-elf-g++"} ``` This assumes the compiler is installed in the system path, and its executables are called `tricore-elf-gcc` and `tricore-elf-g++`. And then, cross-build and create a package for TriCore using this profile, for example the default `cmake_lib`: ```bash $ conan new cmake_lib -d name=mypkg -d version=0.1 $ conan create . -pr=tricore.profile ``` #### NOTE - This support is new and experimental. Please create a ticket in [https://github.com/conan-io/conan/issues](https://github.com/conan-io/conan/issues) for any feedback or issues - Linking applications (like if using `conan new cmake_exe`) requires a specific linker script, definition of entry-points, etc. Trying to build it as above will produce linking errors. We will try to add further examples for this case. --- https://docs.conan.io/2/examples/cross_build/android/android_studio.html.md --- # Integrating Conan in Android Studio At the [Cross building to Android with the NDK](https://docs.conan.io/2//examples/cross_build/android/ndk.html.md#examples-cross-build-android-ndk) we learned how to build a package for Android using the NDK. In this example we are going to learn how to do it with the Android Studio and how to use the libraries in a real Android application. ## Creating a new project First of all, download and install the [Android Studio IDE](https://developer.android.com/studio). Then create a `new project` selecting `Native C++` from the templates. In the next wizard window, select a name for your application, for example MyConanApplication, you can leave the “Minimum SDK” with the suggested value (21 in our case), but remember the value as we are using it later in the Conan profile at `os.api_level` In the “Build configuration language” you can choose between `Groovy DSL (build.gradle)` or `Kotlin DSL (build.gradle.kts)` in order to use conanInstall task bellow. Select a “C++ Standard” in the next window, again, remember the choice as later we should use the same in the profile at `compiler.cppstd`. In the project generated with the wizard we have a folder `cpp` with a `native-lib.cpp`. We are going to modify that file to use `zlib` and print a message with the used `zlib` version. Copy only the highlighted lines, it is important to keep the function name. ```c++ #include #include #include "zlib.h" extern "C" JNIEXPORT jstring JNICALL Java_com_example_myconanapp_MainActivity_stringFromJNI( JNIEnv* env, jobject /* this */) { std::string hello = "Hello from C++, zlib version: "; hello.append(zlibVersion()); return env->NewStringUTF(hello.c_str()); } ``` Now we are going to learn how to introduce a requirement to the `zlib` library and how to prepare our project. ## Introducing dependencies with Conan ### conanfile.txt We need to provide the `zlib` package with Conan. Create a file `conanfile.txt` in the `cpp` folder: ```text [requires] zlib/1.2.12 [generators] CMakeToolchain CMakeDeps [layout] cmake_layout ``` ### build.gradle We are going to automate calling `conan install` before building the Android project, so the requires are prepared, open the `build.gradle` file in the `My_Conan_App.app` (Find it in the Gradle Scripts section of the Android project view). Paste the `task conanInstall` contents after the `plugins` and before the `android` elements: Groovy Kotlin ```groovy plugins { ... } task conanInstall { def conanExecutable = "conan" // define the path to your conan installation def buildDir = new File("app/build") buildDir.mkdirs() ["Debug", "Release"].each { String build_type -> ["armv7", "armv8", "x86", "x86_64"].each { String arch -> def cmd = conanExecutable + " install " + "../src/main/cpp --profile android -s build_type="+ build_type +" -s arch=" + arch + " --build missing -c tools.cmake.cmake_layout:build_folder_vars=['settings.arch']" print(">> ${cmd} \n") def sout = new StringBuilder(), serr = new StringBuilder() def proc = cmd.execute(null, buildDir) proc.consumeProcessOutput(sout, serr) proc.waitFor() println "$sout $serr" if (proc.exitValue() != 0) { throw new Exception("out> $sout err> $serr" + "\nCommand: ${cmd}") } } } } android { compileSdk 32 defaultConfig { ... ``` ```kotlin plugins { ... } tasks.register("conanInstall") { val conanExecutable = "conan" // define the path to your conan installation val buildDir = file("app/build") buildDir.mkdirs() val buildTypes = listOf("Debug", "Release") val architectures = listOf("armv7", "armv8", "x86", "x86_64") doLast { buildTypes.forEach { buildType -> architectures.forEach { arch -> val cmd = "$conanExecutable install ../../src/main/cpp --profile android-studio " + "-s build_type=$buildType -s arch=$arch --build missing " + "-c tools.cmake.cmake_layout:build_folder_vars=['settings.arch']" println(">> $cmd") val proc = ProcessBuilder(cmd.split(" ")) .directory(buildDir) .start() val result = proc.inputStream.bufferedReader().readText() val errors = proc.errorStream.bufferedReader().readText() proc.waitFor() if (proc.exitValue() != 0) { throw Exception("Execution failed! Output: $result Error: $errors") } println(result) if (errors.isNotBlank()) { println("Errors: $errors") } } } } } tasks.named("preBuild").configure { dependsOn("conanInstall") } android { compileSdk 32 defaultConfig { ... ``` The `conanInstall` task is calling **conan install** for Debug/Release and for each architecture we want to build, you can adjust these values to match your requirements. If we focus on the `conan install` task we can see: > 1. We are passing a `--profile android`, so we need to create the profile. Go to the `profiles` folder in the > conan config home directory (check it running **conan config home**) and create a file named `android` > with the following contents: > System NDK > Conan NDK package > ```text > include(default) > [settings] > os=Android > os.api_level=27 > compiler=clang > compiler.version=18 > compiler.libcxx=c++_static > compiler.cppstd=17 > [conf] > tools.android:ndk_path=/opt/homebrew/share/android-ndk > ``` > ```text > include(default) > [settings] > os=Android > os.api_level=27 > compiler=clang > compiler.version=18 > compiler.libcxx=c++_static > compiler.cppstd=17 > [tool_requires] > *: android-ndk/r27 > ``` > You might need to modify: > > - `tools.android:ndk_path` conf: The location of the NDK provided by Android Studio. You should be able to see the path > > to the NDK if you open the `cpp/includes` folder in your IDE. > > - `compiler.version`: Check the NDK documentation or find a `bin` folder containing the compiler executables like > > `x86_64-linux-android31-clang`. In a Macos installation it is found in the NDK path + `toolchains/llvm/prebuilt/darwin-x86_64/bin`. > > Run `./x86_64-linux-android31-clang --version` to check the running `clang` version and adjust the profile. > > - `compiler.libcxx`: The supported values are `c++_static` and `c++_shared`. > > - `compiler.cppstd`: The C++ standard version, this should be the value you selected in the Wizard. > > - `os.api_level`: Use the same value you selected in the Wizard. > 2. We are passing `-c tools.cmake.cmake_layout:build_folder_vars=['settings.arch']`, thanks to that, Conan will create a different > folder for the specified `settings.arch` so we can have all the configurations available at the same time. To make Conan work we need to pass CMake a custom toolchain. We can do it introducing a single line in the same file, in the `android/defaultConfig/externalNativeBuild/cmake` element: ```groovy android { compileSdk 32 defaultConfig { applicationId "com.example.myconanapp" minSdk 27 targetSdk 27 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" externalNativeBuild { cmake { cppFlags '-v' arguments("-DCMAKE_TOOLCHAIN_FILE=conan_android_toolchain.cmake") } } ``` ### conan_android_toolchain.cmake Create a file called `conan_android_toolchain.cmake` in the `cpp` folder, that file will be responsible of including the right toolchain depending on the `ANDROID_ABI` variable that indicates the build configuration that the IDE is currently running: ```cmake # During multiple stages of CMake configuration, the toolchain file is processed and command-line # variables may not be always available. The script exits prematurely if essential variables are absent. if ( NOT ANDROID_ABI OR NOT CMAKE_BUILD_TYPE ) return() endif() if(${ANDROID_ABI} STREQUAL "x86_64") include("${CMAKE_CURRENT_LIST_DIR}/build/x86_64/${CMAKE_BUILD_TYPE}/generators/conan_toolchain.cmake") elseif(${ANDROID_ABI} STREQUAL "x86") include("${CMAKE_CURRENT_LIST_DIR}/build/x86/${CMAKE_BUILD_TYPE}/generators/conan_toolchain.cmake") elseif(${ANDROID_ABI} STREQUAL "arm64-v8a") include("${CMAKE_CURRENT_LIST_DIR}/build/armv8/${CMAKE_BUILD_TYPE}/generators/conan_toolchain.cmake") elseif(${ANDROID_ABI} STREQUAL "armeabi-v7a") include("${CMAKE_CURRENT_LIST_DIR}/build/armv7/${CMAKE_BUILD_TYPE}/generators/conan_toolchain.cmake") else() message(FATAL "Not supported configuration") endif() ``` ### CMakeLists.txt Finally, we need to modify the `CMakeLists.txt` to link with the `zlib` library: ```cmake cmake_minimum_required(VERSION 3.18.1) project("myconanapp") add_library(myconanapp SHARED native-lib.cpp) find_library(log-lib log) find_package(ZLIB CONFIG) target_link_libraries(myconanapp ${log-lib} ZLIB::ZLIB) ``` ## Building the application If we build our project we can see that conan install is called multiple times building the different configurations of `zlib`. Then if we run the application in a Virtual Device or in a real device pairing it with the QR code we can see: ![Android application showing the zlib 1.2.11](images/examples/cross_build/android/android_studio/zlib_1_2_11.png) Once we have our project configured, it is very easy to change our dependencies and keep developing the application, for example, we can edit the `conanfile.txt` file and change the `zlib` to the version `1.12.2`: ```text [requires] zlib/1.2.12 [generators] CMakeToolchain CMakeDeps [layout] cmake_layout ``` If we click build and then run the application, we will see that the zlib dependency has been updated: ![Android application showing the zlib 1.2.12](images/examples/cross_build/android/android_studio/zlib_1_2_12.jpg) --- https://docs.conan.io/2/examples/cross_build/android/ndk.html.md --- # Cross building to Android with the NDK In this example, we are going to see how to cross-build a Conan package to Android. First of all, download the Android NDK from [the download page](https://developer.android.com/ndk/downloads) and unzip it. In MacOS you can also install it with `brew install android-ndk`. Then go to the `profiles` folder in the conan config home directory (check it running **conan config home**) and create a file named `android` with the following contents: ```text include(default) [settings] # Just an example, you need to use your real settings os=Android os.api_level=27 arch=armv8 compiler=clang compiler.version=18 compiler.libcxx=c++_shared compiler.cppstd=17 [conf] # Use your path here tools.android:ndk_path=/usr/local/share/android-ndk ``` You might need to modify: - `compiler.version`: Check the NDK documentation or find a `bin` folder containing the compiler executables like `x86_64-linux-android31-clang`. In a Macos installation it is found in the NDK path + `toolchains/llvm/prebuilt/darwin-x86_64/bin`. Run `./x86_64-linux-android31-clang --version` to check the running `clang` version and adjust the profile. - `compiler.libcxx`: The supported values are `c++_static` and `c++_shared`. - `compiler.cppstd`: The C++ standard version, adjust as your needs. - `os.api_level`: You can check [here](https://apilevels.com/) the usage of each Android Version/API level and choose the one that fits better with your requirements. This is typically a balance between new features and more compatible applications. - `arch`: There are several architectures supported by Android: `x86`, `x86_64`, `armv7`, and `armv8`. - `tools.android:ndk_path` conf: Write the location of the unzipped NDK. If you are in Windows, it is necessary to have a make-like build system like MinGW-Make or Ninja. We can provision for Ninja directly in our profile with `[tool_requires]`: ```text ... [conf] # Use your path here tools.android:ndk_path=C:\ws\android\android-ndk-r27 tools.cmake.cmaketoolchain:generator=Ninja [tool_requires] ninja/[*] ``` Use the **conan new** command to create a “Hello World” C++ library example project: ```bash $ conan new cmake_lib -d name=hello -d version=1.0 ``` Then we can specify the `android` profile and our hello library will be built for Android: ```bash $ conan create . --profile android [ 50%] Building CXX object CMakeFiles/hello.dir/src/hello.cpp.o [100%] Linking CXX static library libhello.a [100%] Built target hello ... [ 50%] Building CXX object CMakeFiles/example.dir/src/example.cpp.o [100%] Linking CXX executable example [100%] Built target example ``` Both the library and the `test_package` executable are built for Android, so we cannot use them in our local computer. Unless you have access to a root Android device, running the test application or using the built library is not possible directly so it is more common to build an Android application that uses the `hello` library. It is also possible to use the `android-ndk` from a Conan `tool-requires`. There is already a Conan package in ConanCenter containing the AndroidNDK, so writing a profile like: ```text [settings] os=Android os.api_level=27 arch=armv8 compiler=clang compiler.version=18 compiler.libcxx=c++_shared compiler.cppstd=17 build_type=Release # You might need Ninja conf and tool-requires in Windows too [tool_requires] android-ndk/[*] ``` And this will download automatically the latest android-ndk from ConanCenter and inject and apply it automatically to build the package. Note that to use packages from ConanCenter in production the [following approach is recommended](https://docs.conan.io/2//devops/using_conancenter.html.md#devops-consuming-conan-center) #### SEE ALSO - Check the example [Integrating Conan in Android Studio](https://docs.conan.io/2//examples/cross_build/android/android_studio.html.md#examples-cross-build-android-studio) to know how to use your c++ libraries in a native Android application. - Check the tutorial [How to cross-compile your applications using Conan](https://docs.conan.io/2//tutorial/consuming_packages/cross_building_with_conan.html.md#consuming-packages-cross-building-with-conan). --- https://docs.conan.io/2/examples/dev_flow/debug/debugging_visual.html.md --- # Debugging shared libraries with Visual Studio In the previous example we discussed how to debug dependencies in Visual Studio, but when using Conan dependencies in a project it is possible that the original build folder and build files don’t exist. Conan packages don’t contain the necessary information for debugging libraries with Visual Studio by default, this information is stored in PDBs that are generated during the compilation of the libraries. When using Conan these PDBs are generated in the build folder, which is only needed during the building of the libraries. For that reason it’s a common operation to clean the Conan cache with `conan cache clean` to remove the build folder and save disk space. For these cases where the build folder is not present we created a hook that copies the PDBs generated in the build folder to the package folder. This behavior can’t be forced by default because PDB files are usually larger than the whole package, and it would greatly increase the package sizes. This section will follow some examples on how to debug a project in different cases to show how users can make use of the PDB hook. ## Creating a project and debugging as usual First we will debug our project as usual, as it is explained in more detail in the [previous example](https://docs.conan.io/2//examples/dev_flow/debug/step_into_dependencies.html.md#examples-dev-flow-debug-step-into). We can start building our dependencies from sources as in the previous section, only this time we will build them as shared. To begin with, clone the sources needed for the example from the [examples2 repository](https://github.com/conan-io/examples2) in GitHub and create the project. ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/tutorial/consuming_packages/simple_cmake_project $ conan install . -o="*:shared=True" -s build_type=Debug --build="zlib/*" ... Install finished successfully # CMake presets require CMake>=3.23 $ cmake --preset=conan-default ``` #### NOTE We will only cover the case where the dependencies are built as shared because the PDBs and how they are linked to the libraries works differently for static libraries. We can now open the solution `compressor.sln` to open our project in Visual Studio and debug it as explained in the previous example. Setting a breakpoint in line 22, running the debugger and using the step into will allow us to debug inside our dependency file `deflate.c`. ![Debugging with build files in cache](images/examples/dev_flow/debug_with_build_files.png) In this case the original build files were all present so the debugger worked as usual. Next we will see how the debugger works after removing the build files from the Conan cache. ## Removing build files from the Conan cache There are multiple reasons that can cause the build files to not be present after the dependencies are compiled. We will clean our build files from the cache to simulate one of those cases using `conan cache clean`. The `--build` flag makes sure that we only remove the build files, as we will need our source files for this example. ```bash $ conan list "zlib/1.2.11:*" $ conan cache path --folder build zlib/1.2.11:17b26a16efb893750e4481f98a154db2934ead88 $ conan cache clean zlib/1.2.11 --build $ conan cache path --folder build zlib/1.2.11:17b26a16efb893750e4481f98a154db2934ead88 ``` After closing and reopening our solution in Visual Studio, we can try to debug again. If you try to step into the dependency, with the breakpoint on line 22, you will notice it will directly skip over to the next line as Visual Studio doesn’t have any information on the dependencies to debug. ## Installing a hook to copy the PDBs to the package folder To solve the issue of not having the PDBs in the package folder, we created a hook that copies the PDBs from the build folder to the package folder. The hook is available in the [conan-extensions repository](https://github.com/conan-io/conan-extensions). Installing the whole repository will work, but we recommend to only install the hooks folder from the `conan-extensions` repository with: ```text $ conan config install https://github.com/conan-io/conan-extensions.git -sf=extensions/hooks -tf=extensions/hooks ``` The hook is made so it won’t run by default, as it can increase the package size significantly. As explained in the [hooks documentation](https://docs.conan.io/2//reference/extensions/hooks.html.md#reference-extensions-hooks), we need to change the name of our hook to start with `hook_`. To locate the path where the hook was placed, run the command `conan config home` to find your local cache path and go to the `extensions/hooks` folder to rename the `_hook_copy_pdbs_to_package.py` file. Be aware that this hook will run everytime a `package()` method is run, to disable the hook just rename the hook back to start with `_hook_`. The hook is implemented as a post-package hook, which means that it will execute after the package is created through the `package()` method of a recipe. This avoids any potential issue, as the order will be as follows: - The `build()` method of the recipe is executed, generating the DLLs and PDBs - The `package()` method of the recipe is executed, copying the necessary files to the package folder (in this case the DLLs but not the PDBs) - The hook is executed copying the PDBs from the build folder next to its DLL for every DLL in the package The hook makes use of the `dumpbin` tool which is included in the Visual Studio installation. This tool allows us to get information of a DLL, in this case the path where its associated PDB is located. It will be used for every DLL in the package to locate its PDB to copy it to the package folder. For more information on how PDBs work with Visual Studio and how we used it to create the hook can be found in the [hook readme](https://github.com/conan-io/conan-extensions/blob/main/extensions/hooks/README.md). ## Debugging without build files After installing the hook we will create again the project from sources so the hook can now copy the PDBs to the package folder alongside the package DLLs so they can be found by the debugger. ```bash $ conan install . -o="*:shared=True" -s build_type=Debug --build="zlib/*" ... zlib/1.2.11: Calling package() ... [HOOK - hook_copy_pdbs_to_package.py] post_package(): PDBs post package hook running ... Install finished successfully # CMake presets require CMake>=3.23 $ cmake --preset=conan-default ``` Notice that when running the conan install now you will see the outputs of the hook running after the call to `package()`. To test the hook we can clean the cache again to remove the build files, this includes the sources used to build the library and the PDBs that were originally generated. ```bash $ conan cache clean zlib/1.2.11 --build ``` Open the solution in Visual Studio again and start the debugger. When you try to step into the dependency in line 22, an error message will pop up telling us the file was not found and it will ask where the file is located. We can close this window and it will give the option to view the disassembly which can be debugged thanks to the PDB. The PDB only contains the debugging information but Visual Studio is missing the source files, so it won’t be able to debug over those as it did initially. ![Debugging without build files in cache](images/examples/dev_flow/source_file_not_found.png) ## Locating the sources path for the debugger Visual Studio won’t be able to find the source files by itself after deleting the original build files. To be able to debug over the source files, there’s an option to manually set the source folder path so that it’s possible to debug over the source files. This requires that the source files for the dependency exist. In our case we can get the location of this source files by running a `conan cache path`. ```default $ conan cache path --folder source zlib/1.2.11 ``` In case this source path is not present we can use a config to download the sources again. ```default $ conan install . -o="*:shared=True" -s build_type=Debug -c:a="tools.build:download_source=True" ``` Once we have the source path we can set it in Visual Studio so the debugger can find the source files. Right click on the solution in the Solution Explorer and select Properties. Go to Debug Source Files in the Common Properties section and add our source path. ![Setting source path](images/examples/dev_flow/add_path_to_debug_source_files.png) Starting the debugger again will allow to step into the code of the dependency as in the first example we did. #### NOTE If there are patches to the source files we won’t be able to debug over the modified files, as we are using the files from the source folder and the patches are applied in a later step right before being compiled in the build folder. Any modification to the source files will not allow debugging over them, as Visual Studio does a checksum check, so they need to be the exact same files as when the libraries were compiled. --- https://docs.conan.io/2/examples/dev_flow/debug/step_into_dependencies.html.md --- # Debugging and stepping into dependencies Sometimes, when developing and debugging your own code, it could be useful to be able to step-into the dependencies source code too. There are a couple of things to take into account: - Recipes and packages from ConanCenter do not package always all the debug artifacts necessary to debug. For example in Windows, the `*.pdb` files are not packaged, because they are very heavy, and in practice barely used. It is possible to have your own packages to package the PDB files if you want, but that still won’t solve the next point. - Debug artifacts are often not relocatable, that means that such artifacts can only be used in the location they were built from sources. But packages that are uploaded to a server and downloaded to a different machine can put those artifacts in a different folder. Then, the debug artifacts might not correctly locate the source code, the symbols, etc. ## Building from source The recommended approach for debugging dependencies is building them from source in the local cache. This approach should work out of the box for most recipes, including ConanCenter recipes. We can reuse the code from the very first example in the tutorial for this use case. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/tutorial/consuming_packages/simple_cmake_project ``` Then, lets make sure the dependency is built from source: ```bash $ conan install . -s build_type=Debug --build="zlib/*" ... Install finished successfully ``` Assuming that we have CMake>=3.23, we can use the presets (otherwise, please use the `-DCMAKE_TOOLCHAIN_FILE` arguments): ```bash $ cmake . --preset conan-default ``` This will create our project, that we can start building and debugging. ## Step into a dependency with Visual Studio Once the project is created, in Visual Studio, we can double-click on the `compressor.sln` file, or open the file from the open Visual Studio IDE. Once the project is open, the first step is building it, making sure the `Debug` configuration is the active one, going to `Build -> Build Solution` will do it. Then we can define `compressor` as the “Startup project” in project view. Going to the `compressor/main.c` source file, we can introduce a breakpoint in some line there: ```c++ int main(void) { ... // add a breakpoint in deflateInit line in your IDE deflateInit(&defstream, Z_BEST_COMPRESSION); deflate(&defstream, Z_FINISH); ``` Clicking on the `Debug -> Start Debugging` (or F5), the program will start debugging and stop at the `deflateInit()` line. Clicking on the `Debug -> Step Into`, the IDE should be able to navigate to the `deflate.c` source code. If we check this file, its path will be inside the Conan cache, like `C:\Users\\.conan2\p\b\zlib4f7275ba0a71f\b\src\deflate.c` ```c++ int ZEXPORT deflateInit_(strm, level, version, stream_size) z_streamp strm; int level; const char *version; int stream_size; { return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, version, stream_size); /* To do: ignore strm->next_in if we use it as window */ } ``` #### SEE ALSO - Modifying the dependency source code while debugging is not possible with this approach. If that is the intended flow, the recommended approach is to use [editable package](https://docs.conan.io/2//tutorial/developing_packages/editable_packages.html.md#editable-packages). --- https://docs.conan.io/2/examples/dev_flow/tool_requires/mingw.html.md --- # Using a MinGW as tool_requires to build with gcc in Windows If we had MinGW installed in our environment, we could define a profile like: ```default [settings] os=Windows compiler=gcc compiler.version=12 compiler.libcxx=libstdc++11 compiler.threads=posix compiler.exception=sjlj arch=x86_64 build_type=Release [buildenv] PATH+=(path)C:/path/to/mingw/bin # other environment we might need like CXX=C:/path/to/mingw/bin/g++ # etc [conf] # some configuration like 'tools.build:compiler_executables' might be needed for some cases ``` But we can also use a Conan package that contains a copy of the MinGW compiler and use it as a `tool_requires` instead: ```default [settings] os=Windows compiler=gcc compiler.version=12 compiler.libcxx=libstdc++11 compiler.threads=posix compiler.exception=seh arch=x86_64 build_type=Release [tool_requires] mingw-builds/12.2.0 ``` With this profile we can for example create a package in Windows with: ```bash # Using a basic template project $ conan new cmake_lib -d name=mypkg -d version=0.1 $ conan create . -pr=mingw ... -- The CXX compiler identification is GNU 12.2.0 ... ======== Testing the package: Executing test ======== mypkg/0.1 (test package): Running test() mypkg/0.1 (test package): RUN: .\example mypkg/0.1: Hello World Release! mypkg/0.1: _M_X64 defined mypkg/0.1: __x86_64__ defined mypkg/0.1: _GLIBCXX_USE_CXX11_ABI 1 mypkg/0.1: MSVC runtime: MultiThreadedDLL mypkg/0.1: __cplusplus201703 mypkg/0.1: __GNUC__12 mypkg/0.1: __GNUC_MINOR__2 mypkg/0.1: __MINGW32__1 mypkg/0.1: __MINGW64__1 mypkg/0.1 test_package ``` #### SEE ALSO - The ConanCenter web page for the [mingw-builds package](https://conan.io/center/recipes/mingw-builds) - The `conan-center-index` [mingw-builds Github repo recipe](https://github.com/conan-io/conan-center-index/tree/master/recipes/mingw-builds/all) --- https://docs.conan.io/2/examples/extensions/commands/custom_commands.html.md --- # Custom commands * [Custom command: Clean old recipe and package revisions](https://docs.conan.io/2//examples/extensions/commands/clean/custom_command_clean_revisions.html.md) * [Locate the command](https://docs.conan.io/2//examples/extensions/commands/clean/custom_command_clean_revisions.html.md#locate-the-command) * [Run it](https://docs.conan.io/2//examples/extensions/commands/clean/custom_command_clean_revisions.html.md#run-it) * [Code tour](https://docs.conan.io/2//examples/extensions/commands/clean/custom_command_clean_revisions.html.md#code-tour) --- https://docs.conan.io/2/examples/extensions/commands/clean/custom_command_clean_revisions.html.md --- # Custom command: Clean old recipe and package revisions #### NOTE This is mostly an example command. The built-in `conan remove *#!latest` syntax, meaning “all revisions but the latest” would probably be enough for this use case, without needing this custom command. #### WARNING Using this command requires Conan 2.21.0 or higher. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/extensions/commands/clean ``` In this example we are going to see how to create/use a custom command: **conan clean**. It removes every recipe and its package revisions from the local cache or the remotes, except the latest package revision from the latest recipe one. #### NOTE To understand better this example, it is highly recommended to read previously the [Custom commands reference](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#reference-commands-custom-commands). ## Locate the command Copy the command file `cmd_clean.py` into your `[YOUR_CONAN_HOME]/extensions/commands/` folder (create it if it’s not there). If you don’t know where `[YOUR_CONAN_HOME]` is located, you can run **conan config home** to check it. ## Run it Now, you should be able to see the new command in your command prompt: ```bash $ conan -h ... Custom commands clean Deletes (from local cache or remotes) all recipe and package revisions but the latest package revision from the latest recipe revision. $ conan clean -h usage: conan clean [-h] [-r REMOTE] [--force] Deletes (from local cache or remotes) all recipe and package revisions but the latest package revision from the latest recipe revision. optional arguments: -h, --help show this help message and exit -r REMOTE, --remote REMOTE Will remove from the specified remote --force Remove without requesting a confirmation ``` Finally, if you execute **conan clean**: ```bash $ conan clean Found 4 pkg/version recipes matching */* in local cache Do you want to remove all the recipes revisions and their packages ones, except the latest package revision from the latest recipe one? (yes/no): yes Keeping recipe revision: other/1.0#31da245c3399e4124e39bd4f77b5261f and its latest package revisions [Local cache] Removed package revision: other/1.0#31da245c3399e4124e39bd4f77b5261f:da39a3ee5e6b4b0d3255bfef95601890afd80709#a16985deb2e1aa73a8480faad22b722c [Local cache] Removed recipe revision: other/1.0#721995a35b1a8d840ce634ea1ac71161 and all its package revisions [Local cache] Keeping recipe revision: hello/1.0#9a77cdcff3a539b5b077dd811b2ae3b0 and its latest package revisions [Local cache] Removed package revision: hello/1.0#9a77cdcff3a539b5b077dd811b2ae3b0:da39a3ee5e6b4b0d3255bfef95601890afd80709#cee90a74944125e7e9b4f74210bfec3f [Local cache] Removed package revision: hello/1.0#9a77cdcff3a539b5b077dd811b2ae3b0:da39a3ee5e6b4b0d3255bfef95601890afd80709#7cddd50952de9935d6c3b5b676a34c48 [Local cache] Keeping recipe revision: libcxx/0.1#abcdef1234567890abcdef1234567890 and its latest package revisions [Local cache] ``` Nothing should happen if you run it again: ```bash $ conan clean Do you want to remove all the recipes revisions and their packages ones, except the latest package revision from the latest recipe one? (yes/no): yes Keeping recipe revision: other/1.0#31da245c3399e4124e39bd4f77b5261f and its latest package revisions [Local cache] Keeping recipe revision: hello/1.0#9a77cdcff3a539b5b077dd811b2ae3b0 and its latest package revisions [Local cache] Keeping recipe revision: libcxx/0.1#abcdef1234567890abcdef1234567890 and its latest package revisions [Local cache] ``` ## Code tour The `conan clean` command has the following code: ```python from conan.api.conan_api import ConanAPI from conan.api.model import PackagesList, ListPattern from conan.api.input import UserInput from conan.api.output import ConanOutput, Color from conan.cli.command import OnceArgument, conan_command recipe_color = Color.BRIGHT_BLUE removed_color = Color.BRIGHT_YELLOW @conan_command(group="Custom commands") def clean(conan_api: ConanAPI, parser, *args): """ Deletes (from local cache or remotes) all recipe and package revisions but the latest package revision from the latest recipe revision. """ parser.add_argument('-r', '--remote', action=OnceArgument, help='Will remove from the specified remote') parser.add_argument('--force', default=False, action='store_true', help='Remove without requesting a confirmation') args = parser.parse_args(*args) def confirmation(message): return args.force or ui.request_boolean(message) ui = UserInput(non_interactive=False) out = ConanOutput() remote = conan_api.remotes.get(args.remote) if args.remote else None output_remote = remote or "Local cache" # List all recipes revisions and all their packages revisions as well pkg_list = conan_api.list.select(ListPattern("*/*#*:*#*", rrev=None, prev=None), remote=remote) if pkg_list and not confirmation("Do you want to remove all the recipes revisions and their packages ones, " "except the latest package revision from the latest recipe one?"): out.writeln("Aborted") return # Split the package list into based on their recipe reference for sub_pkg_list in pkg_list.split(): latest = max(sub_pkg_list.items(), key=lambda item: item[0])[0] out.writeln(f"Keeping recipe revision: {latest.repr_notime()} " f"and its latest package revisions [{output_remote}]", fg=recipe_color) for rref, packages in sub_pkg_list.items(): # For the latest recipe revision, keep the latest package revision only if latest == rref: # Get the latest package timestamp for each package_id latest_pref_list = [max([p for p in packages if p.package_id == pkg_id], key=lambda p: p.timestamp) for pkg_id in {p.package_id for p in packages}] for pref in packages: if pref not in latest_pref_list: conan_api.remove.package(pref, remote=remote) out.writeln(f"Removed package revision: {pref.repr_notime()} [{output_remote}]", fg=removed_color) else: # Otherwise, remove all outdated recipe revisions and their packages conan_api.remove.recipe(rref, remote=remote) out.writeln(f"Removed recipe revision: {rref.repr_notime()} " f"and all its package revisions [{output_remote}]", fg=removed_color) ``` Let’s analyze the most important parts. ### parser The `parser` param is an instance of the Python command-line parsing `argparse.ArgumentParser`, so if you want to know more about its API, visit [its official website](https://docs.python.org/3/library/argparse.html). ### User output `ConanOutput()`: class to manage user outputs. In this example, we’re using only `out.writeln(message, fg=None, bg=None)` where `fg` is the font foreground, and `bg` is the font background. Apart from that, you have some predefined methods like `out.info()`, `out.success()`, `out.error()`, etc. ### Conan public API #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. The most important part of this example is the usage of the Conan API via `conan_api` parameter. These are some examples which are being used in this custom command: ```python conan_api.remotes.get(args.remote) conan_api.list.select(ListPattern("*/*#*:*#*", rrev=None, prev=None), remote=remote) conan_api.remove.recipe(rrev, remote=remote) conan_api.remove.package(prev, remote=remote) ``` * `conan_api.remotes.get(...)`: `[RemotesAPI]` Returns a RemoteRegistry given the remote name. * `conan_api.list.select(...)`: `[ListAPI]` Returns a list with all the recipes matching the given pattern. * `conan_api.remove.recipe(...)`: `[RemoveAPI]` Removes the given recipe revision and all its package revisions. * `conan_api.remove.package(...)`: `[RemoveAPI]` Removes the given package revision. Besides that, it deserves especial attention these lines: ```python for sub_pkg_list in pkg_list.split(): latest = max(sub_pkg_list.items(), key=lambda item: item[0])[0] ... latest_pref_list = [max([p for p in packages if p.package_id == pkg_id], key=lambda p: p.timestamp) for pkg_id in {p.package_id for p in packages}] ``` Basically, the `pkg_list.split()` is returning a list for the same recipe reference. Then, `sub_pkg_list.items()` returns a list of tuples `(Recipe Reference, Packages References)`, so finally, `max(..., key=...)` is used to get the latest recipe reference based on its timestamp. Later, `latest_pref_list` is created to keep only the latest package revision for each package ID. It iterates over the set of package IDs to get the latest package revision based on its timestamp. If you want to know more about the Conan API, visit the [ConanAPI section](https://docs.conan.io/2//reference/extensions/python_api/ConanAPI.html.md#reference-python-api-conan-api) --- https://docs.conan.io/2/examples/extensions/deployers/builtin_deployers.html.md --- # Builtin deployers * [Creating a Conan-agnostic deploy of dependencies for developer use](https://docs.conan.io/2//examples/extensions/deployers/dev/development_deploy.html.md) --- https://docs.conan.io/2/examples/extensions/deployers/custom_deployers.html.md --- # Custom deployers * [Copy sources from all your dependencies](https://docs.conan.io/2//examples/extensions/deployers/sources/custom_deployer_sources.html.md) * [Locate the deployer](https://docs.conan.io/2//examples/extensions/deployers/sources/custom_deployer_sources.html.md#locate-the-deployer) * [Run it](https://docs.conan.io/2//examples/extensions/deployers/sources/custom_deployer_sources.html.md#run-it) * [Code tour](https://docs.conan.io/2//examples/extensions/deployers/sources/custom_deployer_sources.html.md#code-tour) --- https://docs.conan.io/2/examples/extensions/deployers/dev/development_deploy.html.md --- # Creating a Conan-agnostic deploy of dependencies for developer use With the `full_deploy` deployer it is possible to create a Conan-agnostic copy of dependencies that can be used by developers without even having Conan installed in their computers. The common and recommended flow for most cases is using Conan packages directly from the Conan cache: ![image](images/examples/extensions/deployers/packages_from_cache.png) However, in some situations, it might be useful to be able to deploy a copy of the dependencies into a user folder, so the dependencies can be located there instead of in the Conan cache. This is possible using the Conan deployers. Let’s see it with an example. All the source code is in the [examples2.0 Github repository](https://github.com/conan-io/examples2) ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/extensions/deployers/development_deploy ``` In the folder we can find the following `conanfile.txt`: ```ini [requires] zlib/1.2.13 [tool_requires] cmake/3.25.3 [generators] CMakeDeps CMakeToolchain [layout] cmake_layout ``` The folder also contains a standard `CMakeLists.txt` and a `main.cpp` source file that can create an executable that links with `zlib` library. We can install the Debug and Release dependencies, and deploy a local copy of the packages with: ```bash $ conan install . --deployer=full_deploy --build=missing $ conan install . --deployer=full_deploy -s build_type=Debug --build=missing ``` This will create the following folders: ```text ├──src ├──build │ ├──generators | └── ZLibConfig.cmake ├──full_deploy │ ├──build │ │ └──cmake │ │ └──3.25.3 │ │ └──x86_64 │ │ ├──bin │ │ │ └──host │ └──zlib │ └──1.2.13 │ ├──Debug │ │ └──x86_64 │ │ ├──include │ │ ├──lib │ └──Release │ └──x86_64 │ ├──include │ ├──lib ``` (Note that you could use the `--deployer-folder` argument to change the base folder output path for the deployer) This folder is fully self-contained. It contains both the necessary tools (like `cmake` executable), the headers and compiled libraries of `zlib` and the necessary files like `ZLibConfig.cmake` in the `build/generators` folder, that point to the binaries inside `full_deploy` with a relative path. ![image](images/examples/extensions/deployers/independent_dependencies_deploy.png) The Conan cache can be removed, and even Conan uninstalled, then the folder could be moved elsewhere in the computer or copied to another computer, assuming it has the same configuration of OS, compiler, etc. ```bash $ cd .. $ cp -R development_deploy /some/other/place $ cd /some/other/place ``` And the files could be used by developers as: ```bash $ cd build # Activate the environment to use CMake 3.25 $ generators\conanbuild.bat $ cmake --version cmake version 3.25.3 # Configure, should match the settings used at install $ cmake .. -G \"Visual Studio 17 2022\" -DCMAKE_TOOLCHAIN_FILE=generators/conan_toolchain.cmake $ cmake --build . --config Release $ Release\compressor.exe ZLIB VERSION: 1.2.13 ``` The environment scripts in Linux and OSX are not relocatable, because they contain absolute paths and the `sh` shell [does not have any way to provide access to the current script directory for sourced files](https://stackoverflow.com/questions/29832037/how-to-get-script-directory-in-posix-sh/29835459#29835459). This shouldn’t be a big blocker, as a “search and replace” with `sed` in the generators folder can fix it: ```bash $ cd build/Release/generators # Fix folders in Linux $ sed -i 's,{old_folder},{new_folder},g' * # Fix folders in MacOS $ sed -i '' 's,{old_folder},{new_folder},g' * $ source conanbuild.sh $ cd .. $ cmake --version cmake version 3.25.3 $ cmake ../.. -DCMAKE_TOOLCHAIN_FILE=generators/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release $ cmake --build . $ ./compressor ZLIB VERSION: 1.2.13 ``` #### NOTE **Best practices** The fact that this flow is possible doesn’t mean that it is recommended for the majority of cases. It has some limitations: - It is less efficient, requiring an extra copy of dependencies - Only `CMakeDeps` and `CMakeToolchain` are relocatable at this moment. For other build system integrations, please create a ticket in Github - Linux and OSX shell scripts are not relocatable and require a manual `sed` - The binary variability is limited to Release/Debug. The generated files are exclusively for the current configuration, changing any other setting (os, compiler, architecture) will require a different deploy In the general case, normal usage of the cache is recommended. This “relocatable development deployment” could be useful for distributing final products that looks like an SDK, to consumers of a project not using Conan. --- https://docs.conan.io/2/examples/extensions/deployers/sources/custom_deployer_sources.html.md --- # Copy sources from all your dependencies Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/extensions/deployers/sources ``` In this example we are going to see how to create and use a custom deployer. This deployer copies all the source files from your dependencies and puts them into a specific output folder #### NOTE To better understand this example, it is highly recommended to have previously read the [Deployers](https://docs.conan.io/2//reference/extensions/deployers.html.md#reference-extensions-deployer-direct-deploy) reference. ## Locate the deployer In this case, the deployer is located in the same directory as our example conanfile, but as shown in [Deployers](https://docs.conan.io/2//reference/extensions/deployers.html.md#reference-extensions-deployer-direct-deploy) reference, Conan will look for the specified deployer in a few extra places in order, namely: 1. Absolute paths 2. Relative to cwd 3. In the `[CONAN_HOME]/extensions/deployers` folder 4. Built-in deployers ## Run it For our example, we have a simple recipe that lists both `zlib` and `mcap` as requirements. With the help of the `tools.build:download_source=True` conf, we can force the invocation of its `source()` method, which will ensure that sources are available even if no build needs to be carried out. Now, you should be able to use the new deployer in both `conan install` and `conan graph` commands for any given recipe: ```bash $ conan graph info . -c tools.build:download_source=True --deployer=sources_deploy ``` Inspecting the command output we can see that it copied the sources of our direct dependencies `zlib` and `mcap`, **plus** the sources of our transitive dependencies, `zstd` and `lz4` to a `dependencies_sources` folder. After this is done, extra preprocessing could be done to accomplish more specific needs. Note that you can pass the `--deployer-folder` argument to change the base folder output path for the deployer. ## Code tour The **source_deploy.py** file has the following code: ```python from conan.errors import ConanException from conan.tools.files import copy import os def deploy(graph, output_folder, **kwargs): # Note the kwargs argument is mandatory to be robust against future changes. for name, dep in graph.root.conanfile.dependencies.items(): if dep.folders is None or dep.folders.source_folder is None: raise ConanException(f"Sources missing for {name} dependency.\n" "This deployer needs the sources of every dependency present to work, either building from source, " "or by using the 'tools.build:download_source' conf.") copy(graph.root.conanfile, "*", dep.folders.source_folder, os.path.join(output_folder, "dependency_sources", str(dep))) ``` ### deploy() The `deploy()` method is called by Conan, and gets both a dependency graph and an output folder path as arguments. It iterates all the dependencies of our recipe and copies every source file to their respective folders under `dependencies_sources` using [conan.tools.copy](https://docs.conan.io/2//reference/tools/files/basic.html.md#conan-tools-files-copy). #### NOTE If you’re using this deployer as an example for your own, remember that `tools.build:download_source=True` is necessary so that `dep.folders.source_folder` is defined for the dependencies. Without the conf, said variable will not be defined for those dependencies that do not need to be built from sources nor in those commands that do not require building, such as **conan graph**. #### NOTE If your custom deployer needs access to the full dependency graph, including those libraries that might be skipped, use the `tools.graph:skip_binaries=False` conf. This is useful for collecting, for example, all the licenses in your graph. --- https://docs.conan.io/2/examples/extensions/package_signing/package_signing.html.md --- # Package Signing Plugin * [Signing packages with OpenSSL](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_openssl.html.md) * [Generating the signing keys](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_openssl.html.md#generating-the-signing-keys) * [Configuring the plugin](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_openssl.html.md#configuring-the-plugin) * [Implementation](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_openssl.html.md#implementation) * [Signing packages](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_openssl.html.md#signing-packages) * [Verifying packages](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_openssl.html.md#verifying-packages) * [Signing packages with Sigstore (Cosign)](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_sigstore.html.md) * [Generating the signing key pair](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_sigstore.html.md#generating-the-signing-key-pair) * [Configuring the plugin](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_sigstore.html.md#configuring-the-plugin) * [Implementation](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_sigstore.html.md#implementation) * [Signing packages](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_sigstore.html.md#signing-packages) * [Verifying packages](https://docs.conan.io/2//examples/extensions/package_signing/package_signing_with_sigstore.html.md#verifying-packages) --- https://docs.conan.io/2/examples/extensions/package_signing/package_signing_with_openssl.html.md --- # Signing packages with OpenSSL This is an example of a Package Signing Plugin implementation using the [OpensSSL digest tool](https://docs.openssl.org/3.1/man1/openssl-dgst/). You will need to have `openssl` installed at the system level and available in your `PATH`. #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. This example is available in the examples2 repository: [examples/extensions/plugins/openssl_sign](https://github.com/conan-io/examples2/tree/main/examples/extensions/plugins/openssl_sign). #### NOTE OpenSSL is used here for demonstration purposes only. The Package Signing plugin mechanism is backend-agnostic, and you could implement a similar plugin using other tools available in your system (for example, `gpg`), with minimal changes to the signing and verification commands. ## Generating the signing keys To sign and verify the packages using the plugin, first, we will need a public and private key. To generate the keys using the `openssl` executable, we can run: ```bash $ openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048 ``` This will generate the private key used to sign the packages. Now, we can get the public key from it with this command: ```bash $ openssl pkey -in private_key.pem -pubout -out public_key.pem ``` The plugin will use this public key to verify the packages. ## Configuring the plugin 1. Copy the `examples/extensions/plugins/openssl_sign/sign.py` file to your Conan home at `CONAN_HOME/extensions/plugins/sign/sign.py`. 1. Copy the `sign.py` file to your Conan home: `CONAN_HOME/extensions/plugins/sign/sign.py` 2. Place the generated keys in a folder named after your provider (`my-organization` in this example), next to `sign.py`: Your final folder structure should look like this: ```text CONAN_HOME/ └── extensions/ └── plugins/ └── sign/ ├── sign.py └── my-organization/ ├── private_key.pem └── public_key.pem ``` The `my-organization` folder serves as the **provider** in this example, and it is used by the plugin to identify the organization that owns the keys. ## Implementation The plugin’s implementation is very straightforward. For signing packages, the sign() function is defined, where the packages are signed by the **openssl dgst** command: ```python def sign(ref, artifacts_folder, signature_folder, **kwargs) ... openssl_sign_cmd = [ "openssl", "dgst", "-sha256", "-sign", privkey_filepath, "-out", signature_filepath, manifest_filepath ] try: _run_command(openssl_sign_cmd) ConanOutput().success(f"Package signed for reference {ref}") except Exception as exc: raise ConanException(f"Error signing artifact: {exc}") ... ``` There, the manifest `pkgsign-manifest.json` (created right before `sign()` function is called) is used to sign the package, as it contains the filenames and checksums of the artifacts of the package. The signature file is saved into the `signature_filepath` (the signature folder at `/metadata/sign`), and finally, the metadata of the signature is returned as a dictionary in a list: ```python def sign(ref, artifacts_folder, signature_folder, **kwargs) ... return [{"method": "openssl-dgst", "provider": "my-organization", "sign_artifacts": { "manifest": "pkgsign-manifest.json", "signature": signature_filename}}] ``` This information saved in a file `pkgsign-signatures.json` placed in the signature folder, so it can be used in the verify() to verify the package signature against the correct provider keys, with the correct signing method (`openssl-dgst` for this example) and using the signature files in `sign_artifacts`. For verifying packages, the verify() function is defined. First, the `pkgsign-signatures.json` is loaded to read the metadata of the signatures (multiple signatures are supported): ```python def verify(ref, artifacts_folder, signature_folder, files, **kwargs): ... signatures = json.loads(f.read()).get("signatures") ... for signature in signatures: signature_filename = signature.get("sign_artifacts").get("signature") signature_filepath = os.path.join(signature_folder, signature_filename) ... provider = signature.get("provider") signature_method = signature.get("method") ... ``` Then, the `provider` information is used to select the correct public key for verification that use the right signature verification `method` (`openssl-dgst` for this example) and run the **openssl dgst -verify** command: ```python def verify(ref, artifacts_folder, signature_folder, files, **kwargs): ... openssl_verify_cmd = [ "openssl", "dgst", "-sha256", "-verify", pubkey_filepath, "-signature", signature_filepath, manifest_filepath, ] try: _run_command(openssl_verify_cmd) ConanOutput().success(f"Package verified for reference {ref}") except Exception as exc: raise ConanException(f"Error verifying signature {signature_filepath}: {exc}") ``` The `verify()` function does not return any value in case the package is correct. If the verification fails, then a `ConanException()` should be raised. ## Signing packages Now that the plugin is configured, we can create a package and sign it afterwards: ```bash $ conan new cmake_lib -d name=hello -d version=1.0 $ conan create ``` For signing the recipe and package, use the dedicated command: ```bash $ conan cache sign hello/1.0 hello/1.0: Compressing conan_sources.tgz hello/1.0:dee9f7f985eb1c20e3c41afaa8c35e2a34b5ae0b: Compressing conan_package.tgz Running command: openssl dgst -sha256 -sign C:\Users\user\.conan2\extensions\plugins\sign\my-organization\private_key.pem -out C:\Users\user\.conan2\p\hello092ffa809a9a1\d\metadata\sign\pkgsign-manifest.json.sig C:\Users\user\.conan2\p\hello092ffa809a9a1\d\metadata\sign\pkgsign-manifest.json Package signed for reference hello/1.0 Running command: openssl dgst -sha256 -sign C:\Users\user\.conan2\extensions\plugins\sign\my-organization\private_key.pem -out C:\Users\user\.conan2\p\b\hello5b13c694fef4a\d\metadata\sign\pkgsign-manifest.json.sig C:\Users\user\.conan2\p\b\hello5b13c694fef4a\d\metadata\sign\pkgsign-manifest.json Package signed for reference hello/1.0:dee9f7f985eb1c20e3c41afaa8c35e2a34b5ae0b [Package sign] Results: hello/1.0 revisions 53321bba8793db6fea5ea1a98dd6f3d6 packages dee9f7f985eb1c20e3c41afaa8c35e2a34b5ae0b revisions 4b1eaf2e27996cb39cb3774f185fcd8e [Package sign] Summary: OK=2, FAILED=0 ``` As you see, the command is executing the `sign()` function of the plugin that uses the `openssl` executable to sign the recipe and the package with a command similar to: ```bash $ openssl dgst -sha256 -sign private_key.pem -out pkgsign-manifest.json.sig pkgsign-manifest.json ``` And it is also using the conan-generated `pkgsign-manifest.json` file to create the signature. You can read more about this manifest file at [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). ## Verifying packages For verifying the recipe and package, use the dedicated command: ```bash $ conan cache verify hello/1.0 [Package sign] Checksum verified for file conan_sources.tgz (4ce077cbea9ce87a481b5d6dbb50bd791f4e37e931754cdeb40aeb017baed66c). [Package sign] Checksum verified for file conanfile.py (0ec44c268f0f255ab59a246c3d13ae6dbd487dea7635b584236b701047f92ba0). [Package sign] Checksum verified for file conanmanifest.txt (f7f00bb74ed8469a367ed02faded3c763130da9b63dae23916b2a4f099625b15). Running command: openssl dgst -sha256 -verify C:\Users\user\.conan2\extensions\plugins\sign\my-organization\public_key.pem -signature C:\Users\user\.conan2\p\hello092ffa809a9a1\d\metadata\sign\pkgsign-manifest.json.sig C:\Users\user\.conan2\p\hello092ffa809a9a1\d\metadata\sign\pkgsign-manifest.json Package verified for reference hello/1.0 [Package sign] Checksum verified for file conan_package.tgz (5cc1b9e330fe5bb6ad5904db45d78ecd6bdc71bcc18eff8d19a1ed126ba5a5aa). [Package sign] Checksum verified for file conaninfo.txt (f80367b17176346e10640ed813d6d2f1c45ed526822ff71066696179d16e2f2f). [Package sign] Checksum verified for file conanmanifest.txt (91429ce32c2d0a99de6459a589ac9c35933ed65165ee5c564b6534da57fdfa65). Running command: openssl dgst -sha256 -verify C:\Users\user\.conan2\extensions\plugins\sign\my-organization\public_key.pem -signature C:\Users\user\.conan2\p\b\hello5b13c694fef4a\d\metadata\sign\pkgsign-manifest.json.sig C:\Users\user\.conan2\p\b\hello5b13c694fef4a\d\metadata\sign\pkgsign-manifest.json Package verified for reference hello/1.0:dee9f7f985eb1c20e3c41afaa8c35e2a34b5ae0b [Package sign] Results: hello/1.0 revisions 53321bba8793db6fea5ea1a98dd6f3d6 packages dee9f7f985eb1c20e3c41afaa8c35e2a34b5ae0b revisions 4b1eaf2e27996cb39cb3774f185fcd8e [Package sign] Summary: OK=2, FAILED=0 ``` As you see, Conan is performing an internal checksum verification for the files and calling the `verify()` function of the plugin that uses the `openssl` executable to verify the recipe and the package with a command similar to: ```bash $ openssl dgst -sha256 -verify public_key.pem -signature pkgsign-manifest.json.sig pkgsign-manifest.json ``` #### SEE ALSO If you want to create your own package signing plugin, check the reference documentation at [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). --- https://docs.conan.io/2/examples/extensions/package_signing/package_signing_with_sigstore.html.md --- # Signing packages with Sigstore (Cosign) This is an example of a package signing plugin implementation using [Sigstore](https://www.sigstore.dev/) via [Cosign](https://github.com/sigstore/cosign). You need **Cosign** (version 3.0.0 or newer) on your `PATH`. See the [Cosign releases](https://github.com/sigstore/cosign/releases) page for binaries. #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. This example is available in the examples2 repository: [examples/extensions/plugins/sigstore_sign](https://github.com/conan-io/examples2/tree/main/examples/extensions/plugins/sigstore_sign). #### NOTE Cosign is used here for demonstration only. The package signing plugin mechanism is backend-agnostic; you could implement a similar plugin with other tools (for example OpenSSL or GPG) by changing the commands invoked from `sign()` and `verify()`, as described in [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). ## Generating the signing key pair Generate a Cosign key pair (Cosign prompts for a passphrase to protect the private key): ```bash $ cosign generate-key-pair --output-key-prefix signing ``` This creates `signing.key` (private) and `signing.pub` (public). Use the passphrase later to set the `COSIGN_PASSWORD` environment variable when configuring the plugin (see below). ## Configuring the plugin 1. Copy `sign.py` and `signing-config.json` from the examples2 folder into your Conan home: `CONAN_HOME/extensions/plugins/sign/sign.py` `CONAN_HOME/extensions/plugins/sign/signing-config.json` 2. Place the generated keys in a folder named after the **provider** used by the plugin. This example uses `my-organization` (the name is hardcoded in `sign.py`): `CONAN_HOME/extensions/plugins/sign/my-organization/signing.key` `CONAN_HOME/extensions/plugins/sign/my-organization/signing.pub` 3. Set the `COSIGN_PASSWORD` environment variable. The plugin **requires** this variable to be present when signing: Cosign reads it instead of prompting on the terminal. Set it to the **private key passphrase** you chose when generating the key pair. If the key has **no** passphrase, set `COSIGN_PASSWORD` to an empty value. Your layout should look like this: ```text CONAN_HOME/ └── extensions/ └── plugins/ └── sign/ ├── sign.py ├── signing-config.json └── my-organization/ ├── signing.key └── signing.pub ``` ## Implementation #### NOTE **Method name convention:** Use the literal string `sigstore` (lowercase) in the `method` field when your plugin uses this Cosign/Sigstore tools. This is a convenient way to identify the signing method used to sign the package and so the verifier can pick the right backend. For signing, `sign()` invokes **cosign sign-blob** on Conan’s `pkgsign-manifest.json`, writes a Sigstore **bundle** (`artifact.sigstore.json`) next to the manifest, and returns metadata for `pkgsign-signatures.json`: ```python def sign(ref, artifacts_folder, signature_folder, **kwargs): ... cosign_sign_cmd = [ "cosign", "sign-blob", "--key", privkey_filepath, "--bundle", bundle_filepath, "-y", f"--signing-config={_signing_config_path()}", manifest_filepath, ] try: _run_command(cosign_sign_cmd) ConanOutput().success(f"Package signed for reference {ref}") except Exception as exc: raise ConanException(f"Error signing artifact: {exc}") from exc return [ { "method": "sigstore", "provider": provider, "sign_artifacts": { "manifest": "pkgsign-manifest.json", "bundle": "artifact.sigstore.json", }, } ] ``` For verification, `verify()` reads `pkgsign-signatures.json`, resolves the manifest and bundle paths, loads the public key for the recorded **provider**, and runs **cosign verify-blob** (without Rekor support): ```python def verify(ref, artifacts_folder, signature_folder, files, **kwargs): ... cosign_verify_cmd = [ "cosign", "verify-blob", "--key", pubkey_filepath, "--bundle", bundle_filepath, "--private-infrastructure=true", manifest_filepath, ] try: _run_command(cosign_verify_cmd) ConanOutput().success(f"Package verified for reference {ref}") except Exception as exc: raise ConanException(f"Error verifying signature {bundle_filepath}: {exc}") from exc ``` If verification fails, the plugin raises `ConanException`. On success it does not return a value. You can read more about `pkgsign-manifest.json` at [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). ## Signing packages Create a package and sign it: ```bash $ conan new cmake_lib -d name=hello -d version=1.0 $ conan create $ conan cache sign hello/1.0 hello/1.0: Compressing conan_sources.tgz hello/1.0:dee9f7f985eb1c20e3c41afaa8c35e2a34b5ae0b: Compressing conan_package.tgz Running command: cosign sign-blob --key .../sign/my-organization/signing.key --bundle .../metadata/sign/artifact.sigstore.json -y --signing-config=.../sign/signing-config.json .../metadata/sign/pkgsign-manifest.json Package signed for reference hello/1.0 ... [Package sign] Summary: OK=2, FAILED=0 ``` #### NOTE Starting with Conan 2.26.0, **conan upload** does not sign packages automatically. Use **conan cache sign** before upload when remotes should store signatures. See [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). ## Verifying packages Verify recipe and package binaries in the cache: ```bash $ conan cache verify hello/1.0 [Package sign] Checksum verified for file conan_sources.tgz (...) ... Running command: cosign verify-blob --key .../sign/my-organization/signing.pub --bundle .../metadata/sign/artifact.sigstore.json --private-infrastructure=true .../metadata/sign/pkgsign-manifest.json Package verified for reference hello/1.0 ... [Package sign] Summary: OK=2, FAILED=0 ``` Packages downloaded from a remote are verified on install (for example **conan install**). #### SEE ALSO Plugin API and manifest details: [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). --- https://docs.conan.io/2/examples/extensions/python/build_backend.html.md --- # Python build backend * [Build a Python C/C++ extension using Conan and conan-py-build](https://docs.conan.io/2//examples/extensions/python/build_backend/build_python_extension_with_conan.html.md) * [Build and test](https://docs.conan.io/2//examples/extensions/python/build_backend/build_python_extension_with_conan.html.md#build-and-test) --- https://docs.conan.io/2/examples/extensions/python/build_backend/build_python_extension_with_conan.html.md --- # Build a Python C/C++ extension using Conan and conan-py-build In this example, we are going to create a small Python package with a C++ extension that uses [pybind11](https://pybind11.readthedocs.io/) to expose the C++ code to Python and [fmt](https://fmt.dev/) as a regular C++ dependency. Both dependencies are downloaded and built by Conan, driven by [conan-py-build](https://github.com/conan-io/conan-py-build), a [PEP 517](https://peps.python.org/pep-0517/) build backend that lets `pip` (or `build`, or `uv`) build the C/C++ part of a Python package through Conan. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/extensions/python_build_backend ``` The project has this structure: ```text . ├── pyproject.toml ├── conanfile.py ├── CMakeLists.txt ├── LICENSE ├── src │ └── myadder.cpp └── python └── myadder └── __init__.py ``` Let’s have a look at the *pyproject.toml* file: ```toml [build-system] requires = ["conan-py-build"] build-backend = "conan_py_build.build" [project] name = "myadder" version = "0.1.0" description = "A simple Python package with a C++ extension" license = "MIT" license-files = ["LICENSE"] requires-python = ">=3.8" [tool.conan-py-build.wheel] packages = ["python/myadder"] ``` Setting `conan-py-build` as the `build-backend` means that every time this package is built (`pip wheel .`, `pip install .`, `python -m build`, etc.), the backend will read the recipe declared in the standard *conanfile.py*, resolve and install its dependencies through Conan, run the `build()` and `package()` methods, and copy everything `package()` staged into the resulting wheel. The `[tool.conan-py-build.wheel]` section tells the backend where the pure Python part of the package lives, so it also gets copied into the wheel next to the compiled extension. See the [configuration reference](https://conan-py-build.conan.io/configuration/) for all the available options (dynamic versioning, extra Conan profiles/arguments, entry points, sdist contents, etc.). Now, the *conanfile.py* is a regular Conan recipe, no different from one used to create a C++ package: ```python from conan import ConanFile from conan.tools.cmake import CMake, cmake_layout class MyAdderConan(ConanFile): name = "myadder" settings = "os", "compiler", "build_type", "arch" generators = "CMakeToolchain", "CMakeDeps" def layout(self): cmake_layout(self) def requirements(self): self.requires("pybind11/3.0.1") self.requires("fmt/12.1.0") def build(self): cmake = CMake(self) cmake.configure() cmake.build() def package(self): cmake = CMake(self) cmake.install() ``` It declares **pybind11** and **fmt** as regular requirements, downloaded as precompiled binaries from ConanCenter (or built from source if needed), and uses [CMakeToolchain](https://docs.conan.io/2//reference/tools/cmake/cmaketoolchain.html.md#conan-tools-cmaketoolchain) and [CMakeDeps](https://docs.conan.io/2//reference/tools/cmake/cmakedeps.html.md#conan-tools-cmakedeps) to configure and build the extension with CMake. #### IMPORTANT `conan-py-build` automatically points `CMakeToolchain` at the same Python interpreter driving the build (`Python3_EXECUTABLE`/`Python_EXECUTABLE`), so the recipe doesn’t need to set it and CMake can’t pick up a different, ABI-incompatible Python. #### IMPORTANT For the compiled extension to be importable, it must land under a directory that matches the Python package name, so the `.so`/`.pyd` ends up next to `__init__.py` in the wheel. This is controlled by the `DESTINATION` argument of CMake’s `install(TARGETS ...)`. The *CMakeLists.txt* builds the `_core` extension module with pybind11, links it against `fmt`, and installs it into a `myadder` folder to match the Python package name: ```cmake cmake_minimum_required(VERSION 3.15) project(myadder LANGUAGES CXX) find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module) set(PYBIND11_FINDPYTHON ON) find_package(pybind11 CONFIG REQUIRED) find_package(fmt REQUIRED) pybind11_add_module(_core src/myadder.cpp) target_link_libraries(_core PRIVATE pybind11::module fmt::fmt) install(TARGETS _core DESTINATION myadder) ``` The C++ source exposes an `add()` function to Python, using **fmt** to print the result in bold green text: ```cpp #include #include #include namespace py = pybind11; double add(double a, double b) { double result = a + b; fmt::print(fg(fmt::color::green) | fmt::emphasis::bold, "{} + {} = {}\n", a, b, result); return result; } PYBIND11_MODULE(_core, m) { m.doc() = "Simple Python extension using fmt via Conan."; m.def("add", &add, "Add two numbers and print the result formatted with fmt.", py::arg("a"), py::arg("b")); } ``` And finally, *python/myadder/_\_init_\_.py* just re-exports the function from the compiled module: ```python from myadder._core import add __all__ = ["add"] ``` ## Build and test Build the wheel with `pip`. There’s no need to install `conan-py-build` beforehand: since it’s declared under `[build-system] requires` in *pyproject.toml*, `pip` installs it (and Conan itself) into an isolated build environment automatically: ```bash $ pip wheel . -w dist/ ``` Conan will install **pybind11** and **fmt**, build the extension with CMake, and `conan-py-build` will assemble the resulting wheel and save it into the *dist* folder, e.g. *dist/myadder-0.1.0-cp312-cp312-macosx_14_0_arm64.whl* (the exact filename depends on your platform and Python version). A wheel is just a zip file, so you can check what got packaged without installing it: ```bash $ python -m zipfile -l dist/myadder-*.whl File Name Modified Size myadder/__init__.py 2026-07-08 14:01:30 49 myadder/_core.cpython-312-darwin.so 2026-07-08 14:41:12 233288 myadder-0.1.0.dist-info/METADATA 2026-07-08 14:41:08 212 myadder-0.1.0.dist-info/WHEEL 2026-07-08 14:41:12 101 myadder-0.1.0.dist-info/licenses/LICENSE 2026-07-08 14:01:32 1083 myadder-0.1.0.dist-info/RECORD 2026-07-08 14:41:12 471 ``` Note how the compiled `_core` extension, the one Conan’s `package()` staged during the build, ends up right next to `__init__.py` under `myadder/` — exactly the layout the `DESTINATION` in *CMakeLists.txt* was set up for. Now install it and try it out: ```bash $ pip install dist/myadder-*.whl $ python -c "from myadder import add; add(2, 3)" 2 + 3 = 5 ``` The line above is printed by the C++ extension in bold green, courtesy of **fmt** — a visible sign that the compiled code, not Python, produced it. #### SEE ALSO - [conan-py-build integration](https://docs.conan.io/2//integrations/python.html.md#integrations-python-conan-py-build) - [conan-py-build documentation](https://conan-py-build.conan.io), for configuration options like dynamic versioning, custom Conan profiles, entry points, and shared library handling with `auditwheel`/`delocate`/`delvewheel`. - [Introducing conan-py-build](https://blog.conan.io/cpp/conan/python/2026/05/05/Introducing-conan-py-build.html) blog post. - [conan-py-build examples](https://github.com/conan-io/conan-py-build/tree/main/examples), including Meson, nanobind, and cibuildwheel-based builds. --- https://docs.conan.io/2/examples/graph/requires/consume_cmake_macro.html.md --- # Use a CMake macro packaged in a dependency When a package recipe wants to provide a CMake functionality via a macro, it can be done as follows. Let’s say that we have a `pkg` recipe, that will “export” and “package” a `Macros.cmake` file that contains a `pkg_macro()` CMake macro: ```python from conan import ConanFile from conan.tools.files import copy class Pkg(ConanFile): name = "pkg" version = "0.1" package_type = "static-library" # Exporting, as part of the sources exports_sources = "*.cmake" def package(self): # Make sure the Macros.cmake is packaged copy(self, "*.cmake", src=self.source_folder, dst=self.package_folder) def package_info(self): # We need to define that there are "build-directories", in this case # the current package root folder, containing build files and scripts self.cpp_info.builddirs = ["."] ``` ```cmake function(pkg_macro) message(STATUS "PKG MACRO WORKING!!!") endfunction() ``` When this package is created (`cd pkg && conan create .`), it can be consumed by other package recipes, for example this application: ```python from conan import ConanFile from conan.tools.cmake import CMake class App(ConanFile): package_type = "application" generators = "CMakeToolchain", "CMakeDeps" settings = "os", "compiler", "arch", "build_type" requires = "pkg/0.1" def build(self): cmake = CMake(self) cmake.configure() cmake.build() ``` That has this `CMakeLists.txt`: ```cmake cmake_minimum_required(VERSION 3.15) project(App LANGUAGES NONE) include(Macros) # include the file with the macro (note no .cmake extension) pkg_macro() # call the macro ``` So when we run a local build, we will see how the file is included and the macro called: ```bash $ cd app $ conan build . PKG MACRO WORKING!!! ``` --- https://docs.conan.io/2/examples/graph/tool_requires/different_options.html.md --- # Depending on same version of a tool-require with different options #### NOTE This is an **advanced** use case. It shouldn’t be necessary in the vast majority of cases. In the general case, trying to do something like this: ```python def build_requirements(self): self.tool_requires("gcc/1.0") self.tool_requires("gcc/1.0") ``` Will generate a “conflict”, showing an error like `Duplicated requirement`. However there are some exceptional situations that we could need to depend on the same `tool_requires` version, but using different binaries of that `tool_requires`. This can be achieved by passing different `options` to those `tool_requires`. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```shell git clone https://github.com/conan-io/examples2.git cd examples2/examples/graph/tool_requires/different_options ``` There we have a `gcc` fake recipe with: ```python class Pkg(ConanFile): name = "gcc" version = "1.0" options = {"myoption": [1, 2]} def package(self): # This fake compiler will print something different based on the option echo = f"@echo off\necho MYGCC={self.options.myoption}!!" save(self, os.path.join(self.package_folder, "bin", f"mygcc{self.options.myoption}.bat"), echo) save(self, os.path.join(self.package_folder, "bin", f"mygcc{self.options.myoption}.sh"), echo) os.chmod(os.path.join(self.package_folder, "bin", f"mygcc{self.options.myoption}.sh"), 0o777) ``` This is not an actual compiler, it fakes it with a shell or bat script that prints `MYGCC=current-option` when executed. Note the binary itself is called `mygcc1` and `mygcc2`, that is, it contains the option in the executable name itself. We can create 2 different binaries for `gcc/1.0` with: ```bash $ conan create gcc -o myoption=1 $ conan create gcc -o myoption=2 ``` Now, in the `wine` folder there is a `conanfile.py` like this: ```python class Pkg(ConanFile): name = "wine" version = "1.0" def build_requirements(self): self.tool_requires("gcc/1.0", run=False, options={"myoption": 1}) self.tool_requires("gcc/1.0", run=False, options={"myoption": 2}) def generate(self): gcc1 = self.dependencies.build.get("gcc", options={"myoption": 1}) assert gcc1.options.myoption == "1" gcc2 = self.dependencies.build.get("gcc", options={"myoption": 2}) assert gcc2.options.myoption == "2" def build(self): ext = "bat" if platform.system() == "Windows" else "sh" self.run(f"mygcc1.{ext}") self.run(f"mygcc2.{ext}") ``` The first important point is the `build_requirements()` method, that does a `tool_requires()` to both binaries, but defining `run=False` and `options={"myoption": value}` traits. **This is very important**: we are telling Conan that we actually don’t need to run anything from those packages. As `tool_requires` are not visible, they don’t define headers or libraries and they define different `options`, there is nothing that makes Conan identify those 2 `tool_requires` as conflicting. So the dependency graph can be constructed without errors, and the `wine/1.0` package will contain 2 different tool-requires to both `gcc/1.0` with `myoption=1` and with `myoption=2`. Of course, it is not true that we won’t run anything from those `tool_requires`, but now Conan is not aware of it, and it is completely the responsibility of the user to manage it. #### WARNING Using `run=False` makes the `tool_requires()` completely invisible, that means that profile `[tool_requires]` will not be able to override its version, but it would create an extra tool-require dependency with the version injected from the profile. You might want to exclude specific packages with something like `!wine/*: gcc/3.0`. The recipe still has access in the `generate()` method to each different `tool_require` version, just by providing the options values for the dependency that we want `self.dependencies.build.get("gcc", options={"myoption": 1})`. Finally, the most important part is that the usage of those tools is completely the responsibility of the user. The `bin` folder of both `tool_requires` containing the executables will be in the path thanks to the `VirtualBuildEnv` generator that by default updates the PATH env-var. In this case the executables are different like `mygcc1.sh` and `mygcc2.sh`, so it is not an issue, and each one will be found inside its package. But if the executable file was exactly the same like `gcc.exe`, then it would be necessary to obtain the full folder (typically in the `generate()` method) with something like `self.dependencies.build.get("gcc", options={"myoption": 1}).cpp_info.bindir` and use the full path to disambiguate. Let’s see it working. If we execute: ```bash $ conan create wine ... wine/1.0: RUN: mygcc1.bat MYGCC=1!! wine/1.0: RUN: mygcc2.bat MYGCC=2!! ``` --- https://docs.conan.io/2/examples/graph/tool_requires/different_versions.html.md --- # Depending on different versions of the same tool-require #### NOTE This is an **advanced** use case. It shouldn’t be necessary in the vast majority of cases. In the general case, trying to do something like this: ```python def build_requirements(self): self.tool_requires("gcc/1.0") self.tool_requires("gcc/2.0") ``` Will generate a “conflict”, showing an error like `Duplicated requirement`. This is correct in most situations, when it is obvious that it is not possible to use 2 versions of the same compiler to build the current package. However there are some exceptional situations when something like that is desired. Let’s recreate the potential scenario. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```shell git clone https://github.com/conan-io/examples2.git cd examples2/examples/graph/tool_requires/different_versions ``` There we have a `gcc` fake recipe with: ```python class Pkg(ConanFile): name = "gcc" def package(self): echo = f"@echo off\necho MYGCC={self.version}!!" save(self, os.path.join(self.package_folder, "bin", f"mygcc{self.version}.bat"), echo) save(self, os.path.join(self.package_folder, "bin", f"mygcc{self.version}.sh"), echo) os.chmod(os.path.join(self.package_folder, "bin", f"mygcc{self.version}.sh"), 0o777) ``` This is not an actual compiler, it fakes it with a shell or bat script that prints `MYGCC=current-version` when executed. Note the binary itself is called `mygcc1.0` and `mygcc2.0`, that is, it contains the version in the executable name itself. We can create 2 different versions for `gcc/1.0` and `gcc/2.0` with: ```bash $ conan create gcc --version=1.0 $ conan create gcc --version=2.0 ``` Now, in the `wine` folder there is a `conanfile.py` like this: ```python class Pkg(ConanFile): name = "wine" version = "1.0" def build_requirements(self): # If we specify "run=False" they no longer conflict self.tool_requires("gcc/1.0", run=False) self.tool_requires("gcc/2.0", run=False) def generate(self): # It is possible to individually reference each one gcc1 = self.dependencies.build["gcc/1.0"] assert gcc1.ref.version == "1.0" gcc2 = self.dependencies.build["gcc/2.0"] assert gcc2.ref.version == "2.0" def build(self): ext = "bat" if platform.system() == "Windows" else "sh" self.run(f"mygcc1.0.{ext}") self.run(f"mygcc2.0.{ext}") ``` The first important point is the `build_requirements()` method, that does a `tool_requires()` to both versions, but defining `run=False`. **This is very important**: we are telling Conan that we actually don’t need to run anything from those packages. As `tool_requires` are not visible, they don’t define headers or libraries, there is nothing that makes Conan identify those 2 `tool_requires` as conflicting. So the dependency graph can be constructed without errors, and the `wine/1.0` package will contain 2 different tool-requires to both `gcc/1.0` and `gcc/2.0`. Of course, it is not true that we won’t run anything from those `tool_requires`, but now Conan is not aware of it, and it is completely the responsibility of the user to manage it. #### WARNING Using `run=False` makes the `tool_requires()` completely invisible, that means that profile `[tool_requires]` will not be able to override its version, but it would create an extra tool-require dependency with the version injected from the profile. You might want to exclude specific packages with something like `!wine/*: gcc/3.0`. The recipe has still access in the `generate()` method to each different `tool_require` version, just by providing the full reference like `self.dependencies.build["gcc/1.0"]`. Finally, the most important part is that the usage of those tools is completely the responsibility of the user. The `bin` folder of both `tool_requires` containing the executables will be in the path thanks to the `VirtualBuildEnv` generator that by default updates the PATH env-var. In this case the executables are different like `mygcc1.0.sh` and `mygcc2.0.sh`, so it is not an issue, and each one will be found inside its package. But if the executable file was exactly the same like `gcc.exe`, then it would be necessary to obtain the full folder (typically in the `generate()` method) with something like `self.dependencies.build["gcc/1.0"].cpp_info.bindir` and use the full path to disambiguate. Let’s see it working. If we execute: ```bash $ conan create wine ... wine/1.0: RUN: mygcc1.0.bat MYGCC=1.0!! wine/1.0: RUN: mygcc2.0.bat MYGCC=2.0!! ``` --- https://docs.conan.io/2/examples/graph/tool_requires/use_cmake_modules.html.md --- # Use cmake modules inside a `tool_requires` transparently When we want to reuse some `.cmake` scripts that are inside another Conan package there are several possible different scenarios, like if the `.cmake` scripts are inside a regular `requires` or a `tool_requires`. Also, it is possible to want 2 different approaches: - The consumer of the scripts can do a explicit `include(MyScript)` in their CMakeLists.txt. This approach is nicely explicit and simpler to setup, just define `self.cpp_info.builddirs` in the recipe, and consumers with `CMakeToolchain` will automatically be able to do the `include()` and use the functionality. See the [example here](https://docs.conan.io/2//examples/graph/requires/consume_cmake_macro.html.md#consume-cmake-macro) - The consumer wants to have the dependency cmake modules automatically loaded when the `find_package()` is executed. This current example implements this case. Let’s say that we have a package, intended to be used as a `tool_require`, with the following recipe: ```python import os from conan import ConanFile from conan.tools.files import copy class Conan(ConanFile): name = "myfunctions" version = "1.0" exports_sources = ["*.cmake"] def package(self): copy(self, "*.cmake", self.source_folder, self.package_folder) def package_info(self): self.cpp_info.set_property("cmake_build_modules", ["myfunction.cmake"]) ``` And a `myfunction.cmake` file in: ```cmake function(myfunction) message("Hello myfunction!!!!") endfunction() ``` We can do a `cd myfunctions && conan create .` which will create the `myfunctions/1.0` package containing the cmake script. Then, a consumer package will look like: ```python from conan import ConanFile from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain class Conan(ConanFile): settings = "os", "compiler", "build_type", "arch" tool_requires = "myfunctions/1.0" def generate(self): tc = CMakeToolchain(self) tc.generate() deps = CMakeDeps(self) # By default 'myfunctions-config.cmake' is not created for tool_requires # we need to explicitly activate it deps.build_context_activated = ["myfunctions"] # and we need to tell to automatically load 'myfunctions' modules deps.build_context_build_modules = ["myfunctions"] deps.generate() def build(self): cmake = CMake(self) cmake.configure() ``` And a `CMakeLists.txt` like: ```cmake cmake_minimum_required(VERSION 3.0) project(test) find_package(myfunctions CONFIG REQUIRED) myfunction() ``` Then, the consumer will be able to automatically call the `myfunction()` from the dependency module: ```bash $ conan build . ... Hello myfunction!!!! ``` If for some reason the consumer wants to force the usage from the `tool_requires()` as a CMake module, the consumer could do `deps.set_property("myfunctions", "cmake_find_mode", "module", build_context=True)`, and then `find_package(myfunctions MODULE REQUIRED)` will work. --- https://docs.conan.io/2/examples/graph/tool_requires/using_protobuf.html.md --- # Using the same requirement as a requires and as a tool_requires There are libraries which could behave as a library and as a tool requirement, e.g., [protobuf](https://github.com/conan-io/conan-center-index/tree/master/recipes/protobuf) Those libraries normally contains headers/sources of the library itself, and, perhaps, some extra tools (compilers, shell scripts, etc.). Both parts are used in different contexts, let’s think of this scenario using *protobuf* for instance: * I want to create a library which includes a compiled protobuf message. The protobuf compiler (build context) needs to be invoked at build time, and the library with the compiled *.pb.cc* file needs to be linked against the protobuf library (host context). Given that, we should be able to use protobuf in build/host context in the same Conan recipe. Basically, your package recipe should look like: ```python def requirements(self): self.requires("protobuf/3.18.1") def build_requirements(self): self.tool_requires("protobuf/") ``` #### NOTE The `protobuf/` expression ensures that the same version of the library is used in both contexts. You can read more about it [here](https://docs.conan.io/2//reference/conanfile/methods/build_requirements.html.md#reference-conanfile-build-requirements-host-version). This is the way to proceed with any other library used in both contexts. Nonetheless, let’s see a detailed example to see how the example looks like. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```shell git clone https://github.com/conan-io/examples2.git cd examples2/examples/graph/tool_requires/using_protobuf/myaddresser ``` The structure of the project is the following: ```text ./ ├── conanfile.py ├── CMakeLists.txt ├── addressbook.proto ├── apple-arch-armv8 ├── apple-arch-x86_64 └── src └── myaddresser.cpp └── include └── myaddresser.h └── test_package ├── conanfile.py ├── CMakeLists.txt └── src └── example.cpp ``` The `conanfile.py` looks like: ```python from conan import ConanFile from conan.tools.cmake import CMake, cmake_layout class myaddresserRecipe(ConanFile): name = "myaddresser" version = "1.0" package_type = "library" settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} generators = "CMakeDeps", "CMakeToolchain" # Sources are located in the same place as this recipe, copy them to the recipe exports_sources = "CMakeLists.txt", "src/*", "include/*", "addressbook.proto" def config_options(self): if self.settings.os == "Windows": self.options.rm_safe("fPIC") def configure(self): if self.options.shared: self.options.rm_safe("fPIC") def requirements(self): self.requires("protobuf/3.18.1") def build_requirements(self): self.tool_requires("protobuf/") def layout(self): cmake_layout(self) 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 = ["myaddresser"] self.cpp_info.requires = ["protobuf::libprotobuf"] ``` As you can see, we’re using *protobuf* at the same time but in different contexts. The `CMakeLists.txt` shows how this example uses protobuf compiler and library: ```cmake cmake_minimum_required(VERSION 3.15) project(myaddresser LANGUAGES CXX) find_package(protobuf CONFIG REQUIRED) protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS addressbook.proto) add_library(myaddresser src/myaddresser.cpp ${PROTO_SRCS}) target_include_directories(myaddresser PUBLIC include) target_include_directories(myaddresser PUBLIC $ $ $ ) target_link_libraries(myaddresser PUBLIC protobuf::libprotobuf) set_target_properties(myaddresser PROPERTIES PUBLIC_HEADER "include/myaddresser.h;${PROTO_HDRS}") install(TARGETS myaddresser) ``` Where the library itself defines a simple *myaddresser.cpp* which uses the generated *addressbook.pb.h* header: ```cpp #include #include #include #include "addressbook.pb.h" #include "myaddresser.h" void myaddresser(){ // Testing header generated by protobuf GOOGLE_PROTOBUF_VERIFY_VERSION; tutorial::AddressBook address_book; auto * person = address_book.add_people(); person->set_id(1337); std::cout << "myaddresser(): created a person with id 1337\n"; // Optional: Delete all global objects allocated by libprotobuf. google::protobuf::ShutdownProtobufLibrary(); } ``` Finally, the *test_package* example simply calls the `myaddresser()` function to check that everything works correctly: ```cpp #include #include #include #include "myaddresser.h" int main(int argc, char* argv[]) { myaddresser(); return 0; } ``` So, let’s see if it works fine: ```shell $ conan create . --build missing ... Requirements myaddresser/1.0#71305099cc4dc0b08bb532d4f9196ac1:c4e35584cc696eb5dd8370a2a6d920fb2a156438 - Build protobuf/3.18.1#ac69396cd9fbb796b5b1fc16473ca354:e60fa1e7fc3000cc7be2a50a507800815e3f45e0#0af7d905b0df3225a3a56243841e041b - Cache zlib/1.2.13#13c96f538b52e1600c40b88994de240f:d0599452a426a161e02a297c6e0c5070f99b4909#69b9ece1cce8bc302b69159b4d437acd - Cache Build requirements protobuf/3.18.1#ac69396cd9fbb796b5b1fc16473ca354:e60fa1e7fc3000cc7be2a50a507800815e3f45e0#0af7d905b0df3225a3a56243841e041b - Cache ... -- Install configuration: "Release" -- Installing: /Users/myuser/.conan2/p/b/myser03f790a5a5533/p/lib/libmyaddresser.a -- Installing: /Users/myuser/.conan2/p/b/myser03f790a5a5533/p/include/myaddresser.h -- Installing: /Users/myuser/.conan2/p/b/myser03f790a5a5533/p/include/addressbook.pb.h myaddresser/1.0: package(): Packaged 2 '.h' files: myaddresser.h, addressbook.pb.h myaddresser/1.0: package(): Packaged 1 '.a' file: libmyaddresser.a .... ======== Testing the package: Executing test ======== myaddresser/1.0 (test package): Running test() myaddresser/1.0 (test package): RUN: ./example myaddresser(): created a person with id 1337 ``` After seeing it’s running OK, let’s try to use cross-building. Notice that this part is based on MacOS Intel systems, and cross-compiling for MacOS ARM ones, but you could use your own profiles depending on your needs for sure. #### WARNING MacOS system is required to run this part of the example. ```shell $ conan create . --build missing -pr:b apple-arch-x86_64 -pr:h apple-arch-armv8 ... -- Install configuration: "Release" -- Installing: /Users/myuser/.conan2/p/b/myser03f790a5a5533/p/lib/libmyaddresser.a -- Installing: /Users/myuser/.conan2/p/b/myser03f790a5a5533/p/include/myaddresser.h -- Installing: /Users/myuser/.conan2/p/b/myser03f790a5a5533/p/include/addressbook.pb.h myaddresser/1.0: package(): Packaged 2 '.h' files: myaddresser.h, addressbook.pb.h myaddresser/1.0: package(): Packaged 1 '.a' file: libmyaddresser.a .... ======== Testing the package: Executing test ======== myaddresser/1.0 (test package): Running test() ``` Now, we cannot see the example running because of the host architecture. If we want to check that the *example* executable is built for the correct one: ```shell $ file test_package/build/apple-clang-13.0-armv8-gnu17-release/example test_package/build/apple-clang-13.0-armv8-gnu17-release/example: Mach-O 64-bit executable arm64 ``` Everything works as expected, and the executable was built for 64-bit executable arm64 architectures. --- https://docs.conan.io/2/examples/runners/docker/basic.html.md --- # Creating a Conan package using a Docker runner #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. First of all you need to have the Docker daemon installed and running, plus Conan and the `docker` Python package. This tutorial assumes that you are running Conan inside a Python virtual environment, skip the first line if you already have the `docker` Python package installed in your virtual environment. ```bash # install docker in your virtual environment if you don't have it already installed $ pip install conan docker $ docker ps $ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ``` Now we are going to create create simple `cmake_lib` Conan template to later run inside Docker using the runner feature. Let’s create the Conan package and a Dockerfile inside our project folder. ```bash $ cd $ mkdir mylib $ cd mylib $ conan new cmake_lib -d name=mylib -d version=0.1 $ tree . ├── CMakeLists.txt ├── conanfile.py ├── include │ └── mylib.h ├── src │ └── mylib.cpp └── test_package ├── CMakeLists.txt ├── conanfile.py └── src └── example.cpp ``` `Dockerfile` ```docker FROM ubuntu:22.04 RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ build-essential \ cmake \ python3 \ python3-pip \ python3-venv \ && rm -rf /var/lib/apt/lists/* RUN pip install conan ``` ```bash $ cd /mylib $ tree . ... ├── Dockerfile ... ``` Now, we need to define two new profiles inside the conan `profiles` folder. Replace `` with your real project folder path. `docker_example_host` profile ```text [settings] build_type=Release arch=x86_64 compiler=gcc compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 compiler.version=11 os=Linux [runner] type=docker dockerfile=/mylib cache=copy remove=true platform=linux/amd64 ``` #### NOTE Users are free to configure architecture and platform on the host profile. Conan docker integration will build and run the image using the specified platform. For example, if you are using a Mac Silicon, you can set the platform to `linux/arm64/v8` to build the image using the armv8 architecture. ```text [settings] arch=armv8 # ... [runner] platform=linux/arm64/v8 ``` `docker_example_build` profile ```bash [settings] arch=x86_64 build_type=Release compiler=gcc compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 compiler.version=11 os=Linux ``` We are going to start from a totally clean environment, without any containers, images or conan package. ```bash $ conan list "*:*" Found 0 pkg/version recipes matching * in local cache ``` ```bash $ docker ps --all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ``` ```bash $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ``` Now, it’s time to create our library `mylib` using our new runner definition. ```bash $ conan create . -pr:h docker_example_host -pr:b docker_example_build ``` If we split and analyze the command output, we can see what is happening and where the commands are being executed. **1.** Standard conan execution. ```bash ======== Exporting recipe to the cache ======== mylib/0.1: Exporting package recipe: /mylib/conanfile.py mylib/0.1: Copied 1 '.py' file: conanfile.py mylib/0.1: Copied 1 '.txt' file: CMakeLists.txt mylib/0.1: Copied 1 '.h' file: mylib.h mylib/0.1: Copied 1 '.cpp' file: mylib.cpp mylib/0.1: Exported to cache folder: /Users//.conan2/p/mylib4abd06a04bdaa/e mylib/0.1: Exported: mylib/0.1#8760bf5a311f01cc26f3b95428203210 (2024-07-08 12:22:01 UTC) ======== Input profiles ======== Profile host: [settings] arch=x86_64 build_type=Release compiler=gcc compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 compiler.version=11 os=Linux Profile build: [settings] arch=x86_64 build_type=Release compiler=gcc compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 compiler.version=11 os=Linux ``` **2.** Build docker image ```bash Building the Docker image: conan-runner-default Dockerfile path: '/mylib/Dockerfile' Docker build context: '/mylib' Step 1/3 : FROM ubuntu:22.04 ---> 97271d29cb79 Step 2/3 : RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends build-essential cmake python3 python3-pip python3-venv g++-x86-64-linux-gnu && rm -rf /var/lib/apt/lists/* ... ---> 2bcf70201cce Successfully built 2bcf70201cce Successfully tagged conan-runner-default:latest ``` **3.** Save the local cache running `conan cache save`. ```bash Save host cache in: /Users//sources/test/mylib/.conanrunner/local_cache_save.tgz Found 1 pkg/version recipes matching * in local cache Saving mylib/0.1: mylib4abd06a04bdaa ``` **4.** Create and initialize the docker container. ```bash Creating the docker container Container conan-runner-docker running ``` **5.** Check if the container has a conan version with the runner feature. ```bash conan-runner-docker | $ conan --version conan-runner-docker | Conan version 2.12.1 ``` **6.** Initialize the container conan cache using the host copy running `conan cache restore`. ```bash conan-runner-docker | $ conan cache restore "/root/conanrunner/mylib/.conanrunner/local_cache_save.tgz" conan-runner-docker | Restore: mylib/0.1 in mylib4abd06a04bdaa conan-runner-docker | Local Cache conan-runner-docker | mylib conan-runner-docker | mylib/0.1 conan-runner-docker | revisions conan-runner-docker | 8760bf5a311f01cc26f3b95428203210 (2025-01-31 12:34:25 UTC) conan-runner-docker | packages conan-runner-docker | recipe_folder: mylib4abd06a04bdaa ``` **7.** Run the conan create inside the container and build “mylib”. ```bash conan-runner-docker | $ conan create /root/conanrunner/mylib -pr:h docker_param_example_host -pr:b docker_param_example_build -f json > create.json conan-runner-docker | conan-runner-docker | ======== Exporting recipe to the cache ======== conan-runner-docker | mylib/0.1: Exporting package recipe: /root/conanrunner/mylib/conanfile.py conan-runner-docker | mylib/0.1: Copied 1 '.py' file: conanfile.py conan-runner-docker | mylib/0.1: Copied 1 '.txt' file: CMakeLists.txt conan-runner-docker | mylib/0.1: Copied 1 '.h' file: mylib.h conan-runner-docker | mylib/0.1: Copied 1 '.cpp' file: mylib.cpp conan-runner-docker | mylib/0.1: Exported to cache folder: /root/.conan2/p/mylib4abd06a04bdaa/e conan-runner-docker | mylib/0.1: Exported: mylib/0.1#8760bf5a311f01cc26f3b95428203210 (2025-01-31 12:34:26 UTC) conan-runner-docker | conan-runner-docker | ======== Input profiles ======== conan-runner-docker | Profile host: conan-runner-docker | [settings] conan-runner-docker | arch=x86_64 conan-runner-docker | build_type=Release conan-runner-docker | compiler=gcc conan-runner-docker | compiler.cppstd=gnu17 conan-runner-docker | compiler.libcxx=libstdc++11 conan-runner-docker | compiler.version=11 conan-runner-docker | os=Linux conan-runner-docker | conan-runner-docker | Profile build: conan-runner-docker | [settings] conan-runner-docker | arch=x86_64 conan-runner-docker | build_type=Release conan-runner-docker | compiler=gcc conan-runner-docker | compiler.cppstd=gnu17 conan-runner-docker | compiler.libcxx=libstdc++11 conan-runner-docker | compiler.version=11 conan-runner-docker | os=Linux conan-runner-docker | conan-runner-docker | conan-runner-docker | ======== Computing dependency graph ======== conan-runner-docker | Graph root conan-runner-docker | cli conan-runner-docker | Requirements conan-runner-docker | mylib/0.1#8760bf5a311f01cc26f3b95428203210 - Cache conan-runner-docker | conan-runner-docker | ======== Computing necessary packages ======== conan-runner-docker | mylib/0.1: Forced build from source conan-runner-docker | Requirements conan-runner-docker | mylib/0.1#8760bf5a311f01cc26f3b95428203210:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe - Build conan-runner-docker | ... conan-runner-docker | [ 50%] Building CXX object CMakeFiles/example.dir/src/example.cpp.o conan-runner-docker | [100%] Linking CXX executable example conan-runner-docker | [100%] Built target example conan-runner-docker | conan-runner-docker | conan-runner-docker | ======== Testing the package: Executing test ======== conan-runner-docker | mylib/0.1 (test package): Running test() conan-runner-docker | mylib/0.1 (test package): RUN: ./example conan-runner-docker | mylib/0.1: Hello World Release! conan-runner-docker | mylib/0.1: __x86_64__ defined conan-runner-docker | mylib/0.1: _GLIBCXX_USE_CXX11_ABI 1 conan-runner-docker | mylib/0.1: __cplusplus201703 conan-runner-docker | mylib/0.1: __GNUC__11 conan-runner-docker | mylib/0.1: __GNUC_MINOR__4 conan-runner-docker | mylib/0.1 test_package ``` **8.** Copy just the package created inside the container using the `pkglist.json` info from the previous `conan create`, restore this new package inside the host cache running a `conan cache save` and remove the container. ```bash conan-runner-docker | $ conan cache save --list=pkglist.json --file "/root/conanrunner/mylib"/.conanrunner/docker_cache_save.tgz conan-runner-docker | Saving mylib/0.1: mylib4abd06a04bdaa conan-runner-docker | Saving mylib/0.1:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe: b/mylib11242e0a7e627/p conan-runner-docker | Saving mylib/0.1:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata: b/mylib11242e0a7e627/d/metadata conan-runner-docker | Local Cache conan-runner-docker | mylib conan-runner-docker | mylib/0.1 conan-runner-docker | revisions conan-runner-docker | 8760bf5a311f01cc26f3b95428203210 (2025-01-31 12:34:26 UTC) conan-runner-docker | packages conan-runner-docker | 8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe conan-runner-docker | revisions conan-runner-docker | ded6547554ff2306db5250451340fa43 conan-runner-docker | package_folder: b/mylib11242e0a7e627/p conan-runner-docker | metadata_folder: b/mylib11242e0a7e627/d/metadata conan-runner-docker | info conan-runner-docker | settings conan-runner-docker | os: Linux conan-runner-docker | arch: x86_64 conan-runner-docker | compiler: gcc conan-runner-docker | compiler.cppstd: gnu17 conan-runner-docker | compiler.libcxx: libstdc++11 conan-runner-docker | compiler.version: 11 conan-runner-docker | build_type: Release conan-runner-docker | options conan-runner-docker | fPIC: True conan-runner-docker | shared: False conan-runner-docker | recipe_folder: mylib4abd06a04bdaa conan-runner-docker | Restore host cache from: /Users//sources/test/mylib/.conanrunner/docker_cache_save.tgz Restore: mylib/0.1 in mylib4abd06a04bdaa Restore: mylib/0.1:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe in b/mylib11242e0a7e627/p Restore: mylib/0.1:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata in b/mylib11242e0a7e627/d/metadata Stopping container Removing container ``` If we now check the status of our conan and docker cache, we will see the new mylib package compile for Linux and the new docker image but we don’t have any container because we define `remove=true` ```bash $ conan list "*:*" Found 1 pkg/version recipes matching * in local cache Local Cache mylib mylib/0.1 revisions 8760bf5a311f01cc26f3b95428203210 (2024-07-08 12:33:28 UTC) packages 8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe info settings arch: x86_64 build_type: Release compiler: gcc compiler.cppstd: gnu17 compiler.libcxx: libstdc++11 compiler.version: 11 os: Linux options fPIC: True shared: False ``` ```bash $ docker ps --all CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ``` ```bash $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE my-conan-runner latest 2bcf70201cce 11 minutes ago 531MB ``` What we have just done is to compile a library from scratch inside a Docker container without running any Docker command and retrieve the generated packages in a totally transparent and easily debuggable way thanks to our terminal output. In this way, we can work as we have always done regardless of whether it is on our machine or in a container, without several open terminals and having the result of each operation in the same cache, being able to reuse the compiled packages from a previous compilation in another container automatically and transparently. --- https://docs.conan.io/2/examples/runners/docker/configfile_build_args.html.md --- # Using a docker runner configfile to parameterize a Dockerfile #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. If you need more control over the build and execution of the container, you can define more parameters inside a configfile yaml. For example, you can add arguments in the build step or environment variables when you launch the container. To use it, you just need to add it in the host profile. ```text [settings] ... [runner] type=docker configfile=/configfile cache=copy remove=false ``` **How to use** Let’s create a Dockerfile inside your project folder, a cmake_lib `myparamlib` like the [“Creating a Conan package using a Docker runner”](https://docs.conan.io/2//examples/runners/docker/basic.html.md#examples-runners-docker-basic) example and two profiles. ```bash $ cd $ mkdir myparamlib $ cd myparamlib $ conan new cmake_lib -d name=myparamlib -d version=0.1 $ cd $ tree . ├── CMakeLists.txt ├── conanfile.py ├── include │ └── myparamlib.h ├── src │ └── myparamlib.cpp └── test_package ├── CMakeLists.txt ├── conanfile.py └── src └── example.cpp ``` ```docker ARG BASE_IMAGE FROM $BASE_IMAGE RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ build-essential \ cmake \ python3 \ python3-pip \ python3-venv \ && rm -rf /var/lib/apt/lists/* RUN pip install conan ``` `configfile` ```yaml image: my-conan-runner-image build: dockerfile: build_context: build_args: BASE_IMAGE: ubuntu:22.04 run: name: my-conan-runner-container ``` ```bash $ cd /myparamlib $ tree . ... ├── Dockerfile ... ├── configfile ... ``` `docker_param_example_host` profile ```text [settings] arch=x86_64 build_type=Release compiler=gcc compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 compiler.version=11 os=Linux [runner] type=docker configfile=/myparamlib/configfile cache=copy remove=false ``` `docker_param_example_build` profile ```text [settings] arch=x86_64 build_type=Release compiler=gcc compiler.cppstd=gnu17 compiler.libcxx=libstdc++11 compiler.version=11 os=Linux ``` Now it’s time to create our new library. ```bash $ conan create . -pr:h docker_param_example_host -pr:b docker_param_example_build ... Building the Docker image: conan-runner-default Dockerfile path: '/myparamlib/Dockerfile' Docker build context: '/myparamlib' Step 1/5 : ARG BASE_IMAGE Step 2/5 : FROM $BASE_IMAGE ... Successfully built caa8071cdff7 Successfully tagged my-conan-runner-image:latest ... conan-runner-docker | $ conan create /root/conanrunner/myparamlib -pr:h docker_param_example_host -pr:b docker_param_example_build -f json > create.json ... conan-runner-docker | [ 50%] Building CXX object CMakeFiles/example.dir/src/example.cpp.o conan-runner-docker | [100%] Linking CXX executable example conan-runner-docker | [100%] Built target example conan-runner-docker | conan-runner-docker | ======== Testing the package: Executing test ======== conan-runner-docker | myparamlib/0.1 (test package): Running test() conan-runner-docker | myparamlib/0.1 (test package): RUN: ./example conan-runner-docker | myparamlib/0.1: Hello World Release! conan-runner-docker | myparamlib/0.1: __x86_64__ defined conan-runner-docker | myparamlib/0.1: _GLIBCXX_USE_CXX11_ABI 1 conan-runner-docker | myparamlib/0.1: __cplusplus201703 conan-runner-docker | myparamlib/0.1: __GNUC__11 conan-runner-docker | myparamlib/0.1: __GNUC_MINOR__4 conan-runner-docker | myparamlib/0.1 test_package conan-runner-docker | conan-runner-docker | $ /myparamlib/.conanrunner/docker_cache_save.tgz conan-runner-docker | conan-runner-docker | Saving myparamlib/0.1: mypar36e44205a36b9 conan-runner-docker | Saving myparamlib/0.1:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe: b/mypare0dc449d4125d/p conan-runner-docker | Saving myparamlib/0.1:8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe metadata: b/mypare0dc449d4125d/d/metadata ``` If we now check the status of our conan cache, we will see the new `myparamlib` pacakge. ```bash $ conan list "*:*" Found 1 pkg/version recipes matching * in local cache Local Cache myparamlib myparamlib/0.1 revisions 11cb359a0526fe9ce3cfefb59c5d1953 (2024-07-08 12:47:21 UTC) packages 8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe info settings arch: x86_64 build_type: Release compiler: gcc compiler.cppstd: gnu17 compiler.libcxx: libstdc++11 compiler.version: 11 os: Linux options fPIC: True shared: False ``` --- https://docs.conan.io/2/examples/security/sanitizers.html.md --- # Using Compiler Sanitizers with Conan To better illustrate the [sanitizers integration with Conan](https://docs.conan.io/2//security/sanitizers.html.md#security-sanitizers), this section provides practical examples using AddressSanitizer (ASan) and UndefinedBehaviorSanitizer (UBSan) with simple C++ programs. As a first step, please clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```bash git clone https://github.com/conan-io/examples2.git cd examples2/examples/security/sanitizers/compiler_sanitizers ``` In this example we will see how to prepare Conan to use sanitizers in different ways. To show how to use sanitizers in your builds, let’s consider two examples. ## AddressSanitizer: index out of bounds In this example, we will build a simple C++ program that intentionally accesses an out-of-bounds index in an array, which should trigger ASan when running the program. We will be using a Conan profile to enable ASan: ```ini [settings] arch=x86_64 os=Linux build_type=Debug compiler=gcc compiler.cppstd=gnu20 compiler.libcxx=libstdc++11 compiler.version=15 compiler.sanitizer=Address [conf] tools.build:cflags=['-fsanitize=address'] tools.build:cxxflags=['-fsanitize=address'] tools.build:exelinkflags=['-fsanitize=address'] tools.build:sharedlinkflags+=["-fsanitize=address"] [runenv] ASAN_OPTIONS=halt_on_error=1:detect_leaks=1 ``` Note that in this profile we set the `compiler.sanitizer=Address` does not define what compiler flags to use, but it is a settings to make explicit that both ASan and UBSan are intended to be used. And for further illustration, we also use environment variable `ASAN_OPTIONS=halt_on_error=1:detect_leaks=1` for runtime configuration, to manage ASan to halt execution on the first error and to detect memory leaks when the program exits. ```cpp #include #include int main() { #ifdef __SANITIZE_ADDRESS__ std::cout << "Address sanitizer enabled\n"; #else std::cout << "Address sanitizer not enabled\n"; #endif int foo[100]; foo[100] = 42; // Out-of-bounds write return EXIT_SUCCESS; } ``` **Note:** The preprocessor check above is portable for GCC, Clang and MSVC. The define `__SANITIZE_ADDRESS__` is present when **ASan** is active; **To build and run this example using Conan:** ```bash cd index_out_of_bounds/ conan build . -pr ../profiles/gcc_asan build/Debug/index_out_of_bounds ``` **Expected output (abbreviated):** ```text Address sanitizer enabled ==32018==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fffbe04a6d0 ... WRITE of size 4 at 0x7fffbe04a6d0 thread T0 #0 ... in main .../index_out_of_bounds+0x12ea ... SUMMARY: AddressSanitizer: stack-buffer-overflow ... in main This frame has 1 object(s): [48, 448) 'foo' (line 11) <== Memory access at offset 448 overflows this variable ``` ## UndefinedBehaviorSanitizer: signed integer overflow This example demonstrates how to use UBSan to detect signed integer overflow. It combines ASan and UBSan. Create a dedicated profile: ```ini [settings] arch=x86_64 os=Linux build_type=Debug compiler=gcc compiler.cppstd=gnu20 compiler.libcxx=libstdc++11 compiler.version=15 compiler.sanitizer=AddressUndefinedBehavior [conf] tools.build:cflags+=["-fsanitize=address,undefined", "-fno-omit-frame-pointer"] tools.build:cxxflags+=["-fsanitize=address,undefined", "-fno-omit-frame-pointer"] tools.build:exelinkflags+=["-fsanitize=address,undefined"] tools.build:sharedlinkflags+=["-fsanitize=address,undefined"] ``` It is supported by GCC and Clang. MSVC does not support UBSan. **Source code:** ```cpp #include #include #include int main() { #ifdef __SANITIZE_ADDRESS__ std::cout << "Address sanitizer enabled\n"; #else std::cout << "Address sanitizer not enabled\n"; #endif int x = INT_MAX; x += 42; // signed integer overflow return EXIT_SUCCESS; } ``` **Build and run:** ```bash cd signed_integer_overflow/ conan build . -pr ../profiles/gcc_asan_ubsan build/Debug/signed_integer_overflow ``` **Expected output (abbreviated):** ```text Address sanitizer enabled .../main.cpp:16:9: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' ``` When executing the example application, UBSan detects the signed integer overflow and reports it as expected. --- https://docs.conan.io/2/examples/tools/autotools/autotools.html.md --- # Autotools * [Build a simple Autotools project with Conan dependencies](https://docs.conan.io/2//examples/tools/autotools/build_project_autotools_toolchain.html.md) * [Building on Linux and macOS](https://docs.conan.io/2//examples/tools/autotools/build_project_autotools_toolchain.html.md#building-on-linux-and-macos) * [Create your first Conan package with Autotools](https://docs.conan.io/2//examples/tools/autotools/create_your_first_package.html.md) * [Create your first Conan package with Autotools in Windows (msys2)](https://docs.conan.io/2//examples/tools/autotools/create_your_first_package_windows.html.md) * [AutoTools: Using LLVM/Clang Windows compiler](https://docs.conan.io/2//examples/tools/autotools/llvm_clang.html.md) * [Autotools: LLVM/Clang with `clang` GNU-like frontend](https://docs.conan.io/2//examples/tools/autotools/llvm_clang.html.md#autotools-llvm-clang-with-clang-gnu-like-frontend) * [Autotools: LLVM/Clang with `clang-cl` MSVC-like frontend](https://docs.conan.io/2//examples/tools/autotools/llvm_clang.html.md#autotools-llvm-clang-with-clang-cl-msvc-like-frontend) --- https://docs.conan.io/2/examples/tools/autotools/build_project_autotools_toolchain.html.md --- # Build a simple Autotools project with Conan dependencies #### WARNING This example will only work for Linux and OSX environments and does not support Windows directly, including msys2/cygwin subsystems. However, Windows Subsystem for Linux (WSL) should work since it provides a Linux environment. While Conan offers win_bash = True for some level of support in Windows environments with Autotools, it’s not applicable in this tutorial. In this example, we are going to create a string formatter application that uses one of the most popular C++ libraries: [fmt](https://fmt.dev/latest). We’ll use [Autotools](https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html) as build system and [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/) as a helper tool in this case, so you should get them installed on Linux and Mac before going forward with this example. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```shell git clone https://github.com/conan-io/examples2.git cd examples2/examples/tools/autotools/autotoolstoolchain/string_formatter ``` We start with a very simple C++ language project with the following structure: ```text . ├── configure.ac ├── Makefile.am ├── conanfile.txt └── src └── main.cpp ``` This project contains a basic configure.ac _ including the **fmt** pkg-config dependency and the source code for the string formatter program in *main.cpp*. Let’s have a look at the *main.cpp* file, it only prints a simple message but uses `fmt::print` method for it. ```cpp #include #include int main() { fmt::print("{} - The C++ Package Manager!\n", "Conan"); return EXIT_SUCCESS; } ``` The `configure.ac` file checks for a C++ compiler using the `AC_PROG_CXX` macro and also checks for the `fmt.pc` pkg-config module using the `PKG_CHECK_MODULES` macro. ```text AC_INIT([stringformatter], [0.1.0]) AM_INIT_AUTOMAKE([1.10 -Wall no-define foreign]) AC_CONFIG_SRCDIR([src/main.cpp]) AC_CONFIG_FILES([Makefile]) PKG_CHECK_MODULES([fmt], [fmt]) AC_PROG_CXX AC_OUTPUT ``` The *Makefile.am* specifies that `string_formatter` is the expected executable and that it should be linked to the `fmt` library. ```text AUTOMAKE_OPTIONS = subdir-objects ACLOCAL_AMFLAGS = ${ACLOCAL_FLAGS} bin_PROGRAMS = string_formatter string_formatter_SOURCES = src/main.cpp string_formatter_CPPFLAGS = $(fmt_CFLAGS) string_formatter_LDADD = $(fmt_LIBS) ``` The *conanfile.txt* looks simple as it just installs the **fmt** package and uses two generators to build our project. ```ini [requires] fmt/9.1.0 [generators] AutotoolsToolchain PkgConfigDeps ``` In this case, we will use [PkgConfigDeps](https://docs.conan.io/2//reference/tools/gnu/pkgconfigdeps.html.md#conan-tools-gnu-pkgconfigdeps) to generate information about where the **fmt** library files are installed thanks to the \*.pc files and [AutotoolsToolchain](https://docs.conan.io/2//reference/tools/gnu/autotoolstoolchain.html.md#conan-tools-gnu-autotoolstoolchain) to pass build information to *autotools* using a conanbuild[.sh|.bat] file that describes the compilation environment. We will use Conan to install **fmt** library, generate a toolchain for Autotools, and, .pc files for find **fmt** by pkg-config. ## Building on Linux and macOS First, we should install some requirements. On Linux you need to have `automake` , `pkgconf` and `make` packages installed, their packages names should vary according to the Linux distribution, but essentially, it should include all tools (aclocal, automake, autoconf and make) that you will need to build the following example. For this example, we will not consider a specific Conan profile, but `fmt` is highly compatible with many different configurations. So it should work mostly with versions of GCC and Clang compiler. As the first step, we should install all dependencies listed in the `conanfile.txt`. The command :ref: conan install will not only install the `fmt` package, but also build it from sources in case your profile does not match with a pre-built binary in your remotes. Plus, it will provide these generators listed in the `conanfile.txt` ```shell conan install . --build=missing ``` After running `conan install` command, we should have new files present in the *string_formatter* folder: ```text └── string_formatter ├── Makefile.am ├── conanautotoolstoolchain.sh ├── conanbuild.conf ├── conanbuild.sh ├── conanbuildenv-release-armv8.sh ├── conanfile.txt ├── conanrun.sh ├── conanrunenv-release-armv8.sh ├── configure.ac ├── deactivate_conanbuild.sh ├── deactivate_conanrun.sh ├── fmt-_fmt.pc ├── fmt.pc ├── run_example.sh └── src └── main.cpp ``` These files are the result of those generators listed in the `conanfile.txt`. Once all files needed to build the example are generated and `fmt` is installed, now we can load the script `conanbuild.sh`. ```shell source conanbuild.sh ``` The `conanbuild.sh` is a default file generated by the [VirtualBuildEnv](https://docs.conan.io/2//reference/tools/env/virtualbuildenv.html.md#conan-tools-env-virtualbuildenv) and helps us to load other script files, so we don’t need to execute more manual steps to load each generator file. It will load `conanautotoolstoolchain.sh`, generated by AutotoolsToolchain, which defines environment variables according to our Conan profile, used when running `conan install` command. Those environment variables configured are related to the compiler and `autotools`, like `CFLAGS`, `CPPFLAGS`, `LDFLAGS`, and `PKG_CONFIG_PATH`. As the next step, we can configure the project by running the following commands in sequence: ```shell aclocal automake --add-missing autoconf ./configure ``` The [aclocal](https://www.gnu.org/software/automake/manual/html_node/aclocal-Invocation.html) command will read the file `configure.ac` and generate a new file named `aclocal.m4`, which contains macros needed by the `automake`. As the second step, the [automake](https://www.gnu.org/software/automake/manual/automake.html) command will read the `Makefile.am`, and will generate the file `Makefile.in`. So the command [autoconf](https://www.gnu.org/software/autoconf/) will use those files and generate the `configure` file. Once we run `configure`, all environment variables will be consumed. The `fmt.pc` will be loaded at this step too, as `autotools` uses the custom `PKG_CONFIG_PATH` to find it. Then, finally, we can build the project to generate the string formatter application. Now we run the `make` command, which will consume the `Makefile` generated by `autotools`. ```shell make ``` The `make` command will read the `Makefile` and invoke the compiler, then, build the `main.cpp`, generating the executable `string_formatter` in the same folder. ```shell ./string_formatter Conan - The C++ Package Manager! ``` The final output is the result of a new application, printing a message with the help of `fmt` library, and built by `Autotools`. --- https://docs.conan.io/2/examples/tools/autotools/create_your_first_package.html.md --- # Create your first Conan package with Autotools #### WARNING This example will only work for Linux and OSX environments and does not support Windows directly, including msys2/cygwin subsystems. However, Windows Subsystem for Linux (WSL) should work since it provides a Linux environment. While Conan offers win_bash = True for some level of support in Windows environments with Autotools, it’s not applicable in this tutorial. In the [Create your first Conan package tutorial](https://docs.conan.io/2//tutorial/creating_packages/create_your_first_package.html.md#creating-packages-create-your-first-conan-package) CMake was used as the build system. If you haven’t read that section, read it first to familiarize yourself with the `conanfile.py` and `test_package` concepts, then come back to read about the specifics of the `Autotools` package creation. Use the **conan new** command to create a “Hello World” C++ library example project: ```bash $ conan new autotools_lib -d name=hello -d version=0.1 ``` This will create a Conan package project with the following structure. ```text ├── conanfile.py ├── configure.ac ├── Makefile.am ├── src │   ├── hello.h │   ├── hello.cpp │   └── Makefile.am └── test_package ├── conanfile.py ├── configure.ac ├── mainc.pp └── Makefile.am ``` The structure and files are very similar to the previous CMake example: - **conanfile.py**: On the root folder, there is a *conanfile.py* which is the main recipe file, responsible for defining how the package is built and consumed. - **configure.ac**: An autotools configuration script, that contains the necessary macros and references the `Makefiles` it needs to configure. - **Makefile.am**: A Makefile configuration file, defining only `SUBDIRS = src` - **src** folder: the folder that contains the simple C++ “hello” library. - **src/Makefile.am**: Makefile configuration file containing the library definition and source files like `libhello_la_SOURCES = hello.cpp hello.h` - **test_package** folder: contains an *example* application that will require and link with the created package. In this case the `test_package` also contains an autotools project, but it is possible to have the `test_package` using other build system as CMake if desired. It is not mandatory that the test_package is using the same build system as the package. Let’s have a look at the package recipe *conanfile.py* (only the relevant new parts): ```python exports_sources = "configure.ac", "Makefile.am", "src/*" def layout(self): basic_layout(self) def generate(self): at_toolchain = AutotoolsToolchain(self) at_toolchain.generate() def build(self): autotools = Autotools(self) autotools.autoreconf() autotools.configure() autotools.make() def package(self): autotools = Autotools(self) autotools.install() fix_apple_shared_install_name(self) ``` Let’s explain the different sections of the recipe briefly: - The `layout()` defines a `basic_layout()`, this is less flexible than a CMake one, so it doesn’t allow any parametrization. - The `generate()` method calls `AutotoolsToolchain` that can generate a `conanautotoolstoolchain` environment script defining environment variables like `CXXFLAGS` or `LDFLAGS` that will be used by the `Makefiles` to map the Conan input settings into compile flags. If the project had dependencies with Conan `requires`, it should add `PkgConfigDeps` too - The `build()` method uses the `Autotools()` helper to drive the build, calling the different configure and build steps. - The `package()` method uses the `Autotools` install functionality to define and copy to the package folder the final artifacts. Note the template also includes a call to `fix_apple_shared_install_name()` that uses OSX *install_name_tool* utility to set `@rpath``to fix the ``LC_ID_DYLIB` and `LC_LOAD_DYLIB` fields on Apple dylibs, because it is very unusual that autotools project will manage to do this (CMake can do it) . Let’s build the package from sources with the current default configuration, and then let the `test_package` folder test the package: ```bash $ conan create . ... ======== Testing the package: Executing test ======== hello/0.1 (test package): Running test() hello/0.1 (test package): RUN: ./main hello/0.1: Hello World Release! hello/0.1: __x86_64__ defined hello/0.1: _GLIBCXX_USE_CXX11_ABI 1 hello/0.1: __cplusplus201703 hello/0.1: __GNUC__11 hello/0.1: __GNUC_MINOR__1 hello/0.1 test_package ``` We can now validate that the recipe and the package binary are in the cache: ```bash $ conan list "hello/1.0:*" Local Cache: hello hello/1.0 revisions 5b151b3f08144bf25131266eb306ddff (2024-03-06 12:03:52 UTC) packages 8631cf963dbbb4d7a378a64a6fd1dc57558bc2fe info settings arch: x86_64 build_type: Release compiler: gcc compiler.cppstd: gnu17 compiler.libcxx: libstdc++11 compiler.version: 11 os: Linux options fPIC: True shared: False ``` #### SEE ALSO - [GNU built-in integrations reference](https://docs.conan.io/2//reference/tools/gnu.html.md#conan-tools-gnu). --- https://docs.conan.io/2/examples/tools/autotools/create_your_first_package_windows.html.md --- # Create your first Conan package with Autotools in Windows (msys2) #### WARNING This example is intended for the Windows OS, using the `msys2` subsystem to run the autotools build system. The support is **limited**, the `AutotoolsDeps` generator still doesn’t work for Windows, so the `test_package` in the default template will fail. Note this example is building with the MSVC compiler, not with MinGW/gcc. Even if the build system is autotools, the example is targeting the MSVC compiler, and the resulting package will be binary compatible and can be used from other packages using MSVC with other build systems. It is not necessary to force MinGW/gcc to use some open source dependencies that use autotools, and ConanCenter builds all of them with MSVC. In the [Create your first Conan package with Autotools](https://docs.conan.io/2//examples/tools/autotools/create_your_first_package.html.md#examples-tools-autotools-create-first-package) tutorial, the autotools integrations are presented. Please read first that section, to understand them, as this section will only introduce the Windows/msys2 specific issues. We will use the same the **conan new** command to create a “Hello World” C++ library example project: ```bash $ conan new autotools_lib -d name=mypkg -d version=0.1 ``` Check the above tutorial to understand the created files. Besides these files, we will create a profile file: ```ini include(default) [conf] tools.microsoft.bash:subsystem=msys2 tools.microsoft.bash:path=C:\ws\msys64\usr\bin\bash # since Conan 2.9, this "cl" compiler definition is not necessary # by default for the 'compiler=msvc' # tools.build:compiler_executables={"c": "cl", "cpp": "cl"} ``` Note that you might need to adapt the path to the `bash` system of `msys2`. In the package recipe *conanfile.py* we will have: ```python win_bash = True ``` This is very important, it tells Conan that when this package is to be built, it has to launch a `bash` shell to execute the build in it. #### NOTE It is not necessary, and in fact it is not recommended for most cases to be already running inside an `msys2` terminal. Conan will automatically run the build subprocess for autotools in the defined bash shell. If already running in a bash shell, it is necessary to activate the `tools.microsoft.bash:active=True` conf. Let’s build the package from sources with the current default configuration, making sure to deactivate the `test_package`, because otherwise it will fail. ```bash # Deactivating the test_package, as AutotoolsDeps doesn't work yet. $ conan create . -pr=msys2_profile -tf="" ... mypkg/0.1: package(): Packaged 1 '.h' file: mypkg.h mypkg/0.1: package(): Packaged 1 '.la' file: libmypkg.la mypkg/0.1: package(): Packaged 1 '.lib' file: mypkg.lib mypkg/0.1: Created package revision fa661758835cf6f7f311c857447393cc mypkg/0.1: Package '9bdee485ef71c14ac5f8a657202632bdb8b4482b' created ``` We can now validate that the recipe and the package binary are in the cache: ```bash $ conan list "mypkg:*" Found 1 pkg/version recipes matching mypkg in local cache Local Cache mypkg mypkg/0.1 revisions 6e85b0c27c7fbc8eddc1994dbb543b52 (2024-04-30 18:29:44 UTC) packages 9bdee485ef71c14ac5f8a657202632bdb8b4482b info settings arch: x86_64 build_type: Release compiler: msvc compiler.cppstd: 14 compiler.runtime: dynamic compiler.runtime_type: Release compiler.version: 193 os: Windows options shared: False ``` Note how the binary is a `compiler=msvc` one. #### SEE ALSO - [GNU built-in integrations reference](https://docs.conan.io/2//reference/tools/gnu.html.md#conan-tools-gnu). --- https://docs.conan.io/2/examples/tools/autotools/llvm_clang.html.md --- # AutoTools: Using LLVM/Clang Windows compiler The Clang compiler in Windows can come from 2 different installations or distributions: - The LLVM/Clang compiler, that uses the MSVC runtime - The Msys2 Clang compiler that uses the Msys2 runtime (libstdc++6.dll) This example explains the LLVM/Clang with the MSVC runtime. This Clang distribution can in turn be used in two different ways: - Using the LLVM/Clang downloaded compiler (it still uses the MSVC runtime), via the GNU-like frontend `clang` - Using the LLVM/Clang downloaded compiler (it still uses the MSVC runtime), via the MSVC-like frontend `clang-cl` Let’s start from a simple `autotools_exe` template: ```bash $ conan new autotools_exe -d name=mypkg -d version=0.1 ``` This creates a simple Autotools based project and Conan package recipe that uses `AutotoolsToolchain`. ## Autotools: LLVM/Clang with `clang` GNU-like frontend To build this configuration we will use the following profile: ```ini [settings] os=Windows arch=x86_64 build_type=Release compiler=clang compiler.version=18 compiler.cppstd=14 compiler.runtime=dynamic compiler.runtime_type=Release compiler.runtime_version=v144 [buildenv] PATH=+(path)C:\ws\LLVM\18.1\bin [conf] tools.compilation:verbosity=verbose tools.build:compiler_executables = {"c": "clang", "cpp": "clang++"} tools.microsoft.bash:subsystem=msys2 tools.microsoft.bash:path=C:\ws\msys64\usr\bin\bash.exe ``` Quick explanation of the profile: - The `compiler.runtime` definition is the important differentiator to distinguish between Msys2-Clang and LLVM/Clang with the MSVC runtime. The LLVM/Clang defines this `compiler.runtime`, while the Msys2-Clang doesn’t. - The MSVC runtime can be either dynamic or static. It is important also to define the runtime version (toolset version `v144`) of this runtime, as it is possible to use different ones. - The `[buildenv]` allows to point to the LLVM/Clang compiler, in case it is not already in the path. **Note** the `PATH=+(path)` syntax, to **prepend** that path, so it has higher priority - While defining `tools.microsoft.bash:path`, the full path to the `msys2` `bash.exe` has been used. Otherwise, it is possible that it can find another `bash.exe` in the Windows system that will not be valid. Let’s build it: ```bash $ conan build . -pr=llvm_clang ... conanfile.py (mypkg/0.1): Calling build() conanfile.py (mypkg/0.1): RUN: autoreconf --force --install conanfile.py (mypkg/0.1): RUN: "/c/projectpath/clang/configure" --prefix=/ --bindir=${prefix}/bin --sbindir=${prefix}/bin --libdir=${prefix}/lib --includedir=${prefix}/include --oldincludedir=${prefix}/include conanfile.py (mypkg/0.1): RUN: make -j8 ... clang++ -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -O3 -c -o main.o /c/projectpath/clang/src/main.cpp source='/c/projectpath/clang/src/mypkg.cpp' object='mypkg.o' libtool=no \ DEPDIR=.deps depmode=none /bin/sh /c/projectpath/clang/depcomp \ clang++ -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -O3 -c -o mypkg.o /c/projectpath/clang/src/mypkg.cpp clang++ -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -O3 -fuse-ld=lld-link -o mypkg.exe main.o mypkg.o ``` Note how the `clang++` compiler is used, the runtime is selected with `-D_DLL -D_MT -Xclang --dependent-lib=msvcrt`. We can run our executable, and see how the Clang compiler version and the MSVC runtime match the defined ones: ```bash $ build-release\src\mypkg.exe mypkg/0.1: Hello World Release! mypkg/0.1: _M_X64 defined mypkg/0.1: __x86_64__ defined mypkg/0.1: MSVC runtime: MultiThreadedDLL mypkg/0.1: _MSC_VER1943 mypkg/0.1: _MSVC_LANG201402 mypkg/0.1: __cplusplus201402 mypkg/0.1: __clang_major__18 mypkg/0.1: __clang_minor__1 ``` ## Autotools: LLVM/Clang with `clang-cl` MSVC-like frontend To build this configuration we will use the following profile: ```ini [settings] os=Windows arch=x86_64 build_type=Release compiler=clang compiler.version=18 compiler.cppstd=14 compiler.runtime=dynamic compiler.runtime_type=Release compiler.runtime_version=v144 [buildenv] PATH=+(path)C:/ws/LLVM/18.1/bin [conf] tools.compilation:verbosity=verbose tools.microsoft.bash:subsystem=msys2 tools.build:compiler_executables = {"c": "clang-cl", "cpp": "clang-cl"} tools.microsoft.bash:path=C:\ws\msys64\usr\bin\bash.exe ``` The profile is almost identical to the above one, the main difference is the definition of `tools.build:compiler_executables`, defining the `clang-cl` compiler. #### NOTE The definition of `tools.build:compiler_executables` using the `clang-cl` compiler is what is used by Conan to differentiate among the frontends, also in other build systems. This frontend is not a `setting`, because the compiler is still the same, and the resulting binary should be binary compatible. Let’s build it: ```bash $ conan build . -pr=llvm_clang_cl ... clang-cl -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std:c++14 -MD -O2 -c -o main.obj `cygpath -w '/c/projectpath/clang/src/main.cpp'` source='/c/projectpath/clang/src/mypkg.cpp' object='mypkg.obj' libtool=no \ DEPDIR=.deps depmode=msvc7msys /bin/sh /c/projectpath/clang/depcomp \ clang-cl -DPACKAGE_NAME=\"mypkg\" -DPACKAGE_TARNAME=\"mypkg\" -DPACKAGE_VERSION=\"0.1\" -DPACKAGE_STRING=\"mypkg\ 0.1\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DPACKAGE=\"mypkg\" -DVERSION=\"0.1\" -I. -I/c/projectpath/clang/src -DNDEBUG -std:c++14 -MD -O2 -c -o mypkg.obj `cygpath -w '/c/projectpath/clang/src/mypkg.cpp'` clang-cl -std:c++14 -MD -O2 -o mypkg.exe main.obj mypkg.obj ... ``` See how the desired `clang-cl` is used, and how the `MSVC-like` command line syntax is used, like `-std:c++14`. This MSVC-like syntax uses the `-MD/-MT` flags to differentiate across the dynamic/static MSVC runtimes. We can run our executable, and see how the Clang compiler version and the MSVC runtime match the defined ones: ```bash $ build\Release\mypkg.exe mypkg/0.1: Hello World Release! mypkg/0.1: _M_X64 defined mypkg/0.1: __x86_64__ defined mypkg/0.1: MSVC runtime: MultiThreadedDLL mypkg/0.1: _MSC_VER1943 mypkg/0.1: _MSVC_LANG201402 mypkg/0.1: __cplusplus201402 mypkg/0.1: __clang_major__18 mypkg/0.1: __clang_minor__1 ``` As expected, the output is identical to the previous one, as nothing changed except the compiler frontend. #### NOTE It might be possible to build using the `clang-cl` distributed as a Visual Studio component for autotools-like projects. But it is necessary to provide the full path to that Clang component within the Visual Studio installed folder, so it can be found, via `[buildenv]` and or `tools.build:compiler_executables`, because it is basically an LLVM/Clang compiler, packaged and distributed by the Visual Studio installer. --- https://docs.conan.io/2/examples/tools/cmake/cmake.html.md --- # CMake * [CMakeToolchain: Building your project using CMakePresets](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/build_project_cmake_presets.html.md) * [Generating the toolchain](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/build_project_cmake_presets.html.md#generating-the-toolchain) * [Building the project using `CMakePresets`](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/build_project_cmake_presets.html.md#building-the-project-using-cmakepresets) * [CMakeToolchain: Extending your CMakePresets with Conan generated ones](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/extend_own_cmake_presets.html.md) * [CMakeToolchain: Inject arbitrary CMake variables into dependencies](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/inject_cmake_variables.html.md) * [CMakeToolchain: Using xxx-config.cmake files inside packages](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/use_package_config_cmake.html.md) * [Important considerations](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/use_package_config_cmake.html.md#important-considerations) * [Using CMakeToolchain with different generators: Ninja example](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/use_different_toolchain_generator.html.md) * [Understanding CMake generators](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/use_different_toolchain_generator.html.md#understanding-cmake-generators) * [Using the Ninja generator by default in a profile](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/use_different_toolchain_generator.html.md#using-the-ninja-generator-by-default-in-a-profile) * [CMakeToolchain: Using LLVM/Clang Windows compiler](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/llvm_clang.html.md) * [LLVM/Clang with `clang` GNU-like frontend](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/llvm_clang.html.md#llvm-clang-with-clang-gnu-like-frontend) * [LLVM/Clang with `clang-cl` MSVC-like frontend](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/llvm_clang.html.md#llvm-clang-with-clang-cl-msvc-like-frontend) * [MSVC Clang component (ClangCL Visual Studio toolset)](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/llvm_clang.html.md#msvc-clang-component-clangcl-visual-studio-toolset) --- https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/build_project_cmake_presets.html.md --- # CMakeToolchain: Building your project using CMakePresets In this example we are going to see how to use `CMakeToolchain`, predefined layouts like `cmake_layout` and the `CMakePresets` CMake feature. Let’s create a basic project based on the template `cmake_exe` as an example of a C++ project: ```bash $ conan new cmake_exe -d name=foo -d version=1.0 ``` ## Generating the toolchain The recipe from our project declares the generator “CMakeToolchain”. We can call **conan install** to install both `Release` and `Debug` configurations. Conan will generate a `conan_toolchain.cmake` at the corresponding *generators* folder: ```bash $ conan install . $ conan install . -s build_type=Debug ``` ## Building the project using `CMakePresets` A `CMakeUserPresets.json` file is generated in the same folder of your `CMakeLists.txt` file, so you can use the `--preset` argument from `cmake >= 3.23` or use an IDE that supports it. The `CMakeUserPresets.json` is including the `CMakePresets.json` files located at the corresponding *generators* folder. The `CMakePresets.json` contain information about the `conan_toolchain.cmake` location and even the `binaryDir` set with the output directory. #### NOTE We use CMake presets in this example. This requires CMake >= 3.23 because the “include” from `CMakeUserPresets.json` to `CMakePresets.json` is only supported since that version. If you prefer not to use presets you can use something like: ```bash cmake -G -DCMAKE_TOOLCHAIN_FILE= -DCMAKE_BUILD_TYPE=Release ``` Conan will show the exact CMake command everytime you run `conan install` in case you can’t use the presets feature. If you are using a multi-configuration generator: ```bash $ cmake --preset conan-default $ cmake --build --preset conan-debug $ build\Debug\foo.exe foo/1.0: Hello World Debug! $ cmake --build --preset conan-release $ build\Release\foo.exe foo/1.0: Hello World Release! ``` If you are using a single-configuration generator: ```bash $ cmake --preset conan-debug $ cmake --build --preset conan-debug $ ./build/Debug/foo foo/1.0: Hello World Debug! $ cmake --preset conan-release $ cmake --build --preset conan-release $ ./build/Release/foo foo/1.0: Hello World Release! ``` Note that we didn’t need to create the `build/Release` or `build/Debug` folders, as we did [in the tutorial](https://docs.conan.io/2//tutorial/consuming_packages/the_flexibility_of_conanfile_py.html.md#consuming-packages-flexibility-of-conanfile-py-use-layout). The output directory is declared by the `cmake_layout()` and automatically managed by the CMake Presets feature. This behavior is also managed automatically by Conan (with CMake >= 3.15) when you build a package in the Conan cache (with **conan create** command). The CMake >= 3.23 is not required. Read More: - `cmake_layout()` [reference](https://docs.conan.io/2//reference/tools/cmake/cmake_layout.html.md#cmake-layout) - Conanfile [layout() method reference](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md#reference-conanfile-methods-layout) - Package layout tutorial [tutorial](https://docs.conan.io/2//tutorial/developing_packages/package_layout.html.md#developing-packages-layout) - Understanding [Conan package layouts](https://docs.conan.io/2//tutorial/developing_packages/package_layout.html.md#tutorial-package-layout) --- https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/extend_own_cmake_presets.html.md --- # CMakeToolchain: Extending your CMakePresets with Conan generated ones In this example we are going to see how to extend your own CMakePresets to include Conan generated ones. #### NOTE We use CMake presets in this example. This requires CMake >= 3.23 because the “include” from `CMakeUserPresets.json` to `CMakePresets.json` is only supported since that version. If you prefer not to use presets you can use something like: ```bash cmake -G -DCMAKE_TOOLCHAIN_FILE= -DCMAKE_BUILD_TYPE=Release ``` Conan will show the exact CMake command everytime you run `conan install` in case you can’t use the presets feature. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/cmake/cmake_toolchain/extend_own_cmake_presets ``` Please open the conanfile.py and check how it sets `tc.user_presets_path = 'ConanPresets.json'`. By modifying this attribute of CMakeToolchain, you can change the default filename of the generated preset. ```python def generate(self): tc = CMakeToolchain(self) tc.user_presets_path = 'ConanPresets.json' tc.generate() ... ``` Now you can provide your own `CMakePresets.json`, besides the `CMakeLists.txt`: ```json { "version": 4, "include": ["./ConanPresets.json"], "configurePresets": [ { "name": "default", "displayName": "multi config", "inherits": "conan-default" }, { "name": "release", "displayName": "release single config", "inherits": "conan-release" }, { "name": "debug", "displayName": "debug single config", "inherits": "conan-debug" } ], "buildPresets": [ { "name": "multi-release", "configurePreset": "default", "configuration": "Release", "inherits": "conan-release" }, { "name": "multi-debug", "configurePreset": "default", "configuration": "Debug", "inherits": "conan-debug" }, { "name": "release", "configurePreset": "release", "configuration": "Release", "inherits": "conan-release" }, { "name": "debug", "configurePreset": "debug", "configuration": "Debug", "inherits": "conan-debug" } ] } ``` Note how the `"include": ["./ConanPresets.json"],` and that every preset `inherits` a Conan generated one. We can now install for both Release and Debug (and other configurations also, with the help of `build_folder_vars` if we want): ```bash $ conan install . $ conan install . -s build_type=Debug ``` And build and run our application, by using **our own presets** that extend the Conan generated ones: ```bash # Linux (single-config, 2 configure, 2 builds) $ cmake --preset debug $ cmake --build --preset debug $ ./build/Debug/foo > Hello World Debug! $ cmake --preset release $ cmake --build --preset release $ ./build/Release/foo > Hello World Release! # Windows VS (Multi-config, 1 configure 2 builds) $ cmake --preset default $ cmake --build --preset multi-debug $ build\\Debug\\foo > Hello World Debug! $ cmake --build --preset multi-release $ build\\Release\\foo > Hello World Release! ``` --- https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/inject_cmake_variables.html.md --- # CMakeToolchain: Inject arbitrary CMake variables into dependencies You can find the sources to recreate this project in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/cmake/cmake_toolchain/user_toolchain_profile ``` In the general case, Conan package recipes provide the necessary abstractions via settings, confs, and options to control different aspects of the build. Many recipes define `options` to activate or deactivate features, optional dependencies, or binary characteristics. Configurations like `tools.build:cxxflags` can be used to inject arbitrary C++ compile flags. In some exceptional cases, it might be desired to inject CMake variables directly into dependencies doing CMake builds. This is possible when these dependencies use the `CMakeToolchain` integration. Let’s check it in this simple example. If we have the following package recipe, with a simple `conanfile.py` and a `CMakeLists.txt` printing a variable: ```python from conan import ConanFile from conan.tools.cmake import CMake class AppConan(ConanFile): name = "foo" version = "1.0" settings = "os", "compiler", "build_type", "arch" exports_sources = "CMakeLists.txt" generators = "CMakeToolchain" def build(self): cmake = CMake(self) cmake.configure() cmake.build() ``` ```cmake cmake_minimum_required(VERSION 3.15) project(foo LANGUAGES NONE) message(STATUS "MYVAR1 ${MY_USER_VAR1}!!") ``` We can define a profile file and a `myvars.cmake` file (both in the same folder) like the following: ```ini include(default) [conf] tools.cmake.cmaketoolchain:user_toolchain+={{profile_dir}}/myvars.cmake ``` Note the `{{profile_dir}}` is a jinja template expression that evaluates to the current profile folder, allowing to compute the necessary path to `myvars.cmake` file. The `tools.cmake.cmaketoolchain:user_toolchain` is a **list** of files to inject to the generated `conan_toolchain.cmake`, so the `+=` operator is used to append to it. The `myvars.cmake` can define as many variables as we want: ```cmake set(MY_USER_VAR1 "MYVALUE1") ``` Applying this profile, we can see that the package CMake build effectively uses the variable provided in the external `myvars.cmake` file: ```bash $ conan create . -pr=myprofile ... -- MY_USER_VAR1 MYVALUE1 ``` Note that using `user_toolchain` while defining values for confs like `tools.cmake.cmaketoolchain:system_name` is supported. Also, `user_toolchain` files can define variables for cross-building, such as `CMAKE_SYSTEM_NAME`, `CMAKE_SYSTEM_VERSION` and `CMAKE_SYSTEM_PROCESSOR`. If these variables are defined in the user toolchain file, they will be respected, and the `conan_toolchain.cmake` deduced ones will not overwrite the user defined ones. If those variables are not defined in the user toolchain file, then the Conan automatically deduced ones will be used. The `tools.cmake.cmaketoolchain:user_toolchain` conf value might also be passed in the command line `-c` argument, but the location of the `myvars.cmake` needs to be absolute to be found, as jinja replacement doesn’t happen in the command line. --- https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/llvm_clang.html.md --- # CMakeToolchain: Using LLVM/Clang Windows compiler The Clang compiler in Windows can come from 2 different installations or distributions: - The LLVM/Clang compiler, that uses the MSVC runtime - The Msys2 Clang compiler that uses the Msys2 runtime (libstdc++6.dll) This example explains the LLVM/Clang with the MSVC runtime. This Clang distribution can in turn be used in three different ways: - Using the Clang component installed by Visual Studio installer as part of VS - Using the LLVM/Clang downloaded compiler (it still uses the MSVC runtime), via the GNU-like frontend `clang` - Using the LLVM/Clang downloaded compiler (it still uses the MSVC runtime), via the MSVC-like frontend `clang-cl` Let’s start from a simple `cmake_exe` template: ```bash $ conan new cmake_exe -d name=mypkg -d version=0.1 ``` This creates a simple CMake based project and Conan package recipe that uses `CMakeToolchain`. ## LLVM/Clang with `clang` GNU-like frontend To build this configuration we will use the following profile: ```ini [settings] os=Windows arch=x86_64 build_type=Release compiler=clang compiler.version=18 compiler.cppstd=14 compiler.runtime=dynamic compiler.runtime_type=Release compiler.runtime_version=v144 [buildenv] PATH=+(path)C:/ws/LLVM/18.1/bin [conf] tools.cmake.cmaketoolchain:generator=Ninja tools.compilation:verbosity=verbose [tool_requires] ninja/[*] ``` Quick explanation of the profile: - The `compiler.runtime` definition is the important differentiator to distinguish between Msys2-Clang and LLVM/Clang with the MSVC runtime. The LLVM/Clang defines this `compiler.runtime`, while the Msys2-Clang doesn’t. - The MSVC runtime can be either dynamic or static. It is important also to define the runtime version (toolset version `v144`) of this runtime, as it is possible to use different ones. - The `[buildenv]` allows to point to the LLVM/Clang compiler, in case it is not already in the path. **Note** the `PATH=+(path)` syntax, to **prepend** that path, so it has higher priority, otherwise it is possible that CMake would find and use the Clang component installed inside Visual Studio. - We are using the `Ninja` CMake generator, and installing it from a `[tool_requires]`, but this might not be necessary if Ninja is installed in your system. Let’s build it: ```bash $ conan build . -pr=llvm_clang ... -- The CXX compiler identification is Clang 18.1.8 with GNU-like command-line -- Check for working CXX compiler: C:/ws/LLVM/18.1/bin/clang++.exe - skipped ... [1/3] C:\ws\LLVM\18.1\bin\clang++.exe -O3 -DNDEBUG -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -MD -MT CMakeFiles/mypkg.dir/src/main.cpp.obj -MF CMakeFiles\mypkg.dir\src\main.cpp.obj.d -o CMakeFiles/mypkg.dir/src/main.cpp.obj -c C:/Users/Diego/conanws/kk/clang/src/main.cpp [2/3] C:\ws\LLVM\18.1\bin\clang++.exe -O3 -DNDEBUG -std=c++14 -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -MD -MT CMakeFiles/mypkg.dir/src/mypkg.cpp.obj -MF CMakeFiles\mypkg.dir\src\mypkg.cpp.obj.d -o CMakeFiles/mypkg.dir/src/mypkg.cpp.obj -c C:/Users/Diego/conanws/kk/clang/src/mypkg.cpp [3/3] cmd.exe /C "cd . && C:\ws\LLVM\18.1\bin\clang++.exe -fuse-ld=lld-link -nostartfiles -nostdlib -O3 -DNDEBUG -D_DLL -D_MT -Xclang --dependent-lib=msvcrt -Xlinker /subsystem:console CMakeFiles/mypkg.dir/src/mypkg.cpp.obj CMakeFiles/mypkg.dir/src/main.cpp.obj -o mypkg.exe -Xlinker /MANIFEST:EMBED -Xlinker /implib:mypkg.lib -Xlinker /pdb:mypkg.pdb -Xlinker /version:0.0 -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames && cd ." ``` See how the desired LLVM/Clang compiler installed in the `C:/ws` folder is used, and how the `GNU-like` command line syntax is used. The GNU-like syntax requires the `--dependent-lib=msvcrt` (added automatically by CMake) compiler and linker flags to define linking against the dynamic MSVC runtime, as otherwise LLVM/Clang link it statically. Also note that the `-MD -MT` flags are not related to the C:\project\build\Release\mypkg.exe ``` The `CMAKE_GENERATOR_TOOLSET=ClangCL` is defined, and also the internal VS Clang component is used, and the `19.1.1` version is also displayed. Then, the regular `MSVC-like` syntax, including the definition of the runtime via `/MD` flags is used. We can run our executable, and see how the Clang compiler version (`19`) and the MSVC runtime match the defined ones: ```bash $ build\Release\mypkg.exe mypkg/0.1: Hello World Release! mypkg/0.1: _M_X64 defined mypkg/0.1: __x86_64__ defined mypkg/0.1: MSVC runtime: MultiThreadedDLL mypkg/0.1: _MSC_VER1943 mypkg/0.1: _MSVC_LANG201402 mypkg/0.1: __cplusplus201402 mypkg/0.1: __clang_major__19 mypkg/0.1: __clang_minor__1 ``` --- https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/use_different_toolchain_generator.html.md --- # Using CMakeToolchain with different generators: Ninja example This guide demonstrates how to use [CMakeToolchain](https://docs.conan.io/2//reference/tools/cmake/cmaketoolchain.html.md#conan-tools-cmaketoolchain) with predefined generators like [Ninja](https://ninja-build.org/) and how to configure it to use different generators. #### NOTE We assume you have already installed Ninja in your system. In case you do not have Ninja installed in your system, you can use the [Ninja Conan package](https://conan.io/center/recipes/ninja) in your profile (default or custom) by adding [tool-requires](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-tool-requires). ## Understanding CMake generators The [CMake](https://cmake.org/) client offers a variety of [generators](https://cmake.org/cmake/help/latest/manual/cmake-generators.7.html) to create build system files. If you want to use a generator other than the default chosen by CMake, you can configure `tools.cmake.cmaketoolchain:generator`. #### NOTE Please, note that [CMake](https://cmake.org/) client is not the same as the Conan [CMake](https://docs.conan.io/2//reference/tools/cmake/cmake.html.md#conan-tools-cmake-helper) helper. To see which generators are available on your system, run: ```bash $ cmake --help ``` You can set this [configuration in your profile](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-conf), directly in the command line, or even in your [global configuration](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf-patterns). ## Using the Ninja generator by default in a profile First, let’s create a profile file name `my_custom_profile`, so we can set the Ninja generator as the default for all Conan packages built with this profile. ```bash $ conan profile detect --name=my_custom_profile ``` To set the Ninja generator as the default in `my_custom_profile` profile, add the entry `[conf]` with the generator value in the file: ```text [settings] os=Linux arch=x86_64 compiler=gcc compiler.version=13 compiler.libcxx=libstdc++11 compiler.cppstd=20 build_type=Release [conf] tools.cmake.cmaketoolchain:generator=Ninja ``` Now, we will create a basic project based on the `cmake_exe` template as an example of a C++ project: ```bash $ conan new cmake_exe -d name=foo -d version=0.1.0 ``` Then, we can build your project using the profile we just created: ```bash $ conan create . -pr=my_custom_profile ``` This configuration will be passed to the `conan_toolchain.cmake` file, generated by `CMakeToolchain`, then the Ninja generator will be used. You should see the following output snippet indicating the Ninja generator is being used: ```bash Profile host: [settings] ... [conf] tools.cmake.cmaketoolchain:generator=Ninja ... foo/0.1.0: Calling build() foo/0.1.0: Running CMake.configure() foo/0.1.0: RUN: cmake -G "Ninja" ... ``` Note that same configuration can be passed to the default profile, and used for all Conan packages built with that profile. In case passing the generator configuration by command line, the same will override the profile configuration. --- https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/use_package_config_cmake.html.md --- # CMakeToolchain: Using xxx-config.cmake files inside packages Conan relies in the general case in the `package_info()` abstraction to allow packages built with any build system to be usable from any other package built with any other build system. In the CMake case, Conan relies on the `CMakeDeps` generator to generate `xxxx-config.cmake` files for every dependency, even if those dependencies didn’t generate one or aren’t built with CMake at all. ConanCenter users this abstraction, not packaging the `xxx-config.cmake` files, and using the information in `package_info()`. This is very important to provide as build-system agnostic as possible packages and be fair with different build systems, vendors and users. For example, there are many Conan users happily using native MSBuild (VS) projects without any CMake at all. If ConanCenter packages were only built using the in-package `config.cmake` files, this wouldn’t be possible. But the fact that ConanCenter does that, doesn’t mean that this is not possible or mandatory. It is perfectly possible to use the in-packages `xxx-config.cmake` files, dropping the usage of `CMakeDeps` generator. You can find the sources to recreate this example in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/cmake/pkg_config_files ``` If we have a look to the `conanfile.py`: ```python class pkgRecipe(ConanFile): name = "pkg" version = "0.1" ... def package_info(self): # No information provided, only the in-package .cmake is used here # Other build systems or CMake via CMakeDeps will fail self.cpp_info.builddirs = ["pkg/cmake"] self.cpp_info.set_property("cmake_find_mode", "none") ``` This is a very typical recipe, the main difference is the `package_info()` method. Three important things to notice: - It doesn’t define fields like `self.cpp_info.libs = ["mypkg"]`. Conan will not be propagating this information to the consumer, the only place this information will be is inside the in-package `xxx-config.cmake` file - Just in case there are some users still instantiating `CMakeDeps`, it is disabling the client side generation of the `xxx-config.cmake` file with `set_property("cmake_find_mode", "none")` - It is defining that it will contain the build scripts (like the `xxx-config.cmake` package) inside that folder, to be located by consumers. #### NOTE If the in-package `xxx-config.cmake` file has a different name than the Conan package name, set the `cmake_file_name` property with the right value, so that `find_package()` can locate it: ```python self.cpp_info.set_property("cmake_file_name", "MyPkg") ``` So the responsibility of defining the package details has been transferred to the `CMakeLists.txt` that contains: ```cmake add_library(mylib src/pkg.cpp) # Use a different name than the package, to make sure set_target_properties(mylib PROPERTIES PUBLIC_HEADER "include/pkg.h") target_include_directories(mylib PUBLIC $ $ ) # Use non default mypkgConfig name install(TARGETS mylib EXPORT mypkgConfig) export(TARGETS mylib NAMESPACE mypkg:: # to simulate a different name and see it works FILE "${CMAKE_CURRENT_BINARY_DIR}/mypkgConfig.cmake" ) install(EXPORT mypkgConfig DESTINATION "${CMAKE_INSTALL_PREFIX}/pkg/cmake" NAMESPACE mypkg:: ) ``` With that information, when `conan create` is executed: - The `build()` method will build the package - The `package()` method will call `cmake install`, which will create the `mypkgConfig.cmake` file - It will be created in the package folder `pkg/cmake/mypkgConfig.cmake` file - It will contain enough information for the headers, and it will create a `mypkg::mylib` target. Note that the details of the config filename, the namespace and the target are also not known by Conan, so this is also something that the consumer build scripts should know. This is enough to have a package with an internal `mypkgConfig.cmake` file that can be used by consumers. In this example code, the consumer is just the `test_package/conanfile.py`, but exactly the same wouldn apply to any arbitrary consumer. The consumer `conanfile.py` doesn’t need to use `CMakeDeps` at all, only `generators = "CMakeToolchain"`. Note that the `CMakeToolchain` generator is still necessary, because the `mypkgConfig.cmake` needs to be found inside the Conan cache. The `CMakeToolchain` generated `conan_toolchain.cmake` file contains these paths defined. The consumer `CMakeLists.txt` would be standard: ```cmake find_package(mypkg CONFIG REQUIRED) add_executable(example src/example.cpp) target_link_libraries(example mypkg::mylib) ``` You can verify it works with: ```bash $ conan create . ======== Testing the package: Executing test ======== pkg/0.1 (test package): Running test() pkg/0.1 (test package): RUN: Release\example pkg/0.1: Hello World Release! pkg/0.1: _M_X64 defined pkg/0.1: MSVC runtime: MultiThreadedDLL pkg/0.1: _MSC_VER1939 pkg/0.1: _MSVC_LANG201402 pkg/0.1: __cplusplus199711 pkg/0.1 test_package ``` ## Important considerations The presented approach has one limitation, it doesn’t work for multi-configuration IDEs. Implementing this approach won’t allow developers to directly switch from IDEs like Visual Studio from Release to Debug and vice versa, and it will require a `conan install` to change. It is not an issue at all for single-config setups, but for VS developers it can be a bit inconvenient. The team is working on the VS plugin that might help to mitigate this. The reason is a CMake limitation, `find_package()` can only find one configuration, and with `CMakeDeps` being dropped here, there is nothing that Conan can do to avoid this limitation. It is important to know that it is also the package author and the package `CMakeLists.txt` responsibility to correctly manage transitivity to other dependencies, and this is not trivial in some cases. There are risks that if not done correctly the in-package `xxx-config.cmake` file can locate its transitive dependencies elsewhere, like in the system, but not in the transitive Conan package dependencies. Finally, recall that these packages won’t be usable by other build systems rather than CMake. --- https://docs.conan.io/2/examples/tools/files/files.html.md --- # File interaction * [Patching sources](https://docs.conan.io/2//examples/tools/files/patches/patch_sources.html.md) --- https://docs.conan.io/2/examples/tools/files/patches/patch_sources.html.md --- # Patching sources In this example we are going to see how to patch the source code. This is necessary sometimes, specially when you are creating a package for a third party library. A patch might be required in the build system scripts or even in the source code of the library if you want, for example, to apply a security patch. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples/tools/files/patches ``` ## Patching using ‘replace_in_file’ The simplest way to patch a file is using the `replace_in_file` tool in your recipe. It searches in a file the specified string and replaces it with another string. ### in source() method The source() method is called only once for all the configurations (different calls to **conan create** for different settings/options) so you should patch only in the `source()` method if the changes are common for all the configurations. Look at the `source()` method at the `conanfile.py`: ```python import os from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout from conan.tools.files import get, replace_in_file class helloRecipe(ConanFile): name = "hello" version = "1.0" # Binary configuration settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} def source(self): get(self, "https://github.com/conan-io/libhello/archive/refs/heads/main.zip", strip_root=True) replace_in_file(self, os.path.join(self.source_folder, "src", "hello.cpp"), "Hello World", "Hello Friends!") ... ``` We are replacing the `"Hello World"` string with “Hello Friends!”. We can run `conan create .` and verify that if the replace was done: ```bash $ conan create . ... -------- Testing the package: Running test() -------- hello/1.0: Hello Friends! Release! ... ``` Regular expressions and backreferences are also supported by enabling `regex`. For example, the following call captures the numeric part of `version=123` with `(\d+)` and reuses it in the replacement with `\1`, producing `version=v123`: ```python replace_in_file(self, "file.txt", r"version=(\d+)", r"version=v\1", regex=True) ``` ### in build() method In this case, we need to apply a different patch depending on the configuration (self.settings, self.options…), so it has to be done in the `build()` method. Let’s modify the recipe to introduce a change that depends on the `self.options.shared`: ```python class helloRecipe(ConanFile): ... def source(self): get(self, "https://github.com/conan-io/libhello/archive/refs/heads/main.zip", strip_root=True) def build(self): replace_in_file(self, os.path.join(self.source_folder, "src", "hello.cpp"), "Hello World", "Hello {} Friends!".format("Shared" if self.options.shared else "Static")) cmake = CMake(self) cmake.configure() cmake.build() ... ``` If we call `conan create` with different `option.shared` we can check the output: ```bash $ conan create . ... hello/1.0: Hello Static Friends! Release! ... $ conan create . -o shared=True ... hello/1.0: Hello Shared Friends! Debug! ... ``` ## Patching using “patch” tool If you have a patch file (diff between two versions of a file), you can use the `conan.tools.files.patch` tool to apply it. The rules about where to apply the patch (`source()` or `build()` methods) are the same. We have this patch file, where we are changing again the message to say “Hello Patched World Release!”: ```text --- a/src/hello.cpp +++ b/src/hello.cpp @@ -3,9 +3,9 @@ void hello(){ #ifdef NDEBUG - std::cout << "hello/1.0: Hello World Release!\n"; + std::cout << "hello/1.0: Hello Patched World Release!\n"; #else - std::cout << "hello/1.0: Hello World Debug!\n"; + std::cout << "hello/1.0: Hello Patched World Debug!\n"; #endif // ARCHITECTURES ``` Edit the `conanfile.py` to: 1. Import the `patch` tool. 2. Add `exports_sources` to the patch file so we have it available in the cache. 3. Call the `patch` tool. ```python import os from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout from conan.tools.files import get, replace_in_file, patch class helloRecipe(ConanFile): name = "hello" version = "1.0" # Binary configuration settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} exports_sources = "*.patch" def source(self): get(self, "https://github.com/conan-io/libhello/archive/refs/heads/main.zip", strip_root=True) patch_file = os.path.join(self.export_sources_folder, "hello_patched.patch") patch(self, patch_file=patch_file) ... ``` We can run “conan create” and see that the patch worked: ```bash $ conan create . ... -------- Testing the package: Running test() -------- hello/1.0: Hello Patched World Release! ... ``` We can also use the `conandata.yml` [introduced in the tutorial](https://docs.conan.io/2//tutorial/creating_packages/handle_sources_in_packages.html.md#creating-packages-handle-sources-in-packages-conandata) so we can declare the patches to apply for each version: ```yaml patches: "1.0": - patch_file: "hello_patched.patch" ``` And there are the changes we introduce in the `source()` method: ```python .. code-block:: python def source(self): get(self, "https://github.com/conan-io/libhello/archive/refs/heads/main.zip", strip_root=True) patches = self.conan_data["patches"][self.version] for p in patches: patch_file = os.path.join(self.export_sources_folder, p["patch_file"]) patch(self, patch_file=patch_file) ``` Check [patch](https://docs.conan.io/2//reference/tools/files/patches.html.md#conan-tools-files-patch) for more details. If we run the **conan create**, the patch is also applied: ```bash $ conan create . ... -------- Testing the package: Running test() -------- hello/1.0: Hello Patched World Release! ... ``` ## Patching using “apply_conandata_patches” tool The example above works but it is a bit complex. If you follow the same yml structure (check the [apply_conandata_patches](https://docs.conan.io/2//reference/tools/files/patches.html.md#conan-tools-files-apply-conandata-patches) to see the full supported yml) you only need to call `apply_conandata_patches`: ```python from conan import ConanFile from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout from conan.tools.files import get, apply_conandata_patches class helloRecipe(ConanFile): name = "hello" version = "1.0" ... def source(self): get(self, "https://github.com/conan-io/libhello/archive/refs/heads/main.zip", strip_root=True) apply_conandata_patches(self) ``` Let’s check if the patch is also applied: ```bash $ conan create . ... -------- Testing the package: Running test() -------- hello/1.0: Hello Patched World Release! ... ``` --- https://docs.conan.io/2/examples/tools/gnu/gnu.html.md --- # GNU * [Using PkgConfig.fill_cpp_info with PKG_CONFIG_PATH from a profile](https://docs.conan.io/2//examples/tools/gnu/pkg_config_sysroot.html.md) --- https://docs.conan.io/2/examples/tools/gnu/pkg_config_sysroot.html.md --- # Using PkgConfig.fill_cpp_info with PKG_CONFIG_PATH from a profile The [PkgConfig](https://docs.conan.io/2//reference/tools/gnu/pkgconfig.html.md#conan-tools-gnu-pkgconfig) helper can read a `.pc` file and use its contents to fill a `cpp_info` object with `fill_cpp_info()`. When `pkg_config_path` is not passed explicitly, `pkg-config` locates the `.pc` file via the `PKG_CONFIG_PATH` environment variable, which can be defined in the profile `[buildenv]` section. A common scenario is cross-compilation with an external toolchain: the toolchain provides a sysroot that already ships `.pc` files describing its libraries (`gl.pc`, `EGL.pc`, `zlib.pc`, …), and the host profile points `PKG_CONFIG_PATH` at the sysroot’s `pkgconfig` folder. A wrapper recipe can then read those `.pc` files at `package()` time and expose the information to consumers without hard-coding include and library paths. The challenge comes when users try to define `PKG_CONFIG_PATH` in the `[buildenv]` section of a profile, because that is not available in the `package_info()` method of the recipes, as the package information cannot rely on the “build environment”, as the build environment is only available when the package is being built, but not necessarily when the package is being consumed. The example below uses a fabricated `mylibastral.pc` next to the profile to keep it self-contained, but the mechanism is exactly the same as pointing to a real sysroot folder, to illustrate how this could be implemented if necessary. #### IMPORTANT This strategy is valid only for “system” packages, that is, recipes that act as a wrapper around a system or sysroot dependency (typical in cross-compilation with an external toolchain). Regular Conan packages that build and package their own artifacts should not use this. The **profile** below adds a folder containing `.pc` files to `PKG_CONFIG_PATH`. The `profile_dir` Jinja variable resolves to the folder that contains the profile itself, so a `mypcs/` folder next to the profile can be used directly: ```ini [settings] os=Linux arch=armv8 [buildenv] PKG_CONFIG_PATH+=(path){{ profile_dir }}/mypcs ``` In a real cross-compilation setup, that path would typically point to the sysroot folder shipped by the toolchain, for example `{{ sysroot }}/usr/lib/pkgconfig`. The `.pc` file located in the `mypcs` folder besides the profile describes the library (include folders, library folders, libs, defines, link flags, …): ```text prefix=/usr/local exec_prefix=${prefix} libdir=${exec_prefix}/lib includedir=${prefix}/include Name: mylibastral Description: Interface library for Astral data flows Version: 6.6.6 Libs: -L${libdir}/libastral -lastral -lm -Wl,--whole-archive Cflags: -I${includedir}/libastral -D_USE_LIBASTRAL ``` The `conanfile.py` recipe uses `PkgConfig` to read `mylibastral.pc` and populate a `CppInfo` object. It does it at `package()` time, when the package is being built (the policies are added so the package is automatically build when necessary in the current machine, and binaries are never uploaded, as the information from that .pc file will only be valid in the current machine). Notice that `pkg_config_path` is not passed: it is picked up from `PKG_CONFIG_PATH` defined in the profile. The resulting `CppInfo` is serialized to the package folder in `package()`, and reloaded in `package_info()`: ```python import os from conan import ConanFile from conan.tools.gnu import PkgConfig from conan.tools import CppInfo class Pkg(ConanFile): name = "mypkg" version = "0.1" build_policy = "missing" upload_policy = "skip" def package(self): # This method executes at package build time, it has # available the build environment "buildenv" pkg_config = PkgConfig(self, "mylibastral") cpp_info = CppInfo(self) pkg_config.fill_cpp_info(cpp_info, is_system=False, system_libs=["m"]) cpp_info.save(os.path.join(self.package_folder, "cpp_info.json")) def package_info(self): # This method executes at package consumption time, it will # NOT have available the build environment, but it can load a file # generated at build/package time self.cpp_info = CppInfo(self).load("cpp_info.json") ``` Let’s now create and consume the package: ```bash $ conan create . -pr=myprofile $ conan install --requires=mypkg/0.1 -pr=myprofile -g CMakeDeps ``` The generated `mypkg-none-armv8-data.cmake` will contain the include/lib folders, libs, defines and link flags read from `mylibastral.pc`, something like: ```cmake set(mypkg_INCLUDE_DIRS_NONE "/usr/local/include/libastral") set(mypkg_LIB_DIRS_NONE "/usr/local/lib/libastral") set(mypkg_LIBS_NONE astral) set(mypkg_SYSTEM_LIBS_NONE m) set(mypkg_DEFINITIONS_NONE "-D_USE_LIBASTRAL") set(mypkg_COMPILE_DEFINITIONS_NONE "_USE_LIBASTRAL") set(mypkg_SHARED_LINK_FLAGS_NONE "-Wl,--whole-archive") ``` --- https://docs.conan.io/2/examples/tools/google/bazel.html.md --- # Bazel * [Build a simple Bazel project using Conan](https://docs.conan.io/2//examples/tools/google/bazeltoolchain/build_simple_bazel_project.html.md) * [Build a simple Bazel 7.x project using Conan](https://docs.conan.io/2//examples/tools/google/bazeltoolchain/build_simple_bazel_7x_project.html.md) --- https://docs.conan.io/2/examples/tools/google/bazeltoolchain/build_simple_bazel_7x_project.html.md --- # Build a simple Bazel 7.x project using Conan #### WARNING This example is Bazel >= 7.2 compatible. In this example, we are going to create a Hello World program that uses one of the most popular C++ libraries: [fmt](https://fmt.dev/latest). #### NOTE This example is based on the [Build a simple CMake project using Conan](https://docs.conan.io/2//tutorial/consuming_packages/build_simple_cmake_project.html.md#consuming-packages-build-simple-cmake-project) tutorial. So we highly recommend reading it before trying out this one. We’ll use Bazel as the build system and helper tool in this case, so you should get it installed before going forward with this example. See [how to install Bazel](https://bazel.build/install). Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/google/bazeltoolchain/7_x/string_formatter ``` We start from a very simple C++ language project with this structure: ```text . ├── MODULE.bazel ├── conanfile.txt └── main ├── BUILD └── demo.cpp ``` This project contains a *MODULE.bazel* file loading the Conan dependencies (in this case only `fmt`) and a *main/BUILD* file which defines the *demo* bazel target and it’s in charge of using `fmt` to build a simple Hello World program. Let’s have a look at each file’s content: ```cpp #include #include int main() { fmt::print("{} - The C++ Package Manager!\n", "Conan"); return EXIT_SUCCESS; } ``` ```python include("//conan:conan_deps.MODULE.bazel") ``` ```python load("@rules_cc//cc:cc_binary.bzl", "cc_binary") cc_binary( name = "demo", srcs = ["demo.cpp"], deps = [ "@fmt//:fmt" ], ) ``` ```ini [requires] fmt/10.1.1 [generators] BazelDeps BazelToolchain [layout] bazel_layout ``` Conan uses the [BazelToolchain](https://docs.conan.io/2//reference/tools/google/bazeltoolchain.html.md#conan-tools-google-bazeltoolchain) to generate a `conan_bzl.rc` file which defines the `conan-config` bazel-build configuration. This file and the configuration are passed as parameters to the `bazel build` command. Apart from that, Conan uses the [BazelDeps](https://docs.conan.io/2//reference/tools/google/bazeldeps.html.md#conan-tools-google-bazeldeps) generator to create all the bazel files ( *[DEP]/BUILD.bazel*, *[DEP]/BUILD.rules_cc.bazel*, *conan_deps.MODULE.bazel*, *conan_deps_module_extension.bzl*, and *conan_deps_repo_rules.bzl*) which define the rule and all the dependencies to create/load them as Bazel repositories. The *MODULE.bazel* above includes the generated *conan_deps.MODULE.bazel* snippet, which will tell the *main/BUILD* all the information about the `@fmt//:fmt` bazel target. As the first step, we should install all the dependencies listed in the `conanfile.txt`. The command [conan install](https://docs.conan.io/2//reference/commands/install.html.md#reference-commands-install) does not only install the `fmt` package, it also builds it from sources in case your profile does not match with a pre-built binary in your remotes. Furthermore, it will save all the files created by the generators listed in the `conanfile.txt` in a folder named *conan/* (default folder defined by the `bazel_layout`). ```bash $ conan install . --build=missing # ... ======== Finalizing install (deploy, generators) ======== conanfile.txt: Writing generators to /Users/user/develop/examples2/examples/tools/google/bazeltoolchain/7_x/string_formatter/conan conanfile.txt: Generator 'BazelDeps' calling 'generate()' conanfile.txt: Generator 'BazelToolchain' calling 'generate()' conanfile.txt: Generating aggregated env files conanfile.txt: Generated aggregated env files: ['conanbuild.sh', 'conanrun.sh'] Install finished successfully ``` Now we are ready to build and run our application: ```bash $ bazel --bazelrc=./conan/conan_bzl.rc build --config=conan-config //main:demo Computing main repo mapping: Loading: Loading: 0 packages loaded Analyzing: target //main:demo (1 packages loaded, 0 targets configured) Analyzing: target //main:demo (1 packages loaded, 0 targets configured) [0 / 1] [Prepa] BazelWorkspaceStatusAction stable-status.txt INFO: Analyzed target //main:demo (69 packages loaded, 369 targets configured). [5 / 7] Compiling main/demo.cpp; 0s darwin-sandbox INFO: Found 1 target... Target //main:demo up-to-date: bazel-bin/main/demo INFO: Elapsed time: 2.955s, Critical Path: 1.70s INFO: 7 processes: 5 internal, 2 darwin-sandbox. INFO: Build completed successfully, 7 total actions ``` ```bash $ ./bazel-bin/main/demo Conan - The C++ Package Manager! ``` --- https://docs.conan.io/2/examples/tools/google/bazeltoolchain/build_simple_bazel_project.html.md --- # Build a simple Bazel project using Conan #### WARNING This example is Bazel 6.x compatible. In this example, we are going to create a Hello World program that uses one of the most popular C++ libraries: [fmt](https://fmt.dev/latest). #### NOTE This example is based on the main [Build a simple CMake project using Conan](https://docs.conan.io/2//tutorial/consuming_packages/build_simple_cmake_project.html.md#consuming-packages-build-simple-cmake-project) tutorial. So we highly recommend reading it before trying out this one. We’ll use Bazel as the build system and helper tool in this case, so you should get it installed before going forward with this example. See [how to install Bazel](https://bazel.build/install). Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/google/bazeltoolchain/6_x/string_formatter ``` We start from a very simple C++ language project with this structure: ```text . ├── WORKSPACE ├── conanfile.txt └── main ├── BUILD └── demo.cpp ``` This project contains a *WORKSPACE* file loading the Conan dependencies (in this case only `fmt`) and a *main/BUILD* file which defines the *demo* bazel target and it’s in charge of using `fmt` to build a simple Hello World program. Let’s have a look at each file’s content: ```cpp #include #include int main() { fmt::print("{} - The C++ Package Manager!\n", "Conan"); return EXIT_SUCCESS; } ``` ```python load("@//conan:dependencies.bzl", "load_conan_dependencies") load_conan_dependencies() ``` ```python cc_binary( name = "demo", srcs = ["demo.cpp"], deps = [ "@fmt//:fmt" ], ) ``` ```ini [requires] fmt/10.1.1 [generators] BazelDeps BazelToolchain [layout] bazel_layout ``` Conan uses the [BazelToolchain](https://docs.conan.io/2//reference/tools/google/bazeltoolchain.html.md#conan-tools-google-bazeltoolchain) to generate a `conan_bzl.rc` file which defines the `conan-config` bazel-build configuration. This file and the configuration are passed as parameters to the `bazel build` command. Apart from that, Conan uses the [BazelDeps](https://docs.conan.io/2//reference/tools/google/bazeldeps.html.md#conan-tools-google-bazeldeps) generator to create all the bazel files ( *[DEP]/BUILD.bazel* and *dependencies.bzl*) which define all the dependencies as public bazel targets. The *WORKSPACE* above is already ready to load the *dependencies.bzl* which will tell the *main/BUILD* all the information about the `@fmt//:fmt` bazel target. As the first step, we should install all the dependencies listed in the `conanfile.txt`. The command [conan install](https://docs.conan.io/2//reference/commands/install.html.md#reference-commands-install) does not only install the `fmt` package, it also builds it from sources in case your profile does not match with a pre-built binary in your remotes. Furthermore, it will save all the files created by the generators listed in the `conanfile.txt` in a folder named *conan/* (default folder defined by the `bazel_layout`). ```bash $ conan install . --build=missing # ... ======== Finalizing install (deploy, generators) ======== conanfile.txt: Writing generators to /Users/user/develop/examples2/examples/tools/google/bazeltoolchain/6_x/string_formatter/conan conanfile.txt: Generator 'BazelDeps' calling 'generate()' conanfile.txt: Generator 'BazelToolchain' calling 'generate()' conanfile.txt: Generating aggregated env files conanfile.txt: Generated aggregated env files: ['conanbuild.sh', 'conanrun.sh'] Install finished successfully ``` Now we are ready to build and run our application: ```bash $ bazel --bazelrc=./conan/conan_bzl.rc build --config=conan-config //main:demo Starting local Bazel server and connecting to it... INFO: Analyzed target //main:demo (38 packages loaded, 272 targets configured). INFO: Found 1 target... INFO: From Linking main/demo: ld: warning: ignoring duplicate libraries: '-lc++' Target //main:demo up-to-date: bazel-bin/main/demo INFO: Elapsed time: 60.180s, Critical Path: 7.68s INFO: 6 processes: 4 internal, 2 darwin-sandbox. INFO: Build completed successfully, 6 total actions ``` ```bash $ ./bazel-bin/main/demo Conan - The C++ Package Manager! ``` --- https://docs.conan.io/2/examples/tools/meson/build_simple_meson_project.html.md --- # Build a simple Meson project using Conan In this example, we are going to create a string compressor application that uses one of the most popular C++ libraries: [Zlib](https://zlib.net/). #### NOTE This example is based on the main [Build a simple CMake project using Conan](https://docs.conan.io/2//tutorial/consuming_packages/build_simple_cmake_project.html.md#consuming-packages-build-simple-cmake-project) tutorial. So we highly recommend reading it before trying out this one. We’ll use Meson as build system and pkg-config as helper tool in this case, so you should get them installed before going forward with this example. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) in GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/meson/mesontoolchain/simple_meson_project ``` We start from a very simple C language project with this structure: ```text . ├── meson.build └── src └── main.c ``` This project contains a basic *meson.build* including the **zlib** dependency and the source code for the string compressor program in *main.c*. Let’s have a look at the *main.c* file: ```cpp #include #include #include #include int main(void) { char buffer_in [256] = {"Conan is a MIT-licensed, Open Source package manager for C and C++ development " "for C and C++ development, allowing development teams to easily and efficiently " "manage their packages and dependencies across platforms and build systems."}; char buffer_out [256] = {0}; z_stream defstream; defstream.zalloc = Z_NULL; defstream.zfree = Z_NULL; defstream.opaque = Z_NULL; defstream.avail_in = (uInt) strlen(buffer_in); defstream.next_in = (Bytef *) buffer_in; defstream.avail_out = (uInt) sizeof(buffer_out); defstream.next_out = (Bytef *) buffer_out; deflateInit(&defstream, Z_BEST_COMPRESSION); deflate(&defstream, Z_FINISH); deflateEnd(&defstream); printf("Uncompressed size is: %lu\n", strlen(buffer_in)); printf("Compressed size is: %lu\n", strlen(buffer_out)); printf("ZLIB VERSION: %s\n", zlibVersion()); return EXIT_SUCCESS; } ``` Also, the contents of *meson.build* are: ```text project('tutorial', 'c') zlib = dependency('zlib', version : '1.2.11') executable('compressor', 'src/main.c', dependencies: zlib) ``` Let’s create a *conanfile.txt* with the following content to install **Zlib**: ```ini [requires] zlib/1.3.1 [generators] PkgConfigDeps MesonToolchain ``` In this case, we will use [PkgConfigDeps](https://docs.conan.io/2//reference/tools/gnu/pkgconfigdeps.html.md#id1) to generate information about where the **Zlib** library files are installed thanks to the \*.pc files and [MesonToolchain](https://docs.conan.io/2//reference/tools/meson/mesontoolchain.html.md#id1) to pass build information to *Meson* using a conan_meson_[native|cross].ini file that describes the native/cross compilation environment, which in this case is a conan_meson_native.ini one. We will use Conan to install **Zlib** and generate the files that Meson needs to find this library and build our project. We will generate those files in the folder *build*. To do that, run: ```bash $ conan install . --output-folder=build --build=missing ``` Now we are ready to build and run our **compressor** app: ```bash $ cd build $ meson setup --native-file conan_meson_native.ini .. meson-src $ meson compile -C meson-src $ meson-src\compressor.exe Uncompressed size is: 233 Compressed size is: 147 ZLIB VERSION: 1.2.11 ``` ```bash $ cd build $ meson setup --native-file conan_meson_native.ini .. meson-src $ meson compile -C meson-src $ ./meson-src/compressor Uncompressed size is: 233 Compressed size is: 147 ZLIB VERSION: 1.2.11 ``` --- https://docs.conan.io/2/examples/tools/meson/create_your_first_package.html.md --- # Create your first Conan package with Meson In the [Create your first Conan package tutorial](https://docs.conan.io/2//tutorial/creating_packages/create_your_first_package.html.md#creating-packages-create-your-first-conan-package) CMake was used as the build system. If you haven’t read that section, read it first to familiarize yourself with the `conanfile.py` and `test_package` concepts, then come back to read about the specifics of the `Meson` package creation. Use the **conan new** command to create a “Hello World” C++ library example project: ```bash $ conan new meson_lib -d name=hello -d version=1.0 ``` This will create a Conan package project with the following structure. ```text ├── conanfile.py ├── meson.build ├── hello.vcxproj ├── src │   ├── hello.h │   └── hello.cpp └── test_package ├── conanfile.py ├── meson.build └── src └── example.cpp ``` The structure and files are very similar to the previous CMake example: - **conanfile.py**: On the root folder, there is a *conanfile.py* which is the main recipe file, responsible for defining how the package is built and consumed. - **meson.build**: A Meson build script. This script doesn’t need to contain anything Conan-specific, it is completely agnostic of Conan, because the integration is transparent. - **src** folder: the folder that contains the simple C++ “hello” library. - **test_package** folder: contains an *example* application that will require and link with the created package. In this case the `test_package` also contains a `meson.build`, but it is possible to have the `test_package` using other build system as CMake if desired. It is not mandatory that the test_package is using the same build system as the package. Let’s have a look at the package recipe *conanfile.py* (only the relevant new parts): ```python exports_sources = "meson.build", "src/*" def layout(self): basic_layout(self) def generate(self): tc = MesonToolchain(self) tc.generate() def build(self): meson = Meson(self) meson.configure() meson.build() def package(self): meson = Meson(self) meson.install() ``` Let’s explain the different sections of the recipe briefly: - The `layout()` defines a `basic_layout()`, this is less flexible than a CMake one, so it doesn’t allow any parametrization. - The `generate()` method calls `MesonToolchain` that can generate `conan_meson_native.ini` and `conan_meson_cross.ini` Meson toolchain files for cross builds. If the project had dependencies with Conan `requires`, it should add `PkgConfigDeps` too - The `build()` method uses the `Meson()` helper to drive the build - The `package()` method uses the `Meson` install functionality to define and copy to the package folder the final artifacts. The **test_package** folder also contains a `meson.build` file that declares a dependency to the tested package, and links an application, to verify the package was correctly created and contains that library: ```default project('Testhello', 'cpp') hello = dependency('hello', version : '>=0.1') executable('example', 'src/example.cpp', dependencies: hello) ``` Note the `test_package/conanfile.py` contains also a `generators = "PkgConfigDeps", "MesonToolchain"`, because the `test_package` has the “hello” package as dependency, and `PkgConfigDeps` is necessary to locate it. #### NOTE This example assumes Meson, Ninja and PkgConfig are installed in the system, which might not always be the case. If they are not, you can create a profile `myprofile` with: ```default include(default) [tool_requires] meson/[*] pkgconf/[*] ``` We added Meson and pkg-config as [tool requirements to the profile](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-tool-requires). By executing `conan create . -pr=myprofile`, those tools will be installed and made available during the package’s build process. Let’s build the package from sources with the current default configuration, and then let the `test_package` folder test the package: ```bash $ conan create . ... ======== Testing the package: Executing test ======== hello/1.0 (test package): Running test() hello/1.0 (test package): RUN: .\example hello/1.0: Hello World Release! hello/1.0: _M_X64 defined hello/1.0: MSVC runtime: MultiThreadedDLL hello/1.0: _MSC_VER1939 hello/1.0: _MSVC_LANG201402 hello/1.0: __cplusplus201402 hello/1.0 test_package ``` We can now validate that the recipe and the package binary are in the cache: ```bash $ conan list "hello/1.0:*" Local Cache: hello hello/1.0 revisions 856c535669f78da11502a119b7d8a6c9 (2024-03-04 17:52:39 UTC) packages c13a22a41ecd72caf9e556f68b406569547e0861 info settings arch: x86_64 build_type: Release compiler: msvc compiler.cppstd: 14 compiler.runtime: dynamic compiler.runtime_type: Release compiler.version: 193 os: Windows ``` #### SEE ALSO - [Meson built-in integrations reference](https://docs.conan.io/2//reference/tools/meson.html.md#conan-tools-meson). - [PkgConfigDeps built-in integrations reference](https://docs.conan.io/2//reference/tools/gnu/pkgconfigdeps.html.md#conan-tools-gnu-pkgconfigdeps). --- https://docs.conan.io/2/examples/tools/meson/meson.html.md --- # Meson * [Build a simple Meson project using Conan](https://docs.conan.io/2//examples/tools/meson/build_simple_meson_project.html.md) * [Create your first Conan package with Meson](https://docs.conan.io/2//examples/tools/meson/create_your_first_package.html.md) --- https://docs.conan.io/2/examples/tools/microsoft/msbuild.html.md --- # MSBuild * [Create your first Conan package with Visual Studio/MSBuild](https://docs.conan.io/2//examples/tools/microsoft/msbuild/create_your_first_package.html.md) --- https://docs.conan.io/2/examples/tools/microsoft/msbuild/create_your_first_package.html.md --- # Create your first Conan package with Visual Studio/MSBuild In the [Create your first Conan package tutorial](https://docs.conan.io/2//tutorial/creating_packages/create_your_first_package.html.md#creating-packages-create-your-first-conan-package) CMake was used as the build system. If you haven’t read that section, read it first to familiarize yourself with the `conanfile.py` and `test_package` concepts, then come back to read about the specifics of the `Visual Studio` package creation. Use the **conan new** command to create a “Hello World” C++ library example project: ```bash $ conan new msbuild_lib -d name=hello -d version=1.0 ``` This will create a Conan package project with the following structure. ```text . ├── conanfile.py ├── hello.sln ├── hello.vcxproj ├── include │   └── hello.h ├── src │   └── hello.cpp └── test_package ├── conanfile.py ├── test_hello.sln ├── test_hello.vcxproj └── src └── test_hello.cpp ``` The structure and files are very similar to the previous CMake example: - **conanfile.py**: On the root folder, there is a *conanfile.py* which is the main recipe file, responsible for defining how the package is built and consumed. - **hello.sln**: A Visual Studio solution file that can be opened with the IDE. - **hello.vcxproj**: A Visual Studio C/C++ project, part of the solution above. - **src** and **include** folders: the folders that contains the simple C++ “hello” library. - **test_package** folder: contains an *example* application that will require and link with the created package. In this case the `test_package` also contains a Visual Studio solution and project, but it is possible to have the `test_package` using other build system as CMake if desired. It is not mandatory that the test_package is using the same build system as the package. Let’s have a look at the package recipe *conanfile.py* (only the relevant new parts): ```python # Sources are located in the same place as this recipe, copy them to the recipe exports_sources = "hello.sln", "hello.vcxproj", "src/*", "include/*" def layout(self): vs_layout(self) def generate(self): tc = MSBuildToolchain(self) tc.generate() def build(self): msbuild = MSBuild(self) msbuild.build("hello.sln") def package(self): copy(self, "*.h", os.path.join(self.source_folder, "include"), dst=os.path.join(self.package_folder, "include")) copy(self, "*.lib", src=self.build_folder, dst=os.path.join(self.package_folder, "lib"), keep_path=False) ``` Let’s explain the different sections of the recipe briefly: - Note there are no `options` like the `shared` option in this recipe. The current project always builds a static library, so it is not optional. - The `layout()` defines a typical VS layout, this is less flexible than a CMake one, so it doesn’t allow any parametrization. - The `generate()` method calls `MSBuildToolchain` to generate a `conantoolchain.props` file, that the project must add to its properties. If the project had dependencies with Conan `requires`, it should add `MSBuildDeps` too and add the relevant generated files property sheets. - The `build()` method uses the `MSBuild()` helper to drive the build of the solution - As the project doesn’t have any “install” functionality in the build scripts, the `package()` method can manually define which files must be copied. The `hello.vcxproj` project file adds the generated property sheets like `conantoolchain.props` to the project, so the build can receive the Conan input `settings` and act accordingly. ```xml ``` If the project had dependencies, it should add the dependencies generated `.props` files too. The **test_package** folder also contains a `test_hello.vcxproj` file, that includes both the toolchain and the dependencies property sheets: ```xml ``` Note the `test_package/conanfile.py` contains also a `generators="MSBuildDeps"`. Let’s build the package from sources with the current default configuration, and then let the `test_package` folder test the package: ```bash $ conan create . ... ======== Testing the package: Executing test ======== hello/1.0 (test package): Running test() hello/1.0 (test package): RUN: x64\Release\test_hello hello/1.0: Hello World Release! hello/1.0: _M_X64 defined hello/1.0: MSVC runtime: MultiThreadedDLL hello/1.0: _MSC_VER1939 hello/1.0: _MSVC_LANG201402 hello/1.0: __cplusplus199711 hello/1.0 test_package ``` We can now validate that the recipe and the package binary are in the cache: ```bash $ conan list hello/1.0:* Local Cache: hello hello/1.0 revisions 856c535669f78da11502a119b7d8a6c9 (2024-03-04 17:52:39 UTC) packages c13a22a41ecd72caf9e556f68b406569547e0861 info settings arch: x86_64 build_type: Release compiler: msvc compiler.cppstd: 14 compiler.runtime: dynamic compiler.runtime_type: Release compiler.version: 193 os: Windows ``` #### SEE ALSO - Check the [Conan Visual Studio Extension](https://docs.conan.io/2//integrations/visual_studio.html.md#integrations-visual-studio-extension). - [MSBuild built-in integrations reference](https://docs.conan.io/2//reference/tools/microsoft.html.md#conan-tools-microsoft). --- https://docs.conan.io/2/examples/tools/scm/git/capture_scm/git_capture_scm.html.md --- # Capturing Git scm information There are 2 main strategies to handle source code in recipes: - **Third-party code**: When the `conanfile.py` recipe is packaging third party code, like an open source library, it is typically better to use the `source()` method to download or clone the sources of that library. This is the approach followed by the `conan-center-index` repository for ConanCenter. - **Your own code**: When the `conanfile.py` recipe is packaging your own code, it is typically better to have the `conanfile.py` in the same repository as the sources. Then, there are 2 alternatives for achieving reproducibility: - Using the `exports_sources` (or `export_source()` method) to capture a copy of the sources together with the recipe in the Conan package. This is very simple and pragmatic and would be recommended for the majority of cases. - For cases when it is not possible to store the sources beside the Conan recipe, for example when the package is to be consumed for someone that shouldn’t have access to the source code at all, then the current **scm capture** method would be the way. In the **scm capture** method, instead of capturing a copy of the code itself, the “coordinates” for that code are captured instead, in the `Git` case, the `url` of the repository and the `commit`. If the recipe needs to build from source, it will use that information to get a clone, and if the user who tries that is not authorized, the process will fail. They will still be able to use the pre-compiled binaries that we distribute, but not build from source or have access to the code. Let’s see how it works with an example. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/scm/git/capture_scm ``` There we will find a small “hello” project, containing this `conanfile.py`: ```python from conan import ConanFile from conan.tools.cmake import CMake, cmake_layout from conan.tools.scm import Git class helloRecipe(ConanFile): name = "hello" version = "0.1" # Binary configuration settings = "os", "compiler", "build_type", "arch" options = {"shared": [True, False], "fPIC": [True, False]} default_options = {"shared": False, "fPIC": True} generators = "CMakeDeps", "CMakeToolchain" def export(self): git = Git(self, self.recipe_folder) # save the url and commit in conandata.yml git.coordinates_to_conandata() def source(self): # we recover the saved url and commit from conandata.yml and use them to get sources git = Git(self) git.checkout_from_conandata_coordinates() ... ``` We need this code to be in its own Git repository, to see how it works in the real case, so please create a folder outside of the `examples2` repository, and copy the contents of the current folder there, then: ```text $ mkdir /home/myuser/myfolder # or equivalent in other OS $ cp -R . /home/myuser/myfolder # or equivalent in other OS $ cd /home/myuser/myfolder # or equivalent in other OS # Initialize the git repo $ git init . $ git add . $ git commit . -m wip # Finally create the package $ conan create . ... ======== Exporting recipe to the cache ======== hello/0.1: Exporting package recipe: /myfolder/conanfile.py hello/0.1: Calling export() hello/0.1: RUN: git status . --short --no-branch --untracked-files hello/0.1: RUN: git rev-list HEAD -n 1 --full-history -- "." hello/0.1: RUN: git remote -v hello/0.1: RUN: git branch -r --contains cb7815a58529130b49da952362ce8b28117dee53 hello/0.1: RUN: git fetch origin --dry-run --depth=1 cb7815a58529130b49da952362ce8b28117dee53 hello/0.1: WARN: Current commit cb7815a58529130b49da952362ce8b28117dee53 doesn't exist in remote origin This revision will not be buildable in other computer hello/0.1: RUN: git rev-parse --show-toplevel hello/0.1: Copied 1 '.py' file: conanfile.py hello/0.1: Copied 1 '.yml' file: conandata.yml hello/0.1: Exported to cache folder: /.conan2/p/hello237d6f9f65bba/e ... ======== Installing packages ======== hello/0.1: Calling source() in /.conan2/p/hello237d6f9f65bba/s hello/0.1: Cloning git repo hello/0.1: RUN: git clone "" "." hello/0.1: Checkout: cb7815a58529130b49da952362ce8b28117dee53 hello/0.1: RUN: git checkout cb7815a58529130b49da952362ce8b28117dee53 ``` Let’s explain step by step what is happening: - When the recipe is exported to the Conan cache, the `export()` method executes, `git.coordinates_to_conandata()`, which stores the Git URL and commit in the `conandata.yml` file by internally calling `git.get_url_and_commit()`. See the [Git reference](https://docs.conan.io/2//reference/tools/scm/git.html.md#conan-tools-scm-git) for more information about these methods. - This obtains the URL of the repo pointing to the local `/capture_scm` and the commit `8e8764c40bebabbe3ec57f9a0816a2c8e691f559` - It warns that this information will **not** be enough to re-build from source this recipe once the package is uploaded to the server and is tried to be built from source in other computer, which will not contain the path pointed by `/capture_scm`. This is expected, as the repository that we created doesn’t have any remote defined. If our local clone had a remote defined and that remote contained the `commit` that we are building, the `scm_url` would point to the remote repository instead, making the build from source fully reproducible. - The `export()` method stores the `url` and `commit` information in the `conandata.yml` for future reproducibility. - When the package needs to be built from sources and it calls the `source()` method, it recovers the information from the `conandata.yml` file inside the `git.checkout_from_conandata_coordinates()` method, which internally calls `git.clone()` with it to retrieve the sources. In this case, it will be cloning from the local checkout in `/capture_scm`, but if it had a remote defined, it will clone from it. #### WARNING To achieve reproducibility, it is very important for this **scm capture** technique that the current checkout is not dirty If it was dirty, it would be impossible to guarantee future reproducibility of the build, so `git.get_url_and_commit()` can raise errors, and require to commit changes. If more than 1 commit is necessary, it would be recommended to squash those commits before pushing changes to upstream repositories. If we do now a second `conan create .`, as the repo is dirty we would get: ```text $ conan create . hello/0.1: Calling export() ERROR: hello/0.1: Error in export() method, line 19 scm_url, scm_commit = git.get_url_and_commit() ConanException: Repo is dirty, cannot capture url and commit: .../capture_scm ``` This could be solved by cleaning the repo with `git clean -xdf`, or by adding a `.gitignore` file to the repo with the following contents (which might be a good practice anyway for source control): ```text test_package/build test_package/CMakeUserPresets.json ``` The capture of coordinates uses the `Git.get_url_and_commit()` method, that by default does: - If the repository is dirty, it will raise an exception - If the repository is not dirty, but the commit doesn’t exist in the remote, it will warn, but it will return the local folder as repo `url`. This way, local commits can be tested without needing to push them to the server. The `core.scm:local_url=allow` can silence the warning and the `core.scm:local_url=block` will immediately raise an error: This last value can be useful for CI scenarios, to fail fast and save a build that would have been blocked later in the `conan upload`. - Packages built with local commit will fail if trying to upload them to the server with `conan upload` as those local commits are not in the server and then the package might not be reproducible. This upload error can be avoided by setting `core.scm:local_url=allow`. - If the repository is not dirty, and the commit exists in the server, it will return the remote URL and the commit. ## Credentials management In the example above, credentials were not necessary, because our local repo didn’t require them. But in real world scenarios, the credentials can be required. The first important bit is that `git.get_url_and_commit()` will capture the url of the `origin` remote. This url must not encode tokens, users or passwords, for several reasons. First because that will make the process not repeatable, and different builds, different users would get different urls, and consequently different recipe revisions. The `url` should always be the same. The recommended approach is to manage the credentials in an orthogonal way, for example using ssh keys. The provided example contains a Github action that does this: ```yaml name: Build "hello" package capturing SCM in Github actions run-name: ${{ github.actor }} checking hello-ci Git scm capture on: [push] jobs: Build: runs-on: ubuntu-latest steps: - name: Check out repository code uses: actions/checkout@v3 with: ssh-key: ${{ secrets.SSH_PRIVATE_KEY }} - uses: actions/setup-python@v4 with: python-version: '3.10' - uses: webfactory/ssh-agent@v0.7.0 with: ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }} - run: pip install conan - run: conan profile detect - run: conan create . ``` This `hello-demo.yml` takes care of the following: - The checkout `actions/checkout@v3` action receives the `ssh-key` to checkout as `git@` instead of `https` - The `webfactory/ssh-agent@v0.7.0` action takes care that the ssh key is also activated during the execution of the following tasks, not only during the checkout. - It is necessary to setup the `SSH_PRIVATE_KEY` secret in the Github interface, as well as the `deploy key` for the repo (with the private and public parts of the ssh-key) In this way, it is possible to keep completely separated the authentication and credentials from the recipe functionality, without any risk to leaking credentials. #### NOTE **Best practices** - Do not use an authentication mechanism that encodes information in the urls. This is risky, can easily disclose credentials in logs. It is recommended to use system mechanisms like ssh keys. - Doing `conan create` is not recommended for local development, but instead running `conan install` and building locally, to avoid too many unnecessary commits. Only when everything works locally, it is time to start checking the `conan create` flow. --- https://docs.conan.io/2/examples/tools/system/system.html.md --- # System Packages * [Wrapping system requirements in a Conan package](https://docs.conan.io/2//examples/tools/system/system_package/package_manager.html.md) * [Wrapping a library installed in the system as a Conan package](https://docs.conan.io/2//examples/tools/system/system_package/package_manager.html.md#wrapping-a-library-installed-in-the-system-as-a-conan-package) * [Consuming system requirements only when building a package](https://docs.conan.io/2//examples/tools/system/system_package/consuming_system_packages.html.md) * [Consume a Conan package wrapper for a system package as build requirement](https://docs.conan.io/2//examples/tools/system/system_package/consuming_system_packages.html.md#consume-a-conan-package-wrapper-for-a-system-package-as-build-requirement) * [Consume the system package directly in the build() method](https://docs.conan.io/2//examples/tools/system/system_package/consuming_system_packages.html.md#consume-the-system-package-directly-in-the-build-method) --- https://docs.conan.io/2/examples/tools/system/system_package/consuming_system_packages.html.md --- # Consuming system requirements only when building a package In some cases, you may want to consume system requirements only when building a package, but not when installing it. It can be useful when you want to build a package in a CI/CD pipeline, but you don’t want to run the system package manager when installing the Conan package in a different environment. For those cases, there are few approaches that can be used to achieve this goal. ## Consume a Conan package wrapper for a system package as build requirement In this approach, you can use a Conan package for a [wrapped system package](https://docs.conan.io/2//examples/tools/system/system_package/package_manager.html.md#examples-tools-system-package-manager). Then, the package can be consumed regularly by the method [build_requirements()](https://docs.conan.io/2//reference/conanfile/methods/build_requirements.html.md#reference-conanfile-methods-build-requirements). ```python from conan import ConanFile class MyPackage(ConanFile): name = "mypackage" settings = "os", "compiler", "build_type", "arch" def build_requirements(self): self.tool_requires("ncurses/system") ... ``` This ensures that downstream consumers of the package *mypackage* will not directly invoke the system package manager (e.g., apt-get). Only the direct package consumer of the system wrap package for `ncurses` will execute the system package manager when building the package. Centralizing and wrapping `ncurses` in a separated recipe makes it reusable across multiple cases and is good practice to avoid code duplication. ## Consume the system package directly in the build() method In case wanting to run the system package manager only when building the package, but not having a Conan package to wrap the system library information, it’s possible to run the system package manager in the **build()** method: ```python from conan import ConanFile from conan.tools.system import package_manager class MyPackage(ConanFile): settings = "os", "compiler", "build_type", "arch" ... def build(self): if self.settings.os == "Linux": apt = package_manager.Apt(self) apt.install(["libncurses-dev"], update=True, check=True) ``` This way, the system package manager will be called only when building the package, not when installing it. There is the advantage of not needed to create a separated Conan package to wrap the system library information, this is a much simpler case, when only a single recipe need to install the system package. Still, this approach may lead to code duplication if multiple recipes consume the same system package. It is recommended to use this method sparingly and only for well-contained cases. --- https://docs.conan.io/2/examples/tools/system/system_package/package_manager.html.md --- # Wrapping system requirements in a Conan package Conan can manage system packages, allowing you to install platform-specific dependencies easily. This is useful when you need to install platform-specific system packages. For example, you may need to install a package that provides a specific driver or graphics library that only works on a specific platform. Conan provides a way to install system packages using the [system package manager](https://docs.conan.io/2//reference/tools/system/package_manager.html.md#conan-tools-system-package-manager) tool. In this example, we are going to explore the steps needed to create a wrapper package around a system library and what is needed to consume it in a Conan package. Note that the package will not contain the binary artifacts, it will just manage to check/install them calling `system_requirements()` and the respective system package managers (e.g Apt, Yum). In this example, we are going to create a Conan package to wrap the system [ncurses](https://invisible-island.net/ncurses/) requirement and then show how to use this requirement in an application. Please, first clone the sources to recreate this project. You can find them in the [examples2 repository](https://github.com/conan-io/examples2) on GitHub: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/system/package_manager/ ``` You will find the following tree structure: ```text . ├── conanfile.py └── consumer ├── CMakeLists.txt ├── conanfile.py └── ncurses_version.c ``` The `conanfile.py` file is the recipe that wraps the ncurses system library. Finally, the **consumer** directory contains a simple C application that uses the ncurses library, we will visit it later. When wrapping a pre-built system library, we do not need to build the project from source, only install the system library and package its information. In this case, we are going to check the **conanfile.py** file that packages the ncurses library first: ```python from conan import ConanFile from conan.tools.system import package_manager from conan.tools.gnu import PkgConfig from conan.errors import ConanInvalidConfiguration required_conan_version = ">=2.0" class SysNcursesConan(ConanFile): name = "ncurses" version = "system" description = "A textual user interfaces that work across a wide variety of terminals" topics = ("curses", "terminal", "toolkit") homepage = "https://invisible-mirror.net/archives/ncurses/" license = "MIT" package_type = "shared-library" settings = "os", "arch", "compiler", "build_type" def package_id(self): self.info.clear() def validate(self): supported_os = ["Linux", "Macos", "FreeBSD"] if self.settings.os not in supported_os: raise ConanInvalidConfiguration(f"{self.ref} wraps a system package only supported by {supported_os}.") def system_requirements(self): dnf = package_manager.Dnf(self) dnf.install(["ncurses-devel"], update=True, check=True) yum = package_manager.Yum(self) yum.install(["ncurses-devel"], update=True, check=True) apt = package_manager.Apt(self) apt.install(["libncurses-dev"], update=True, check=True) pacman = package_manager.PacMan(self) pacman.install(["ncurses"], update=True, check=True) zypper = package_manager.Zypper(self) zypper.install(["ncurses"], update=True, check=True) brew = package_manager.Brew(self) brew.install(["ncurses"], update=True, check=True) pkg = package_manager.Pkg(self) pkg.install(["ncurses"], update=True, check=True) def package_info(self): self.cpp_info.bindirs = [] self.cpp_info.includedirs = [] self.cpp_info.libdirs = [] self.cpp_info.set_property("cmake_file_name", "Curses") self.cpp_info.set_property("cmake_target_name", "Curses::Curses") self.cpp_info.set_property("cmake_additional_variables_prefixes", ["CURSES",]) pkg_config = PkgConfig(self, 'ncurses') pkg_config.fill_cpp_info(self.cpp_info, is_system=True) ``` In this **conanfile.py** file, we are using the [system package manager](https://docs.conan.io/2//reference/tools/system/package_manager.html.md#conan-tools-system-package-manager) tool to install the ncurses library based on different package managers, under the [system_requirements](https://docs.conan.io/2//reference/conanfile/methods/system_requirements.html.md#reference-conanfile-methods-system-requirements) method. It’s important to note that the `system_requirements` method is called always, when building, or even if the package is already installed. This is useful to ensure that the package is installed in the system. Each package manager may vary the package name used to install the ncurses library, so we need to check the package manager documentation to find the correct package name first. Another important detail is the **package_info** method. In this method, we are using the [PkgConfig](https://docs.conan.io/2//reference/tools/gnu/pkgconfig.html.md#conan-tools-gnu-pkgconfig) tool to fill the **cpp_info** data, based on the file `ncurses.pc` installed by the system package manager. See [Using PkgConfig.fill_cpp_info with PKG_CONFIG_PATH from a profile](https://docs.conan.io/2//examples/tools/gnu/pkg_config_sysroot.html.md#examples-tools-gnu-pkg-config-sysroot) for a variant of this pattern in a cross-compilation scenario, where the `.pc` files are provided by a sysroot pointed to by `PKG_CONFIG_PATH` in the profile `[buildenv]`. Now, let’s install the ncurses library using the **conanfile.py** file: ```bash $ conan create . --build=missing -c tools.system.package_manager:mode=install -c tools.system.package_manager:sudo=true ``` Note that we are using the [Conan configuration](https://docs.conan.io/2//reference/tools/system/package_manager.html.md#conan-tools-system-package-manager-config) `tools.system.package_manager:mode` as **install**, otherwise, Conan will not install the system package, but check if it is installed only. The same for `tools.system.package_manager:sudo` as **True** to run the package manager with root privileges. As a result of this command, you should be able to see the **ncurses** library installed in your system, in case not been installed yet. Now, let’s check the **consumer** directory. This directory contains a simple C application that uses the ncurses library. The **conanfile.py** file in the **consumer** directory is: ```python from conan import ConanFile from conan.tools.build import can_run from conan.tools.cmake import cmake_layout, CMake import os class AppNCursesVersionConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "CMakeDeps", "CMakeToolchain" package_type = "application" exports_sources = "CMakeLists.txt", "ncurses_version.c" def requirements(self): if self.settings.os in ["Linux", "Macos", "FreeBSD"]: self.requires("ncurses/system") def layout(self): cmake_layout(self) def build(self): cmake = CMake(self) cmake.configure() cmake.build() app_path = os.path.join(self.build_folder, "ncurses_version") self.output.info(f"The example application has been successfully built.\nPlease run the executable using: '{app_path}'") ``` The recipe is simple. It requires the **ncurses** package we just created and uses the **CMake** tool to build the application. Once the application is built, it shows the **ncurses_version** application path, so you can run it manually as you wish and check its output. The **ncurses_version.c** file is a simple C application that uses the ncurses library to print the ncurses version, but using white background and blue text: ```c #include #include #include #include int main(void) { int max_y, max_x; char message [256] = {0}; initscr(); start_color(); init_pair(1, COLOR_BLUE, COLOR_WHITE); getmaxyx(stdscr, max_y, max_x); snprintf(message, sizeof(message), "Conan 2.x Examples - Installed ncurses version: %s\n", curses_version()); attron(COLOR_PAIR(1)); mvprintw(max_y / 2, max_x / 2 - (strlen(message) / 2), "%s", message); attroff(COLOR_PAIR(1)); refresh(); return EXIT_SUCCESS; } ``` The **CMakeLists.txt** file is a simple CMake file that builds the **ncurses_version** application: ```cmake cmake_minimum_required(VERSION 3.15) project(ncurses_version C) find_package(Curses CONFIG REQUIRED) add_executable(${PROJECT_NAME} ncurses_version.c) target_link_libraries(${PROJECT_NAME} PRIVATE Curses::Curses) ``` The CMake target **Curses::Curses** is provided by the **ncurses** package we just created. It follows the official CMake module for [FindCurses](https://cmake.org/cmake/help/latest/module/FindCurses.html). The information about libraries and include directories is now available in the **cpp_info** object, as we filled it using the **PkgConfig** tool. Now, let’s build the application: ```bash $ cd consumer/ $ conan build . --name=ncurses-version --version=0.1.0 ... conanfile.py (ncurses-version/0.1.0): The example application has been successfully built. Please run the executable using: '/tmp/consumer/build/Release/ncurses_version' ``` After building the application, it will show the executable path. You can run it to check the output: ```bash $ /tmp/consumer/build/Release/ncurses_version Conan 2.x Examples - Installed ncurses version: ncurses 6.0.20160213 ``` Don’t worry if the displayed version is different from the one shown here or the executable path different. It depends on the version installed in your system and where you built the application. That’s it! You have successfully packaged a system library and consumed it in a Conan package. ## Wrapping a library installed in the system as a Conan package As a variant of the above case, it is also possible to apply the above strategy to libraries that are installed in the system, but not necessarily installed by the system package manager, nor necessarily in the common system locations where the compilers will find them by default. Suppose that there is an existing library, already compiled in a user folder such as: ```text /home/myuser/mymath └── include ├── mymath.h └── lib ├── mymath.lib ``` And `/home/myuser/mymath` is not added to the compilers default paths or anything like that. In general, a more recommended approach is to create a full package from those precompiled binaries, and upload that package, and then manage it as any other regular package. See the tutorial about [creating packages from pre-compiled binaries here](https://docs.conan.io/2//tutorial/creating_packages/other_types_of_packages/package_prebuilt_binaries.html.md#creating-packages-other-prebuilt). But in some scenarios, it might still be desirable to use that library from its installed location `/home/myuser/mymath` without putting the artifacts inside a Conan package. This can be done with a “wrapper” recipe, similar to the one above, but which does not have any `system_requirements()` method. It could be something like: ```python from conan import ConanFile class MyMath(ConanFile): name = "mymath" version = "1.2" # In this case an actual version might make more sense package_type = "static-library" def package_info(self): self.cpp_info.bindirs = [] # Absolute paths are allowed here self.cpp_info.includedirs = ["/home/myuser/mymath/include"] self.cpp_info.libdirs = ["/home/myuser/mymath/lib"] self.cpp_info.libs = ["mymath"] ``` Note that it is also possible to still do conditions based on settings, in case that the library is installed in the system in different locations based on the platform: ```python settings = "os" def package_info(self): self.cpp_info.bindirs = [] # Absolute paths are allowed here if self.settings.os == "Windows": self.cpp_info.includedirs = ["C:/Users/myuser/mymath/include"] self.cpp_info.libdirs = ["C:/Users/myuser/mymath/lib"] else: self.cpp_info.includedirs = ["/home/myuser/mymath/include"] self.cpp_info.libdirs = ["/home/myuser/mymath/lib"] self.cpp_info.libs = ["mymath"] ``` It might even be possible to parametrize those absolute paths with some environment variable specific for that platform too. #### NOTE **Best practices** - The use of “wrapper” recipes like this one should be minimized, as it makes reproducibility and traceability harder. Creating a real package putting the headers and libraries inside it, uploading it to the server, makes it possible to achieve such traceability and reproducibility. - This type of “wrapper” recipe can be convenient together with the `[replace_requires]` feature, for specific platform constraints, like a platform that mandates that some `openssl` library must be the one contained in a sysroot, not the one from the Conan package `openssl/version`, but in general, such a dependency to `openssl/version` is required by other packages. In those cases, writing a wrapper recipe around the sysroot `openssl` and using `[replace_requires]` to force the dependency graph to resolve to it could make sense. --- https://docs.conan.io/2/integrations/android.html.md --- # ![android_logo](images/integrations/conan-android-logo.png) Android Conan provides support for cross-building for Android, and it’s easy to integrate with Android Studio. Please check these examples for more information on how to build your binaries for Android: - [Cross building to Android with the NDK](https://docs.conan.io/2//examples/cross_build/android/ndk.html.md#examples-cross-build-android-ndk) - [Integrating Conan in Android Studio](https://docs.conan.io/2//examples/cross_build/android/android_studio.html.md#examples-cross-build-android-studio) --- https://docs.conan.io/2/integrations/autotools.html.md --- # ![autotools_logo](images/integrations/conan-autotools-logo.png) Autotools Conan provides different tools to help manage your projects using Autotools. They can be imported from `conan.tools.gnu`. The most relevant tools are: - AutotoolsDeps: the dependencies generator for Autotools, which generates shell scripts containing environment variable definitions that the Autotools build system can understand. - AutotoolsToolchain: the toolchain generator for Autotools, which generates shell scripts containing environment variable definitions that the Autotools build system can understand. - Autotools build helper, a wrapper around the command line invocation of autotools that abstracts calls like ./configure or make into Python method calls. - PkgConfigDeps: the dependencies generator for pkg-config which generates pkg-config files for all the required dependencies of a package. For the full list of tools under `conan.tools.gnu` please check the [reference](https://docs.conan.io/2//reference/tools/gnu.html.md#conan-tools-gnu) section. #### SEE ALSO - Reference for [AutotoolsDeps](https://docs.conan.io/2//reference/tools/gnu/autotoolsdeps.html.md#conan-tools-gnu-autotoolsdeps), [AutotoolsToolchain](https://docs.conan.io/2//reference/tools/gnu/autotoolstoolchain.html.md#conan-tools-gnu-autotoolstoolchain), [Autotools](https://docs.conan.io/2//reference/tools/gnu/autotools.html.md#conan-tools-gnu-build-helper) and [PkgConfigDeps](https://docs.conan.io/2//reference/tools/gnu/pkgconfigdeps.html.md#conan-tools-gnu-pkgconfigdeps). --- https://docs.conan.io/2/integrations/bazel.html.md --- # ![bazel_logo](images/integrations/conan-bazel-logo.png) Bazel Conan provides different tools to help manage your projects using Bazel. They can be imported from `conan.tools.google`. The most relevant tools are: - `BazelDeps`: the dependencies generator for Bazel, which generates a *[DEPENDENCY]/BUILD.bazel* file for each dependency and a *dependencies.bzl* file containing a Bazel function to load all those ones. That function must be loaded by your *WORKSPACE* file. - `BazelToolchain`: the toolchain generator for Bazel, which generates a `conan_bzl.rc` file that contains a build configuration `conan-config` to inject all the parameters into the **bazel build** command. - `Bazel`: the Bazel build helper. It’s simply a wrapper around the command line invocation of Bazel. #### SEE ALSO - Reference for [BazelDeps](https://docs.conan.io/2//reference/tools/google/bazeldeps.html.md#conan-tools-google-bazeldeps). - Reference for [BazelToolchain](https://docs.conan.io/2//reference/tools/google/bazeltoolchain.html.md#conan-tools-google-bazeltoolchain). - Reference for [Bazel](https://docs.conan.io/2//reference/tools/google/bazel.html.md#conan-tools-google-bazel). - [Build a simple Bazel project using Conan](https://docs.conan.io/2//examples/tools/google/bazeltoolchain/build_simple_bazel_project.html.md#examples-tools-bazel-toolchain-build-simple-bazel-project) - [Build a simple Bazel 7.x project using Conan](https://docs.conan.io/2//examples/tools/google/bazeltoolchain/build_simple_bazel_7x_project.html.md#examples-tools-bazel-7x-toolchain-build-simple-bazel-project) --- https://docs.conan.io/2/integrations/clion.html.md --- # ![clion_logo](images/integrations/clion/conan-icon-clion.png) CLion ## Introduction There’s a plugin [available in the JetBrains Marketplace](https://plugins.jetbrains.com/plugin/11956-conan) that’s compatible with CLion versions higher than *2022.3*. With this plugin, you can browse Conan packages available in [Conan Center](https://conan.io/center), add them to your project, and install them directly from the CLion IDE interface. This plugin utilizes [cmake-conan](https://github.com/conan-io/cmake-conan/tree/develop2), a [CMake dependency provider](https://cmake.org/cmake/help/latest/guide/using-dependencies/index.html#dependency-providers) for Conan. It injects `conan_provider.cmake` using the `CMAKE_PROJECT_TOP_LEVEL_INCLUDES` definition. This dependency provider translates the CMake configuration to Conan. For instance, if you select a *Debug* profile in CLion, Conan will install and use the packages for *Debug*. Bear in mind that *cmake-conan* activates the Conan integration every time CMake calls `find_package()`. This means that no library will be installed until the CMake configure step runs. At that point, Conan will attempt to install the required libraries and build them if necessary. Also, note that dependency providers are a relatively new feature in CMake. Therefore, you will need CMake version >= 3.24 and Conan >= 2.0.5. ## Installing the plugin To install the new Conan CLion plugin, navigate to the JetBrains marketplace. Open CLion, go to *Settings > Plugins*, then select the *Marketplace* tab. Search for the Conan plugin and click on the Install button. ![clion_install_plugin](images/integrations/clion/clion-install-plugin.png) After restarting CLion, a new “Conan” tool tab will appear at the bottom of the IDE. ## Configuring the plugin Open a CMake project or create a new one in CLion. Then, go to the “Conan” tool tab at the bottom of the IDE. The only enabled action in the toolbar of the plugin will be the one with the “wheel” (configuration) symbol. Click on it. ![clion_configuration_1](images/integrations/clion/clion-configuration-1.png) The first thing you should do is configure the Conan client executable that will be used. You can point to a specific installation in an arbitrary location on your system, or you can select “Use Conan installed in the system” to use the system-level installation. ![clion_configuration_2](images/integrations/clion/clion-configuration-2.png) Several options are marked as default. Let’s review them: - You’ll see checkboxes indicating which configurations Conan should manage. In our case, since we only have the Debug configuration, it’s the only one checked. Below that, “Automatically add Conan support for all configurations” is checked by default. This means you don’t need to manually add Conan support to new build configurations; the plugin will do it automatically. - There’s also a checkbox allowing Conan to modify the default CLion settings and run CMake sequentially instead of in parallel. This is necessary because the Conan cache isn’t concurrent yet in Conan 2. If you’re using the Conan plugin, you typically wouldn’t uncheck these options. After setting your preferences, click the OK button to finalize the configuration. **Note:** At this point, CLion will run the configure step for CMake automatically. Since the plugin sets up the *conan.cmake* dependency provider, a warning will appear in the CMake output. This warning indicates that we haven’t added a find_package() to our *CMakeLists.txt* yet. This warning will disappear once we add the necessary find_package() calls to the *CMakeLists.txt* file. After the initial configuration, you’ll notice that the list of libraries is enabled. The “update” and “inspect” buttons are also active. We’ll explain these in detail later. ## Using the plugin With the plugin configured, you can browse available libraries and install them from CLion. For example, if you want to use [libcurl](https://curl.se/libcurl/) to download an image from the Internet, navigate to the library list and search for *libcurl*. Information on how to add it to CMake will be displayed, along with a “Use in project” button. Select the version you want and click the button. ![clion_use_libcurl](images/integrations/clion/clion-use-libcurl.png) If you click on the “eye” (inspect) icon, you’ll see all the libraries added to the project (assuming you added more than one). This view includes basic target information for CMake and the necessary code snippets to integrate them into CMake. ![clion_inspect](images/integrations/clion/clion-inspect.png) Conan stores information about the used packages in a *conandata.yml* file in your project folder. This file is read by a *conanfile.py*, which is also created during this process. You can customize these files for advanced plugin usage, but ensure you read the information in the corresponding files to do this correctly. Modify your *CMakeLists.txt* according to the instructions, which should look something like this: ```cmake cmake_minimum_required(VERSION 3.15) project(project_name) set(CMAKE_CXX_STANDARD 17) find_package(CURL) add_executable(project_name main.cpp) target_link_libraries(project_name CURL::libcurl) ``` After reloading the CMake project, you should see Conan installing the libraries in the CMake output tab. #### SEE ALSO - For more details, check the [entry in the Conan blog about the plugin](https://blog.conan.io/introducing-new-conan-clion-plugin/). --- https://docs.conan.io/2/integrations/cmake.html.md --- # ![cmake_logo](images/integrations/conan-cmake-logo.png) CMake Conan provides different tools to integrate with CMake in a transparent way. Using these tools, the consuming `CMakeLists.txt` file does not need to be aware of Conan at all. The CMake tools also provide better IDE integration via cmake-presets. To learn how to integrate Conan with your current CMake project you can follow the [Conan tutorial](https://docs.conan.io/2//tutorial.html.md#tutorial) that uses CMake along all the sections. Please also check the reference for the CMakeDeps, CMakeToolchain, and CMake tools: - `CMakeDeps`: responsible for generating the CMake config files for all the required dependencies of a package. - `CMakeConfigDeps`: A modern and better alternative to `CMakeDeps`, released in Conan 2.25 that has several improvements and fixes. - `CMakeToolchain`: generates all the information needed for CMake to build the packages according to the information passed to Conan about things like the operating system, the compiler to use, architecture, etc. in a `conan_toolchain.cmake` toolchain file. It will also generate cmake-presets files for easy integration with some IDEs that support this CMake feature off-the-shelf. - `CMake` build helper is the tool used by Conan `conanfile.py` recipes to run CMake and will pass all the arguments that CMake needs to build successfully, such as the toolchain file, build type file, and all the CMake definitions set in the recipe. The `CMakeDeps` and `CMakeConfigDeps`, together with `CMakeToolchain` follow for the classic consumption flow described along the tutorial and many other sections in this documentation: ```bash $ conan install ... $ cmake --preset conan-xxxx # or use the -DCMAKE_TOOLCHAIN_FILE=conan_toolchain.cmake ``` This flow is important, the `conan install` command generates CMake presets and `conan_toolchain.cmake` toolchain files that helps locating the dependencies, besides trying to align as best as possible with the profile information. This is the recommended flow for most cases. In extraordinary and exceptional scenarios, it might be desired for the `CMake` execution to call `conan install` to simplify the flow, for example for some IDE integrations like the CLion one, so the users don’t need to call `conan install` themselves. For this purpose, the [cmake-conan integration](https://github.com/conan-io/cmake-conan) exists. It uses the CMake “dependency providers” feature to intercept the first `find_package()` and do a call to `conan install` to fetch the dependencies at that point. This `cmake-conan` project stability is not guaranteed, and it has some known issues and limitations. Refer to the Github repository for more details. And note that calling `conan install` explicitly before calling `cmake` is still the preferred and most recommended flow for most cases. #### SEE ALSO - Check the [Building your project using CMakePresets](https://docs.conan.io/2//examples/tools/cmake/cmake_toolchain/build_project_cmake_presets.html.md#examples-tools-cmake-toolchain-build-project-presets) example - Reference for [CMakeDeps](https://docs.conan.io/2//reference/tools/cmake/cmakedeps.html.md#conan-tools-cmakedeps), [CMakeConfigDeps generator](https://docs.conan.io/2//reference/tools/cmake/cmakeconfigdeps.html.md#conan-tools-cmakeconfigdeps), [CMakeToolchain](https://docs.conan.io/2//reference/tools/cmake/cmaketoolchain.html.md#conan-tools-cmaketoolchain) and [CMake build helper](https://docs.conan.io/2//reference/tools/cmake/cmake.html.md#conan-tools-cmake-helper) - [Conan tutorial](https://docs.conan.io/2//tutorial.html.md#tutorial) --- https://docs.conan.io/2/integrations/community.html.md --- # Community #### IMPORTANT This section contains links to different integrations created and supported by the community. Conan is not responsible for any of them, and does not provide any guarantee of compatibility or support. - **conan2-rs Rust-Conan integration**: A Rust wrapper of the conan C/C++ package manager (conan.io) to simplify usage in build scripts. For source and support go to the [conan2-rs Github page](https://github.com/ravenexp/conan2-rs). Created by [@ravenexp](https://github.com/ravenexp) - **Cruiz Conan GUI**. A Graphical User Interface for Conan client from [Mark Final](https://github.com/markfinal). Source and support in [cruiz Github page](https://github.com/markfinal/cruiz). - **Gradle Conan plugin**: A plugin to use Conan from the Gradle build system. See it in the [Gradle plugins site](https://plugins.gradle.org/plugin/net.sf.loggersoft.cpp-conan). Project [wiki here](https://sourceforge.net/p/gradle-cpp/wiki/cpp-conan/), for source, suppport (tickets), go to [project Sourceforge page](https://sourceforge.net/projects/gradle-cpp/) #### NOTE **Notes** - If you have an integration that you think could be valuable for the community, and you are willing to support it, feel free to open a Pull Request to this page in the Github repo. - Recall that these integrations are not supported by the Conan team. If you have any questions, issues or feedback about them, please reach out to their maintainers in their issue trackers. --- https://docs.conan.io/2/integrations/emscripten.html.md --- # ![emscripten_logo](images/integrations/conan-emscripten-logo.png) Emscripten Conan provides support for cross-building for both [asm.js](http://asmjs.org) and [WASM](https://webassembly.org) (Web Assembly) targets using [Emscripten](https://emscripten.org). This enables developers to compile C/C++ code for the browser and other JavaScript environments. For detailed examples and step-by-step instructions, refer to: - [Cross-building with Emscripten](https://docs.conan.io/2//examples/cross_build/emscripten.html.md#examples-cross-build-emscripten) --- https://docs.conan.io/2/integrations/github.html.md --- # ![github_logo](images/integrations/conan-github-logo.png) GitHub #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. The Conan [GitHub Actions](https://github.com/features/actions) integration allows you to setup Conan client in your GitHub Actions workflows in a simple and effective way. The project can be found on its [GitHub marketplace page](https://github.com/marketplace/actions/setup-conan-client), or its [GitHub source page](https://github.com/conan-io/setup-conan) directly. To use the integration, add a step in your workflow YAML file. The integration will install the Conan client and set up the environment for you. You can customize the following parameters: - **Conan version**: Specify the Conan version to install (e.g., 2.15.1). Default: latest stable. - **Configuration URLs**: A list of configuration URLs to download and install in Conan home. By default, no configuration is installed. - **Conan Audit Token**: The [audit](https://docs.conan.io/2//devops/audit.html.md#devops-audit) token used for the audit command to scan vulnerabilities in packages. By default, no token is used. - **Conan home path**: Set a custom location for the Conan home folder. By default, no custom path is used. - **Cache Conan packages**: Cache all packages in your Conan cache automatically and re-use them in a next build. By default, no cache is used. - **Python version**: You can specify the Python version to be installed with Conan, the same will be available in the environment. By default, Python 3.10 is installed. The integration is available for all platforms supported by GitHub Actions, including Linux, Windows, and macOS. ## Examples This section provides some examples of how to use the integration in your GitHub Actions workflows. ### Scanning Packages for Vulnerabilities in a Nightly Build #### WARNING Do not share your Conan audit token or expose it in your code. Always use GitHub secrets for sensitive data. First, you need to set up the Conan audit token in your [GitHub secrets](https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions). Then, use the following example to scan for vulnerabilities in a package and its dependencies: ```yaml name: Nightly security scan on: schedule: - cron: "0 0 * * *" jobs: scan-vulnerabilities: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install and setup Conan uses: conan-io/setup-conan@v1 with: audit_token: ${{ secrets.MY_CONAN_AUDIT_TOKEN }} - name: Scan for vulnerabilities with Conan Audit run: | conan audit scan . ``` This example scans all dependencies in a `conanfile.py` in the current directory. Note that it uses a [GitHub schedule](https://docs.github.com/en/actions/writing-workflows/choosing-when-your-workflow-runs/events-that-trigger-workflows#schedule) to run the scan every day at midnight, this is in the case of using the free service token, to avoid hitting the daily limits, but still having security checks every day. ### Installing Conan configuration and building packages This example installs a custom Conan configuration from a URL, restores cached packages from previous builds, builds the package defined in the `conanfile.py`, and uploads it to the Conan server. ```yaml name: Build and upload Conan package on: push: branches: - 'main' jobs: build: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Install and setup Conan uses: conan-io/setup-conan@v1 with: config_urls: https://mycompany.com/conan/configs.git cache_packages: true - name: Build and upload package run: | conan create . -pr:a myprofile --build=missing conan remote login artifactory developer -p ${{ secrets.MY_CONAN_PASSWORD }} conan upload "*" --confirm --remote artifactory ``` In this example, the action’s option `cache_packages` is set to true, so all packages in the Conan cache are cached for the next build. Remote information is expected from the configuration installed from the URL pointed by the option `config_urls`. Remote authentication uses GitHub secrets for security. The remote authentication is done using the GitHub secrets, which is a secure way to store sensitive information. --- https://docs.conan.io/2/integrations/jfrog.html.md --- # ![jfrog_logo](images/integrations/conan-jfrog-logo.png) JFrog ## Artifactory Build Info #### WARNING The support of Artifactory Build Info via extension commands is not covered by [the Conan stability commitment](https://docs.conan.io/2//introduction.html.md#stability). The [Artifactory build info](https://www.buildinfo.org/) is a recollection of the metadata of a build. This json-formatted file includes all the details about the build broken down into segments like version history, artifacts, project modules, dependencies, and everything that was required to create the build. Build infos are identified with a `build name` and a `build number`, similar to how many CI services identify the builds. They are conveniently stored in Artifactory to keep track of the build metadata to later perform different operations. Conan does not offer built-in support for the build info format. However, we have developed some [custom commands](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#reference-commands-custom-commands) at at the [extensions repository](https://github.com/conan-io/conan-extensions) using the feature, that provides support to create and manage the build info files. ### How to install the build info extension commands Using the dedicated repository for Conan extensions [https://github.com/conan-io/conan-extensions](https://github.com/conan-io/conan-extensions), it is as easy as: ```bash $ conan config install https://github.com/conan-io/conan-extensions.git -sf=extensions/commands/art -tf=extensions/commands/art ``` ### Generating a Build Info A Build Info can be generated from a create or install command: ```bash $ conan create . --format json -s build_type=Release > create_release.json ``` Then upload the created package to your repository: ```bash $ conan upload ... -c -r ... ``` Now, using the JSON output from the create/install commands, a build info file can be generated: ```bash $ conan art:build-info create create_release.json mybuildname_release 1 --server my_artifactory --with-dependencies > mybuildname_release.json ``` And then uploaded to Artifactory: ```bash $ conan art:build-info upload mybuildname_aggregated.json --server my_artifactory ``` For more reference, see the full example at [https://github.com/conan-io/conan-extensions/tree/main/extensions/commands/art#how-to-manage-build-infos-in-artifactory](https://github.com/conan-io/conan-extensions/tree/main/extensions/commands/art#how-to-manage-build-infos-in-artifactory) #### SEE ALSO - JFrog Artifactory has a [dedicated API](https://jfrog.com/help/r/jfrog-rest-apis/build-info) to manage build infos that has been integrated into the custom commands for Artifactory. - Check the `conan art:build-info` documentation for reference: [https://github.com/conan-io/conan-extensions/blob/main/extensions/commands/art/readme_build_info.md](https://github.com/conan-io/conan-extensions/blob/main/extensions/commands/art/readme_build_info.md) --- https://docs.conan.io/2/integrations/makefile.html.md --- # ![gnu_make_logo](images/integrations/conan-autotools-logo.png) Makefile Conan provides different tools to help manage your projects using Make. They can be imported from `conan.tools.gnu`. Besides the most popular variant, GNU Make, Conan also supports other variants like BSD Make. The most relevant tools are: - MakeDeps: the dependencies generator for Make, which generates a Makefile containing definitions that the Make build tool can understand. Currently, there is no `MakeToolchain` generator, it should be added in the future. For the full list of tools under `conan.tools.gnu` please check the [reference](https://docs.conan.io/2//reference/tools/gnu.html.md#conan-tools-gnu) section. #### SEE ALSO - Reference for [MakeDeps](https://docs.conan.io/2//reference/tools/gnu/makedeps.html.md#conan-tools-gnu-makedeps). --- https://docs.conan.io/2/integrations/meson.html.md --- # ![meson_logo](images/integrations/conan-meson-logo.png) Meson Conan provides different tools to help manage your projects using Meson. They can be imported from `conan.tools.meson`. The most relevant tools are: - MesonToolchain: generates the .ini files for Meson with the definitions of all the Meson properties related to the Conan options and settings for the current package, platform, etc. MesonToolchain normally works together with [PkgConfigDeps](https://docs.conan.io/2//reference/tools/gnu/pkgconfigdeps.html.md#conan-tools-gnu-pkgconfigdeps) to manage all the dependencies. - Meson build helper, a wrapper around the command line invocation of Meson. #### SEE ALSO - Reference for [MesonToolchain](https://docs.conan.io/2//reference/tools/meson/mesontoolchain.html.md#conan-tools-meson-mesontoolchain) and [Meson](https://docs.conan.io/2//reference/tools/meson/meson.html.md#conan-tools-meson-meson). - Build a simple Meson project using Conan [example](https://docs.conan.io/2//examples/tools/meson/build_simple_meson_project.html.md#examples-tools-meson-toolchain-build-simple-meson-project) Build a simple Meson project using Conan --- https://docs.conan.io/2/integrations/premake.html.md --- # ![premake_logo](images/integrations/conan-premake-logo.png) Premake Conan provides different tools to help manage your projects using Premake. They can be imported from `conan.tools.premake`. The most relevant tools are: - `PremakeDeps`: the dependencies generator for Premake, to allow consuming dependencies from Premake projects. - `PremakeToolchain`: the toolchain generator for Premake. It will create a wrapper over premake scripts allowing premake workspace and projects customization. - `Premake`: the Premake build helper. It’s simply a wrapper around the command line invocation of Premake. #### SEE ALSO - Reference for [PremakeDeps](https://docs.conan.io/2//reference/tools/premake/premakedeps.html.md#conan-tools-premake-premakedeps). - Reference for [PremakeToolchain](https://docs.conan.io/2//reference/tools/premake/premaketoolchain.html.md#conan-tools-premake-premaketoolchain). - Reference for [Premake](https://docs.conan.io/2//reference/tools/premake/premake.html.md#conan-tools-premake-premake). --- https://docs.conan.io/2/integrations/python.html.md --- # Python ## conan-py-build [conan-py-build](https://github.com/conan-io/conan-py-build) is a [PEP 517](https://peps.python.org/pep-0517/) build backend that lets Conan manage the C/C++ side of Python packages that ship compiled extensions (via [pybind11](https://pybind11.readthedocs.io/), [nanobind](https://nanobind.readthedocs.io/), the Python C API, etc.). Once it’s declared as the `build-backend` in `pyproject.toml`, commands like `pip wheel`, `pip install` or `python -m build` will: - Read the dependencies and build steps from a regular Conan `conanfile.py`. - Resolve and install those dependencies with Conan, downloading precompiled binaries from ConanCenter or building them from source. - Run the recipe’s `build()`/`package()` methods with any build system Conan can drive (CMake, Meson, etc.). - Copy what `package()` staged into the resulting wheel, alongside the pure Python part of the package. This removes the need for a separate, ad-hoc step to fetch and build C/C++ dependencies before packaging, and keeps that logic in the same `conanfile.py` format used for regular C/C++ packages. It also supports profiles and lockfiles for reproducible builds, dynamic versioning, PEP 621 entry points, and integrates with `auditwheel`/`delocate-wheel`/`delvewheel` and [cibuildwheel](https://cibuildwheel.pypa.io/) to produce self-contained wheels with bundled shared libraries. #### SEE ALSO - Build a simple Python extension using Conan [example](https://docs.conan.io/2//examples/extensions/python/build_backend/build_python_extension_with_conan.html.md#examples-extensions-python-build-backend-build-python-extension-with-conan). - [conan-py-build documentation](https://conan-py-build.conan.io), for the full getting started guide, configuration reference, and more examples (Meson, nanobind, cibuildwheel). - [Introducing conan-py-build](https://blog.conan.io/cpp/conan/python/2026/05/05/Introducing-conan-py-build.html) blog post. ## PyEnv The [PyEnv](https://docs.conan.io/2//reference/tools/system/pyenv.html.md#conan-tools-system-pyenv) tool installs executable Python packages with `pip` inside a dedicated virtual environment, isolating them from the system Python and from the Conan package itself. It’s meant for Python CLI tools needed during a recipe’s build, such as a build system or code generator invoked from `build()`, not for Python libraries imported by the recipe. #### SEE ALSO - [PyEnv reference](https://docs.conan.io/2//reference/tools/system/pyenv.html.md#conan-tools-system-pyenv), for the full API and a recipe example. --- https://docs.conan.io/2/integrations/ros.html.md --- # ![ros_logo](images/integrations/conan-ros-logo.png) ROS #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. Conan provides integration for your Robot Operating System (ROS) C/C++ based projects. This will allow you to consume Conan packages inside your ROS package projects. The Conan packages can be installed and used in CMake with the help of the [ROSEnv generator](https://docs.conan.io/2//reference/tools/ros/rosenv.html.md#conan-tools-ros-rosenv) created for the purpose. It provides a clean integration that requires no Conan-specific modifications in your *CMakeLists.txt*. #### IMPORTANT This integration supports **ROS2**, it has been developed using the **Kilted version** and the aim is to **support newer versions going forward**. If you have any issues with other ROS versions, please let us know by opening an issue in our GitHub repository. #### NOTE **Pre-requisites to run the example:** 1. In order to run the example, it is expected that you have an Ubuntu environment with [ROS2 installed](https://docs.ros.org/en/kilted/Installation/Ubuntu-Install-Debs.html). For convenience, you can also use this Dockerfile instead: ```docker FROM osrf/ros:kilted-desktop RUN apt-get update && apt-get install -y \ curl \ python3-pip \ git \ ros-kilted-nav2-msgs \ && rm -rf /var/lib/apt/lists/* RUN pip3 install --upgrade pip && pip3 install conan==2.* RUN conan profile detect CMD ["bash"] ``` Simply copy the Dockerfile, build your image with `docker build -t conanio/ros-kilted .`, and finally run it with `docker run -it conanio/ros-kilted`. There is also the possibility to run ROS2 on Windows. Follow the [installation instructions in the ROS 2 documentation]([https://docs.ros.org/en/kilted/Installation/Windows-Install-Binary.html](https://docs.ros.org/en/kilted/Installation/Windows-Install-Binary.html)). 1. The files for this example can be found at [our examples repository](https://github.com/conan-io/examples2/tree/main/examples/tools/ros/rosenv/workspace). Clone it like so to get started: ```bash $ git clone https://github.com/conan-io/examples2.git $ cd examples2/examples/tools/ros/rosenv ``` ## Consuming Conan packages using the ROSEnv generator Imagine we have a ROS C++ package called str_printer that uses some functionality from the third party string formatting library [fmt](https://conan.io/center/recipes/fmt) to print fancy strings. We have the following project structure: ```bash $ tree /f workspace ├───str_printer │ │ CMakeLists.txt │ │ conanfile.txt │ │ package.xml │ ├───include │ │ └──str_printer │ │ str_printer.h │ └───src │ str_printer.cpp └───consumer │ CMakeLists.txt │ package.xml └───src main.cpp ``` Where: - The str_printer is a ROS package that implements a function and **depends on the fmt Conan package**. - The consumer is also a ROS package that depends on the str_printer ROS package and uses its functionality in a **final executable**. The only difference in the str_printer package with respect to a normal ROS package is that it includes a *conanfile.txt* file. This is the file used by Conan to install the required dependencies and generate the files needed to perform the build. ```text [requires] fmt/11.0.2 [generators] CMakeDeps CMakeToolchain ROSEnv ``` In this case, we will install the 11.0.2 version of fmt and Conan will generate files for CMake and ROS so we can build the str_printer package later. To install the fmt library using Conan we should do the following: ```bash $ cd workspace $ conan install str_printer/conanfile.txt --build missing --output-folder install/conan ======== Computing dependency graph ======== fmt/11.0.2: Not found in local cache, looking in remotes... fmt/11.0.2: Checking remote: conancenter fmt/11.0.2: Downloaded recipe revision 5c7438ef4d5d69ab106a41e460ce11f3 Graph root conanfile.txt: /home/user/examples2/examples/tools/ros/rosenv/workspace/str_printer/conanfile.txt Requirements fmt/11.0.2#5c7438ef4d5d69ab106a41e460ce11f3 - Downloaded (conancenter) ======== Computing necessary packages ======== Requirements fmt/11.0.2#5c7438ef4d5d69ab106a41e460ce11f3:29da3f322a17cc9826b294a7ab191c2f298a9f49#d8d27fde7061f89f7992c671d98ead71 - Download (conancenter) ======== Installing packages ======== -------- Downloading 1 package -------- fmt/11.0.2: Retrieving package 29da3f322a17cc9826b294a7ab191c2f298a9f49 from remote 'conancenter' fmt/11.0.2: Package installed 29da3f322a17cc9826b294a7ab191c2f298a9f49 fmt/11.0.2: Downloaded package revision d8d27fde7061f89f7992c671d98ead71 ======== Finalizing install (deploy, generators) ======== conanfile.txt: Writing generators to /home/user/examples2/examples/tools/ros/rosenv/workspace/install/conan conanfile.txt: Generator 'CMakeDeps' calling 'generate()' conanfile.txt: CMakeDeps necessary find_package() and targets for your CMakeLists.txt find_package(fmt) target_link_libraries(... fmt::fmt) conanfile.txt: Generator 'CMakeToolchain' calling 'generate()' conanfile.txt: CMakeToolchain generated: conan_toolchain.cmake conanfile.txt: Preset 'conan-release' added to CMakePresets.json. Invoke it manually using 'cmake --preset conan-release' if using CMake>=3.23 conanfile.txt: If your CMake version is not compatible with CMakePresets (<3.23) call cmake like: 'cmake -G "Unix Makefiles" -DCMAKE_TOOLCHAIN_FILE=/home/danimtb/examples2/examples/tools/ros/rosenv/workspace/install/conan/conan_toolchain.cmake -DCMAKE_POLICY_DEFAULT_CMP0091=NEW -DCMAKE_BUILD_TYPE=Release' conanfile.txt: CMakeToolchain generated: CMakePresets.json conanfile.txt: CMakeToolchain generated: ../../str_printer/CMakeUserPresets.json conanfile.txt: Generator 'ROSEnv' calling 'generate()' conanfile.txt: Generated ROSEnv Conan file: conanrosenv.sh Use 'source /home/user/examples2/examples/tools/ros/rosenv/workspace/install/conan/conanrosenv.sh' to set the ROSEnv Conan before 'colcon build' conanfile.txt: Generating aggregated env files conanfile.txt: Generated aggregated env files: ['conanrosenv.sh'] Install finished successfully ``` This will download the fmt Conan package to the local cache and generate the CMake and ROS environment files in the conan subfolder of the install directory. Now we can source our ROS environment, then **source the Conan ROSEnv environment**, so the conan-installed package are found by CMake, and then we can build the str_printer package as usual with Colcon. ```bash $ source /opt/ros/kilted/setup.bash $ source install/conan/conanrosenv.sh $ colcon build --packages-select str_printer Starting >>> str_printer Finished <<< str_printer [10.8s] Summary: 1 package finished [12.4s] ``` ## Bridging the Conan-provided transitive dependencies to another ROS package As the consumer ROS package depends on str_printer, the targets of transitive dependencies should be exported. This is done as usual in the str_printers’s *CMakeLists.txt* using ament_export_dependencies(): ```text cmake_minimum_required(VERSION 3.8) project(str_printer) if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") add_compile_options(-Wall -Wextra -Wpedantic) endif() # find dependencies find_package(ament_cmake REQUIRED) find_package(fmt REQUIRED) # Retrieved with Conan C/C++ Package Manager add_library(str_printer src/str_printer.cpp) target_include_directories(str_printer PUBLIC $ $) target_compile_features(str_printer PUBLIC c_std_99 cxx_std_17) # Require C99 and C++17 ament_target_dependencies(str_printer fmt) ament_export_targets(str_printerTargets HAS_LIBRARY_TARGET) ament_export_dependencies(fmt) install( DIRECTORY include/ DESTINATION include ) install( TARGETS str_printer EXPORT str_printerTargets LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin INCLUDES DESTINATION include ) ament_package() ``` To build the consumer ROS package, you can proceed as usual (make sure that you have both the ROS environment and the Conan ROSEnv environment *sourced* before building as in previous step): ```bash $ colcon build --packages-select consumer Starting >>> consumer Finished <<< consumer [7.9s] Summary: 1 package finished [9.4s] ``` And after this, our consumer application should be ready to run with just: ```bash $ source install/setup.bash $ ros2 run consumer main Hi there! I am using fmt library fetched with Conan C/C++ Package Manager ``` #### SEE ALSO - Reference for [ROSEnv generator](https://docs.conan.io/2//reference/tools/ros/rosenv.html.md#conan-tools-ros-rosenv). --- https://docs.conan.io/2/integrations/visual_studio.html.md --- # ![visual_studio_logo](images/integrations/conan-visual_studio-logo.png) Visual Studio ## Recipe tools for Visual Studio Conan provides several tools to help manage your projects using Microsoft Visual Studio. These tools can be imported from `conan.tools.microsoft` and allow for native integration with Microsoft Visual Studio, without the need to use CMake and instead directly using Visual Studio solutions, projects, and property files. The most relevant tools are: - MSBuildDeps: the dependency information generator for Microsoft MSBuild build system. It will generate multiple `xxxx.props` properties files, one per dependency of a package, to be used by consumers using MSBuild or Visual Studio, just by adding the generated properties files to the solution and projects. - MSBuildToolchain: the toolchain generator for MSBuild. It will generate MSBuild properties files that can be added to the Visual Studio solution projects. This generator translates the current package configuration, settings, and options, into MSBuild properties files syntax. - MSBuild build helper is a wrapper around the command line invocation of MSBuild. It will abstract the calls like `msbuild "MyProject.sln" /p:Configuration= /p:Platform=` into Python method calls. For the full list of tools under `conan.tools.microsoft` please check the [reference](https://docs.conan.io/2//reference/tools/microsoft.html.md#conan-tools-microsoft) section. ## Conan extension for Visual Studio There’s an extension [available in the VisualStudio Marketplace](https://marketplace.visualstudio.com/items?itemName=conan-io.conan-vs-extension) that’s compatible beginning from Visual Studio version *2022*. With this extension, you can browse Conan packages available in [Conan Center](https://conan.io/center), add them to your project, and they will be automatically installed before building your projects. #### NOTE The Visual Studio extension is only compatible with C/C++ projects based on MSBuild. It will not work with CMake-based projects or projects using other technologies. For CMake-based projects, please refer to the [cmake-conan dependency provider](https://github.com/conan-io/cmake-conan). ### Installation The Conan Visual Studio Extension can be installed directly from within Visual Studio: - Open the Extensions menu. - Select Manage Extensions. - Search for “Conan” in the Online marketplace. - Download and install the extension. Alternatively, you can download the latest release from our [releases page](https://github.com/conan-io/conan-vs-extension/releases/latest) and install it manually. ### Initial Configuration After installing the Conan extension, you can access it from the “Conan” tool window in Visual Studio. To do so, go to **View > Other Windows > Conan C/C++ Package Manager**. ![Initial configuration](images/integrations/vs_extension/tool-window-extension.png) Initially, you will need to configure the Conan executable to be used by the extension. By clicking on the *configure* button (gear icon) from the extension’s window, you can set up the path to the Conan client executable. You can either specify a custom path or choose to use the Conan client installed at the system level. ![Select Conan executable](images/integrations/vs_extension/select-conan-executable.png) Once you have configured the Conan client, the extension is ready to use, and you can start adding libraries to your project. ### Searching and Adding Libraries Once configured, the library list in the Conan tool window becomes active, and you can search for Conan packages using the search bar. Selecting a library will allow you to view its details, including available versions and integration options. ![Search for Conan packages](images/integrations/vs_extension/search-packages.png) If you now click the Add requirement button, the extension will add a conanfile.py and a conandata.yml to your project with the necessary information to install the selected Conan packages. It will also add a prebuild event to the project to install those libraries on the next compilation of the project. At any point, you can also use the *refresh* button (circular arrow icon) to update the list of available packages in [Conan Center](https://conan.io/center). Now, if you initiate the build process for your project, the pre-build event will trigger Conan to install the packages and inject the necessary properties into the project, enabling Visual Studio to compile and link against those libraries. ![Build project with Conan packages](images/integrations/vs_extension/build-project.png) #### WARNING The initial compilation might fail if Visual Studio does not have sufficient time to process the injected properties. If this happens, simply rebuild the project, and it should build successfully. For a more in-depth introduction to the Conan Visual Studio extension with a practical example, please check this [example in Conan blog](https://blog.conan.io/2024/03/21/Introducing-new-conan-visual-studio-extension.html). #### SEE ALSO - Reference for [MSBuildDeps](https://docs.conan.io/2//reference/tools/microsoft/msbuilddeps.html.md#conan-tools-microsoft-msbuilddeps), [MSBuildToolchain](https://docs.conan.io/2//reference/tools/microsoft/msbuildtoolchain.html.md#conan-tools-microsoft-msbuildtoolchain) and [MSBuild](https://docs.conan.io/2//reference/tools/microsoft/msbuild.html.md#conan-tools-microsoft-msbuild). - [CLion Conan plugin](https://docs.conan.io/2//integrations/clion.html.md#integrations-clion). --- https://docs.conan.io/2/integrations/xcode.html.md --- # ![xcode_logo](images/integrations/conan-xcode-logo.jpg) Xcode Conan provides different tools to integrate with Xcode IDE, providing all the necessary information about the dependencies, build options and also to build projects created with Xcode in recipes. They can be imported from `conan.tools.apple`. The most relevant tools are: - XcodeDeps: the dependency information generator for Xcode. It will generate multiple .xcconfig configuration files, that can be used by consumers using xcodebuild in the command line or adding them to the Xcode IDE. - XcodeToolchain: the toolchain generator for Xcode. It will generate .xcconfig configuration files that can be added to Xcode projects. This generator translates the current package configuration, settings, and options, into Xcode .xcconfig files syntax. - XcodeBuild build helper is a wrapper around the command line invocation of Xcode. It will abstract the calls like `xcodebuild -project app.xcodeproj -configuration -arch ...` For the full list of tools under `conan.tools.apple` please check the [reference](https://docs.conan.io/2//reference/tools/apple.html.md#conan-tools-apple) section. #### SEE ALSO - Reference for [XcodeDeps](https://docs.conan.io/2//reference/tools/apple/xcodedeps.html.md#conan-tools-apple-xcodedeps), [XcodeToolchain](https://docs.conan.io/2//reference/tools/apple/xcodetoolchain.html.md#conan-tools-apple-xcodetoolchain) and [XcodeBuild build helper](https://docs.conan.io/2//reference/tools/apple/xcodebuild.html.md#conan-tools-apple-xcodebuild) --- https://docs.conan.io/2/knowledge/academy.html.md --- # JFrog Academy: Conan 2 Training Conan 2 training is available on the JFrog Academy in two paths: **Conan 2 Essentials** and **Conan 2 Advanced**. There are 29 video lessons across 7 modules (16 in Essentials, 13 in Advanced). The courses are practical (with code you can follow along), free, and self-paced. The examples in the courses use the [Conan Training 2 GitHub repository](https://github.com/conan-io/conan-training2). If you run into problems with the code or have feedback, open an issue there. ## Conan 2 Essentials Fundamentals of consuming and creating packages. Good starting point if you have little or no Conan experience. **Register here:** [Conan 2 Essentials](https://academy.jfrog.com/path/conan-cc-package-manager?utm_source=Conan+Docs) **Modules:** * **Module 1: Fundamentals of Package Usage** (Lessons 1–7, ~59 min) — Building a simple CMake project, multiple configurations (Release/Debug, static/shared), *conanfile.py* for consumption, build tools as Conan packages, cross-compilation (host/build profiles), versioning (revisions, version ranges, lockfiles), Conan Audit. * **Module 2: Package Creation and Uploading** (Lessons 8–13, ~48 min) — First package, dependencies and generators, `package()` and `package_info()`, settings and options (`package_id`), testing packages, remotes and uploading. * **Module 3: Advanced Package Creation Scenarios** (Lessons 14–16, ~21 min) — Header-only libraries, prebuilt binaries, tool requires. ## Conan 2 Advanced For users who already know Conan 2 basics. Local development, dependency graph, extensibility, and the advanced binary model. **Register here:** [Conan 2 Advanced](https://academy.jfrog.com/path/conan-2-advanced?utm_source=Conan+Docs) **Modules:** * **Module 1: Developing Packages Locally** (Lessons 17–18, ~16 min) — Package development flow (source, install, build, export-pkg), editable mode. * **Module 2: The Dependency Graph** (Lessons 19–21, ~25 min) — Package types, `test_requires`, advanced versioning and lockfiles. * **Module 3: Extensibility & Customization** (Lessons 22–26, ~47 min) — Config and extensibility (config install), deployers, custom commands, hooks, `python_requires`. * **Module 4: Advanced Binary Model** (Lessons 27–29, ~28 min) — Binary model, extending the model (custom settings, conf in `package_id`), defining binary compatibility. --- https://docs.conan.io/2/knowledge/cheatsheet.html.md --- # Cheat sheet This is a visual cheat sheet for basic Conan commands and concepts which users can print out and use as a handy reference. It is available as both a PDF and PNG. [`PDF Format`](https://docs.conan.io/2//images/cheatsheet/conan2-cheatsheet-v5.pdf) [`PNG Format`](https://docs.conan.io/2//images/cheatsheet/conan2-cheatsheet-v5.png) ![image](images/cheatsheet/conan2-cheatsheet-v5.png) --- https://docs.conan.io/2/knowledge/community_resources.html.md --- # Community Resources In this section, you can find documentation and Conan resources created by the community. We hope you find them useful. If you have your own resources that you believe could help the community grow, don’t hesitate to share them with us on our [GitHub](https://github.com/conan-io/conan). * [The Conan Cookbook](https://gitlab.com/batteriesincluded/conan-cookbook) * [Localization of Conan Documentation](https://github.com/localizethedocs/conan-docs-l10n) --- https://docs.conan.io/2/knowledge/faq.html.md --- # FAQ #### SEE ALSO There is a great community behind Conan with users helping each other in [Cpplang Slack](https://cppalliance.org/slack/). Please join us in the `#conan` channel! ## ERROR: Missing prebuilt package When installing packages (with **conan install** or **conan create**) it is possible that you get an error like the following one: ```text ERROR: Missing binary: zlib/1.3.1:b1d267f77ddd5d10d06d2ecf5a6bc433fbb7eeed zlib/1.3.1: WARN: Can't find a 'zlib/1.3.1' package binary 'b1d267f77ddd5d10d06d2ecf5a6bc433fbb7eeed' for the configuration: [settings] arch=x86_64 build_type=Release compiler=apple-clang compiler.cppstd=gnu11 compiler.libcxx=libc++ compiler.version=14 os=Macos [options] fPIC=True shared=False ERROR: Missing prebuilt package for 'zlib/1.3.1'. You can try: - List all available packages using 'conan list "{ref}:*" -r=remote' - Explain missing binaries: replace 'conan install ...' with 'conan graph explain ...' - Try to build locally from sources using the '--build=zlib/1.3.1' argument More Info at 'https://docs.conan.io/en/2/knowledge/faq.html#error-missing-prebuilt-package' ``` This means that the package recipe `zlib/1.3.1` exists, but for some reason there is no precompiled package for your current settings or options. Maybe the package creator didn’t build and shared pre-built packages at all and only uploaded the package recipe, or they are only providing packages for some platforms or compilers. E.g. the package creator built packages from the recipe for apple-clang 11, but you are using apple-clang 14. Also you may want to check your package ID mode as it may have an influence on the packages available for it. These would be the things to check: - Run a `conan graph explain` with exactly the same arguments as you did. It will give you hints about the differences between the binaries that exists in the cache and remotes and the binaries you are requesting to install. - You an also use a `conan list :*` command to list binaries in your cache and in your remotes and manually compare differences - If the binaries are missing because dependencies versions diverge, maybe your current Conan cache is using older revisions or versions, try adding an `--update` argument to the `conan install` command. - If finally the binary that is being requested doesn’t really exists anywhere, you might want to build it from sources. By default, Conan doesn’t build packages from sources. There are several possibilities to overcome this error: - You can try to build the package for your settings from sources, indicating some build policy as argument, like **--build zlib\*** or **--build missing**. If the package recipe and the source code work for your settings you will have your binaries built locally and ready for use. - If building from sources fails, and you are using the conancenter remote, you can open an issue in [the Conan Center Index repository](https://github.com/conan-io/conan-center-index) ## ERROR: Invalid setting It might happen sometimes, when you specify a setting not present in the defaults that you receive a message like this: ```bash $ conan install . -s compiler.version=4.19 ... ERROR: Invalid setting '4.19' is not a valid 'settings.compiler.version' value. Possible values are ['4.4', '4.5', '4.6', '4.7', '4.8', '4.9', '5.1', '5.2', '5.3', '5.4', '6.1', '6.2'] ``` This doesn’t mean that such compiler version is not supported by Conan, it is just that it is not present in the actual defaults settings. You can find in your user home folder `~/.conan2/settings.yml` a settings file that you can modify, edit, add any setting or any value, with any nesting if necessary. See [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md#reference-config-files-settings-yml) to learn how you can customize your settings to model your binaries at your will. As long as your team or users have the same settings (`settings.yml` and `settings_user.yml` an be easily shared with the `conan config install` command), everything will work. The *settings.yml* file is just a mechanism so users agree on a common spelling for typical settings. Also, if you think that some settings would be useful for many other conan users, please submit it as an issue or a pull request, so it is included in future releases. It is possible that some built-in helper or integrations, like `CMake` or `CMakeToolchain` will not understand the new added settings, don’t use them or even fail if you added some new unexpected value to existing settings. Such helpers as `CMake` are simple utilities to translate from conan settings to the respective build system syntax and command line arguments, so they can be extended or replaced with your own one that would handle your own private settings. ## ERROR: AuthenticationException: This error can happen, if there are no or false authentication credentials in the HTTP request from conan. To get more information try enabling the debug level for HTTP connections: ```python import http.client http.client.HTTPConnection.debuglevel = 1 ``` One source of error can be the `.netrc` file, which is [honored by the requests library](https://requests.readthedocs.io/en/latest/user/quickstart/#custom-headers). ## ERROR: Obtaining different revisions in Linux and Windows Git will (by default) checkout files in Windows systems using `CRLF` line endings, effectively producing different files than in Linux that files will use `LF` line endings. As files are different, the Conan recipe revision will be different from the revisions computed in other platforms such as Linux, resulting in missing the respective binaries in the other revision. Conan will not normalize or change in any way the source files, it is not its responsibility and there are risks of breaking things. The source control is the application changing the files, so that is a more correct place to handle this. It is necessary to instruct Git to do the checkout with the same line endings. This can be done several ways, for example, by adding a `.gitattributes` file to the project repository with something like: ```ini * text eol=lf ``` Above will mark all files in repo with `text` attribute and force `lf` as end of line. Treating binary files as `text` lead to data corruption although. If there are binary files alongside, make sure to exclude them back: ```ini * text eol=lf *.png binary *.jpg binary *.jpeg binary ``` Other approach would be to change the `.gitconfig` to change it globally. Modern editors (even Notepad) in Windows can perfectly work with files with `LF`, it is no longer necessary to change the line endings. ## Defining options for dependencies in conanfile.py recipes doesn’t work Conan expands the dependency graph depth-first, this is important to be able to implement many of the very special C/C++ propagation logic (headers, static and shared libraries, applications, tool-requires, test-requires, conflicts, overrides, etc.). This means that when a `conanfile.py` declares something like: ```python class MyPkg(ConanFile): name = "mypkg" version = "0.1" default_options = {"zlib/*:shared": True} # Or def requirements(self): self.requires("zlib/1.3", options={"shared": True}) ``` it cannot be always honored, and the `zlib` dependency might end with different `shared=False` option value. This in-recipe options values definition for dependencies only works if: - There are no other packages depending on `zlib` in the graph - There are other packages depending on `zlib` in the graph, but `mypkg/0.1` is the first require (the first branch in the dependency graph) that is required. That means that `requires = "mypkg/0.1", "zlib/1.3"` will work and will have `zlib` as shared, but `requires = "zlib/1.3", "mypkg/0.1"` will expand first `zlib` with its default, which is `shared=False` and when the `mypkg/0.1` is computed it will be too late to change `zlib` to be `shared=True`. In case there are some recipe that won’t work at all with some option of the dependency, the recommendation is to define a `validate()` method in the recipe to guarantee that it will raise an error if for some reason the upstream dependency doesn’t have the right options values. Conan might be able to show some (not guaranteed to be exhaustive) of these issues in the output of the Conan commands, please read it carefully. ```default Options conflicts liba/0.1:myoption=1 (current value) libc/0.1->myoption=2 It is recommended to define options values in profiles, not in recipes ``` In general, it is more recommended to define options values in profile files, not in recipes. Recipe defined options always have less precedence than options defined in profiles. #### IMPORTANT Defining options values for dependencies in recipes does not have strong guarantees: - This applies to any recipe definition of dependencies options, via `default_options`, `configure()`, or requirements `options=` trait. - It is not possible to change the options of non-visible transitive dependencies, for example `test_requires` or `tool_requires` of dependencies cannot be affected by any definition of options values in downstream recipes, because they are private. - The “locality” of the definition makes it a bad location for large projects with developers working on different packages in the dependency graph. So in general, defining options values for dependencies in recipes is **discouraged**. The strongly recommended way to define options values for dependencies is in **profile files**. ## Getting version conflicts even when using version ranges It is possible that when installing dependencies, there are version conflict error messages like: ```default ... Version conflict: Conflict between math/1.0.1 and math/1.0 in the graph ``` This [tutorial about version conflicts](https://docs.conan.io/2//tutorial/versioning/conflicts.html.md#tutorial-versioning-conflicts) summarizes how different versions of the same package dependency can conflict in a dependency graph and how to resolve those conflicts. However, there are some situations in which the conflict is not that evident, for example when there are some mixed version ranges and fixed dependencies, something like: ```python def requirements(self): self.requires("libb/1.0") # requires liba/[>=1.0 <2] self.requires("libc/1.0") # requires liba/1.0 ``` And it happens that `libb/1.0` has a transitive requirement to `liba/[>=1.0 <2]`, and `libc/1.0` requires `liba/1.0`, and there exist the `liba/1.1` or higher packages. In this case, Conan might also throw a “version conflict” error. The root cause is that resolving the joint compatibility for all the possible constraints that version-ranges define in a graph is a known NP-hard problem, known as SAT-solver. Evaluating each hypothesis in this NP-hard problem in Conan is very expensive, because it usually requires to look for a version/revision in all remotes defined, then download such version/revision compressed files, unzip them, load and Python-parse and evaluate them and finally to do all the graph computation processing, which involves a full propagation down the already expanded graph to propagate the C/C++ requirement traits that can produce the conflicts. This would make the problem intractable in practice, that would require to wait for many hours to finish. So instead of doing that, Conan uses a “greedy” algorithm that does not require backtracking, but still will try to reconcile version-ranges with fixed versions when possible. The most important point to know about this is that Conan implements a “depth-first” graph expansion, evaluating the `requires` in the order they are declared. Knowing this can help to solve this conflict. In the case above the error happens because `libb/1.0` is expanded first, it finds a requirement of `liba/[>=1.0 <2]`, and as no other constraint to `liba` has been found before, it freely resolves to the latest `liba/1.1`. When later `libc/1.0` is expanded, it finds a requirement to `liba/1.0`, but it is already too late, as it will conflict with the previous `liba/1.1`. Going back in the previous hypothesis is the “backtracking” part that converts the problem in NP-hard, so the algorithm stops there and raises the conflict. This can be solved just by swapping the order of `requires`: ```python def requirements(self): self.requires("libc/1.0") # requires liba/1.0 self.requires("libb/1.0") # requires liba/[>=1.0 <2] ``` If `libc/1.0` is expanded first, it resolves to `liba/1.0`. When later `libb/1.0` is expanded, its transitive requirement `liba/[>=1.0 <2]` can be successfully satisfied by the previous `libb/1.0`, so it can resolve the graph successfully. The general best practices are: - For the same dependency, try to use the same approach everywhere: use version ranges everywhere, or fixed versions everywhere for that specific dependency. - Keep the versions aligned. If using a version range try to use the same version range everywhere. - Declare first dependencies that use fixed version, not version ranges - Use the `conan graph info ... --format=html > graph.html` graphical interactive output to understand and navigate conflicts. ## Conan is redirecting its output to stderr As explained [in the commands reference](https://docs.conan.io/2//reference/commands.html.md#commands-output), by design Conan redirects its logging information to the standard error output (stderr), while the actual results of the commands are sent to the standard output (stdout). This is done to allow users to easily redirect the output of Conan commands to files or other processes without having the logging information mixed with the actual results. For example, running a command like: ```text $ conan graph info --requires=zlib/1.3.1 --format=json > graph.json ... ======== Computing dependency graph ======== Graph root cli Requirements zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76 - Cache ======== Computing necessary packages ======== Connecting to remote 'conancenter' anonymously Requirements zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76:dbb40f41e6e9a5c4a9a1fd8d9e6ccf6d92676c92#8976086f07d37e3f6288e2fccf9650ae - Cache ``` will create a file named `graph.json` with the JSON output of the command, but it will not include any logging information, which will be printed to the console. Note that this approach is common in many command-line tools such as `git` and `curl`, and it is not specific to Conan. ## Missing binary for a (tool) package that was just created with `conan create` There is sometimes the case for a package, intended to be used as a `tool_requires` by other packages, whose recipe contains a `test_package` folder that requires such tool as: ```python from conan import ConanFile class secure_scannerTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" def build_requirements(self): self.tool_requires(self.tested_reference_str) ``` Then, users doing the creation of the package with: ```bash $ conan create ... mytool/0.1: Package created successfully ======== Launching test_package ======== ... ======== Computing necessary packages ======== ... ERROR: Missing binary: mytool/0.1 ``` will find a “Missing binary” error in the `test_package` step. How is this possible, if the package binary was created a few lines above? The `conan create` command by default creates packages for the “host” context, using the “host” profile. But if the package we are creating is intended to be used as a tool, that is, as a `tool_requires`, then it needs to be built for the “build” context. If for any reason, the “host” and the “build” context are not identical, then the binary that is built in the initial package creation will be a binary for the “host” context, but then the `test_package` will require it as `tool_requires()`, requiring it in the “build” context, and such binary will be missing, as it hasn’t been built. This is evident in the case of a cross-compilation, from example, building on a Windows laptop a binary for the RaspberryPI with a cross-compiler. The “build” context will be the “Windows” one, while the “host” context will be the “RaspberryPI” one. A regular `conan create .` for “mytool/0.1”, will create by default a binary for “RaspberryPI”! So when later, the `test_package` wants to use it as a `tool_requires()` it will look for the “Windows” binary, as it needs to run it in the current Windows machine, the “build” context. The `--build-require` argument specifies this. When this argument is provided, the current recipe binary will be built to run in the “build” context #### NOTE When doing `conan create` for a package intended to be used as a `tool_requires`, always specify the `conan create ... --build-require` argument. ## Using Conan with both corporate and public remotes (SSL certificates) In corporate environments it is common to need access to both a private Artifactory remote (secured with a self-signed or internal CA certificate) and a public remote such as ConanCenter at the same time. The problem appears because: * Without any custom CA configuration Conan may reject the corporate remote (`CERTIFICATE_VERIFY_FAILED`). * Setting `core.net.http:cacert_path` to point **only** to the corporate CA makes ConanCenter unreachable, because the public root CAs are no longer in the trust bundle. The solution is to build a **single combined CA bundle** that contains both the public root certificates **and** the corporate CA, and then configure Conan to use it via `core.net.http:cacert_path` (see [Configuration of client certificates](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf-ssl-certificates)). The combined bundle can be created by appending the corporate CA (in PEM format) to the default public CA bundle. The `certifi` Python package ships the Mozilla root CA bundle that Conan uses by default: ```bash # 1. Copy the default public CA bundle to a working location cp "$(python -m certifi)" combined-ca-bundle.pem # 2. Append the corporate CA (PEM format) to the bundle cat my-corporate-ca.crt >> combined-ca-bundle.pem ``` You can append as many additional CAs as needed. Then point Conan at the combined file: ```text core.net.http:cacert_path=/path/to/combined-ca-bundle.pem ``` #### SEE ALSO [Configuration of client certificates](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf-ssl-certificates) for the full reference on `core.net.http:cacert_path`, `core.net.http:client_cert`, and alternative ways to aggregate certificates (including `update-ca-certificates` on Debian/Ubuntu). ## Conan doesn’t skip failing remotes This frequent question happens when users have defined some remotes, some of them are not available for any reasons, and Conan fails with an error reporting about that unresponsive or disconnected server remote. There are different scenarios in which silently skipping a server can cause production issues, for example when trying to build a new binary of an application that had some new versions of some new dependencies in that server. If that server doesn’t work properly and the pipeline continues it will result in a binary without the new versions without the bug fixes on upgrades. There could be extra checks later, validation gates, etc, to try to avoid that binary without the fixes in production, but those are often too late or just non existing. So Conan will always treat the defined and available servers as “must be alive”, and fail immediately if they do not work. Conan already provides some mechanisms to control the remote servers that are used for package resolution: - `conan remote enable/disable` to temporarily enable, disable servers - Explicit listing of the remotes you want to use conan install `-r=remote1 -r=remote8 -r=remote3`, in the order you want the precedence - `conan config install/install-pkg` for easy configuration of remotes for different projects or needs. --- https://docs.conan.io/2/knowledge/guidelines.html.md --- # Core guidelines ## Good practices - **build() should be simple, prepare the builds in generate() instead**: The recipes’ `generate()` method purpose is to prepare the build as much as possible. Users calling `conan install` will execute this method, and the generated files should allow users to do “native” builds (calling directly “cmake”, “meson”, etc.) as easy as possible. Thus, avoiding as much as possible any logic in the `build()` method, and moving it to the `generate()` method helps developers achieve the same build locally as the one that would be produced by a `conan create` build in the local cache. - **Always use your own profiles in production**, instead of relying on the auto-detected profile, as the output of such auto detection can vary over time, resulting in unexpected results. Profiles (and many other configuration), can be managed with `conan config install`. - **Developers should not be able to upload to “development” and “production” repositories** in the server. Only CI builds have write permissions in the server. Developers should only have read permissions and at most to some “playground” repositories used to work and share things with colleagues, but which packages are never used, moved or copied to the development or production repositories. - **The test_package purpose is to validate the correct creation of the package, not for functional testing**. The `test_package` purpose is to check that the package has been correctly created (that is, that it has correctly packaged the headers, the libraries, etc, in the right folders), not that the functionality of the package is correct. Then, it should be kept as simple as possible, like building and running an executable that uses the headers and links against a packaged library should be enough. Such execution should be as simple as possible too. Any kind of unit and functional tests should be done in the `build()` method. - **All input sources must be common for all binary configurations**: All the “source” inputs, including the `conanfile.py`, the `conandata.yml`, the `exports` and `exports_source`, the `source()` method, patches applied in the `source()` method, cannot be conditional to anything, platform, OS or compiler, as they are shared among all configurations. Furthermore, the line endings for all these things should be the same, it is recommended to use always just line-feeds in all platforms, and do not convert or checkout to `crlf` in Windows, as that will cause different recipe revisions. - **Keep \`\`python_requires\`\` as simple as possible**. Avoid transitive `python_requires`, keep them as reduced as possible, and at most, require them explicitly in a “flat” structure, without `python_requires` requiring other `python_requires`. Avoid inheritance (via `python_requires_extend`) if not strictly necessary, and avoid multiple inheritance at all costs, as it is extremely complicated, and it does not work the same as the built-in Python one. - At the moment the **Conan cache is not concurrent**. Avoid any kind of concurrency or parallelism, for example different parallel CI jobs should use different caches (with CONAN_HOME env-var). This might change in the future and we will work on providing concurrency in the cache, but until then, use isolated caches for concurrent tasks. - **Avoid ‘force’ and ‘override’ traits as a versioning mechanism.** The `force` and `override` traits to solve conflicts are not recommended as a general versioning solution, just as a temporary workaround to solve a version conflict. Its usage should be avoided whenever possible, and updating versions or version ranges in the graph to avoid the conflicts without overrides and forces is the recommended approach. - **Please, do not abuse ‘tool_requires’**. Those are intended only for executables like `cmake` and `ninja` running in the “build” context, not for libraries or library-like dependencies, that must use `requires` or `test_requires`. - Positional arguments when invoking Conan should be specified first, before any named argument. For example, `conan install . -s="os=Windows"` is correct, but `conan install -s="os=Windows" .` is not. Likewise, it’s recommended to use `=` instead of spaces between the name and value of named arguments. This is to avoid some ambiguity scenarios when parsing the command line arguments. - **It is strongly discouraged to use user/channel** for any quality, stage, maturity or variable information The `channel` part is very legacy, and should be avoided in most cases, or use a fixed string as `stable`. The `user` might be used for intra-organization private packages, while the recommendation for packages coming from ConanCenter or forks of `conan-center-index` Github repo is to use them without any user or channel, like the `zlib/1.3.1` ConanCenter references, even for customization of the recipes and packages for those third party libraries. - The way to manage package quality, stage or maturity **promotions is by using different server repositories**, and the well known developer’s best practices recommend to manage the pipelines by doing promotions (copying) immutable artifacts or packages between those different server repositories, for example copying packages from a `staging` repository to a `production` repository once they have passed some quality checks. But it is very important that this promotion does not change in any way those packages, which must be completely immutable, not even changing its `user/channel`, this is why the above point discourages using user and channel, packages and artifacts must be immutable. - Define **dependencies options values** in **profile files**, not in recipes. Do not define `default_options` for dependencies like `default_options = {"mydep*:myoption": "value"}`. Do not use `configure()` to define options values for dependencies, and avoid using the `options` requirement trait as much as possible. Use the dependencies default options, if necessary change those defaults directly in the dependencies to default to your most used configurations and use **profile** files whenever is necessary to diverge from those defaults. See [this FAQ about options values for dependencies](https://docs.conan.io/2//knowledge/faq.html.md#faq-different-options-values) for more information. - Do not export packages with versions that have an alphanumeric major version when you want to use minor versions too. That is, do not use `v1.3`, etc. (but `system`, `develop`, etc. are fine). The reason is that the checks for package binary compatibility that Conan performs special-case the major as alphanumeric cases, and will consider that `v1.0` and `v1.3` to be the same version regardless of the minor version, which might lead to unexpected results, such as a missing binary not being built when it should, and a package releasing without a critical bugfix. This can be mitigated by ensuring that both the `package_id_non_embed_mode` and `package_id_unknown_mode` are explicitly set in the recipe to something other than `major_mode`, `minor_mode`, `patch_mode` or `semver_mode`, which are the affected modes. But it is simpler to just avoid alphanumeric major versions if you want to use minor versions too. ## Forbidden practices - **Conan is not re-entrant**: Calling the Conan process from Conan itself cannot be done. That includes calling Conan from recipe code, hooks, plugins, and basically every code that already executes when Conan is called. Doing it will result in undefined behavior. For example it is not valid to run `conan search` from a `conanfile.py`. This includes indirect calls, like running Conan from a build script (like `CMakeLists.txt`) while this build script is already being executed as a result of a Conan invocation. For the same reason **Conan Python API cannot be used from recipes**: The Conan Python API can only be called from Conan custom commands or from user Python scripts, but never from `conanfile.py` recipes, hooks, extensions, plugins, or any other code executed by Conan. - **Settings and configuration (conf) are read-only in recipes**: The settings and configuration cannot be defined or assigned values in recipes. Something like `self.settings.compiler = "gcc"` in recipes shouldn’t be done. That is undefined behavior and can crash at any time, or just be ignored. Settings and configuration can only be defined in profiles, in command line arguments or in the `profile.py` plugin. - **Recipes reserved names**: Conan `conanfile.py` recipes user attributes and methods should always start with `_`. Conan reserves the “public” namespace for all attributes and methods, and `_conan` for private ones. Using any non-documented Python function, method, class, attribute, even if it is “public” in the Python sense, is undefined behavior if such element is not documented in this documentation. - **Conan artifacts are immutable**: Conan packages and artifacts, once they are in the Conan cache, they are assumed to be immutable. Any attempt to modify the exported sources, the recipe, the conandata.yml or any of the exported or the packaged artifacts, is undefined behavior. For example, it is not possible to modify the contents of a package inside the `package_info()` method or the `package_id()` method, those methods should never modify, delete or create new files inside the packages. If you need to modify some package, you might use your own custom `deployer`. - **Conan cache paths are internal implementation detail**: The Conan cache paths are an internal implementation detail. Conan recipes provide abstractions like `self.build_folder` to represent the necessary information about folders, and commands like `conan cache path` to get information of the current folders. The Conan cache might be checked while debugging, as read-only, but it is not allowed to edit, modify or delete artifacts or files from the Conan cache by any other means that Conan command line or public API. - **Sources used in recipes must be immutable**. Once a recipe is exported to the Conan cache, it is expected that the sources are immutable, that is, that retrieving the sources in the future will always retrieve the exact same sources. It is not allowed to use moving targets like a `git` branch or a download of a file that is continuously rewritten in the server. `git` checkouts must be of an immutable tag or a commit, and `download()/get()` must use checksums to verify the server files doesn’t change. Not using immutable sources will be undefined behavior. --- https://docs.conan.io/2/knowledge/videos.html.md --- # Videos #### WARNING This section presents some conference talks and presentations regarding Conan. While they can be very informative and educational, please note that some of them might be outdated. Always use the documentation and reference as the source of truth, not the videos. ## Using std::cpp 2026 ### “Using std::cpp 2026: Cross-Platform C++ AI Development with Conan, CMake, and CUDA” - Luis Caro > Every year, the ISO C++ survey delivers the same verdict: dependency management is the #1 pain > point for developers. For AI and machine learning development, introducing CUDA into the mix > can cause that “pain point” to become a bigger bottleneck when developers these days are > demanding “one-line, cross-platform” solutions. > Setting up a cross-platform AI development environment can involve a fragile “ritual” of manual > installs, environment variables, and platform-specific hacks. Moving from a Windows dev-box to > a Linux CI server or a Jetson Orin at the edge? That’s often a week of lost productivity, > especially for large teams that need to support multiple versions of CUDA on multiple platforms. > This talk demonstrates how to use Conan and CMake to model the CUDA compatibility matrix > directly in your code, achieving an ideal pipeline that works both on development machines, and > CI, regardless of your target platform: One source checkout. One command. Identical builds on > every platform. ## ACCU 2025 ### “Continuous Integration for Large Scale C/C++ Projects With Conan2” - Diego Rodriguez-Losada > There are two main paradigms to develop large scale C, C++ projects: using mono-repos and package-based development, both have different pros and cons. Using package managers such as Conan allows easy retrieval of dependencies, including binaries, avoiding continuous and expensive rebuilds from source. > While this works easily for third party dependencies, when dependencies are very stable, quick evolution in a large dependency graph when there are different developers working concurrently in different packages, can be more challenging. > With Conan 2’s new tools it is possible to implement an efficient Continuous Integration process for large scale projects, computing what packages need to be built, and in what specific order and parallelism. > The concept of “products pipeline” will be introduced as an scalable approach that allows to focus on the business value while allowing efficiency. The dependency graph build order for every different product can be computed, for every different configuration (platform, compiler, build_type, etc). This is done efficiently, taking into account the versioning scheme and the package types (header-only, static library, shared library, application) with a explicit novel model of the dependencies effect in the packages binaries. > Then all the different computed graph “build-orders” can be merged into a single one to avoid duplicated builds. The final graph merged “build-order” can be distributed efficiently to different build agents, as it also specifies which package builds can be done in parallel. For projects with concurrent changes, using lockfiles is very important in this stage to guarantee consistency and reproducibility of the dependencies. > Finally, the concept of stages in the CI process using multiple server repositories and copying of packages across those repositories will be presented. This process is known as package promotions and is a known best practice in DevOps for other technologies, and is critical to avoid disruptions to developers and production systems that the CI builds could introduce. > The talk will present both the theoretical foundations and a full real example with available source code to demonstrate the presented functionalities. ## Using std::cpp 2025 ### “An introduction to the Common Package Specification (CPS) for C and C++” - Diego Rodriguez-Losada > The Common Package Specification format is an effort to create a standard > description of binary packages to improve the reuse of C and C++ software > and the interoperability of different build systems and tools. > This talk briefly introduces the specification and its main concepts, > the project, and summarize the efforts of the team so far. > This specification already has some experimental support in different open > source tools, like CMake and Conan C++ package manager. This will be > demonstrated, showing how it can achieve such interoperability of build > systems. ### “Open source C++ packages vulnerabilities and tools” - Luis Caro Campos > The highest priority of the C++ language is security in the language > itself. But what happens after a security issue is identified in some > existing open source C or C++ library? > This talk gives an introduction of CVEs for C and C++ packages, report > the state of the art and introduce different tools in this domain. > It also presents the Software Build of Materials (SBOMs) concept, and > the main standards such as CycloneDX and SPDX. > The talk finish demonstrating some of these concepts with Conan C++ > package manager and the JFrog platform security tools. ## Using std::cpp 2024 ### “Unlock the power of Conan 2 - 15 new features you didn’t know about!” - Luis Caro & Diego Rodriguez-Losada > Conan 2.0 was released over a year ago with a large number of new features and improvements. Since its release, the team has continued to add improvements based on user feedback, releasing many more new features than in the previous years combined. >
> Join Diego and Luis from the Conan team for an overview of practical examples of what Conan 2 can do for your C and C++ package management development workflows. Some highlights include: transparent fall back to system-provided dependencies, managing metadata files, and the flexible and fully transparent CMake integrations, and more! >
## ACCU 2022 ### “Advanced Dependencies Model in Conan 2.0 C, C++ Package Manager” - Diego Rodriguez-Losada > Conan 2.0 introduces a new dependencies model with requirements “traits” like visibility, > definition and propagation of headers and libraries independently, and more that allow modeling all these advanced use cases. > This talk will present this new model, and apply it to solve different advanced use cases, with real life examples ## CppCon 2022 ### “What’s New in Conan 2.0 C/C++ Package Manager” - Diego Rodriguez-Losada > During the years since Conan 1.0 was released, we have continued to learn from the C++ ecosystem as we watched it grow; > learning many lessons, challenges and trends in the industry from the feedback from tens of thousands of conversations with users and customers, > including many of the largest C++ related companies in the world. This talk summarizes some of these lessons > and how they have been used to create the new major version of Conan. ## Meeting C++ 2023 ### “CMake and Conan: past, present and future” - Diego Rodriguez-Losada > This talk will quickly review the past approaches, their pitfalls, and how modern CMake and Conan integrations have improved over them: >
> From variables, to targets, to transparent targets integration with modern Conan generators >
> Better separation of concerns to align binary configurations using CMake toolchains >
> Improving the developer experience with CMake presets >
> The new CMake-Conan integration using CMake’s new dependency providers feature for transparent installation of dependencies >
## Using std::cpp 2021 ### “Why you shouldn’t write your own C++ package manager” - Luis Caro Campos > This talk will provide a quick overview of how Conan deals with intrinsic C++ complexities: >
> Headers vs binary symbols >
> Shared and static library >
> Symbol visibility >
> Binary compatibility: is there a one-size fits all approach to modeling it? >
> Build-time dependency resolution is only half the battle, what about runtime dependencies? >
## Meeting C++ online book & tool fair ### “Conan 2.0 demo” - Chris McArthur --- https://docs.conan.io/2/reference/binary_model.html.md --- # Binary model This section introduces first how the `package_id`, the package binaries identifier is computed, hashing the configuration (settings + options + dependencies versions). While the effect of `settings` and `options` is more straightforward, understanding the effects of the dependencies requires more explanations, so that will be done in its own section. Conan binary model is extensible, and users can define their custom settings, options and configuration to model their own binaries characteristics. Finally, the default binary compatibility model will be described, and how it can be customized to adapt to different needs. * [How the `package_id` is computed](https://docs.conan.io/2//reference/binary_model/package_id.html.md) * [How settings and options of a recipe influence its package ID](https://docs.conan.io/2//reference/binary_model/settings_and_options.html.md) * [The effect of dependencies on `package_id`](https://docs.conan.io/2//reference/binary_model/dependencies.html.md) * [Extending the binary model](https://docs.conan.io/2//reference/binary_model/extending.html.md) * [Customizing the binary compatibility](https://docs.conan.io/2//reference/binary_model/custom_compatibility.html.md) --- https://docs.conan.io/2/reference/commands.html.md --- # Commands This section describes the Conan built-in commands, like `conan install` or `conan search`. It is also possible to create user custom commands, visit [custom commands reference](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#reference-commands-custom-commands) and these [custom command examples](https://docs.conan.io/2//examples/extensions/commands/custom_commands.html.md#examples-extensions-custom-commands) **Consumer commands:** - [conan cache](https://docs.conan.io/2//reference/commands/cache.html.md): Return the path of recipes and packages in the cache - [conan config](https://docs.conan.io/2//reference/commands/config.html.md): Manage Conan configuration (remotes, settings, plugins, etc) - [conan graph](https://docs.conan.io/2//reference/commands/graph.html.md): Obtain information about the dependency graph without fetching binaries - [conan inspect](https://docs.conan.io/2//reference/commands/inspect.html.md): Inspect a conanfile.py to return the public fields - [conan install](https://docs.conan.io/2//reference/commands/install.html.md): Install dependencies - [conan list](https://docs.conan.io/2//reference/commands/list.html.md): List recipes, revisions and packages in the local cache or in remotes - [conan lock](https://docs.conan.io/2//reference/commands/lock.html.md): Create and manage lockfiles - [conan pkglist](https://docs.conan.io/2//reference/commands/pkglist.html.md): Manipulate package lists, merge them or find packages in remotes. - [conan profile](https://docs.conan.io/2//reference/commands/profile.html.md): Display and manage profile files - [conan remove](https://docs.conan.io/2//reference/commands/remove.html.md): Remove packages from the local cache or from remotes - [conan remote](https://docs.conan.io/2//reference/commands/remote.html.md): Add, remove, login/logout and manage remote server - [conan search](https://docs.conan.io/2//reference/commands/search.html.md): Search packages matching a name - [conan version](https://docs.conan.io/2//reference/commands/version.html.md): Give information about the Conan client version - [conan workspace](https://docs.conan.io/2//reference/commands/workspace.html.md): Manage Conan workspaces - [conan run](https://docs.conan.io/2//reference/commands/run.html.md): Execute binaries with automatic environment activation - [conan require](https://docs.conan.io/2//reference/commands/require.html.md): Adds/removes requirements to/from your local conanfile **Creator commands:** - [conan build](https://docs.conan.io/2//reference/commands/build.html.md): Install package and call its build method - [conan create](https://docs.conan.io/2//reference/commands/create.html.md): Create a package from a recipe - [conan download](https://docs.conan.io/2//reference/commands/download.html.md): Download (without install) a single conan package from a remote server. - [conan editable](https://docs.conan.io/2//reference/commands/editable.html.md): Allows working with a package in user folder - [conan export](https://docs.conan.io/2//reference/commands/export.html.md): Export a recipe to the Conan package cache - [conan export-pkg](https://docs.conan.io/2//reference/commands/export-pkg.html.md): Create a package directly from pre-compiled binaries - [conan new](https://docs.conan.io/2//reference/commands/new.html.md): Create a new recipe from a predefined template - [conan source](https://docs.conan.io/2//reference/commands/source.html.md): Calls the source() method - [conan test](https://docs.conan.io/2//reference/commands/test.html.md): Test a package - [conan upload](https://docs.conan.io/2//reference/commands/upload.html.md): Upload packages from the local cache to a specified remote **Security Commands** - [conan audit](https://docs.conan.io/2//reference/commands/audit.html.md): Checks for vulnerabilities in your Conan packages. - [conan report](https://docs.conan.io/2//reference/commands/report.html.md): Get information about the packages **Commands Output to stdout and stderr** Conan commands output information following a deliberate design choice that aligns with common practices in many CLI tools and the [POSIX standard](https://pubs.opengroup.org/onlinepubs/9699919799/functions/stderr.html): - `stdout`: For final command results (e.g., JSON, HTML). - `stderr`: For diagnostic output, including logs, warnings, errors, and progress messages. More info can be found more in the [FAQ section](https://docs.conan.io/2//knowledge/faq.html.md#faq-stdout-stderr-redirects). **Redirecting Output to Files** You can redirect Conan output to files using shell redirection: ```bash $ conan install . --format=json > output.json ``` Alternatively, use the `--out-file` argument (available since Conan 2.12.0) to specify an output file directly: ```bash $ conan install . --format=json --out-file=output.json ``` ## Command formatters Almost all the commands have the parameter `--format xxxx` which is used to apply an output conversion. The command formatters help users see the command output in a different way that could fit better with their needs. Here, there are only some of the most important ones whose details are worthy of having a separate section. - [graph-info formatter](https://docs.conan.io/2//reference/commands/formatters/graph_info_json_formatter.html.md): Show the graph information in JSON format. It’s used by several commands. --- https://docs.conan.io/2/reference/conan_server.html.md --- # Conan Server #### IMPORTANT This server is mainly used for testing (though it might work fine for small teams). We recommend using the free [Artifactory Community Edition for C/C++](https://docs.conan.io/2//tutorial/conan_repositories/setting_up_conan_remotes/artifactory/artifactory_ce_cpp.html.md#artifactory-ce-cpp) for private development or **Artifactory Pro** as Enterprise solution. ## Configuration By default your server configuration is saved under `~/.conan_server/server.conf`, however you can modify this behaviour by either setting the `CONAN_SERVER_HOME` environment variable or launching the server with `-d` or `--server_dir` command line argument followed by desired path. In case you use one of the options your configuration file will be stored under `server_directory/server.conf` Please note that command line argument will override the environment variable. You can change configuration values in `server.conf`, prior to launching the server. Note that the server does not support hot-reload, and thus in order to see configuration changes you will have to manually relaunch the server. The server configuration file is by default: ```ini [server] jwt_secret: IJKhyoioUINMXCRTytrR jwt_expire_minutes: 120 ssl_enabled: False port: 9300 public_port: host_name: localhost authorize_timeout: 1800 disk_storage_path: ./data disk_authorize_timeout: 1800 updown_secret: HJhjujkjkjkJKLUYyuuyHJ [write_permissions] # "opencv/2.3.4@lasote/testing": default_user,default_user2 [read_permissions] */*@*/*: * [users] demo: demo ``` ### Server Parameters #### NOTE The Conan server supports relative URLs, allowing you to avoid setting `host_name`, `public_port` and `ssl_enabled`. The URLs used to upload/download packages will be automatically generated in the client following the URL of the remote. This allows accessing the Conan server from different networks. * `port`: Port where **conan_server** will run. * The client server authorization is done with JWT. `jwt_secret` is a random string used to generate authentication tokens. You can change it safely anytime (in fact it is a good practice). The change will just force users to log in again. `jwt_expire_minutes` is the amount of time that users remain logged-in within the client without having to introduce their credentials again. * `host_name`: If you set `host_name`, you must use the machine’s IP where you are running your server (or domain name), something like **host_name: 192.168.1.100**. This IP (or domain name) has to be visible (and resolved) by the Conan client, so take it into account if your server has multiple network interfaces. * `public_port`: Might be needed when running virtualized, Docker or any other kind of port redirection. File uploads/downloads are served with their own URLs, generated by the system, so the file storage backend is independent. Those URLs need the public port they have to communicate from the outside. If you leave it blank, the `port` value is used. **Example:** Use conan_server in a Docker container that internally runs in the 9300 port but exposes the 9999 port (where the clients will connect to): > ```bash > docker run ... -p9999:9300 ... # Check Docker docs for that > ``` > **server.conf** > ```text > [server] > ssl_enabled: False > port: 9300 > public_port: 9999 > host_name: localhost > ``` * `ssl_enabled` Conan doesn’t handle the SSL traffic by itself, but you can use a proxy like [Nginx to redirect the SSL traffic to your Conan server](#reference-conan-server-nginx). If your Conan clients are connecting with “https”, set ssl_enabled to True. This way the conan_server will generate the upload/download urls with “https” instead of “http”. #### NOTE **Important**: The Conan client, by default, will validate the server SSL certificates and won’t connect if it’s invalid. If you have self signed certificates you have two options: 1. Use the **conan remote** command to disable the SSL certificate checks. E.g., *conan remote add/update myremote https://somedir False* 2. If using the *core.net.http:cacert_path* configuration in the Conan client, append the server *.crt* file contents to the *cacert.pem* location. The folder in which the uploaded packages are stored (i.e., the folder you would want to backup) is defined in the `disk_storage_path`. The storage backend might use a different channel, and uploads/downloads are authorized up to a maximum of `authorize_timeout` seconds. The value should sufficient so that large downloads/uploads are not rejected, but not too big to prevent hanging up the file transfers. The value `disk_authorize_timeout` is not currently used. File transfers are authorized with their own tokens, generated with the secret `updown_secret`. This value should be different from the above `jwt_secret`. ### Permissions Parameters By default, the server configuration when set to Read can be done anonymous, but uploading requires you to be registered users. Users can easily be registered in the `[users]` section, by defining a pair of `login: password` for each one. Plain text passwords are used at the moment, but as the server is on-premises (behind firewall), you just need to trust your sysadmin :) If you want to restrict read/write access to specific packages, configure the `[read_permissions]` and `[write_permissions]` sections. These sections specify the sequence of patterns and authorized users, in the form: ```text # use a comma-separated, no-spaces list of users package/version@user/channel: allowed_user1,allowed_user2 ``` E.g.: ```text */*@*/*: * # allow all users to all packages PackageA/*@*/*: john,peter # allow john and peter access to any PackageA */*@project/*: john # Allow john to access any package from the "project" user ``` The rules are evaluated in order. If the left side of the pattern matches, the rule is applied and it will not continue searching for matches. ### Authentication By default, Conan provides a simple `user: password` users list in the `server.conf` file. There is also a plugin mechanism for setting other authentication methods. The process to install any of them is a simple two-step process: 1. Copy the authenticator source file into the `.conan_server/plugins/authenticator` folder. 2. Add `custom_authenticator: authenticator_name` to the `server.conf` [server] section. This is a list of available authenticators, visit their URLs to retrieve them, but also to report issues and collaborate: - **htpasswd**: Use your server Apache htpasswd file to authenticate users. Get it: [https://github.com/d-schiffner/conan-htpasswd](https://github.com/d-schiffner/conan-htpasswd) - **LDAP**: Use your LDAP server to authenticate users. Get it: [https://github.com/uilianries/conan-ldap-authentication](https://github.com/uilianries/conan-ldap-authentication) #### Create Your Own Custom Authenticator If you want to create your own Authenticator, create a Python module in `~/.conan_server/plugins/authenticator/my_authenticator.py` **Example:** ```python def get_class(): return MyAuthenticator() class MyAuthenticator(object): def valid_user(self, username, plain_password): return username == "foo" and plain_password == "bar" ``` The module has to implement: - A factory function `get_class()` that returns a class with a `valid_user()` method instance. - The class containing the `valid_user()` that has to return True if the user and password are valid or False otherwise. ### Authorizations By default, Conan uses the contents of the `[read_permissions]` and `[write_permissions]` sections to authorize or reject a request. A plugin system is also available to customize the authorization mechanism. The installation of such a plugin is a simple two-step process: 1. Copy the authorizer’s source file into the `.conan_server/plugins/authorizer` folder. 2. Add `custom_authorizer: authorizer_name` to the `server.conf` [server] section. #### Create Your Own Custom Authorizer If you want to create your own Authorizer, create a Python module in `~/.conan_server/plugins/authorizer/my_authorizer.py` **Example:** ```python from conan.internal.errors import AuthenticationException, ForbiddenException def get_class(): return MyAuthorizer() class MyAuthorizer(object): def _check_conan(self, username, ref): if ref.user == username: return if username: raise ForbiddenException("Permission denied") else: raise AuthenticationException() def _check_package(self, username, pref): self._check(username, pref.ref) check_read_conan = _check_conan check_write_conan = _check_conan check_delete_conan = _check_conan check_read_package = _check_package check_write_package = _check_package check_delete_package = _check_package ``` The module has to implement: - A factory function `get_class()` that returns an instance of a class conforming to the Authorizer’s interface. - A class that implements all the methods defined in the Authorizer interface: : - `check_read_conan()` is used to decide whether to allow read access to a recipe. - `check_write_conan()` is used to decide whether to allow write access to a recipe. - `check_delete_conan()` is used to decide whether to allow a recipe’s deletion. - `check_read_package()` is used to decide whether to allow read access to a package. - `check_write_package()` is used to decide whether to allow write access to a package. - `check_delete_package()` is used to decide whether to allow a package’s deletion. The `check_*_conan()` methods are called with a username and `conans.model.ref.ConanFileReference` instance as their arguments. Meanwhile the `check_*_package()` methods are passed a username and `conans.model.ref.PackageReference` instance as their arguments. These methods should raise an exception, unless the user is allowed to perform the requested action. ## Running the Conan Server with SSL using Nginx > **server.conf** > ```text > [server] port: 9300 > ``` > **nginx conf file** > ```text > server { > listen 443; server_name myservername.mydomain.com; > location / { > proxy_pass http://0.0.0.0:9300; > } ssl on; ssl_certificate /etc/nginx/ssl/server.crt; ssl_certificate_key > /etc/nginx/ssl/server.key; > } > ``` > **remote configuration in Conan client** > ```text > $ conan remote add myremote https://myservername.mydomain.com > ``` ## Running the Conan Server with SSL using Nginx in a Subdirectory > **server.conf** > ```text > [server] port: 9300 > ``` > **nginx conf file** > ```text > server { > listen 443; ssl on; ssl_certificate /usr/local/etc/nginx/ssl/server.crt; > ssl_certificate_key /usr/local/etc/nginx/ssl/server.key; server_name > myservername.mydomain.com; > location /subdir/ { > proxy_pass http://0.0.0.0:9300/; > } > } > ``` > **remote configuration in Conan client** > ```text > $ conan remote add myremote https://myservername.mydomain.com/subdir/ > ``` ## Running Conan Server using Apache > You need to install `mod_wsgi`. If you want to use Conan installed from `pip`, the > conf file should be similar to the following example: > **Apache conf file** (e.g., /etc/apache2/sites-available/0_conan.conf) > ```text > > WSGIScriptAlias / > /usr/local/lib/python3.6/dist-packages/conans/server/server_launcher.py > WSGICallableObject app WSGIPassAuthorization On > > Require all granted > > > ``` > If you want to use Conan checked out from source in, for example in /srv/conan, the > conf file should be as follows: > **Apache conf file** (e.g., /etc/apache2/sites-available/0_conan.conf) > ```text > > WSGIScriptAlias / /srv/conan/conans/server/server_launcher.py > WSGICallableObject app WSGIPassAuthorization On > > Require all granted > > > ``` > The directive `WSGIPassAuthorization On` is needed to pass the HTTP basic > authentication to Conan. > Also take into account that the server config files are located in the home of the > configured Apache user, e.g., var/www/.conan_server, so remember to use that directory > to configure your Conan server. #### SEE ALSO * [Setting-up a Conan Server](https://docs.conan.io/2//tutorial/conan_repositories/setting_up_conan_remotes/conan_server.html.md#conan-server) --- https://docs.conan.io/2/reference/conanfile.html.md --- # conanfile.py The `conanfile.py` is the recipe file of a package, responsible for defining how to build it and consume it. > ```python > from conan import ConanFile > class HelloConan(ConanFile): > ... > ``` #### IMPORTANT *conanfile.py* recipes use a variety of attributes and methods to operate. In order to avoid collisions and conflicts, follow these rules: - Public attributes and methods, like `build()`, `self.package_folder`, are reserved for Conan. Don’t use public members for custom fields or methods in the recipes. - Use “protected” access for your own members, like `self._my_data` or `def _my_helper(self):`. Conan only reserves “protected” members starting with `_conan`. Contents: * [Attributes](https://docs.conan.io/2//reference/conanfile/attributes.html.md) * [Package reference](https://docs.conan.io/2//reference/conanfile/attributes.html.md#package-reference) * [Metadata](https://docs.conan.io/2//reference/conanfile/attributes.html.md#metadata) * [Requirements](https://docs.conan.io/2//reference/conanfile/attributes.html.md#requirements) * [Sources](https://docs.conan.io/2//reference/conanfile/attributes.html.md#sources) * [Binary model](https://docs.conan.io/2//reference/conanfile/attributes.html.md#binary-model) * [Build](https://docs.conan.io/2//reference/conanfile/attributes.html.md#build) * [Folders and layout](https://docs.conan.io/2//reference/conanfile/attributes.html.md#folders-and-layout) * [Layout](https://docs.conan.io/2//reference/conanfile/attributes.html.md#layout) * [Package information for consumers](https://docs.conan.io/2//reference/conanfile/attributes.html.md#package-information-for-consumers) * [Other](https://docs.conan.io/2//reference/conanfile/attributes.html.md#other) * [Methods](https://docs.conan.io/2//reference/conanfile/methods.html.md) * [Running and output](https://docs.conan.io/2//reference/conanfile/running_and_output.html.md) * [Output text from recipes](https://docs.conan.io/2//reference/conanfile/running_and_output.html.md#output-text-from-recipes) * [Running commands](https://docs.conan.io/2//reference/conanfile/running_and_output.html.md#running-commands) --- https://docs.conan.io/2/reference/conanfile_txt.html.md --- # conanfile.txt The `conanfile.txt` file is a simplified version of `conanfile.py`, aimed at simple consumption of dependencies, but it cannot be used to create a package. Also, it is not necessary to have a `conanfile.txt` for consuming dependencies, a `conanfile.py` is perfectly suited for simple consumption of dependencies. It also provides a simplified functionality, for example it is not possible to express conditional requirements in `conanfile.txt`, and it will be necessary to use a `conanfile.py` for that. Read [Understanding the flexibility of using conanfile.py vs conanfile.txt](https://docs.conan.io/2//tutorial/consuming_packages/the_flexibility_of_conanfile_py.html.md#consuming-packages-flexibility-of-conanfile-py) for more information about this. ## [requires] List of requirements, specifying the full reference. Equivalent to `self.requires()` in `conanfile.py`. ```text [requires] poco/1.9.4 zlib/1.3.1 ``` This section supports references with version-ranges too: ```text [requires] poco/[>1.0 <1.9] zlib/1.3.1 ``` And specific recipe revisions can be pinned too: ```text [requires] zlib/1.2.13#revision1 boost/1.70.0#revision2 ``` #### NOTE Note that pinning a revision when using version ranges has not effect and Conan will warn about it. ## [tool_requires] List of tool requirements (executable tools) specifying the full reference. Equivalent to `self.tool_requires()` in `conanfile.py`. ```text [tool_requires] 7zip/16.00 cmake/3.23.0 ``` This section also supports version ranges and pinned recipe revisions, as above. In practice the `[tool_requires]` will be always installed (same as `[requires]`) as installing from a *conanfile.txt* means that something is going to be built, so the tool requirements are indeed needed. Note however, that by default `tool_requires` live in the “build” context, they cannot be libraries to built with, just executable tools, and for example, using the `CMakeDeps` generator, they will not create CMake config files for them (an exception is possible, but it requires using a `conanfile.py`, read the [CMakeDeps reference](https://docs.conan.io/2//reference/tools/cmake/cmakedeps.html.md#conan-tools-cmakedeps) for more information). ## [test_requires] List of test requirements specifying the full reference. Equivalent to `self.test_requires()` in `conanfile.py`. ```text [test_requires] gtest/1.12.1 ``` This section also supports version ranges and pinned recipe revisions, as above. The behavior of `test_requires` is totally equivalent to the `[requires]` section above, as the only difference is that `test_requires` are not propagated to consumers, but as a `conanfile.txt` is never creating a package that can be consumed, it is irrelevant. It is provided to maintain the equivalence with `conanfile.py` ## [generators] List of built-in generators to be used, equivalent to the `conanfile.py` `generators = "CMakeDeps", ...` attribute. ```text [requires] poco/1.9.4 zlib/1.2.13 [generators] CMakeDeps CMakeToolchain ``` ## [options] List of options scoped for each package with a pattern like **package_name\*:option = Value**. ```text [requires] poco/1.9.4 zlib/1.3.1 [generators] CMakeDeps CMakeToolchain [options] poco/*:shared=True openssl/*:shared=True ``` For example using `*:shared=True` will define `shared=True` for all packages in the dependency graph that have this option defined. #### WARNING Defining options values in conanfile.txt does not have strong guarantees, please check [this FAQ about options values for dependencies](https://docs.conan.io/2//knowledge/faq.html.md#faq-different-options-values). The recommended way to define options values is in **profile files**. ## [layout] You can specify one name of a predefined layout. The available values are: - cmake_layout - vs_layout - bazel_layout (experimental) ```text [layout] cmake_layout ``` #### SEE ALSO Read [Understanding the flexibility of using conanfile.py vs conanfile.txt](https://docs.conan.io/2//tutorial/consuming_packages/the_flexibility_of_conanfile_py.html.md#consuming-packages-flexibility-of-conanfile-py) for more information about conanfile.txt vs conanfile.py. --- https://docs.conan.io/2/reference/config_files.html.md --- # Configuration files These are the most important configuration files, used to customize conan. * [global.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md) * [Introduction to configuration](https://docs.conan.io/2//reference/config_files/global_conf.html.md#introduction-to-configuration) * [User/Tools configurations](https://docs.conan.io/2//reference/config_files/global_conf.html.md#user-tools-configurations) * [Configuration file template](https://docs.conan.io/2//reference/config_files/global_conf.html.md#configuration-file-template) * [Configuration data types](https://docs.conan.io/2//reference/config_files/global_conf.html.md#configuration-data-types) * [Configuration data operators](https://docs.conan.io/2//reference/config_files/global_conf.html.md#configuration-data-operators) * [Configuration patterns](https://docs.conan.io/2//reference/config_files/global_conf.html.md#configuration-patterns) * [global_user.conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#global-user-conf) * [Configuration precedence](https://docs.conan.io/2//reference/config_files/global_conf.html.md#configuration-precedence) * [Important configurations with `!` specifier](https://docs.conan.io/2//reference/config_files/global_conf.html.md#important-configurations-with-specifier) * [Information about built-in confs](https://docs.conan.io/2//reference/config_files/global_conf.html.md#information-about-built-in-confs) * [Policies](https://docs.conan.io/2//reference/config_files/global_conf.html.md#policies) * [Networking confs](https://docs.conan.io/2//reference/config_files/global_conf.html.md#networking-confs) * [MSYS2 subsystem environments](https://docs.conan.io/2//reference/config_files/global_conf.html.md#msys2-subsystem-environments) * [Storage configurations](https://docs.conan.io/2//reference/config_files/global_conf.html.md#storage-configurations) * [UX confs](https://docs.conan.io/2//reference/config_files/global_conf.html.md#ux-confs) * [profiles](https://docs.conan.io/2//reference/config_files/profiles.html.md) * [Introduction to profiles](https://docs.conan.io/2//reference/config_files/profiles.html.md#introduction-to-profiles) * [Using profiles](https://docs.conan.io/2//reference/config_files/profiles.html.md#using-profiles) * [Profile sections](https://docs.conan.io/2//reference/config_files/profiles.html.md#profile-sections) * [Profile rendering](https://docs.conan.io/2//reference/config_files/profiles.html.md#profile-rendering) * [Profile patterns](https://docs.conan.io/2//reference/config_files/profiles.html.md#profile-patterns) * [Profile includes](https://docs.conan.io/2//reference/config_files/profiles.html.md#profile-includes) * [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md) * [Operating systems](https://docs.conan.io/2//reference/config_files/settings.html.md#operating-systems) * [Compilers](https://docs.conan.io/2//reference/config_files/settings.html.md#compilers) * [Architectures](https://docs.conan.io/2//reference/config_files/settings.html.md#architectures) * [C++ standard libraries (aka compiler.libcxx)](https://docs.conan.io/2//reference/config_files/settings.html.md#c-standard-libraries-aka-compiler-libcxx) * [Customizing settings](https://docs.conan.io/2//reference/config_files/settings.html.md#customizing-settings) * [settings_user.yml](https://docs.conan.io/2//reference/config_files/settings.html.md#settings-user-yml) * [remotes.json](https://docs.conan.io/2//reference/config_files/remotes.html.md) * [source_credentials.json](https://docs.conan.io/2//reference/config_files/source_credentials.html.md) * [credentials.json](https://docs.conan.io/2//reference/config_files/credentials.html.md) * [.conanrc](https://docs.conan.io/2//reference/config_files/conanrc.html.md) --- https://docs.conan.io/2/reference/environment.html.md --- # Environment variables These are very few environment variables that can be used to configure some of the Conan behavior. These variables are the exception, for customization and configuration control, Conan uses the [global.conf configuration](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf) and the [profile [conf] section](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles) ## CONAN_HOME This variable controls the location of the Conan home folder. By default, if it is not defined, it will be `/.conan2`. #### NOTE Recall that the Conan package cache, contained in the Conan home, is not concurrent. Different parallel tasks like those that can happen in CI, need to use a separate cache, and defining `CONAN_HOME` is the way to do it. ## CONAN_DEFAULT_PROFILE, CONAN_DEFAULT_BUILD_PROFILE The default profile will be the `"default"` file in the Conan cache. These environment variables allow to define a different default for the host and build profiles respectively. There are also equivalent `conf` items `core:default_profile` and `core:default_build_profile` to define such default profile names. In general, env-vars should be used only when the `conf` is not enough. ## Remote login variables `CONAN_LOGIN_USERNAME`, `CONAN_LOGIN_USERNAME_{REMOTE_NAME}` define the login username for a given remote. `CONAN_PASSWORD`, `CONAN_PASSWORD_{REMOTE_NAME}` define the login password for a given remote. These environment variables are just a substitute of the interactive input of the username or password when Conan CLI requests it. They do not perform any kind of authentication unless the remote server throws an authentication challenge. That means that for some remote servers configured to allow anonymous usage, these will not be used, and the user will remain as an unauthenticated user, unless a `conan remote login` or `conan remote auth` is done first. When the Conan CLI is about to ask the user for the remote password, it will check the variable `CONAN_LOGIN_USERNAME_{REMOTE_NAME}` or `CONAN_PASSWORD_{REMOTE_NAME}` first, if the variable is not declared Conan will try to use the variable `CONAN_LOGIN_USERNAME` and `CONAN_PASSWORD` respectively, if the variable is not declared either, Conan will request to the user to input a password or fail. The remote name is transformed to all uppercase. If the remote name contains “-“, you have to replace it with “_” in the variable name. #### NOTE - These variables are useful for unattended executions like CI servers or automated tasks, as CI secrets - These variables are not recommended for developer machines. - Recall that these variables do not perform authentication unless the remote server requests it. - The `core:non_interactive` conf can be defined in `global.conf` to force Conan to fail if any interactive prompt is requested, to avoid CI process being stuck. ## Terminal color variables Conan default behavior is try to autodetect the output. If the output is redirected to a file, or other support not `tty`, that cannot print colors, it will disable colored output. For regular terminals, it will try to do colored output, unless some of the following change that behavior: - `CLICOLOR_FORCE` Forces the generation of terminal color escape characters, no matter what the autodetection of terminal is. - `NO_COLOR` disables the generation of color escape characters. This will be ignored if `CLICOLOR_FORCE` is activated. - `CONAN_COLOR_DARK` will revert the color scheme for white/light background terminals (default assumes dark background). ## Logging The environment variable `CONAN_LOG_LEVEL` can define the Conan command line verbosity in the same way that the `-v` command line argument, with the same values (`error`, `verbose`, etc.). It also has priority over the value of the command line arg if both are present. This can be useful to temporarily change the log level in CI pipelines, in automation, etc., without needing to modify the command line arguments. --- https://docs.conan.io/2/reference/extensions.html.md --- # Extensions Conan can be extended in a few ways, with custom user code: - `python_requires` allow to put common recipe code in a recipe package that can be reused by other recipes by declaring a `python_requires = "mypythoncode/version"` - You can create your own custom Conan commands to solve self-needs thanks to Python and Conan public API powers altogether. - It’s also possible to make your own custom Conan generators in case you are using build systems that are not supported by the built-in Conan tools. Those can be used from `python_requires` or installed globally. - `hooks` are “pre” and “post” recipe methods (like `pre_build()` and `post_build()`) extensions that can be used to complement recipes with orthogonal functionality, like quality checks, binary analyzing, logging, etc. - Binary compatibility `compatibility.py` extension allows to write custom rules for defining custom binary compatibility across different settings and options - The `cmd_wrapper.py` extension allows to inject arbitrary command wrappers to any `self.run()` recipe command invocation, which can be useful to inject wrappers as parallelization tools - The package signing extension allows to sign and verify packages at upload and install time respectively - Deployers, a mechanism to facilitate copying files from one folder, usually the Conan cache, to user folders #### NOTE Besides the built-in Conan extensions listed in this document, there is a repository that contains extensions for Conan, such as custom commands and deployers, useful for different purposes like artifactory tasks, Conan Center Index, etc. You can find more information on how to use those extensions in [the GitHub repository](https://github.com/conan-io/conan-extensions). Contents: * [Python requires](https://docs.conan.io/2//reference/extensions/python_requires.html.md) * [Introduction](https://docs.conan.io/2//reference/extensions/python_requires.html.md#introduction) * [Extending base classes](https://docs.conan.io/2//reference/extensions/python_requires.html.md#extending-base-classes) * [Reusing files](https://docs.conan.io/2//reference/extensions/python_requires.html.md#reusing-files) * [Testing python-requires](https://docs.conan.io/2//reference/extensions/python_requires.html.md#testing-python-requires) * [Effect in package_id](https://docs.conan.io/2//reference/extensions/python_requires.html.md#effect-in-package-id) * [Resolution of python_requires](https://docs.conan.io/2//reference/extensions/python_requires.html.md#resolution-of-python-requires) * [Custom commands](https://docs.conan.io/2//reference/extensions/custom_commands.html.md) * [Location and naming](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#location-and-naming) * [Decorators](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#decorators) * [Argument definition and parsing](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#argument-definition-and-parsing) * [Formatters](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#formatters) * [Commands parameters](https://docs.conan.io/2//reference/extensions/custom_commands.html.md#commands-parameters) * [Custom Conan generators](https://docs.conan.io/2//reference/extensions/custom_generators.html.md) * [Custom generators as python_requires](https://docs.conan.io/2//reference/extensions/custom_generators.html.md#custom-generators-as-python-requires) * [Using global custom generators](https://docs.conan.io/2//reference/extensions/custom_generators.html.md#using-global-custom-generators) * [Generators from tool_requires](https://docs.conan.io/2//reference/extensions/custom_generators.html.md#generators-from-tool-requires) * [Python API](https://docs.conan.io/2//reference/extensions/python_api.html.md) * [Conan API Reference](https://docs.conan.io/2//reference/extensions/python_api/ConanAPI.html.md) * [Audit API](https://docs.conan.io/2//reference/extensions/python_api/AuditAPI.html.md) * [Cache API](https://docs.conan.io/2//reference/extensions/python_api/CacheAPI.html.md) * [Command API](https://docs.conan.io/2//reference/extensions/python_api/CommandAPI.html.md) * [Config API](https://docs.conan.io/2//reference/extensions/python_api/ConfigAPI.html.md) * [Download API](https://docs.conan.io/2//reference/extensions/python_api/DownloadAPI.html.md) * [Export API](https://docs.conan.io/2//reference/extensions/python_api/ExportAPI.html.md) * [Graph API](https://docs.conan.io/2//reference/extensions/python_api/GraphAPI.html.md) * [Install API](https://docs.conan.io/2//reference/extensions/python_api/InstallAPI.html.md) * [List API](https://docs.conan.io/2//reference/extensions/python_api/ListAPI.html.md) * [Local API](https://docs.conan.io/2//reference/extensions/python_api/LocalAPI.html.md) * [Lockfile API](https://docs.conan.io/2//reference/extensions/python_api/LockfileAPI.html.md) * [New API](https://docs.conan.io/2//reference/extensions/python_api/NewAPI.html.md) * [Profiles API](https://docs.conan.io/2//reference/extensions/python_api/ProfilesAPI.html.md) * [Remotes API](https://docs.conan.io/2//reference/extensions/python_api/RemotesAPI.html.md) * [Remove API](https://docs.conan.io/2//reference/extensions/python_api/RemoveAPI.html.md) * [Report API](https://docs.conan.io/2//reference/extensions/python_api/ReportAPI.html.md) * [Upload API](https://docs.conan.io/2//reference/extensions/python_api/UploadAPI.html.md) * [Models](https://docs.conan.io/2//reference/extensions/python_api/model.html.md) * [Deployers](https://docs.conan.io/2//reference/extensions/deployers.html.md) * [Built-in deployers](https://docs.conan.io/2//reference/extensions/deployers.html.md#built-in-deployers) * [Custom deployers](https://docs.conan.io/2//reference/extensions/deployers.html.md#custom-deployers) * [Hooks](https://docs.conan.io/2//reference/extensions/hooks.html.md) * [Hook structure](https://docs.conan.io/2//reference/extensions/hooks.html.md#hook-structure) * [Importing from a module](https://docs.conan.io/2//reference/extensions/hooks.html.md#importing-from-a-module) * [Hook interface](https://docs.conan.io/2//reference/extensions/hooks.html.md#hook-interface) * [Storage, activation and sharing](https://docs.conan.io/2//reference/extensions/hooks.html.md#storage-activation-and-sharing) * [Official Hooks](https://docs.conan.io/2//reference/extensions/hooks.html.md#official-hooks) * [Binary compatibility](https://docs.conan.io/2//reference/extensions/binary_compatibility.html.md) * [Profile plugin](https://docs.conan.io/2//reference/extensions/profile_plugin.html.md) * [Authorization plugins](https://docs.conan.io/2//reference/extensions/authorization_plugins.html.md) * [Auth remote plugin](https://docs.conan.io/2//reference/extensions/authorization_plugins.html.md#auth-remote-plugin) * [Auth source plugin](https://docs.conan.io/2//reference/extensions/authorization_plugins.html.md#auth-source-plugin) * [Command wrapper](https://docs.conan.io/2//reference/extensions/command_wrapper.html.md) * [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md) * [Configuration](https://docs.conan.io/2//reference/extensions/package_signing.html.md#configuration) * [Implementation](https://docs.conan.io/2//reference/extensions/package_signing.html.md#implementation) * [Commands](https://docs.conan.io/2//reference/extensions/package_signing.html.md#commands) * [Plugin implementation examples](https://docs.conan.io/2//reference/extensions/package_signing.html.md#plugin-implementation-examples) * [Compiler flags mapper plugin](https://docs.conan.io/2//reference/extensions/compiler_flags_plugin.html.md) --- https://docs.conan.io/2/reference/policies.html.md --- # Policies Policies are a set of rules to enforce certain behaviors from Conan. Policies are handled by the `core:policies` configuration in your `global.conf`, which is a list of strings, where each string is the name of a policy to be enabled. ```default core:policies = ["required_conan_version>=2.28"] ``` ## List of current policies ### required_conan_version>=version *Introduced in Conan 2.28* This policy is unique, as the version specified in the policy is used to enable different behaviors based on the version. This allows to opt-in to bugfixes that can be considered breaking changes, without having to wait for a new Conan release to include them by default. The same behaviours are also enabled recipe-wise when the `required_conan_version` attribute is defined in the recipe, such that the policy can be enabled for specific recipes, without having to enable it globally. If both the policy and the recipe attribute are defined, the behavior will be enabled if either of them matches the required version range. * If using `required_conan_version>=2.28` or later, the following bugfixes will be enabled: : * Bugfix [https://github.com/conan-io/conan/pull/19705](https://github.com/conan-io/conan/pull/19705): : * The computation of `package_id` for static libraries and non-embed mode was taking into account transitive (non-direct) dependencies, even if they were not being embedded and not contributing headers at all. See the docs for the [effect of dependencies in the package_id](https://docs.conan.io/2//reference/binary_model/dependencies.html.md#reference-binary-model-dependencies). * Bugfix [https://github.com/conan-io/conan/pull/19849](https://github.com/conan-io/conan/pull/19849): : * The `VirtualBuildEnv` generator used to include the `bindir` paths of tool requires regardless of their `run` trait in the generated environment. With the bugfix enabled, only tool requires with the `run` trait set to `True` will have their `bindir` paths propagated. * Behaviour change [https://github.com/conan-io/conan/pull/19286](https://github.com/conan-io/conan/pull/19286): : * For the new `consistent` trait, its default value currently keeps the old graph expansion behaviour, which had some inconsistencies regarding the handling of private dependencies. With the new behaviour enabled, the graph expansion is more consistent and private dependencies are handled in a more intuitive way, but some graphs can be expanded differently. For a detailed explanation of the changes, see [the trait documentation section](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-methods-requirements-consistent). * If using `required_conan_version>=2.30` or later, the following bugfixes will be enabled: : * Bugfix [https://github.com/conan-io/conan/pull/20073](https://github.com/conan-io/conan/pull/20073): : * The `transitive_headers` trait propagation of some diamond structures was not working correctly and unexpected headers were being propagated to consumers. With the bugfix enabled, the propagation of transitive headers is fixed and works as expected in all cases, but the consumer package_id can change if it was previously affected by this bug. #### NOTE This policy is independent of the `core:required_conan_version` conf, which is exclusively used to define the minimum required Conan version. --- https://docs.conan.io/2/reference/runners.html.md --- # Runners #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. Runners provide a seamless method to execute Conan on remote build environments like Docker ones, directly from your local setup by simply configuring your host profile. - Installing a version of Conan with runner dependencies `pip install conan[runners]`. - Install the tools to run each of the runners (`docker`). - Add the `[runner]` section defined in the documentation of each runner to the host profile. Runners: * [Docker runner](https://docs.conan.io/2//reference/runners/docker.html.md) --- https://docs.conan.io/2/reference/tools.html.md --- # Recipe tools Tools are all things that can be imported and used in Conan recipes. The import path is always like: ```python from conan.tools.cmake import CMakeToolchain, CMakeDeps, CMake from conan.tools.microsoft import MSBuildToolchain, MSBuildDeps, MSBuild ``` The main guidelines are: - Everything that recipes can import belong to `from conan.tools`. Any other thing is private implementation and shouldn’t be used in recipes. - Only documented, public (not preceded by `_`) tools can be used in recipes. Contents: * [conan.tools.android](https://docs.conan.io/2//reference/tools/android.html.md) * [android_abi()](https://docs.conan.io/2//reference/tools/android.html.md#android-abi) * [conan.tools.apple](https://docs.conan.io/2//reference/tools/apple.html.md) * [XcodeDeps](https://docs.conan.io/2//reference/tools/apple/xcodedeps.html.md) * [XcodeToolchain](https://docs.conan.io/2//reference/tools/apple/xcodetoolchain.html.md) * [XcodeBuild](https://docs.conan.io/2//reference/tools/apple/xcodebuild.html.md) * [conan.tools.apple.fix_apple_shared_install_name()](https://docs.conan.io/2//reference/tools/apple/other.html.md) * [conan.tools.apple.is_apple_os()](https://docs.conan.io/2//reference/tools/apple/other.html.md#conan-tools-apple-is-apple-os) * [conan.tools.apple.to_apple_arch()](https://docs.conan.io/2//reference/tools/apple/other.html.md#conan-tools-apple-to-apple-arch) * [conan.tools.apple.XCRun()](https://docs.conan.io/2//reference/tools/apple/other.html.md#conan-tools-apple-xcrun) * [conan.tools.build](https://docs.conan.io/2//reference/tools/build.html.md) * [Building](https://docs.conan.io/2//reference/tools/build.html.md#building) * [Cppstd](https://docs.conan.io/2//reference/tools/build.html.md#cppstd) * [cstd](https://docs.conan.io/2//reference/tools/build.html.md#cstd) * [Compiler](https://docs.conan.io/2//reference/tools/build.html.md#compiler) * [conan.tools.cmake](https://docs.conan.io/2//reference/tools/cmake.html.md) * [CMakeDeps](https://docs.conan.io/2//reference/tools/cmake/cmakedeps.html.md) * [CMakeConfigDeps](https://docs.conan.io/2//reference/tools/cmake/cmakeconfigdeps.html.md) * [CMakeToolchain](https://docs.conan.io/2//reference/tools/cmake/cmaketoolchain.html.md) * [CMake](https://docs.conan.io/2//reference/tools/cmake/cmake.html.md) * [cmake_layout](https://docs.conan.io/2//reference/tools/cmake/cmake_layout.html.md) * [conan.tools.CppInfo](https://docs.conan.io/2//reference/tools/cpp_info.html.md) * [Aggregating information in custom generators](https://docs.conan.io/2//reference/tools/cpp_info.html.md#aggregating-information-in-custom-generators) * [CppInfo interface](https://docs.conan.io/2//reference/tools/cpp_info.html.md#cppinfo-interface) * [conan.tools.env](https://docs.conan.io/2//reference/tools/env.html.md) * [Environment](https://docs.conan.io/2//reference/tools/env/environment.html.md) * [EnvVars](https://docs.conan.io/2//reference/tools/env/envvars.html.md) * [VirtualBuildEnv](https://docs.conan.io/2//reference/tools/env/virtualbuildenv.html.md) * [VirtualRunEnv](https://docs.conan.io/2//reference/tools/env/virtualrunenv.html.md) * [conan.tools.files](https://docs.conan.io/2//reference/tools/files.html.md) * [conan.tools.files basic operations](https://docs.conan.io/2//reference/tools/files/basic.html.md) * [conan.tools.files downloads](https://docs.conan.io/2//reference/tools/files/downloads.html.md) * [conan.tools.files patches](https://docs.conan.io/2//reference/tools/files/patches.html.md) * [conan.tools.files checksums](https://docs.conan.io/2//reference/tools/files/checksum.html.md) * [conan.tools.files.symlinks](https://docs.conan.io/2//reference/tools/files/symlinks.html.md) * [conan.tools.gnu](https://docs.conan.io/2//reference/tools/gnu.html.md) * [AutotoolsDeps](https://docs.conan.io/2//reference/tools/gnu/autotoolsdeps.html.md) * [AutotoolsToolchain](https://docs.conan.io/2//reference/tools/gnu/autotoolstoolchain.html.md) * [Autotools](https://docs.conan.io/2//reference/tools/gnu/autotools.html.md) * [MakeDeps](https://docs.conan.io/2//reference/tools/gnu/makedeps.html.md) * [PkgConfigDeps](https://docs.conan.io/2//reference/tools/gnu/pkgconfigdeps.html.md) * [PkgConfig](https://docs.conan.io/2//reference/tools/gnu/pkgconfig.html.md) * [conan.tools.google](https://docs.conan.io/2//reference/tools/google.html.md) * [Bazel](https://docs.conan.io/2//reference/tools/google/bazel.html.md) * [BazelDeps](https://docs.conan.io/2//reference/tools/google/bazeldeps.html.md) * [BazelToolchain](https://docs.conan.io/2//reference/tools/google/bazeltoolchain.html.md) * [conan.tools.intel](https://docs.conan.io/2//reference/tools/intel.html.md) * [IntelCC](https://docs.conan.io/2//reference/tools/intel.html.md#intelcc) * [Reference](https://docs.conan.io/2//reference/tools/intel.html.md#reference) * [conan.tools.layout](https://docs.conan.io/2//reference/tools/layout.html.md) * [Predefined layouts](https://docs.conan.io/2//reference/tools/layout.html.md#predefined-layouts) * [basic_layout](https://docs.conan.io/2//reference/tools/layout.html.md#basic-layout) * [conan.tools.meson](https://docs.conan.io/2//reference/tools/meson.html.md) * [MesonToolchain](https://docs.conan.io/2//reference/tools/meson/mesontoolchain.html.md) * [Meson](https://docs.conan.io/2//reference/tools/meson/meson.html.md) * [conan.tools.microsoft](https://docs.conan.io/2//reference/tools/microsoft.html.md) * [MSBuild](https://docs.conan.io/2//reference/tools/microsoft/msbuild.html.md) * [MSBuildDeps](https://docs.conan.io/2//reference/tools/microsoft/msbuilddeps.html.md) * [MSBuildToolchain](https://docs.conan.io/2//reference/tools/microsoft/msbuildtoolchain.html.md) * [VCVars](https://docs.conan.io/2//reference/tools/microsoft/vcvars.html.md) * [NMakeDeps](https://docs.conan.io/2//reference/tools/microsoft/nmake.html.md) * [NMakeToolchain](https://docs.conan.io/2//reference/tools/microsoft/nmake.html.md#nmaketoolchain) * [vs_layout](https://docs.conan.io/2//reference/tools/microsoft/visual_layout.html.md) * [check_min_vs](https://docs.conan.io/2//reference/tools/microsoft/helpers.html.md) * [msvc_runtime_flag](https://docs.conan.io/2//reference/tools/microsoft/helpers.html.md#msvc-runtime-flag) * [is_msvc](https://docs.conan.io/2//reference/tools/microsoft/helpers.html.md#is-msvc) * [is_msvc_static_runtime](https://docs.conan.io/2//reference/tools/microsoft/helpers.html.md#is-msvc-static-runtime) * [msvs_toolset](https://docs.conan.io/2//reference/tools/microsoft/helpers.html.md#msvs-toolset) * [unix_path](https://docs.conan.io/2//reference/tools/microsoft/helpers.html.md#unix-path) * [conan.tools.qbs](https://docs.conan.io/2//reference/tools/qbs.html.md) * [Qbs](https://docs.conan.io/2//reference/tools/qbs/qbs.html.md) * [QbsDeps](https://docs.conan.io/2//reference/tools/qbs/qbsdeps.html.md) * [QbsProfile](https://docs.conan.io/2//reference/tools/qbs/qbsprofile.html.md) * [conan.tools.ros](https://docs.conan.io/2//reference/tools/ros.html.md) * [ROSEnv](https://docs.conan.io/2//reference/tools/ros/rosenv.html.md) * [conan.tools.sbom](https://docs.conan.io/2//reference/tools/sbom.html.md) * [CycloneDX](https://docs.conan.io/2//reference/tools/sbom.html.md#cyclonedx) * [conan.tools.scm](https://docs.conan.io/2//reference/tools/scm.html.md) * [Git](https://docs.conan.io/2//reference/tools/scm/git.html.md) * [Version](https://docs.conan.io/2//reference/tools/scm/version.html.md) * [conan.tools.scons](https://docs.conan.io/2//reference/tools/scons.html.md) * [SConsDeps](https://docs.conan.io/2//reference/tools/scons.html.md#sconsdeps) * [conan.tools.premake](https://docs.conan.io/2//reference/tools/premake.html.md) * [PremakeDeps](https://docs.conan.io/2//reference/tools/premake/premakedeps.html.md) * [PremakeToolchain](https://docs.conan.io/2//reference/tools/premake/premaketoolchain.html.md) * [Premake](https://docs.conan.io/2//reference/tools/premake/premake.html.md) * [conan.tools.system](https://docs.conan.io/2//reference/tools/system.html.md) * [conan.tools.system.package_manager](https://docs.conan.io/2//reference/tools/system/package_manager.html.md) * [PyEnv](https://docs.conan.io/2//reference/tools/system/pyenv.html.md) --- https://docs.conan.io/2/reference/workspace.html.md --- # Workspace #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. Workspaces are defined by the `conanws.yml` and/or `conanws.py` files that will define the “root” workspace folder. ## conanws.yml The most basic implementation of a workspace is a `conanws.yml` file. It defines the workspace’s `packages` (editable packages). For instance, a workspace `conanws.yml` defining 2 `packages` could be: ```yaml packages: - path: dep1 ref: dep1/0.1 - path: dep2 ref: dep2/0.1 ``` Moreover, it could not have the `ref` field, and let Conan read the *name/version* from the respective *path/conanfile.py*: ```yaml packages: - path: dep1 - path: dep2 ``` #### WARNING Support for `python_requires` in a workspace is limited and highly **experimental**. Discovering the workspace packages does not resolve `python_requires`, as remotes and the Conan cache are not necessarily available at that point. If a package’s `name`/`version` is declared directly (or via its own `set_name()`/`set_version()`), it works out of the box. If it is inherited from a `python_requires`, it cannot be deduced automatically, and a `get_ref()` method must be defined in `conanws.py` (see below). Python-requires are also expected to declare `package_type = "python-require"` directly as a class attribute, not inherited, so they can be filtered out from the workspace packages. #### NOTE **Best practices** Workspaces are in general not expected to contain `python-require` recipes. The purpose of a workspace is to be able to develop the C/C++ code of several packages simultaneously in a convenient way. The recipes should be rarely modified in this flow, and it is not expected that the common Python code that lives in a `python-require` needs to be modified by developers in a Workspace together with the C/C++ code. By the time a developer is putting several different packages into a Workspace to work on them, the common recipe logic living in a `python-require` is expected to be read-only, not editable, and managed as an external dependency, not an editable one within the workspace. A `python-require` might still be added to a workspace, with some limitations and caveats, but still the intention is that this is a very exceptional scenario, and not something that regular developers would do. ## conanws.py A `conanws.yml` can be extended with a way more powerful `conanws.py` that follows the same relationship as a `ConanFile` does with its `conandata.yml`. If we want to dynamically define the `packages`, for example based on the existence of some `name.txt` and `version.txt` files in folders, the packages could be defined in `conanws.py` as: ```python import os from conan import Workspace class MyWorkspace(Workspace): def packages(self): result = [] for f in os.listdir(self.folder): if os.path.isdir(os.path.join(self.folder, f)): with open(os.path.join(self.folder, f, "name.txt")) as fname: name = fname.read().strip() with open(os.path.join(self.folder, f, "version.txt")) as fversion: version = fversion.read().strip() result.append({"path": f, "ref": f"{name}/{version}"}) return result ``` It is also possible to re-use the `conanfile.py` logic in `set_name()` and `set_version()` methods, using the `Workspace.load_conanfile()` helper: ```python import os from conan import Workspace class MyWorkspace(Workspace): def packages(self): result = [] for f in os.listdir(self.folder): if os.path.isdir(os.path.join(self.folder, f)): conanfile = self.load_conanfile(f) result.append({"path": f, "ref": f"{conanfile.name}/{conanfile.version}"}) return result ``` ### get_ref() If a package’s `name`/`version` cannot be deduced because it is inherited from a `python_requires` (which is not resolved while discovering the workspace packages), `conanws.py` can define a `get_ref(folder)` method to provide the reference explicitly: ```python from conan import Workspace class MyWorkspace(Workspace): def get_ref(self, folder): return {"pkga": "pkga/1.0", "pkgb": "pkgb/2.0"}.get(folder) ``` `get_ref()` can return a `name/version[@user/channel]` string, a `RecipeReference`, or `None` if it doesn’t apply to that `folder`. When the reference for a package cannot be deduced by any of these means (`ref` in `conanws.yml`, `name`/`version` attributes, `set_name()`/`set_version()`, or `get_ref()`), Conan raises an error listing all the available alternatives. ### conanws.py super-build `ConanFile` The `conanws.py` file can contain the definition of a `ConanFile` that represents the super-build. When the workspace dependency graph is computed, all packages in the workspace are collapsed into a single node in the dependency graph, and that node will have dependencies to the other packages external to the workspace, that is, installed in the Conan cache. The `ConanFile` that represents the workspace super-build project is defined as: ```python from conan import ConanFile, Workspace from conan.tools.cmake import cmake_layout class MyWs(ConanFile): settings = "os", "compiler", "arch", "build_type" generators = "CMakeToolchain", "CMakeDeps" def layout(self): cmake_layout(self) class Ws(Workspace): def root_conanfile(self): return MyWs ``` It defines that our super-build project will be a CMake project that uses the `CMakeToolchain` and `CMakeDeps` generators to integrate and find the external package dependencies. It is not necessary that the `ConanFile` defines `requires` at all, they will be computed by aggregating the requires of all packages in the workspace. #### IMPORTANT The `ConanFile` inside `conanws.py` is a special conanfile, used exclusively for the workspace super-build definition of layout and generators. It shouldn’t have any kind of requirements, not regular `requires`, `tool_requires` or `test_requires`. It obtains its dependencies collecting and aggregating the workspace packages requirements. It shouldn’t have `build()` or `package()` methods either. ### conanws.py super-build workspace packages With the `workspace_packages` attribute, the `conanws.py` super-build `ConanFile` can have access to the workspace packages, to be able to reuse their functionality. For example, if we wanted to collect the behavior of workspace packages toolchain definitions we could do the following. Let’s imagine that we have a workspace with 2 packages, `pkga/1.2.3` and `pkgb/2.3.4` ```python from conan import ConanFile class PkgA(ConanFile): name = "pkga" version = "1.2.3" def configure_toolchain(self, tc): tc.preprocessor_definitions["PKGA_SOME_DEFINITION"] = self.version def generate(self): tc = CMakeToolchain(self) self.configure_toolchain(tc) tc.generate() ``` ```python from conan import ConanFile class PkgB(ConanFile): name = "pkgb" version = "2.3.4" def configure_toolchain(self, tc): tc.preprocessor_definitions["SOME_PKGB_DEFINE"] = self.version def generate(self): tc = CMakeToolchain(self) self.configure_toolchain(tc) tc.generate() ``` ```python from conan import ConanFile from conan import Workspace from conan.tools.cmake import CMakeToolchain class MyWs(ConanFile): settings = "arch", "build_type" def generate(self): tc = CMakeToolchain(self) for ref, dep in self.workspace_packages.items(): dep.configure_toolchain(tc) tc.generate() class Ws(Workspace): def root_conanfile(self): return MyWs ``` Then, the `workspace_packages.items()` iteration will be able to call every package in the workspace `configure_toolchain()` and collect all their behavior in the current super-build `CMakeToolchain`. The resulting toolchain will contain the definitions for `SOME_PKGB_DEFINE=2.3.4` and `PKGA_SOME_DEFINITION=1.2.3`. #### WARNING **Important** The access of `workspace_packages` to the workspace packages `ConanFiles` must be **read-only** and **pure**. It cannot modify the workspace `pkga` and `pkgb` packages data, and it cannot have any side effect. For example it is forbidden to call any method such as `.build()` or even the `.generate()` method. If there is logic to be reused, it is the responsibility of the developer to define some convention, such as the `configure_toolchain()` method that if called from the `conanws.py` will not modify at all (pure) the `pkga` or `pkgb` data. ### conanws.py super-build options A particular case of the above `workspace_packages` access could be reading the individual workspace packages options. A `conanws.py` used for a super-build workspaces file can manage options in two different ways: - It can define its own `options` with the normal `conanfile.py` syntax, so the generated `conan_toolchain.cmake` for the super-project uses those inputs. - It can collect the options of the workspace’s packages with the `workspace_packages` and process them in any user-custom way. **super-project options** A `conanws.py` must define the options for the super-build in the `ConanFile` class, and use those options in the `generate()` method, as it usually happens with `conanfile.py` files, something like: ```python from conan import ConanFile, Workspace class MyWs(ConanFile): settings = "arch", "build_type" options = {"myoption": [1, 2, 3]} def generate(self): self.output.info(f"Generating with my option {self.options.myoption}!!!!") class Ws(Workspace): def root_conanfile(self): return MyWs ``` Then, options can be provided with the usual syntax, via profiles or command line: ```bash $ conan workspace super-install -of=build -o "*:myoption=1" > conanws.py base project Conanfile: Generating with my option 1!!!! ``` Note there can be overlap with the `options` defined in the workspace packages, as for super-projects those options are simply ignored, and only the options of the super-project are taken into account to generate the `conan_toolchain.cmake`. For example, the `conanws.py` can define a `shared` option if it is desired that the `conan_toolchain.cmake` will correctly define `BUILD_SHARED_LIBS` or not when defining something like `-o "*:shared=True"`, as the workspace packages having the `shared` option information is discarded when the workspace packages are collapsed in the dependency graph to model the super-project. **packages options** The second alternative is to collect the `options` of the workspace packages that have been collapsed. Recall that in the final dependency graph, the workspace packages are no longer represented, as they are no longer individual packages but part as the current super-build. The way to access their options information is via the `workspace_packages`, and that information can be used in the `generate()` method to do any desired action at the super-build project level. So let’s say that a workspace containing a `dep/0.1` package that contains the standard `shared` options defines the following super-build `ConanFile`: ```python from conan import ConanFile, Workspace class MyWs(ConanFile): def generate(self): for pkg, dep in self.workspace_packages.items(): for k, v in dep.options.items(): self.output.info(f"Generating with opt {pkg}:{k}={v}!!!!") class Ws(Workspace): def root_conanfile(self): return MyWs ``` Then, when the workspace package options are defined, the workspace `ConanFile` can collect them. ```bash $ conan workspace super-install -of=build -o "*:shared=True" > conanws.py base project Conanfile: Generating with opt dep/0.1:shared=True!!!!!!!! ``` #### NOTE In practice it is the responsibility of the workspace creator to define what to do with the options, either by defining its own options or collecting the workspace packages ones. Note it is not possible to automatically map workspace packages options to the super-project, as options are defined per-package. Two different packages could have different `shared=True` and `shared=False` values. Also, very often, the effect on the generated toolchain files is custom and implemented in each package `generate()` method. This effect is programmatic (not declarative), it would be extremely challenging to aggregate all these effects in a single toolchain. #### SEE ALSO Read [the Workspace tutorial](https://docs.conan.io/2//tutorial/developing_packages/workspaces.html.md#tutorial-workspaces) section. --- https://docs.conan.io/2/reference/binary_model/custom_compatibility.html.md --- # Customizing the binary compatibility The default binary compatibility requires an almost exact match of settings and options, and a versioned match of dependencies versions, as explained in the [previous section about dependencies](https://docs.conan.io/2//reference/binary_model/dependencies.html.md#reference-binary-model-dependencies). In summary, the required binaries `package_id` when installing dependencies should match by default: - All the settings in the `package_id` except `compiler.cppstd` should match exactly the ones provided in the input profiles, including the compiler version. So `compiler.version=9` is different than `compiler.version=9.1`. - The default behavior will assume binary compatibility among different `compiler.cppstd` values for C++ packages, being able to fall back to other values rather than the one specified in the input profiles, if the `cppstd` required by the input profile does not exist. This is controlled by the `compatibility.py` plugin, that can be customized by users. - All the options in the `package_id` should match exactly the ones provided in the input profiles. - The versions of the dependencies should match: - In case of “embedding dependencies”, should match the exact version, including the recipe-revision and the dependency `package_id`. The `package_revision` is never included as it is assumed to be ill-formed to have more than one `package_revision` for the same `package_id`. - In case of “non-embedding dependencies”, the versions of the dependencies should match down to the `minor` version, being the `patch`, `recipe_revision` and further information not taken into account. - In case of “tool dependencies”, the versions of the dependencies do not affect at all by default to the consumer `package_id`. These rules can be customized and changed using different approaches, depending on the needs, as explained in following sections ## Customizing binary compatibility of settings and options ### Information erasure in package_id() method Recipes can **erase** information from their `package_id` using their `package_id()` method. For example, a package containing only an executable can decide to remove the information from `settings.compiler` and `settings.build_type` from their `package_id`, assuming that an executable built with any compiler will be valid, and that it is not necessary to store different binaries built with different compilers: ```python def package_id(self): del self.info.settings.compiler del self.info.settings.build_type ``` It is also possible to assign a value for a given setting, for example if we want to have one single binary for all gcc versions included in the [>=5 <7>] range, we could do: ```python def package_id(self): if self.info.settings.compiler == "gcc": version = Version(self.info.settings.compiler.version) if version >= "5.0" and version < "7.0": self.info.settings.compiler.version = "gcc5-6" ``` #### NOTE **Best practice** Note that information erasure in `package_id()` means that 1 single `package_id` will represent a whole range of different settings, but the information of what exact setting was used to create the binary will be lost, and only 1 binary can be created for that range. Re-creating the package with different settings in the range, will create a new binary that overwrites the previous one (with a new package-revision). If we want to be able to create, store and manage different binaries for different input settings, information erasure can’t be used, and using the below `compatibility` approaches is recommended. #### SEE ALSO - [Conan packages binary compatibility: the package ID](https://docs.conan.io/2//tutorial/creating_packages/configure_options_settings.html.md#creating-packages-configure-options-settings) - [package_id() method reference](https://docs.conan.io/2//reference/conanfile/methods/package_id.html.md#reference-conanfile-methods-package-id) ### The compatibility() method Recipes can define their binary compatibility rules, using their `compatibility()` method. For example, if we want that binaries built with gcc versions 4.8, 4.7 and 4.6 to be considered compatible with the ones compiled with 4.9 we could declare a `compatibility()` method like this: ```python def compatibility(self): if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9": return [{"settings": [("compiler.version", v)]} for v in ("4.8", "4.7", "4.6")] ``` Read more about the `compatibility()` method in [the compatibility() method reference](https://docs.conan.io/2//reference/conanfile/methods/compatibility.html.md#reference-conanfile-methods-compatibility) ### The `compatibility.py` plugin Compatibility can be defined globally via the `compatibility.py` plugin, in the same way that the `compatibility()` method does for one recipe, but for all packages globally. Check the binary compatibility [compatibility.py extension](https://docs.conan.io/2//reference/extensions/binary_compatibility.html.md#reference-extensions-binary-compatibility). ## Customizing binary compatibility of dependencies versions ### Global default package_id modes The `core.package_id:default_xxx` configurations defined in `global.conf` can be used to globally change the defaults of how dependencies affect their consumers ```ini core.package_id:default_build_mode: By default, 'None' core.package_id:default_embed_mode: By default, 'full_mode' core.package_id:default_non_embed_mode: By default, 'minor_mode' core.package_id:default_python_mode: By default, 'minor_mode' core.package_id:default_unknown_mode: By default, 'semver_mode' ``` These confs affect how [the package id](https://docs.conan.io/2//reference/binary_model/package_id.html.md#reference-binary-model-package-id) is calculated, so changing them will affect your generated binaries. It’s thus recommended that they stay consistent across your organization. #### NOTE **Best practices** It is strongly recommended that the `core.package_id:default_xxx` should be global, consistent and immutable across organizations. It can be confusing to change these defaults for different projects or teams, because it will result in missing binaries. It should also be consistent and shared with the consumers of generated packages if those packages are shared outside the organization, in that case sharing the `global.conf` file via `conan config install` could be recommended. Consider using the Conan defaults, they should be a good balance between efficiency and safety, ensuring exact re-building for embed cases, and good control via versions for non-embed cases. ### Custom package_id modes for recipe consumers Recipes can define their default effect to their consumers, via some `package_id_xxxx_mode` attributes. The `package_id_embed_mode, package_id_non_embed_mode, package_id_unknown_mode` are class attributes that can be defined in recipes to define the effect they have on their consumers `package_id`, when they are consumed as `requires`. The `build_mode` (experimental) is a class attribute that affects the package consumers when these consumers use it as `tool_requires`. Can be declared as: ```python from conan import ConanFile class Pkg(ConanFile): ... package_id_embed_mode = "full_mode" package_id_non_embed_mode = "patch_mode" package_id_unknown_mode = "minor_mode" build_mode = "patch_mode" # when this is used with tool_requires # For exceptional cases when we explicitly want to make consumers # depend on this dependency option value package_id_abi_options = ["shared"] ``` Read more in [package_id_{embed,non_embed,python,unknown}_mode, build_mode](https://docs.conan.io/2//reference/conanfile/attributes.html.md#reference-conanfile-attributes-package-id-modes) and in [package_id_abi_options](https://docs.conan.io/2//reference/conanfile/attributes.html.md#reference-conanfile-attributes-package-id-abi-options). ### Custom package_id from recipe dependencies Recipes can define how their dependencies affect their `package_id`, using the `package_id_mode` trait: ```python from conan import ConanFile class Pkg(ConanFile): def requirements(self): self.requires("mydep/1.0", package_id_mode="patch_mode") ``` Using `package_id_mode` trait does not differentiate between the “embed” and “non-embed” cases, it is up to the user to define the correct value. It is likely that this approach should only be used for very special cases that do not have variability of shared/static libraries controlled via `options`. Note that the `requirements()` method is evaluated while the graph is being expanded, the dependencies do not exist yet (haven’t been computed), so it is not possible to know the dependencies options. In this case it might be preferred to use the `package_id()` method. The `package_id()` method can define how the dependencies affect the current package with: ```python from conan import ConanFile class Pkg(ConanFile): def package_id(self): self.info.requires["mydep"].major_mode() ``` The different modes that can be used are defined in [package_id_{embed,non_embed,python,unknown}_mode, build_mode](https://docs.conan.io/2//reference/conanfile/attributes.html.md#reference-conanfile-attributes-package-id-modes) --- https://docs.conan.io/2/reference/binary_model/dependencies.html.md --- # The effect of dependencies on `package_id` When a given package depends on a another package and uses it, the effect of dependencies can be different based on the package types: For libraries: - **Non-embed mode**: When an application or a shared library depends on another shared library, or when a static library depends on another static library, the “consumer” library does not do a copy of the binary artifacts of the “dependency” at all. We call it non-embed mode, the dependency binaries are not being linked or embedded in the consumer. This assumes that there are not inlined functionalities in the dependency headers, and the headers are pure interface and not implementation. - **Embed mode**: When an application or a shared library depends on a header-only or a static-library, the dependencies binaries are copied or partially copied (depending on the linker) in the consumer binary. Also when a static library depends on a header-only library, it is considered that there will be embedding in the consumer binary of such headers, as they will also contain the implementation, it is impossible that they are a pure interface. For header-only libraries: - Header only libraries are always independent of their dependencies, because they do not link them. No change in the dependencies versions changes the final package of the header-only library. For applications (`tool_requires`): - **Build mode**: When some package uses a `tool_requires` of another package, the binary artifacts in the dependency are never copied or embedded. When the package types are not known (the recipes do not define the `shared` option, or they do not define `package_type` attribute): - **Unknown mode**: This mode is generally not recommended, as it is the result of not having enough information about the package types, and it results in a excesively optimistic `package_id` computation with a `semver` approach for binary rebuilds, which is generally insufficient for C and C++ libraries. The recommendation is to clear specify the `shared` option or to explicitly define `package_type`. ## Non-embed mode When we list the binaries of a package like `openssl` with dependencies: ```bash $ conan list openssl/3.1.2:* -r=conancenter conancenter openssl openssl/3.1.2 revisions 8879e931d726a8aad7f372e28470faa1 (2023-09-13 18:52:54 UTC) packages 0348efdcd0e319fb58ea747bb94dbd88850d6dd1 # package_id info options shared: True ... requires zlib/1.3.Z ``` This binary was a `shared` library, linking with `zlib` as a shared library. This means it was using “non-embed” mode. The default of non-embed mode is `minor_mode`, which means: - All `zlib` patch versions will be mapped to the same `zlib/1.3.Z`. This means that if our `openssl/3.1.2` package binary `0348efdcd0e319fb58ea747bb94dbd88850d6dd1` binary is considered binary compatible with all `zlib/1.3.Z` versions (for any `Z`), and will not require to rebuild the `openssl` binary. - New `zlib` minor versions, like `zlib/1.4.0` will result in a “minor-mode” identifier like `zlib/1.4.Z`, and then, it will require a new `openssl/3.1.2` package binary, with a new `package_id` #### NOTE There was a bug in Conan versions previous to Conan 2.28 in this **non-embed mode**, in which transitive dependencies could affect the `package_id` of consumers, even if they were not direct dependencies, they were not being embedded, and they were not propagating headers to it. This was causing sub-optimal behavior, that could require some unnecessary builds from source for new `package_ids`. To avoid breaking existing users, this bug fix was introduced as opt-in via policies: - If a recipe defines `required_conan_version = ">=2.28"` or higher, it will automatically enable the new fixed `package_id` computation. Recipes that don’t update their required Conan version will still use the older `package_id`. - If the global configuration in `global.conf` defines the `core:policies=["required_conan_version>=2.28"]` it will have the same behavior, enabling this bugfix for all packages. See the [documentation for policies](https://docs.conan.io/2//reference/policies.html.md#reference-policies) for more information. - The recommendation is to activate the new behavior via policies. It will save resources like build time, and it will also be more future-proof, future Conan versions might enable this behavior unconditionally. ## Embed mode The following commands illustrate the concept of embed-mode. We create a `dep/0.1` package with a static library, and then we create a `app/0.1` package with an executable that links with static library inside `dep/0.1`. We can use the `conan new` command for quickly creating these two packages: ```bash $ mkdir dep && cd dep $ conan new cmake_lib -d name=dep -d version=0.1 $ conan create . -tf="" $ cd .. && mkdir app && cd app $ conan new cmake_exe -d name=app -d version=0.1 -d requires=dep/0.1 $ conan create . dep/0.1: Hello World Release! ... app/0.1: Hello World Release! ``` If we now list the `app/0.1` binaries, we will see the binary just created: ```bash $ conan list app/0.1:* Local Cache app/0.1 revisions 632e236936211ac2293ec33339ce582b (2023-09-25 22:34:17 UTC) packages 3ca530d20914cf632eb00efbccc564da48190314 info settings ... requires dep/0.1#d125304fb1fb088d5b92d4f8135f4dff:9bdee485ef71c14ac5f8a657202632bdb8b4482b ``` It is now visible that the `app/0.1` package-id depends on the full identifier of the `dep/0.1` dependency, that includes both its recipe revision and `package_id`. If we do a change now to the `dep` code, and re-create the `dep/0.1` package , even if we don’t bump the version, it will create a new recipe revision: ```bash $ cd ../dep # Change the "src/dep.cpp" code to print a new message, like "Hello Moon" $ conan create . -tf="" # New recipe revision dep/0.1#1c90e8b8306c359b103da31faeee824c ``` So if we try now to install `app/0.1` binary, it will fail with a “missing binary” error: ```text $ conan install --requires=app/0.1 ERROR: Missing binary: app/0.1:ef2b5ed33d26b35b9147c90b27b217e2c7bde2d0 app/0.1: WARN: Can't find a 'app/0.1' package binary 'ef2b5ed33d26b35b9147c90b27b217e2c7bde2d0' for the configuration: [settings] ... [requires] dep/0.1#1c90e8b8306c359b103da31faeee824c:9bdee485ef71c14ac5f8a657202632bdb8b4482b ERROR: Missing prebuilt package for 'app/0.1' ``` As the `app` executable links with the `dep` static library, it needs to be rebuilt to include the latest changes, even if `dep/0.1` didn’t bump its version, `app/0.1` depends on “embed-mode” on `dep/0.1`, so it wil use down to the `package_id` of such dependency identifier. Let’s build the new `app/0.1` binary: ```bash $ cd ../app $ conan create . dep/0.1: Hello Moon Release! # Message changed to Moon ... app/0.1: Hello World Release! ``` Now we will have two `app/0.1` different binaries: ```bash $ conan list "app/0.1:*" Local Cache app app/0.1 revisions 632e236936211ac2293ec33339ce582b (2023-09-25 22:49:32 UTC) packages 3ca530d20914cf632eb00efbccc564da48190314 info settings ... requires dep/0.1#d125304fb1fb088d5b92d4f8135f4dff:9bdee485ef71c14ac5f8a657202632bdb8b4482b ef2b5ed33d26b35b9147c90b27b217e2c7bde2d0 info settings ... requires dep/0.1#1c90e8b8306c359b103da31faeee824c:9bdee485ef71c14ac5f8a657202632bdb8b4482b ``` We will have these two different binaries, one of them linking with the first revision of the `dep/0.1` dependency (with the “Hello World” message), and the other binary with the other `package_id` linked with the second revision of the `dep/0.1` dependency (with the “Hello Moon” message). The above described mode is called `full_mode`, and it is the default for the `embed_mode`. ## Package types and default modes The “embed/non-embed/unknown” modes are derived from the recipes definitions of `package_type`. Recall that `package_type` can be explicitly defined as a recipe attribute, but it can also be implicity derived from the `shared` option. The resulting `package_id_mode` defines when a binary package needs to be built from source, depending on the chanages of the dependency version. #### IMPORTANT It is very important to have a correct definition of `package_type`, and it is extremely recommended to define it, either explicitly with `package_type` recipe attribute, or by the definition of the `shared` options. The following summarizes the defaults: - Embed mode - Package types: - A `shared-library` or `application` consuming a `static-library` - An `application`, `shared-library` or `static-library` consuming a `header-library` - Default `package_id_mode`: `full_mode` any change (version, recipe, or binary) forces a consumer rebuild - Non-embed mode - Package types: - A `static-library` linking with another `static-library` - An `application` or `shared-librayr` linking another `shared-library`. - Default `package_id_mode`: `minor_mode`: patch-version changes are ignored; minor or major changes force a rebuild - Header-only library - Package types: - A `header-library` depending on any other `static-library`, `shared-library` or `headed-library`. - Default `package_id_mode`: None. Header-only libraries are not affected in their `package_id` by their dependencies versions. - Build mode - Package types: - Any package doing a `tool_requires` to other package (in recipe or by profile injection via `[tool_requires]`) - Default `package_id_mode`: None. By default, tools do not change the binary they help to produce (the binary is the same built with different versions of CMake, for example. For compilers this might not be true, but that effect is already captured by `compiler.version` setting). - Unknown mode - Package types: - When any of the package types are not defined - Default `package_id_mode`: `semver_mode`: for versions `>=1.0` only major changes force a rebuild; for `<1.0` any change forces a rebuild #### NOTE There are different ways to change the defaults, like defining `core.package_id:default_embed_mode`, `core.package_id:default_non_embed_mode`, and `core.package_id:default_unknown_mode` in `global.conf`, or defining the equivalent recipe attributes. All of this will be explained in following sections. --- https://docs.conan.io/2/reference/binary_model/extending.html.md --- # Extending the binary model There are a few mechanisms to extend the default Conan binary model: ## Custom settings It is possible to add new settings or subsettings in the *settings.yml* file, something like: ```yaml os: Windows: new_subsetting: [null, "subvalue1", "subvalue2"] new_root_setting: [null, "value1", "value2"] ``` Where the `null` value allows leaving the setting undefined in profiles. If not including, it will be mandatory that profiles define a value for them. The custom settings will be used explicitly or implicitly in recipes and packages: ```python class Pkg(ConanFile): # If we explicitly want this package binaries to vary according to 'new_root_setting' settings = "os", "compiler", "build_type", "arch", "new_root_setting" # While all packages with 'os=Windows' will implicitly vary according to 'new_subsetting' ``` #### SEE ALSO For the full reference of how `settings.yml` file can be customized [visit the settings section](https://docs.conan.io/2//reference/config_files/settings.html.md#reference-config-files-customizing-settings). In practice, it is not necessary to modify the `settings.yml` file, and instead, it is possible to provide `settings_user.yml` file to extend the existing settings. See [the settings_user.yml documentation](https://docs.conan.io/2//examples/config_files/settings/settings_user.html.md#examples-config-files-settings-user). ## Custom options `Options` are custom to every recipe, there is no global definition of options like the `settings.yml` one. Package `conanfile.py` recipes define their own options, with their own range of valid values and their own defaults: ```python class MyPkg(ConanFile): ... options = {"build_tests": [True, False], "option2": ["ANY"]} default_options = {"build_tests": True, "option1": 42, "z*:shared": True} ``` The options `shared`, `fPIC` and `header_only` have special meaning for Conan, and are considered automatically by most built-in build system integrations. They are also the recommended default to represent when a library is shared, static or header-only. #### SEE ALSO - [documentation for options](https://docs.conan.io/2//reference/conanfile/attributes.html.md#conan-conanfile-properties-options) - [documentation for default_options](https://docs.conan.io/2//reference/conanfile/attributes.html.md#conan-conanfile-properties-default-options). - [Defining options for dependencies in recipes does not have strong guarantees](https://docs.conan.io/2//knowledge/faq.html.md#faq-different-options-values) ## Settings vs options vs conf When to use settings or options or configuration? - **Settings** are a project-wide configuration, something that typically affects the whole project that is being built and affects the resulting package binaries. For example, the operating system or the architecture would be naturally the same for all packages in a dependency graph, linking a Linux library to build a Windows app, or mixing architectures is impossible. Settings cannot be defaulted in a package recipe. A recipe for a given library cannot say that its default is `os=Windows`. The `os` will be given by the environment in which that recipe is processed. It is a mandatory input to be defined in the input profiles. - On the other hand, **options** are a package-specific configuration that affects the resulting package binaries. Static or shared library are not settings that apply to all packages. Some can be header only libraries while other packages can be just data, or package executables. For example, `shared` is a common option (the default for specifying if a library can be static or shared), but packages can define and use any options they want. Options are defined in the package `conanfile.py` recipe, including their supported and default values with `options` and `default_options`. - Configuration via `conf` is intended for configuration that does not affect the resulting package binaries in the general case. For example, building one library with the `tools.cmake.cmaketoolchain:generator=Ninja` shouldn’t result in a binary different than if built with Visual Studio (just a typically faster build thanks to Ninja). There are some exceptions to the above. For example, settings can be defined per-package using the `setting=value`, both in profiles and command line: ```bash $ conan install . -s mypkg/*:compiler=gcc -s compiler=clang .. ``` This will use `gcc` for “mypkg” and `clang` for the rest of the dependencies (in most cases it is recommended to use the same compiler for the whole dependency graph, but some scenarios when strong binary compatibility is guaranteed, it is possible to mix libraries built with different compilers). There are situations whereby many packages use the same option value, thereby allowing you to set its value once using patterns, like: ```bash $ conan install . -o *:shared=True ``` ## Custom configuration As commented above, the Conan `conf` configuration system is intended to tune some of the tools and behaviors, but without really affecting the resulting package binaries. Some typical `conf` items are activating parallel builds, configuring “retries” when uploading to servers, or changing the CMake generator. Read more about [the Conan configuration system in this section](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf). There is also the possibility to define `user.xxxx:conf=value` for user-defined configuration, that in the same spirit as core and tools built-in configurations, do not affect the `package_id` of binaries. But there might be some special situations in which it is really desired that some `conf` defines different `package_ids`, creating different package binaries. It is possible to do this in two different places: - Locally, in the recipe’s `package_id` method, via the `self.info.conf` attribute: ```python def package_id(self): # We can get the value from the actual current conf value, or define a new value value = self.conf.get("user.myconf:myitem") # This ``self.info.conf`` will become part of the ``package_id`` self.info.conf.define("user.myconf:myitem", value) ``` - Globally, with the `tools.info.package_id:confs` configuration, receiving as argument a list of existing configuration to be part of the package ID, so you can define in profiles: ```ini tools.info.package_id:confs=["tools.build:cxxflags", ...] ``` The value of the `package_id` will contain the value provided in the `tools.build:cxxflags` and other configurations. Note that this value is managed as a string, changing the string, will produce a different result and a different `package_id`, so if this approach is used, it is very important to be very consistent with the provided values for different configurations like `tools.build:cxxflags`. It is also possible to use regex expressions to match several `confs`, instead of listing all of them, for example `.*cmake` could match any configuration that contains “cmake” in its name (not that this is recommended, see best practices below). #### NOTE **Best practices** In general, defining variability of binaries `package_id` via `conf` should be reserved for special situations and always managed with care. Passing many different `confs` to the `tools.info.package_id:confs` can easily result in issues like missing binaries or unnecessarily building too many binaries. If that is the case, consider building higher level abstraction over your binaries with new custom settings or options. ## Cross build target settings The `self.settings_target` is a `conanfile.py` attribute that becomes relevant in cross-compilation scenarios for the `tool_requires` tools in the “build” context. When we have a `tool_requires` like CMake, lets say the `cmake/3.25.3`, the package binary is independent of the possible platform that cross-compiling will target, it is the same `cmake` executable for all different target platforms. The `settings` for a cross-building from Windows-X64 to Linux-armv8 scenario for the `cmake` conanfile recipe would be: - `self.settings`: The settings where the current `cmake/3.25.3` will run. As it is a tool-require, it will run in the Windows machine, so `self.settings.os = Windows` and `self.settings.arch = x86_64`. - `self.settings_build`: The settings of the current build machine that would build this package if necessary. This is also the Windows-x64 machine, so `self.settings_build.os = Windows` and `self.settings_build.arch = x86_64` too. - `self.settings_target`: The settings that the current application outcome will target. In this case it will be `self.settings_target.os = Linux` and `self.settings_target.arch = armv8` In the `cmake` package scenario, as we pointed out, the target is irrelevant. It is not used in the `cmake` conanfile recipe at all, and it doesn’t affect the `package_id` of the `cmake` binary package. But there are situations when the binary package can be different based on the target platform. For example a cross-compiler `gcc` that has a different `gcc` executable based on the target it will compile for. This is typical in the GNU ecosystem where we can find `arm-gcc` toolchains, for example, specific for a given architecture. This scenario can be reflected by Conan, extending the `package_id` with the value of these `settings_target`: ```python def package_id(self): self.info.settings_target = self.settings_target # If we only want the ``os`` and ``arch`` settings, then we remove the other: self.info.settings_target.rm_safe("compiler") self.info.settings_target.rm_safe("build_type") ``` --- https://docs.conan.io/2/reference/binary_model/package_id.html.md --- # How the `package_id` is computed Let’s take some package and list its binaries, for example: ```bash $ conan list "zlib/1.2.13:*" -r=conancenter Local Cache zlib zlib/1.2.13 revisions 97d5730b529b4224045fe7090592d4c1 (2023-08-22 02:51:57 UTC) packages d62dff20d86436b9c58ddc0162499d197be9de1e # package_id info settings arch: x86_64 build_type: Release compiler: apple-clang compiler.version: 13 os: Macos options fPIC: True shared: False abe5e2b04ea92ce2ee91bc9834317dbe66628206 # package_id info settings arch: x86_64 build_type: Release compiler: gcc compiler.version: 11 os: Linux options shared: True ``` We can see several binaries for the latest recipe revision of `zlib/1.2.13`. Every binary is identified by its own `package_id`, and below it we can see some information for that binary under `info`. This information is the one used to compute the `package_id`. Every time something changes in this information, like the architecture, or being a static or a shared library, a new `package_id` is computed because it represents a different binary. ![image](images/conan_package_id.png) The `package_id` is computed as the sha1 hash of the `conaninfo.txt` file, containing the `info` displayed above. It is relatively easy to display such file: ```bash $ conan install --requires=zlib/1.2.13 --build=missing # Use the listed in the install $ conan cache path zlib/1.2.13: # cat the conaninfo.txt in the returned path $ cat /conaninfo.txt [settings] arch=x86_64 build_type=Release compiler=msvc compiler.runtime=dynamic compiler.runtime_type=Release compiler.version=193 os=Windows [options] shared=False $ sha1sum /conaninfo.txt # Should be the "package_id"! ``` The `package_id` is the sha1 checksum of the `conaninfo.txt` file inside the package. You can validate it with the `sha1sum` utility. If now we have a look to the binaries of `openssl` we can see something like: ```bash $ conan list "openssl/3.1.2:*" -r=conancenter conancenter openssl openssl/3.1.2 revisions 8879e931d726a8aad7f372e28470faa1 (2023-09-13 18:52:54 UTC) packages 0348efdcd0e319fb58ea747bb94dbd88850d6dd1 # package_id info settings arch: x86_64 build_type: Release compiler: apple-clang compiler.version: 13 os: Macos options 386: False ... shared: True requires zlib/1.3.Z ``` We see now that the `conaninfo.txt` contains a new section the `requires` section. This happens because `openssl` depends on `zlib`, and due to the C and C++ compilation model, the dependencies can affect the binaries that use them. Some examples are when using inline or templates from `#include` header files of the dependency. Expanding the image above: ![image](images/conan_package_id_full.png) As it can be seen, even if the `settings` and the `options` are the same, different binaries will be obtained if the dependencies versions change. In the next section [how the versions affect the package_id](https://docs.conan.io/2//reference/binary_model/dependencies.html.md#reference-binary-model-dependencies) is explained. --- https://docs.conan.io/2/reference/binary_model/settings_and_options.html.md --- # How settings and options of a recipe influence its package ID In Conan, a package ID is a unique identifier for a package binary that takes into account all the factors that affect its binary compatibility. These factors include recipe options and settings as well as requirements or tool requirements. Let’s see how settings and options affect the package ID and some examples where they should not. ## How settings influence the package ID Settings are development project-wide variables, like the compiler, its version, or the OS itself. These variable values have to be defined, they should match the values of our development environment, and they cannot have a default value like options do. For example, let’s define a recipe that generates packages that are only OS dependent: ```python from conan import ConanFile class Pkg(ConanFile): name = "pkg" version = "1.0.0" settings = "os" # Only OS setting affects the package ID ``` If we generate a package from this recipe for Linux we will get the following package ID: ```bash $ conan create . --settings os=Linux ... pkg/1.0.0: Package '9a4eb3c8701508aa9458b1a73d0633783ecc2270' created $ conan list pkg/1.0.0:* Local Cache pkg pkg/1.0.0 revisions 476929a74c859bb5f646363a4900f7cf (2024-03-07 09:13:43 UTC) packages 9a4eb3c8701508aa9458b1a73d0633783ecc2270 info settings os: Linux ``` If we do the same thing with Windows, now the package ID will be different: ```bash $ conan create . --settings os=Windows ... pkg/1.0.0: Package 'ebec3dc6d7f6b907b3ada0c3d3cdc83613a2b715' created $ conan list pkg/1.0.0:* Local Cache pkg pkg/1.0.0 revisions 476929a74c859bb5f646363a4900f7cf (2024-03-07 09:13:43 UTC) packages 9a4eb3c8701508aa9458b1a73d0633783ecc2270 info settings os: Linux ebec3dc6d7f6b907b3ada0c3d3cdc83613a2b715 info settings os: Windows ``` Whenever a value of the settings or subsettings changes, the package ID will be different to reflect that. The most common usage for settings is to model the different project-wide aspects that might influence the package ID. A recipe that does that will be: ```python from conan import ConanFile class Pkg(ConanFile): name = "pkg" version = "1.0.0" settings = "os", "arch", "compiler", "build_type" ``` Now, compiling a package with different compiler versions will result into different package IDs: ```bash $ conan create . --settings compiler.version=192 ... pkg/1.0.0: Package '4f267380690f99b3ef385199826c268f63147457' created $ conan create . --settings compiler.version=193 ... pkg/1.0.0: Package 'c13a22a41ecd72caf9e556f68b406569547e0861' created $ conan list pkg/1.0.0:* Local Cache pkg pkg/1.0.0 revisions f1f48830ecb04f3b328429b390fc5de8 (2024-03-07 09:21:07 UTC) packages 4f267380690f99b3ef385199826c268f63147457 info settings arch: x86_64 build_type: Release compiler: msvc compiler.cppstd: 14 compiler.runtime: dynamic compiler.runtime_type: Release compiler.version: 192 os: Windows c13a22a41ecd72caf9e556f68b406569547e0861 info settings arch: x86_64 build_type: Release compiler: msvc compiler.cppstd: 14 compiler.runtime: dynamic compiler.runtime_type: Release compiler.version: 193 os: Windows ``` ### Removing settings for a package used as a tool_require There could be cases when a setting should not influence the resulting package ID. An example of this could be when a recipe packages a tool that would be used to build other packages via `tool_requires` In that case, the value of the compiler used is needed for the compilation of the tool but not that relevant for consumers, as we only want to execute the tool to build other projects. So we could eventually remove the influence of the compiler from the pacakge ID: ```python from conan import ConanFile class CMake(ConanFile): name = "cmake" version = "1.0.0" settings = "os", "arch", "compiler", "build_type" # Only OS and architecture influence the resulting package def build(self): # self.settings.compiler value will be used here to compile cmake def package_id(self): # Remove compiler setting from package ID del self.info.settings.compiler ``` Why not removing the setting from the settings attribute? Because the compiler value is still needed in the build() method to perform the compilation of the executable. #### NOTE In the case we are generating our own executables (our own apps, not a `tool_require`), **removing the compiler setting from package ID is not recommended**, as we would always want to know that the package was generated with a specific compiler. However, in case we are packaging a tool that does not even require a compiler input for building (a python script for example), we could also directly remove the settings attribute: ```python from conan import ConanFile class MyPythonScripts(ConanFile): name = "my-python-scripts" version = "1.0.0" # No settings this time ``` Or, if the tool is platform specific we can just keep the OS and architecture information: ```python from conan import ConanFile class MyScripts(ConanFile): name = "my-scripts" version = "1.0.0" settings = "os", "arch" ``` ## How options influence the package ID Options are used to specify characteristics that are particular to a single recipe, contrasting with settings that generally remain consistent across recipes within a project. They are usually a set of particular characteristics of a library executable or conan package may have. For example, a shared option is a very common option used in recipes that can produce shared libraries. However, it could not be a setting as not all recipes produce shared libraries. ```python from conan import ConanFile class Pkg(ConanFile): name = "pkg" version = "1.0.0" options = {"shared": [True, False]} default_options = {"shared": True} ``` As in the previous case with settings, the different values of an option will influence the package ID and therefore, generate different packages depending on it. ```bash $ conan create . --options shared=True ... pkg/1.0.0: Package '1744785cb24e3bdca70e27041dc5abd20476f947' created $ conan create . --options shared=False ... pkg/1.0.0: Package '55c609fe8808aa5308134cb5989d23d3caffccf2' created ``` In the same way, there might be “options” that are needed as input in a recipe to generate a package which shouldn’t be taken into account in the package ID. An example of this could be an option to control something that during the build phase but that does not influence the package result, like the *verbosity* of a compilation. In that case, the recipe should remove the option in the [package_id() method](https://docs.conan.io/2//reference/conanfile/methods/package_id.html.md#reference-conanfile-methods-package-id): However, the general advice is that **options should always affect the package ID**, and in case we would like to have an input to the recipe that should **not** affect it, it should be done via the [conf section](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-conf) of your profile. Then in the recipe we should just add: ```python from conan import ConanFile class MyPkg(ConanFile): name = "my-pkg" version = "1.0.0" def build(self): verbosity = self.conf.get("user.my-pkg:verbosity") self.output.info(f"Using verbosity level: {verbosity}) ... ``` ```text [conf] user.my-pkg:verbosity=silent ``` That way the package ID will be not affected, the recipe will be cleaner (without irrelevant options for package ID) and the input is easily managed via the profile’s conf section. #### SEE ALSO - [How the package_id is computed](https://docs.conan.io/2//reference/binary_model/package_id.html.md#reference-binary-model-package-id) - [Configure settings and options in recipes](https://docs.conan.io/2//tutorial/creating_packages/configure_options_settings.html.md#tutorial-creating-configure) --- https://docs.conan.io/2/reference/commands/audit.html.md --- # conan audit #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. *New feature in Conan 2.14.0* The `conan audit` command is used to check for known vulnerabilities in your Conan packages. See [the audit devops page](https://docs.conan.io/2//devops/audit.html.md#devops-audit) to see examples on how to use the `conan audit` command. ## conan audit scan ```text $ conan audit scan -h usage: conan audit scan [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--build-require] [-sl SEVERITY_LEVEL] [--context {host,build}] [-p PROVIDER] [path] Scan a given recipe for vulnerabilities in its dependencies. positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --build-require Whether the provided reference is a build-require -sl SEVERITY_LEVEL, --severity-level SEVERITY_LEVEL Set threshold for severity level to raise an error. By default raises an error for any critical CVSS (9.0 or higher). Use 100.0 to disable it. --context {host,build} Context to scan, by default both contexts are scanned if not specified -p PROVIDER, --provider PROVIDER Provider to use for scanning remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan audit scan` command checks for vulnerabilities in the given references and their transitive dependencies. This command receives configuration arguments such as profiles and settings, to control the expansion of the graph. ## conan audit list ```text $ conan audit list -h usage: conan audit list [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LIST] [-s SBOM] [-lock LOCKFILE] [-r REMOTE] [-p PROVIDER] [reference] List the vulnerabilities of the given reference. positional arguments: reference Reference to list vulnerabilities for options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LIST, --list LIST Package list file to list vulnerabilities for -s SBOM, --sbom SBOM SBOM file to list vulnerabilities for -lock LOCKFILE, --lockfile LOCKFILE Path to the lockfile to check for vulnerabilities -r REMOTE, --remote REMOTE Remote to use for listing -p PROVIDER, --provider PROVIDER Provider to use for scanning ``` The `conan audit list` command lists vulnerabilities for the given references, without checking their transitive dependencies. You can pass a single reference, a pkglist file with multiple references, a cyclonedx SBOM file generated with the [conan.tools.sbom](https://docs.conan.io/2//reference/tools/sbom.html.md#conan-tools-sbom) module, or a Conan lockfile. ## conan audit provider ```text $ conan audit provider -h usage: conan audit provider [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--url URL] [--type {conan-center-proxy,private}] [--token TOKEN] {add,list,auth,remove} [name] Manage security providers for the 'conan audit' command. positional arguments: {add,list,auth,remove} Action to perform from 'add', 'list' , 'remove' or 'auth' name Provider name options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --url URL Provider URL --type {conan-center-proxy,private} Provider type --token TOKEN Provider token ``` The `conan audit provider` command manages the list of providers used to check for vulnerabilities. By default the `conan audit` subcommands use the ConanCenter provider, but you can add your own providers to the list. For now, besides the default ConanCenter provider, only private JFrog Security providers are supported, see [the audit devops page](https://docs.conan.io/2//devops/audit.html.md#devops-audit-private-providers) for more information. There are 3 subcommands: - `conan audit provider auth`: Authenticates a provider with a token. - `conan audit provider add`: Adds a provider to the list. - `conan audit provider remove`: Removes a provider from the list. #### SEE ALSO - Read more in the dedicated [blog post](https://blog.conan.io/introducing-conan-audit-command/). --- https://docs.conan.io/2/reference/commands/build.html.md --- # conan build ```text $ conan build -h usage: conan build [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-g GENERATOR] [-of OUTPUT_FOLDER] [-d DEPLOYER] [--deployer-folder DEPLOYER_FOLDER] [--build-require] [--envs-generation {false}] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [path] Install dependencies and call the build() method. positional arguments: path Path to a python-based recipe file or a folder containing a conanfile.py recipe. conanfile.txt cannot be used with conan build. Defaults to current directory options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -g GENERATOR, --generator GENERATOR Generators to use -of OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER The root output folder for generated and build files -d DEPLOYER, --deployer DEPLOYER Deploy using the provided deployer to the output folder. Built-in deployers: 'full_deploy', 'direct_deploy', 'runtime_deploy' --deployer-folder DEPLOYER_FOLDER Deployer output folder, base build folder by default if not set --build-require Whether the provided path is a build-require --envs-generation {false} Generation strategy for virtual environment files for the root -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan build` command installs the recipe specified in `path` and calls its `build()` method. #### SEE ALSO - Read the tutorial about the [local package development flow](https://docs.conan.io/2//tutorial/developing_packages/local_package_development_flow.html.md#local-package-development-flow). --- https://docs.conan.io/2/reference/commands/cache.html.md --- # conan cache Perform file operations in the local cache (of recipes and/or packages). ## conan cache path ```text $ conan cache path -h usage: conan cache path [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--folder {export_source,source,build,metadata}] reference Show the path to the Conan cache for a given reference. positional arguments: reference Recipe reference or Package reference options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --folder {export_source,source,build,metadata} Path to show. The 'build' requires a package reference. If the argument is not passed, it shows 'exports' path for recipe references and 'package' folder for package references. ``` The `conan cache path` returns the path in the cache of a given reference. Depending on the reference, it could return the path of a recipe, or the path to a package binary. Let’s say that we have created a package in our current cache with: ```text $ conan new cmake_lib -d name=pkg -d version=0.1 $ conan create . ... Requirements pkg/0.1#cdc0d9d0e8f554d3df2388c535137d77 - Cache Requirements pkg/0.1#cdc0d9d0e8f554d3df2388c535137d77:2401fa1d188d289bb25c37cfa3317e13e377a351 - Build ``` And now we are interested in obtaining the path where our `pkg/0.1` recipe `conanfile.py` has been exported: ```text $ conan cache path pkg/0.1 /p/5cb229164ec1d245/e $ ls /p/5cb229164ec1d245/e conanfile.py conanmanifest.txt ``` By default, if the recipe revision is not specified, it means the “latest” revision in the cache. This can also be made explicit by the literal `#latest`, and also any recipe revision can be explicitly defined, these commands are equivalent to the above: ```text $ conan cache path pkg/0.1#latest /p/5cb229164ec1d245/e # The recipe revision might be different in your case. # Check the "conan create" output to get yours $ conan cache path pkg/0.1#cdc0d9d0e8f554d3df2388c535137d77 /p/5cb229164ec1d245/e ``` Together with the recipe folder, there are a two other folders that are common to all the binaries produced with this recipe: the “export_source” folder and the “source” folder. Both can be obtained with: ```text $ conan cache path pkg/0.1 --folder=export_source /p/5cb229164ec1d245/es $ ls /p/5cb229164ec1d245/es CMakeLists.txt include/ src/ $ conan cache path pkg/0.1 --folder=source /p/5cb229164ec1d245/s $ ls /p/5cb229164ec1d245/s CMakeLists.txt include/ src/ ``` In this case the contents of the “source” folder are identical to the ones of the “export_source” folder because the recipe did not implement any `source()` method that could retrieve code or do any other operation over the code, like applying patches. The recipe revision by default will be `#latest`, this follows the same rules as above. Note that these two folders will not exist if the package has not been built from source, like when a precompiled binary is retrieve from a server. It is also possible to obtain the folders of the binary packages providing the `package_id`: ```text # Your package_id might be different, it depends on the platform # Check the "conan create" output to obtain yours $ conan cache path pkg/0.1:2401fa1d188d289bb25c37cfa3317e13e377a351 /p/1cae77d6250c23b7/p $ ls /p/1cae77d6250c23b7/p conaninfo.txt conanmanifest.txt include/ lib/ ``` As above, by default it will resolve to the “latest” recipe revision and package revision. The command above is equal to explicitly defining `#latest` or the exact revisions. All the commands below are equivalent to the above one: ```text $ conan cache path pkg/0.1#latest:2401fa1d188d289bb25c37cfa3317e13e377a351 /p/1cae77d6250c23b7/p $ conan cache path pkg/0.1#latest:2401fa1d188d289bb25c37cfa3317e13e377a351#latest /p/1cae77d6250c23b7/p $ conan cache path pkg/0.1#cdc0d9d0e8f554d3df2388c535137d77:2401fa1d188d289bb25c37cfa3317e13e377a351 /p/1cae77d6250c23b7/p ``` It is possible to access the “build” folder with all the temporary build artifacts: ```text $ conan cache path pkg/0.1:2401fa1d188d289bb25c37cfa3317e13e377a351 --folder=build /p/1cae77d6250c23b7/b ls -al /p/1cae77d6250c23b7/b build/ CMakeLists.txt CMakeUserPresets.json conaninfo.txt include/ src/ ``` Again, the “build” folder will only exist if the package was built from source. #### NOTE **Best practices** - This `conan cache path` command is intended for eventual inspection of the cache, but the cache package storage must be considered **read-only**. Do not modify, change, remove or add files from the cache. - If you are using this command to obtain the path to artifacts and then copying them, consider the usage of a `deployer` instead. In the general case, extracting artifacts from the cache manually is discouraged. - Developers can use the `conan list ... --format=compact` to get the full references in a compact way that can be copied and pasted into the `conan cache path` command ## conan cache clean ```text $ conan cache clean -h usage: conan cache clean [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LIST] [-s] [-b] [-d] [-t] [-bs] [-p PACKAGE_QUERY] [pattern] Remove non-critical folders from the cache, like source, build and/or download (.tgz store) ones. positional arguments: pattern Selection pattern for references to clean options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LIST, --list LIST Package list of packages to clean -s, --source Clean source folders -b, --build Clean build folders -d, --download Clean download and metadata folders -t, --temp Clean temporary folders -bs, --backup-sources Clean backup sources -p PACKAGE_QUERY, --package-query PACKAGE_QUERY Remove only the packages matching a specific query, e.g., os=Windows AND (arch=x86 OR compiler=gcc) ``` This command will remove all temporary folders, along with the source, build and download folder that Conan generates in its execution. It will do so for every matching reference passed in *pattern*, or the contents of the pkglist file if the `--list` option is used. It’s possible to limit the cleaning to certain kinds of folders with different flags. **Examples**: - Remove all non-critical files: ```text $ conan cache clean "*" ``` - Remove all temporary files: ```text $ conan cache clean "*" --temp ``` - Remove the download folders for the `zlib` recipe: ```text $ conan cache clean "zlib/*" --download ``` - Remove everything but the download folder for the `zlib` recipe: ```text $ conan cache clean "zlib/*" --source --build --temp ``` - Get a list of packages to remove temp files from, then remove them: > ```text > $ conan list "zlib/*" -f=json > pkglist.json > $ conan cache clean --list pkglist.json > ``` ## conan cache check-integrity ```text $ conan cache check-integrity -h usage: conan cache check-integrity [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LIST] [-p PACKAGE_QUERY] [pattern] Check the integrity of the local cache for the given references positional arguments: pattern Selection pattern for references to check integrity for options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LIST, --list LIST Package list of packages to check integrity for -p PACKAGE_QUERY, --package-query PACKAGE_QUERY Only the packages matching a specific query, e.g., os=Windows AND (arch=x86 OR compiler=gcc) ``` The `conan cache check-integrity` command checks the integrity of Conan packages in the local cache that match the given *pattern*, or the contents of the pkglist file if the `--list` option is used. This means that it will throw an error if any file included in the `conanmanifest.txt` is missing or does not match the declared checksum in that file. For example, to verify the integrity of the whole Conan local cache, do: ```text $ conan cache check-integrity "*" mypkg/1.0: Integrity checked: ok mypkg/1.0:454923cd42d0da27b9b1294ebc3e4ecc84020747: Integrity checked: ok mypkg/1.0:454923cd42d0da27b9b1294ebc3e4ecc84020747: Integrity checked: ok zlib/1.3.1: Integrity checked: ok zlib/1.3.1:6fe7fa69f760aee504e0be85c12b2327c716f9e7: Integrity checked: ok ``` This command can also return a pkglist when the `--format=json` option is used. This returns the packages the are corrupted, which is useful for generating a list of packages that can later be used, for example, to remove all potentially corrupted packages in a single operation: ```text $ conan cache check-integrity "*" --format=json --out-file pkglist.json $ conan remove --list pkglist.json ``` ## conan cache backup-upload ```text $ conan cache backup-upload -h usage: conan cache backup-upload [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] Upload all the source backups present in the cache options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` The `conan cache backup-upload` will upload all source backups present in the local cache to the backup server, (excluding those which have been fetched from the excluded urls listed in the `core.sources:exclude_urls` conf), regardless of which package they belong to, if any. ## conan cache save ```text $ conan cache save -h usage: conan cache save [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LIST] [--file FILE] [--no-source] [pattern] Get the artifacts from a package list and archive them positional arguments: pattern A pattern in the form 'pkg/version#revision:package_id#revision', e.g: zlib/1.2.13:* means all binaries for zlib/1.2.13. If revision is not specified, it is assumed latest one. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LIST, --list LIST Package list of packages to save --file FILE Save to this file. Allowed extensions .tgz, .txz, .tzst (.txz and .tzst experimental and .tzst requires Python>=3.14) --no-source Exclude the sources ``` Read more in [Save and restore packages from/to the cache](https://docs.conan.io/2//devops/save_restore.html.md#devops-save-restore). ## conan cache restore ```text $ conan cache restore -h usage: conan cache restore [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] file Put the artifacts from an archive into the cache positional arguments: file Path to archive to restore options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Read more in [Save and restore packages from/to the cache](https://docs.conan.io/2//devops/save_restore.html.md#devops-save-restore). ## conan cache ref ```text $ conan cache ref -h usage: conan cache ref [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] path Show the reference for a given Conan cache folder positional arguments: path Path to a Conan cache folder options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` For a given cache folder, returns the Conan reference, that is, a recipe reference in the form `name/version#recipe_revision`, or a package reference in the form `name/version#recipe_revision:package_id#package_revision` (both could also have user/channel), depending on the contents of the folder. This is a developer and debugging command, intended for occasional developer usage while debugging potential issues, but it is not recommended for any other use case. #### NOTE **Best practices** Navigating the Conan cache is not an intended or supported use case. Using the `conan cache ref` command in any automation, CI or scripting is strongly discouraged. The `conan cache ref` is intended exclusively to be a helper command for developers while debugging. ## conan cache sign #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan cache sign -h usage: conan cache sign [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LIST] [-p PACKAGE_QUERY] [pattern] Sign packages with the Package Signing Plugin positional arguments: pattern Selection pattern for references to be signed options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LIST, --list LIST Package list of packages to be signed -p PACKAGE_QUERY, --package-query PACKAGE_QUERY Only the packages matching a specific query, e.g., os=Windows AND (arch=x86 OR compiler=gcc) ``` Signs the packages matching the pattern/reference or package list provided. For example: ```text $ conan list zlib/1.3.1:* --format=json > list.json $ conan cache sign --list=list.json [Package sign] Results: zlib/1.3.1 revisions bfceb3f8904b735f75c2b0df5713b1e6 packages 7bfde258ff4f62f75668d0896dbddedaa7480a0f [Package sign] Summary: OK=1, FAILED=0 ``` This command requires a configured package signing plugin, read more in [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). ## conan cache verify #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan cache verify -h usage: conan cache verify [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LIST] [-p PACKAGE_QUERY] [pattern] Check the signature of packages with the Package Signing Plugin positional arguments: pattern Selection pattern for references to verify their signature options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LIST, --list LIST Package list of packages to verify their signature -p PACKAGE_QUERY, --package-query PACKAGE_QUERY Only the packages matching a specific query, e.g., os=Windows AND (arch=x86 OR compiler=gcc) ``` Verifies the signatures of the packages matching the pattern/reference or a package list. This command requires as configured package signing plugin, read more in [Package signing](https://docs.conan.io/2//reference/extensions/package_signing.html.md#reference-extensions-package-signing). --- https://docs.conan.io/2/reference/commands/config.html.md --- # conan config Manage the Conan configuration in the Conan home. ## conan config home ```text $ conan config home -h usage: conan config home [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] Show the Conan home folder. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` The `conan config home` command returns the path of the Conan home folder. ```text $ conan config home /home/user/.conan2 ``` ## conan config install ```text $ conan config install -h usage: conan config install [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--verify-ssl [VERIFY_SSL] | --insecure] [-t {git,dir,file,url}] [-a ARGS] [-sf SOURCE_FOLDER] [-tf TARGET_FOLDER] item Install the configuration (remotes, profiles, conf), from git, http or a folder, into the Conan home folder. positional arguments: item git repository, local file or folder or zip file (local or http) where the configuration is stored options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --verify-ssl [VERIFY_SSL] Verify SSL connection when downloading file --insecure Allow insecure server connections when using SSL. Equivalent to --verify-ssl=False -t {git,dir,file,url}, --type {git,dir,file,url} Type of remote config -a ARGS, --args ARGS String with extra arguments for "git clone" -sf SOURCE_FOLDER, --source-folder SOURCE_FOLDER Install files only from a source subfolder from the specified origin -tf TARGET_FOLDER, --target-folder TARGET_FOLDER Install to that path in the conan cache ``` The `conan config install` command is intended to install in the current home a common shared Conan configuration, like the definitions of `remotes`, `profiles`, `settings`, `hooks`, `extensions`, etc. The command can use as source any of the following: - A URL pointing to a zip archive containing the configuration files - A git repository containing the files - A local folder - Just one file Files in the current Conan home will be replaced by the ones from the installation source. All the configuration files can be shared and installed this way: - `remotes.json` for the definition of remotes - Any custom profile files inside a `profiles` subfolder - Custom `settings.yml` - Custom `global.conf` - All the extensions, including plugins, hooks. - Custom user commands. This command reads a `.conanignore` file which, if present, filters which files and folders are copied over to the user’s Conan home folder. This file uses [fnmatch](https://docs.python.org/3/library/fnmatch.html) patterns to match over the folder contents, excluding those entries that match from the config installation. See [conan-io/command-extensions’s .conanignore](https://github.com/conan-io/command-extensions/blob/main/.conanignore) for an example of such a file. You can force certain files to be copied over by using the `!` negation syntax: ```text # Ignore all files * # But copy the file named "settings.yml" !settings.yml ``` **Examples**: - Install the configuration from a URL: ```text $ conan config install http://url/to/some/config.zip ``` - Install the configuration from a URL, but only getting the files inside a *origin* folder inside the zip file, and putting them inside a *target* folder in the local cache: ```text $ conan config install http://url/to/some/config.zip -sf=origin -tf=target ``` - Install configuration from 2 different zip files from 2 different urls, using different source and target folders for each one, then update all: ```text $ conan config install http://url/to/some/config.zip -sf=origin -tf=target $ conan config install http://url/to/some/config.zip -sf=origin2 -tf=target2 $ conan config install http://other/url/to/other.zip -sf=hooks -tf=hooks ``` - Install the configuration from a Git repository with submodules: ```text $ conan config install http://github.com/user/conan_config/.git --args="--recursive" ``` You can also force the git download by using **--type git** (in case it is not deduced from the URL automatically): ```text $ conan config install http://github.com/user/conan_config/.git --type git ``` - Install the configuration from a specific Git branch: ```text $ conan config install http://github.com/user/conan_config/.git --args="--branch mybranch" ``` - Install from a URL skipping SSL verification: ```text $ conan config install http://url/to/some/config.zip --verify-ssl=False ``` This will disable the SSL check of the certificate. - Install a specific file from a local path: ```text $ conan config install my_settings/settings.yml ``` - Install the configuration from a local path: ```text $ conan config install /path/to/some/config.zip ``` #### NOTE Since Conan 2.31, `conan config install` will warn if a `config_version.json` file already exists in the Conan home (which is created by `conan config install-pkg` to track installed configuration package versions). Mixing `conan config install` with `conan config install-pkg` is not recommended, as the plain `conan config install` is not tracked in `config_version.json` and may result in a configuration that is inconsistent with the tracked versions. In that case, consider running `conan config clean` first, or avoid mixing the two commands. ## conan config install-pkg #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan config install-pkg -h usage: conan config install-pkg [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [-f] [--insecure] [--url URL] [-pr PROFILE] [-s SETTINGS] [-o OPTIONS] [reference] (Experimental) Install the configuration (remotes, profiles, conf), from a Conan package or from a conanconfig.yml file positional arguments: reference Package reference 'pkg/version' to install configuration from or path to 'conanconfig.yml' file options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile -f, --force Force the re-installation of configuration --insecure Allow insecure server connections when using SSL --url URL (Experimental) Provide Conan repository URL (for first install without remotes) -pr PROFILE, --profile PROFILE Profile to install config -s SETTINGS, --settings SETTINGS Settings to install config -o OPTIONS, --options OPTIONS Options to install config ``` This command allows to install configuration from a Conan package stored in a Conan server. The packages containing configuration follow some special rules: - They must define the `package_type = "configuration"` - The configuration files must be packaged in the final “binary” package, following the same layout as they would for other `conan config install` cases. - They cannot be used as `requires` of other packages, because that would result in a chicken-and-egg problem. - They cannot contain `requires` to other packages - The configuration packages are created with `conan create` and `conan export-pkg` as other packages, and uploaded to the servers with `conan upload` To install a configuration from a Conan configuration package, it is possible: - To generate a lockfile file with `--lockfile-out`. This lockfile file can be passed to `conan config install-pkg --lockfile` (it will automatically loaded it if is named `conan.lock` and found in the current directory) in the future to guarantee the same exact version. - Version ranges can be used `conan config install-pkg "myconf/[>=1.0 <2]"` is correct, and it will install the latest one in that range. - `conan config install-pkg` always look in the server for the latest version or revision. - If the same version and revision was downloaded and installed from the server, `conan config install-pkg` will be a no-op unless `--force` is used, in this case the configuration will be overwritten. It is also possible to make the version of the configuration affect all packages `package_id` and be part of the binary model, by activating the `core.package_id:config_mode` conf (this is also experimental), to any available mode, like `minor_mode`. Note that the order of the installation of packages in case multiple configuration packages are installed is important. This is why Conan will raise an error if the relative order of installed configuration packages changes as the result of installing updates for those configuration packages. As the `conan config install-pkg` command downloads the package from a Conan remote server, it can download from an already existing remote, or it can download from a Conan remote directly specifying the repository URL: ```bash $ conan config install-pkg myconf/version --url= ``` In the same way that `conan remote add` can define `--insecure` to disable the SSL verification for that remote, it is possible to disable it for `conan config install-pkg` with: ```bash $ conan config install-pkg myconf/version --url= --insecure ``` When specifying the `--url` argument, a Conan remote named `config_install_url` is created on the fly. That means that if authentication is desired via env-vars, the env-var names will be `CONAN_LOGIN_USERNAME_CONFIG_INSTALL_URL` or `CONAN_PASSWORD_CONFIG_INSTALL_URL`. Conan configuration packages can also be parameterized depending on profiles, settings and options. For example, if some organization would like to manage their configuration slightly differently for Windows and other platforms they could do: ```python import os from conan import ConanFile from conan.tools.files import copy class Conf(ConanFile): name = "myconf" version = "0.1" settings = "os" package_type = "configuration" def package(self): f = "win" if self.settings.os == "Windows" else "nix" copy(self, "*.conf", src=os.path.join(self.build_folder, f), dst=self.package_folder) ``` And if they had a layout with different `global.conf` for the different platforms, like: ```text conanfile.py win/global.conf nix/global.conf ``` They could create and upload their configuration package as: ```bash $ conan export-pkg . -s os=Windows $ conan export-pkg . -s os=Linux $ conan upload "*" -r=remote -c ``` Then, developers could do: ```bash $ conan config install-pkg "myconf/[*]" -s os=Linux # or even implicitly, if they default build profile defines os=Linux $ conan config install-pkg "myconf/[*]" ``` And they will get the correct configuration for their platform. #### SEE ALSO - If you lock installed configuration packages in a lockfile, you could use the [conan lock upgrade-config](https://docs.conan.io/2//reference/commands/lock/upgrade_config.html.md#reference-commands-lock-upgrade-config) command to update such a lockfile. ### conanconfig.yml The `conan config install-pkg` admits also as an input a yaml `conanconfig.yml` file that can contain more than one package requirement, something like: ```yaml packages: - myconf_a/0.1 - myconf_b/0.1 - myconf_c/[>=1 <2] ``` and be used like `conan config install-pkg .` or even just `conan config install-pkg`. The file also admits the definition of `urls` with the same meaning as the `--url` command line argument, to simplify the initial installation of configuration when doing a Conan setup: ```yaml packages: - myconf_a/0.1 - myconf_b/0.1 - myconf_c/[>=1 <2] urls: - https://my/conan/remote/repo/url ``` Like in the `remotes.json` file, the `urls` in the `conanconfig.yml` file can also add the `verify_ssl` specifier to disable SSL verification, with the same behavior as the command line argument `--insecure`: ```yaml packages: - myconf/0.1 urls: - url: https://some.server.com verify_ssl: false ``` #### IMPORTANT When installing more than 1 configuration package, the order of installation is important, as the later installed packages can overwrite configuration files installed by the previous ones. Consequently, if you decide to make the configuration part of the packages `package_id` via `core.package_id:config_mode` conf, the order is taken into account. Then any installation or re-installation of packages or updates that change this order will be raised as an error. For example if after installing the configuration from the `conanconfig.yml` above we try to do a `conan config install-pkg myconf_a/0.2`, that will be raised as an error, because that would make `myconf_a` to be the latest installed one, not the first. But on the other hand, doing an update with the previous file will not be an error, because it will re-install the `myconf_a`, `myconf_b` and `myconf_c` in order. Likewise, doing an update only for `myconf_c` wouldn’t be an error, because it is the last one and preserves the relative order. ### Configuration packages in lockfiles When a configuration package is stored in a lockfile, with the `--lockfile-out` argument, it will create an entry in the lockfile `config_requires` entry. This entry has different purposes: - When installing configuration packages with `conan config install-pkg` using command line arguments or a `conanconfig.yml` file that contains version ranges, or even pinned versions, but no recipe-revision, the provided lockfile can constraint that input to force and guarantee the exact version and recipe revision for that package defined in the lockfile. - When using a lockfile as input in regular `conan install/build/create/graph-info`, etc, it will perform a check of the installed configuration packages, and if they are not aligned with the lockfile defined `config_requires` it will raise an error. Users then can issue a `conan config install-pkg` command to install the required configuration packages so their environments align. The idea is that lockfiles `config_requires` are there to guarantee the same configuration. The check goes in both directions, configuration packages already installed in the current user cache must satisfy the lockfile constraints, and lockfile declared `config_requires` must be installed. If for any reason, this behaviour wouldn’t be desired, it is possible to use a different lockfile just for the configurations, independent from the regular packages lockfiles, avoiding in this way a populated `config_requires` when using regular packages installation commands. ## conan config list ```text $ conan config list -h usage: conan config list [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [pattern] Show all the Conan available configurations: core and tools. positional arguments: pattern Filter configuration items that matches this pattern options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Displays all the Conan built-in configurations. There are 2 groups: - `core.xxxx`: These can only be defined in `global.conf` and are used by Conan internally - `tools.xxxx`: These can be defined both in `global.conf` and profiles, and will be used by recipes and tools used within recipes, like `CMakeToolchain` ```text $ conan config list core.cache:storage_path: Absolute path where the packages and database are stored core.download:download_cache: Define path to a file download cache. Files uploaded to a server are also stored here, so a later download of the same artifact can be skipped core.download:parallel: Number of concurrent threads to download packages core.download:retry: (int, default: 2) Number of retries in case of failure when downloading from Conan server core.download:retry_wait: (int, default: 1s) Seconds to wait between download attempts from Conan server core.graph:compatibility_mode: (Experimental) Set this to 'optimized' to enable the improved compatibility behaviour when querying multiple compatible binaries in remotes core.gzip:compresslevel: The Gzip compression level for Conan artifacts (default=9) core.net.http:cacert_path: Path containing a custom Cacert file core.net.http:clean_system_proxy: If defined, the proxies system env-vars will be discarded core.net.http:client_cert: Path or tuple of files containing a client cert (and key) core.net.http:max_retries: Maximum number of connection retries (requests library) core.net.http:no_proxy_match: List of urls to skip from proxies configuration core.net.http:proxies: Dictionary containing the proxy configuration core.net.http:timeout: Number of seconds without response to timeout (requests library) core.package_id:config_mode: How the 'config_version' affects binaries. By default 'None' core.package_id:default_build_mode: By default, 'None' core.package_id:default_embed_mode: By default, 'full_mode' core.package_id:default_non_embed_mode: By default, 'minor_mode' core.package_id:default_python_mode: By default, 'minor_mode' core.package_id:default_unknown_mode: By default, 'semver_mode' core.scm:excluded: List of excluded patterns for builtin git dirty checks core.scm:local_url: By default allows to store local folders as remote url, but not upload them. Use 'allow' for allowing upload and 'block' to completely forbid it core.sources.patch:extra_path: Extra path to search for patch files for conan create core.sources:download_cache: Folder to store the sources backup core.sources:download_urls: List of URLs to download backup sources from core.sources:exclude_urls: URLs which will not be backed up core.sources:upload_url: Remote URL to upload backup sources to core.upload:compression_format: The compression format used when uploading Conan packages. Possible values: 'zst', 'xz', 'gz' (default=gz) core.upload:parallel: Number of concurrent threads to upload packages core.upload:retry: (int, default: 1) Number of retries in case of failure when uploading to Conan server core.upload:retry_wait: (int, default: 5s) Seconds to wait between upload attempts to Conan server core.version_ranges:resolve_prereleases: Whether version ranges can resolve to pre-releases or not core:allow_uppercase_pkg_names: Temporarily (will be removed in 2.X) allow uppercase names core:compresslevel: The compression level for Conan artifacts (default zstd=3, gz=9) core:default_build_profile: Defines the default build profile ('default' by default) core:default_profile: Defines the default host profile ('default' by default) core:non_interactive: Disable interactive user input, raises error if input necessary core:policies: A list of opt-in behaviors that can be defined in the configuration to control specific aspects of Conan's behavior, such as keeping deprecated behaviours: - If required_conan_version>=2.28, bugfix https://github.com/conan-io/conan/pull/19705 for transitive static libraries package_id - If required_conan_version>=2.28, bugfix https://github.com/conan-io/conan/pull/19849 for VirtualBuildEnv bindir path propagation based on requirement run trait - If required_conan_version>=2.28, https://github.com/conan-io/conan/pull/19286 defaults the new 'consistent' trait to True for the host context, even when 'visible=False' - If required_conan_version>=2.30, bugfix https://github.com/conan-io/conan/pull/20073 for propagation of the 'transitive_header' trait core:required_conan_version: Raise if current version does not match the defined range. core:skip_warnings: Do not show warnings matching any of the patterns in this list. Current warning tags are 'network', 'deprecated', 'experimental' core:update_policy: (Legacy). If equal 'legacy' when multiple remotes, update based on order of remotes, only the timestamp of the first occurrence of each revision counts. core:warnings_as_errors: Treat warnings matching any of the patterns in this list as errors and then raise an exception. Current warning tags are 'network', 'deprecated' tools.android:cmake_legacy_toolchain: Define to explicitly pass ANDROID_USE_LEGACY_TOOLCHAIN_FILE in CMake toolchain tools.android:ndk_path: Argument for the CMAKE_ANDROID_NDK tools.apple:enable_arc: (boolean) Enable/Disable ARC Apple Clang flags tools.apple:enable_bitcode: (boolean) Enable/Disable Bitcode Apple Clang flags tools.apple:enable_visibility: (boolean) Enable/Disable Visibility Apple Clang flags tools.apple:sdk_path: Path to the SDK to be used tools.build.cross_building:can_run: (boolean) Indicates whether is possible to run a non-native app on the same architecture. It's used by 'can_run' tool tools.build.cross_building:cross_build: (boolean) Decides whether cross-building or not regardless of arch/OS settings. Used by 'cross_building' tool tools.build:add_rpath_link: Add -Wl,-rpath-link flags pointing to all lib directories for host dependencies (CMake and Meson toolchains) tools.build:asmflags: List of extra ASM flags used by CMakeToolchain tools.build:cflags: List of extra C flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain tools.build:compiler_executables: Defines a Python dict-like with the compilers path to be used. Allowed keys {'c', 'cpp', 'cuda', 'objc', 'objcxx', 'rc', 'fortran', 'asm', 'hip', 'ispc'} tools.build:cxxflags: List of extra CXX flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain tools.build:defines: List of extra definition flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain tools.build:download_source: Force download of sources for every package tools.build:exelinkflags: List of extra flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain tools.build:install_strip: (boolean or list) True/False to strip on install for every CMake, Meson and Autotools integration, or a list of 'cmake', 'meson', 'autotools' to strip only for those. tools.build:jobs: Default compile jobs number -jX Ninja, Make, /MP VS (default: max CPUs) tools.build:linker_scripts: List of linker script files to pass to the linker used by different toolchains like CMakeToolchain, AutotoolsToolchain, and MesonToolchain tools.build:rcflags: List of extra RC (resource compiler) flags used by different toolchains like CMakeToolchain, MSBuildToolchain and MesonToolchain tools.build:sharedlinkflags: List of extra flags used by different toolchains like CMakeToolchain, AutotoolsToolchain and MesonToolchain tools.build:skip_test: Do not execute CMake.test() and Meson.test() when enabled tools.build:sysroot: Pass the --sysroot= flag if available. (None by default) tools.build:verbosity: Verbosity of build systems if set. Possible values are 'quiet' and 'verbose' tools.cmake.cmake_layout:build_folder: (Experimental) Allow configuring the base folder of the build for local builds tools.cmake.cmake_layout:build_folder_vars: Settings and Options that will produce a different build folder and different CMake presets names tools.cmake.cmake_layout:test_folder: (Experimental) Allow configuring the base folder of the build for test_package tools.cmake.cmakedeps:new: Use the new CMakeDeps generator tools.cmake.cmaketoolchain:enabled_blocks: Select the specific blocks to use in the conan_toolchain.cmake tools.cmake.cmaketoolchain:extra_variables: Dictionary with variables to be injected in CMakeToolchain (potential override of CMakeToolchain defined variables) tools.cmake.cmaketoolchain:find_package_prefer_config: Argument for the CMAKE_FIND_PACKAGE_PREFER_CONFIG tools.cmake.cmaketoolchain:generator: User defined CMake generator to use instead of default tools.cmake.cmaketoolchain:presets_environment: String to define wether to add or not the environment section to the CMake presets. Empty by default, will generate the environment section in CMakePresets. Can take values: 'disabled'. tools.cmake.cmaketoolchain:system_name: Define CMAKE_SYSTEM_NAME in CMakeToolchain tools.cmake.cmaketoolchain:system_processor: Define CMAKE_SYSTEM_PROCESSOR in CMakeToolchain tools.cmake.cmaketoolchain:system_version: Define CMAKE_SYSTEM_VERSION in CMakeToolchain tools.cmake.cmaketoolchain:toolchain_file: Use other existing file rather than conan_toolchain.cmake one tools.cmake.cmaketoolchain:toolset_arch: Toolset architecture to be used as part of CMAKE_GENERATOR_TOOLSET in CMakeToolchain tools.cmake.cmaketoolchain:toolset_cuda: (Experimental) Path to a CUDA toolset to use, or version if installed at the system level tools.cmake.cmaketoolchain:user_presets: (Experimental) Select a different name or relative filepath instead of CMakeUserPresets.json, empty to disable. A relative filepath (with directory component) enables CMake 4.4+ --preset-file mode tools.cmake.cmaketoolchain:user_toolchain: Inject existing user toolchains at the beginning of conan_toolchain.cmake tools.cmake:cmake_program: Path to CMake executable tools.cmake:configure_args: Add extra arguments to CMake.configure() command line tools.cmake:ctest_args: Add extra arguments to CMake.ctest() runner command line tools.cmake:install_strip: (Deprecated) Add --strip to cmake.install(). Use tools.build:install_strip instead tools.compilation:verbosity: Verbosity of compilation tools if set. Possible values are 'quiet' and 'verbose' tools.deployer:symlinks: Set to False to disable deployers copying symlinks tools.env.virtualenv:powershell: If specified, it generates PowerShell launchers (.ps1). Use this configuration setting the PowerShell executable you want to use (e.g., 'powershell.exe' or 'pwsh') tools.env:deactivation_mode: (Experimental) If 'function', generate a deactivate function instead of a script to unset the environment variables tools.env:dotenv: (Experimental) Generate dotenv environment files tools.files.download:retry: (int, default: 2) Number of retries in case of failure when downloading tools.files.download:retry_wait: (int, default: 5s) Seconds to wait between download attempts tools.files.download:verify: If set, overrides recipes on whether to perform SSL verification for their downloaded files. Only recommended to be set while testing tools.files.unzip:filter: Define tar extraction filter: 'fully_trusted', 'tar', 'data' tools.gnu:build_triplet: Custom build triplet to pass to Autotools scripts tools.gnu:define_libcxx11_abi: Force definition of GLIBCXX_USE_CXX11_ABI=1 for libstdc++11 tools.gnu:disable_flags: Disable the automatic addition of flags to some build systems. List of possible values: ['arch', 'arch_link', 'libcxx', 'build_type', 'build_type_link', 'threads','cppstd', 'cstd'] tools.gnu:extra_configure_args: List of extra arguments to pass to configure when using AutotoolsToolchain and GnuToolchain tools.gnu:host_triplet: Custom host triplet to pass to Autotools scripts tools.gnu:make_program: Indicate path to make program tools.gnu:pkg_config: Path to pkg-config executable used by PkgConfig build helper tools.google.bazel:bazelrc_path: List of paths to bazelrc files to be used as 'bazel --bazelrc=rcpath1 ... build' tools.google.bazel:configs: List of Bazel configurations to be used as 'bazel build --config=config1 ...' tools.graph:skip_binaries: Allow the graph to skip binaries not needed in the current configuration (True by default) tools.graph:skip_build: (Experimental) Do not expand build/tool_requires tools.graph:skip_test: (Experimental) Do not expand test_requires. If building it might need 'tools.build:skip_test=True' tools.graph:vendor: (Experimental) If 'build', enables the computation of dependencies of vendoring packages to build them tools.info.package_id:confs: List of existing configuration to be part of the package ID tools.intel:installation_path: Defines the Intel oneAPI installation root path tools.intel:setvars_args: Custom arguments to be passed onto the setvars.sh|bat script from Intel oneAPI tools.meson.mesontoolchain:backend: Any Meson backend: ninja, vs, vs2010, vs2012, vs2013, vs2015, vs2017, vs2019, xcode tools.meson.mesontoolchain:extra_machine_files: List of paths for any additional native/cross file references to be appended to the existing Conan ones tools.meson.mesontoolchain:extra_variables: Dict of dicts defining extra variables per meson file section: 'properties', 'binaries', 'project_options' tools.microsoft.bash:active: Set True only when Conan runs in a POSIX Bash (MSYS2/Cygwin) where Python's subprocess (shell=True) uses a POSIX-compatible shell (e.g., /bin/sh). Do not set when using Conan from cmd/PowerShell or with native Windows Python ('win32'). tools.microsoft.bash:path: The path to the shell to run when conanfile.win_bash==True tools.microsoft.bash:subsystem: The subsystem to be used when conanfile.win_bash==True. Possible values: msys2, msys, cygwin, wsl, sfu tools.microsoft.msbuild:installation_path: VS install path, to avoid auto-detect via vswhere, like C:/Program Files (x86)/Microsoft Visual Studio/2019/Community. Use empty string to disable tools.microsoft.msbuild:max_cpu_count: Argument for the /m when running msvc to build parallel projects tools.microsoft.msbuild:vs_version: Defines the IDE version (15, 16, 17) when using the msvc compiler. Necessary if compiler.version specifies a toolset that is not the IDE default tools.microsoft.msbuilddeps:exclude_code_analysis: Suppress MSBuild code analysis for patterns tools.microsoft.msbuildtoolchain:compile_options: Dictionary with MSBuild compiler options tools.microsoft:msvc_update: Force the specific update irrespective of compiler.update (CMakeToolchain and VCVars) tools.microsoft:winsdk_version: Use this winsdk_version in vcvars tools.system.package_manager:mode: Mode for package_manager tools: 'check', 'report', 'report-installed' or 'install' tools.system.package_manager:sudo: Use 'sudo' when invoking the package manager tools in Linux (False by default) tools.system.package_manager:sudo_askpass: Use the '-A' argument if using sudo in Linux to invoke the system package manager (False by default) tools.system.package_manager:tool: Default package manager tool: 'apk', 'apt-get', 'yum', 'dnf', 'brew', 'pacman', 'choco', 'zypper', 'pkg' or 'pkgutil' tools.system.pipenv:python_interpreter: (Deprecated) Use 'tools.system.pyenv:python_interpreter' instead. Path to the Python interpreter to be used to create the virtualenv tools.system.pyenv:python_interpreter: (Experimental) Path to the Python interpreter to be used to create the virtualenv ``` It is possible to list only the configurations that match a given pattern, like: ```bash $ conan config list proxy core.net.http:clean_system_proxy: If defined, the proxies system env-vars will be discarded core.net.http:no_proxy_match: List of urls to skip from proxies configuration core.net.http:proxies: Dictionary containing the proxy configuration ``` #### SEE ALSO - These configurations can be defined in `global.conf`, profile files and command line, see [Conan configuration files](https://docs.conan.io/2//reference/config_files.html.md#reference-config-files) ## conan config show ```text $ conan config show -h usage: conan config show [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] pattern Get the value of the specified conf positional arguments: pattern Conf item(s) pattern for which to query their value options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Shows the values of the conf items that match the given pattern. For a *global.conf* consisting of ```text tools.build:jobs=42 tools.files.download:retry_wait=10 tools.files.download:retry=7 core.net.http:timeout=30 core.net.http:max_retries=5 zlib*/:tools.files.download:retry_wait=100 zlib*/:tools.files.download:retry=5 ``` You can get all the values: ```text $ conan config show "*" core.net.http:max_retries: 5 core.net.http:timeout: 30 tools.files.download:retry: 7 tools.files.download:retry_wait: 10 tools.build:jobs: 42 zlib*/:tools.files.download:retry: 5 zlib*/:tools.files.download:retry_wait: 100 ``` Or just those referring to the `tools.files` section: ```text $ conan config show "*tools.files*" tools.files.download:retry: 7 tools.files.download:retry_wait: 10 zlib*/:tools.files.download:retry: 5 zlib*/:tools.files.download:retry_wait: 100 ``` Notice the first `*` in the pattern. This will match all the package patterns. Removing it will make the command only show global confs: ```text $ conan config show "tools.files*" tools.files.download:retry: 7 tools.files.download:retry_wait: 10 ``` ## conan config clean ```text $ conan config clean -h usage: conan config clean [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] (Experimental) Clean the configuration files in the Conan home folder, while keeping installed packages options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Removes all the custom configuration from the Conan home, such as `remotes.json`, profiles, settings, plugins, extensions, etc. This does not remove packages, only the configuration files. --- https://docs.conan.io/2/reference/commands/create.html.md --- # conan create ```text $ conan create -h usage: conan create [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--build-require] [-tf TEST_FOLDER] [-tm] [-bt BUILD_TEST] [path] Create a package. positional arguments: path Path to a folder containing a recipe (conanfile.py). Defaults to current directory options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --build-require Whether the package being created is a build-require (to be used as tool_requires() by other packages) -tf TEST_FOLDER, --test-folder TEST_FOLDER Alternative test folder name. By default it is "test_package". Use "" to skip the test stage -tm, --test-missing Run the test_package checks only if the package is built from source but not if it already existed (using --build=missing) -bt BUILD_TEST, --build-test BUILD_TEST Same as '--build' but only for the test_package requires. By default if not specified it will take the '--build' value if specified reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL ``` The `conan create` command creates a package from the recipe specified in `path`. This command will first **export** the recipe to the local cache and then build and create the package. If a `test_package` folder (you can change the folder name with the `-tf` argument or with the `test_package_folder` recipe attribute) is found, the command will run the consumer project to ensure that the package has been created correctly. Check [testing Conan packages](https://docs.conan.io/2//tutorial/creating_packages/test_conan_packages.html.md#tutorial-creating-test) section to know more about how to test your Conan packages. ## Using conan create with build requirements The `--build-require` argument allows to create the package using the configuration and settings of the “build” context, as it was a `build_require`. This feature allows to create packages in a way that is consistent with the way they will be used later. ```bash $ conan create . --name=cmake --version=3.23.1 --build-require ``` ## Conan create output The `conan create ... --format=json` creates a json output containing the full dependency graph information. This json is the same as the one created with `conan graph info` (see the [graph info json format](https://docs.conan.io/2//reference/commands/formatters/graph_info_json_formatter.html.md#reference-commands-graph-info-json-format)) with extended information about the binaries, like a more complete `cpp_info` field. This resulting json is the dependency graph of the package recipe being created, excluding all the `test_package` and other possible dependencies of the `test_package/conanfile.py`. These dependencies only exist in the `test_package` functionality, and as such, are not part of the “main” product or package. If you are interested in capturing the dependency graph including the `test_package` (most likely not necessary in most cases), then you can do it running the `conan test` command separately. The same happens for lockfiles created with `--lockfile-out` argument. The lockfile will only contain the created package and its transitive dependencies versions, but it will not contain the `test_package` or the transitive dependencies of the `test_package/conanfile.py`. It is possible to capture a lockfile which includes those with the `conan test` command (though again, this might not be really necessary) #### NOTE **Best practice** In general, having `test_package/conanfile.py` with dependencies other than the tested one should be avoided. The `test_package` functionality should serve as a simple check to ensure the package is correctly created. Adding extra dependencies to `test_package` might indicate that the check is not straightforward or that its functionality is being misused. If, for any reason, your `test_package` has additional dependencies, you can control their build using the `--build-test` argument. ## Methods execution order The `conan create` executes [methods](https://docs.conan.io/2//reference/conanfile/methods.html.md#reference-conanfile-methods) of a *conanfile.py* in the following order: 1. Export recipe to the cache : 1. `init()` 2. `set_name()` 3. `set_version()` 4. `export()` 5. `export_sources()` 2. Compute dependency graph : 1. `ìnit()` 2. `config_options()` 3. `configure()` 4. `requirements()` 5. `build_requirements()` 3. Compute necessary packages : 1. `validate_build()` 2. `validate()` 3. `package_id()` 4. `layout()` 5. `system_requirements()` 4. Install packages : 1. `source()` 2. `build_id()` 3. `generate()` 4. `build()` 5. `package()` 6. `package_info()` Steps `generate()`, `build()`, `package()` from *Install packages* step will not be called if the package is not being built from sources. After that, if you have a folder named *test_package* in your project or you call the `conan create` command with the `--test-folder` flag, the command will invoke the methods of the *conanfile.py* file inside the folder in the following order: 1. Launch test_package : 1. (test package) `init()` 2. (test package) `set_name()` 3. (test package) `set_version()` 2. Compute dependency graph : 1. (test package) `config_options()` 2. (test package) `configure()` 3. (test package) `requirements()` 4. (test package) `build_requirements()` 5. `ìnit()` 6. `config_options()` 7. `configure()` 8. `requirements()` 9. `build_requirements()` 3. Compute necessary packages : 1. `validate_build()` 2. `validate()` 3. `package_id()` 4. `layout()` 5. (test package) `validate_build()` 6. (test package) `validate()` 7. (test package) `package_id()` 8. (test package) `layout()` 9. `system_requirements()` 10. (test package) `system_requirements()` 4. Install packages : 1. `build_id()` 2. `generate()` 3. `build()` 4. `package_info()` 5. Test the package : 1. (test package) `build()` 2. (test package) `test()` The functions with *(test package)* belong to the *conanfile.py* in the *test_package* folder. The steps `build_id()`, `generate()`, `build()` inside the *Install packages* step will be skipped if the project is already installed. Typically, it should be installed just as it was installed in the previous “install packages” step. When using the `cmake_layout()` functionality inside `test_package`, the conf `tools.cmake.cmake_layout:test_folder` can be used to define the location of the build artifacts for the `test_package`. See [cmake_layout() docs](https://docs.conan.io/2//reference/tools/cmake/cmake_layout.html.md#cmake-layout). Likewise, the full path to the build artifacts will be defined by the `self.folders.build_folder_vars` attribute. ## Build modes The `conan create --build=` build modes are very similar to the `conan install` ones documented in [Build Modes](https://docs.conan.io/2//reference/commands/install.html.md#reference-commands-build-modes), with some differences. By default, `conan create` defines the `--build=current_pkg/current_version` to force the build from source for the current revision. This assumes that the source code (recipe, C/C++ code) was changed and it will create a new revision. If that is not the case, then the `--build=missing:current_pkg/current_version`, or `--build="missing:&"` would be recommended to avoid rebuilding from source an already existing binary. When a `--build=xxx` argument is defined in the command line, then the automatically defined `--build=current_pkg/current_version` is no longer passed, and it should be passed as a explicit argument too. #### NOTE **Best practices** Having more than a `package_revision` for a given `recipe_revision` and `package_id` is discouraged in most cases, as it implies unnecessarily rebuilding from sources binaries that were already existing. For that reason, using `conan create` repeatedly over the same recipe without any source changes that would cause a new `recipe_revision` is discouraged, and using `conan create . --build=missing:[pattern]` would be the recommended approach. #### SEE ALSO - Read more about creating packages in the [dedicated tutorial](https://docs.conan.io/2//tutorial/creating_packages.html.md#tutorial-creating-packages) - Read more about [testing Conan packages](https://docs.conan.io/2//tutorial/creating_packages/test_conan_packages.html.md#tutorial-creating-test) --- https://docs.conan.io/2/reference/commands/download.html.md --- # conan download ```text $ conan download -h usage: conan download [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--only-recipe] [-p PACKAGE_QUERY] -r REMOTE [-m METADATA] [-l LIST] [pattern] Download (without installing) a single conan package from a remote server. It downloads just the package, but not its transitive dependencies, and it will not call any generate, generators or deployers. It can download multiple packages if patterns are used, and also works with queries over the package binaries. positional arguments: pattern A pattern in the form 'pkg/version#revision:package_id#revision', e.g: "zlib/1.2.13:*" means all binaries for zlib/1.2.13. If revision is not specified, it is assumed latest one. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --only-recipe Download only the recipe/s, not the binary packages. -p PACKAGE_QUERY, --package-query PACKAGE_QUERY Only download packages matching a specific query. e.g: os=Windows AND (arch=x86 OR compiler=gcc) -r REMOTE, --remote REMOTE Download from this specific remote -m METADATA, --metadata METADATA Download the metadata matching the pattern, even if the package is already in the cache and not downloaded -l LIST, --list LIST Package list file ``` Downloads recipe and binaries to the local cache from the specified remote. #### NOTE Please, be aware that **conan download** unlike **conan install**, will not download any of the transitive dependencies of the downloaded package. The `conan download` command can download packages to 1 server repository specified by the `-r=myremote` argument. It has 2 possible and mutually exclusive inputs: - The `conan download ` pattern-based matching of recipes, with a pattern similar to the `conan list `. - The `conan download --list=` that will download the artifacts specified in the `pkglist` json file You can use patterns to download specific references just like in other commands like **conan list** (see the patterns documentation there [conan list](https://docs.conan.io/2//reference/commands/list.html.md#reference-commands-list)) or **conan upload**: ```bash # download latest revision and packages for all openssl versions in foo remote $ conan download "openssl/*" -r foo ``` #### NOTE **conan download** will download only the latest revision by default. If you want to download more revisions other than the latest one you can use wildcards in the revisions part of the reference pattern argument You may also just download recipes (in this case selecting all the revisions in the pattern, not just the latest one): ```bash # download all recipe revisions for zlib/1.2.13 $ conan download "zlib/1.2.13#*" -r foo --only-recipe ``` If you just want to download the packages belonging to a specific setting, use the `--package-query` argument: ```bash $ conan download "zlib/1.2.13#*" -r foo --package-query="os=Linux and arch=x86" ``` If the `--format=json` formatter is specified, the result will be a “PackageList”, compatible with other Conan commands, for example the `conan upload` command, so it is possible to concatenate a `download + upload`, using the generated json file. See the [Packages Lists examples](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists). ## Downloading metadata The metadata files of the recipes and packages are not downloaded by default. It is possible to explicitly retrieve them with the `conan download --metadata=xxx` argument. The main arguments are the same as above, and Conan will download the specified packages, or skip them if they are already in the cache: ```bash $ conan download pkg/0.1 -r=default --metadata="*" # will download pgkg/0.1 recipe with all the recipe metadata # And also all package binaries (latest package revision) # with all the binaries metadata ``` If only one or several metadata folders or sets of files are desired, it can also be specified: ```bash $ conan download pkg/0.1 -r=default --metadata="logs/*" --metadata="tests/*" # Will download only the logs and tests metadata, but not other potential metadata files ``` For more information see the [metadata section](https://docs.conan.io/2//devops/metadata.html.md#devops-metadata). #### NOTE [See here for examples of using package lists for downloading.](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists) --- https://docs.conan.io/2/reference/commands/editable.html.md --- # conan editable Allow working with a package that resides in user folder. ## conan editable add ```text $ conan editable add -h usage: conan editable add [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [--ref REF] [-of OUTPUT_FOLDER] [-r REMOTE | -nr] [path] Define the given location as the package , so when this package is required, it is used from this location instead of the cache. positional arguments: path Path to the package folder in the user workspace options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --ref REF Full package reference (e.g. pkg/1.0@user/channel), as a shortcut for --name/--version/--user/--channel -of OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER The root output folder for generated and build files -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile ``` ## conan editable remove ```text $ conan editable remove -h usage: conan editable remove [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-r REFS] [path] Remove the "editable" mode for this reference. positional arguments: path Path to a folder containing a recipe conanfile.py or to a recipe file. e.g., ./my_project/conanfile.py. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -r REFS, --refs REFS Directly provide reference patterns ``` ## conan editable list ```text $ conan editable list -h usage: conan editable list [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] List all the packages in editable mode. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` #### SEE ALSO - Read the tutorial about editable packages [editable package](https://docs.conan.io/2//tutorial/developing_packages/editable_packages.html.md#editable-packages). --- https://docs.conan.io/2/reference/commands/export-pkg.html.md --- # conan export-pkg ```text $ conan export-pkg -h usage: conan export-pkg [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-of OUTPUT_FOLDER] [--build-require] [-tf TEST_FOLDER] [-sb] [-r REMOTE | -nr] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [path] Create a package directly from pre-compiled binaries. positional arguments: path Path to a folder containing a recipe (conanfile.py). Defaults to current directory options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -of OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER The root output folder for generated and build files --build-require Whether the provided reference is a build-require -tf TEST_FOLDER, --test-folder TEST_FOLDER Alternative test folder name. By default it is "test_package". Use "" to skip the test stage -sb, --skip-binaries Skip installing dependencies binaries -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL ``` The `conan export-pkg` command creates a package binary directly from pre-compiled binaries in a user folder. This command can be useful in different cases: - When creating a package for some closed source or pre-compiled binaries provided by a vendor. In this case, it is not necessary that the `conanfile.py` recipe contains a `build()` method, and providing the `package()` and `package_info()` method are enough to package those pre-compiled binaries. In this case the `build_policy = "never"` could make sense to indicate it is not possible to `conan install --build=this_pkg`, as it doesn’t know how to build from sources when it is a dependency. - When testing some recipe locally in the [local development flow](https://docs.conan.io/2//tutorial/developing_packages/local_package_development_flow.html.md#local-package-development-flow), it can be used to quickly put the locally built binaries in the cache to make them available to other packages for testing, without needing to go through a full `conan create` that would be slower. In general, it is expected that when `conan export-pkg` executes, the possible Conan dependencies that were necessary to build this package had already been installed via `conan install`, so it is not necessary to download dependencies at `export-pkg` time. But if for some reason this is not the case, the command defines `--remote` and `--no-remote` arguments, similar to other commands, as well as the `--skip-binaries` optimization that could save some time installing dependencies binaries if they are not strictly necessary for the current `export-pkg`. But this is the responsibility of the user, as it is possible that such binaries are actually necessary, for example, if a `tool_requires = "cmake/x.y"` is used and the `package()` method implements a `cmake.install()` call, this will definitely need the binaries for the dependencies installed in the current machine to execute. The `conan export-pkg` is a package creation command, it will create both a new recipe and a new package binary, in the same way that the `conan create` command does. Similarly, it will run after the creation of the package any “test-package” functionality. If there is a `test_package` folder besides the `conanfile.py`, or a different test-package folder is defined via the `--test-folder/-tf` argument or in the recipe `test_package_folder` attribute, then, such test-package will be triggered to test and validate that the created package is usable by the simple consumer project in the test-package folder. #### SEE ALSO - Check the [JSON format output](https://docs.conan.io/2//reference/commands/formatters/graph_info_json_formatter.html.md#reference-commands-graph-info-json-format) for this command. - Read the tutorial about the [local package development flow](https://docs.conan.io/2//tutorial/developing_packages/local_package_development_flow.html.md#local-package-development-flow). --- https://docs.conan.io/2/reference/commands/export.html.md --- # conan export ```text $ conan export -h usage: conan export [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-r REMOTE | -nr] [-l LOCKFILE] [--lockfile-out LOCKFILE_OUT] [--lockfile-partial] [--build-require] [path] Export a recipe to the Conan package cache. positional arguments: path Path to a folder containing a recipe (conanfile.py). Defaults to current directory options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, pkglist --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-partial Do not raise an error if some dependency is not found in lockfile --build-require Whether the provided reference is a build-require reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile ``` The `conan export` command exports the recipe specified in `path` to the Conan package cache. ## Output Formats The **conan export** command accepts two types of formats for the `--format` argument: * `json`: Creates a JSON file containing the information of the exported recipe reference. * `pkglist`: Generates a JSON file in the [pkglist](https://docs.conan.io/2//tutorial/other_features.html.md#other-important-features-pkglist) format, which can be utilized as input for various commands such as **upload**, **download**, and **remove**. --- https://docs.conan.io/2/reference/commands/graph.html.md --- # conan graph The `conan graph` command contains several subcommands that return information of a dependency graph without needing to download the package binaries. * [conan graph info: Computes a dependency graph and displays information about it](https://docs.conan.io/2//reference/commands/graph/info.html.md) * [conan graph build-order: Computes the detailed sequence of packages that need to be built from source](https://docs.conan.io/2//reference/commands/graph/build_order.html.md) * [conan graph build-order-merge: Merge 2 existing build-order sequences into one](https://docs.conan.io/2//reference/commands/graph/build_order_merge.html.md) * [conan graph explain: Explain what is wrong with the dependency graph, showing missing binaries, closest alternatives, and why they do not match](https://docs.conan.io/2//reference/commands/graph/explain.html.md) * [conan graph outdated: List the dependencies in the graph and it's newer versions in the remote](https://docs.conan.io/2//reference/commands/graph/outdated.html.md) --- https://docs.conan.io/2/reference/commands/inspect.html.md --- # conan inspect #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan inspect -h usage: conan inspect [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-r REMOTE | -nr] [-l LOCKFILE] [--lockfile-partial] [path] Inspect a conanfile.py to return its public fields. positional arguments: path Path to a folder containing a recipe (conanfile.py). Defaults to current directory options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -r REMOTE, --remote REMOTE Remote names. Accepts wildcards ('*' means all the remotes available) -nr, --no-remote Do not use remote, resolve exclusively in the cache -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile ``` The **conan inspect** command shows the public attributes of any recipe (conanfile.py) as follows: ```text $ conan inspect . default_options: shared: False fPIC: True neon: True msa: True sse: True vsx: True api_prefix: description: libpng is the official PNG file format reference library. generators: [] homepage: http://www.libpng.org label: license: libpng-2.0 name: libpng options: api_prefix: fPIC: True msa: True neon: True shared: False sse: True vsx: True options_definitions: shared: ['True', 'False'] fPIC: ['True', 'False'] neon: ['True', 'check', 'False'] msa: ['True', 'False'] sse: ['True', 'False'] vsx: ['True', 'False'] api_prefix: ['ANY'] package_type: None requires: [] revision_mode: hash settings: ['os', 'arch', 'compiler', 'build_type'] topics: ['png', 'graphics', 'image'] url: https://github.com/conan-io/conan-center-index ``` `conan inspect` evaluates recipe methods such as `set_name()` and `set_version()`, and is capable of resolving `python_requires` dependencies (which can be locked with the `--lockfile` argument), so its base methods will also be properly executed. #### NOTE The `--remote` argument is used *only* for fetching remote `python_requires` in cases where they are needed, **not** to inspect recipes from a remote. Use [conan graph info](https://docs.conan.io/2//reference/commands/graph/info.html.md#reference-graph-info) for such cases. The **conan inspect ... --format=json** returns a JSON output format in `stdout` (which can be redirected to a file) with the following structure: ```text $ conan inspect . --format=json { "name": "libpng", "url": "https://github.com/conan-io/conan-center-index", "license": "libpng-2.0", "description": "libpng is the official PNG file format reference library.", "homepage": "http://www.libpng.org", "revision_mode": "hash", "default_options": { "shared": false, "fPIC": true, "neon": true, "msa": true, "sse": true, "vsx": true, "api_prefix": "" }, "topics": [ "png", "graphics", "image" ], "package_type": "None", "settings": [ "os", "arch", "compiler", "build_type" ], "options": { "api_prefix": "", "fPIC": "True", "msa": "True", "neon": "True", "shared": "False", "sse": "True", "vsx": "True" }, "options_definitions": { "shared": [ "True", "False" ], "fPIC": [ "True", "False" ], "neon": [ "True", "check", "False" ], "msa": [ "True", "False" ], "sse": [ "True", "False" ], "vsx": [ "True", "False" ], "api_prefix": [ "ANY" ] }, "generators": [], "requires": [], "source_folder": null, "build_folder": null, "generators_folder": null, "package_folder": null, "label": "" } ``` #### NOTE `conan inspect` does not list any requirements listed in the `requirements()` method, only those present in the `requires` attribute will be shown. --- https://docs.conan.io/2/reference/commands/install.html.md --- # conan install ```text $ conan install -h usage: conan install [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [-g GENERATOR] [-of OUTPUT_FOLDER] [-d DEPLOYER] [--deployer-folder DEPLOYER_FOLDER] [--deployer-package DEPLOYER_PACKAGE] [--build-require] [--envs-generation {false}] [path] Install the requirements specified in a recipe (conanfile.py or conanfile.txt). It can also be used to install packages without a conanfile, using the --requires and --tool-requires arguments. If any requirement is not found in the local cache, it will iterate the remotes looking for it. When the full dependency graph is computed, and all dependencies recipes have been found, it will look for binary packages matching the current settings. If no binary package is found for some or several dependencies, it will error, unless the '--build' argument is used to build it from source. After installation of packages, the generators and deployers will be called. positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile -g GENERATOR, --generator GENERATOR Generators to use -of OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER The root output folder for generated and build files -d DEPLOYER, --deployer DEPLOYER Deploy using the provided deployer to the output folder. Built-in deployers: 'full_deploy', 'direct_deploy', 'runtime_deploy' --deployer-folder DEPLOYER_FOLDER Deployer output folder, base build folder by default if not set --deployer-package DEPLOYER_PACKAGE Execute the deploy() method of the packages matching the provided patterns --build-require Whether the provided path is a build-require --envs-generation {false} Generation strategy for virtual environment files for the root remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan install` command is one of the main Conan commands, and it is used to resolve and install dependencies. This command does the following: - Compute the whole dependency graph, for the current configuration defined by settings, options, profiles and configuration. It resolves version ranges, transitive dependencies, conditional requirements, etc, to build the dependency graph. - Evaluate the existence of binaries for every package in the graph, whether or not there are precompiled binaries to download, or if they should be built from sources (as directed by the `--build` argument). If binaries are missing, it will not recompute the dependency graph to try to fallback to previous versions that contain binaries for that configuration. If a certain dependency version is desired, it should be explicitly required. - Download precompiled binaries, or build binaries from sources in the local cache, in the right order for the dependency graph. - Create the necessary files as requested by the “generators”, so build systems and other tools can locate the locally installed dependencies - Optionally, execute the desired `deployers`. #### SEE ALSO - Check the [JSON format output](https://docs.conan.io/2//reference/commands/formatters/graph_info_json_formatter.html.md#reference-commands-graph-info-json-format) for this command. ## Conanfile path or –requires The `conan install` command can use 2 different origins for information. The first one is using a local `conanfile.py` or `conanfile.txt`, containing definitions of the dependencies and generators to be used. ```text $ conan install . # there is a conanfile.txt or a conanfile.py in the cwd $ conan install conanfile.py # also works, direct reference file $ conan install myconan.txt # explicit custom name $ conan install myfolder # there is a conanfile in "myfolder" folder ``` Even if it is possible to use a custom name, in the general case, it is recommended to use the default `conanfile.py` name, located in the repository root, so users can do a straightforward `git clone ... `` + ``conan install .` The other possibility is to not have a `conanfile` at all, and define the requirements to be installed directly in the command line: ```text # Install the zlib/1.2.13 library $ conan install --requires=zlib/1.2.13 # Install the zlib/1.2.13 and bzip2/1.0.8 libraries $ conan install --requires=zlib/1.2.13 --requires=bzip2/1.0.8 # Install the cmake/3.23.5 and ninja/1.11.0 tools $ conan install --tool-requires=cmake/3.23.5 --tool-requires=ninja/1.11.0 # Install the zlib/1.2.13 library and ninja/1.11.0 tool $ conan install --requires=zlib/1.2.13 --tool-requires=ninja/1.11.0 ``` In the general case, it is recommended to use a `conanfile` instead of defining things in the command line. ## Profiles, Settings, Options, Conf There are several arguments that are used to define the effective profiles that will be used, both for the “build” and “host” contexts. By default the arguments refer to the “host” context, so `--settings:host, -s:h` is totally equivalent to `--settings, -s`. Also, by default, the `conan install` command will use the `default` profile both for the “build” and “host” context. That means that if a profile with the “default” name has not been created, it will error. Multiple definitions of profiles can be passed as arguments, and they will compound from left to right (right has the highest priority) ```text # The values of myprofile3 will have higher priority $ conan install . -pr=myprofile1 -pr=myprofile2 -pr=myprofile3 ``` #### NOTE Profiles are searched for in a variety of locations, [see here for more information](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-using-profiles) If values for any of `settings`, `options` and `conf` are provided in the command line, they create a profile that is composed with the other provided `-pr` (or the “default” one if not specified) profiles, with higher priority, not matter what the order of arguments is. ```text # the final "host" profile will always be build_type=Debug, even if "myprofile" # says "build_type=Release" $ conan install . -pr=myprofile -s build_type=Debug ``` ## Generators and deployers The `-g` argument allows to define in the command line the different built-in generators to be used: ```text $ conan install --requires=zlib/1.2.13 -g CMakeDeps -g CMakeToolchain ``` Note that in the general case, the recommended approach is to have the `generators` defined in the `conanfile`, and only for the `--requires` use case, it would be more necessary as command line argument. Generators are intended to create files for the build systems to locate the dependencies, while the `deployers` main use case is to copy files from the Conan cache to user space, and performing any other custom operations over the dependency graph, like collecting licenses, generating reports, deploying binaries to the system, etc. The syntax for deployers is: ```text # does a full copy of the dependencies binaries to the current user folder $ conan install . --deployer=full_deploy ``` There are 3 built-in deployers: - [full_deploy](https://docs.conan.io/2//reference/extensions/deployers.html.md#reference-extensions-deployer-full-deploy) does a complete copy of the dependencies binaries in the local folder, with a minimal folder structure to avoid conflicts between files and artifacts of different packages - [direct_deploy](https://docs.conan.io/2//reference/extensions/deployers.html.md#reference-extensions-deployer-direct-deploy) does a copy of only the immediate direct dependencies, but does not include the transitive dependencies. - [runtime_deploy](https://docs.conan.io/2//reference/extensions/deployers.html.md#reference-extensions-deployer-runtime-deploy) deploys all the shared libraries and the executables of the dependencies into a flat directory structure, preserving subdirectories as-is. Some generators might have the capability of redefining the target “package folder”. That means that if some other generator like `CMakeDeps` is used that is pointing to the packages, it will be pointing to the local deployed copy, and not to the original packages in the Conan cache. See the full example in [Creating a Conan-agnostic deploy of dependencies for developer use](https://docs.conan.io/2//examples/extensions/deployers/dev/development_deploy.html.md#examples-extensions-builtin-deployers-development). It is also possible, and it is a powerful extension point, to write custom user deployers. Read more about custom deployers in [Deployers](https://docs.conan.io/2//reference/extensions/deployers.html.md#reference-extensions-deployers). It is possible to also invoke the package recipes `deploy()` method with the `--deployer-package`: ```bash # Execute deploy() method of every recipe that defines it $ conan install --requires=pkg/0.1 --deployer-package="*" # Execute deploy() method only for "pkg" (any version) recipes $ conan install --requires=pkg/0.1 --deployer-package="pkg/*" # Execute deploy() method for all packages except the "zlib" (transitive dep) one $ conan install --requires=pkg/0.1 --deployer-package="*" --deployer-package="~zlib/*" ``` The `--deployer-package` argument is a pattern and accepts multiple values, all package references matching any of the defined patterns will execute its `deploy()` method. This includes negated patterns, where for example `--deployer-package=~pkg/*` will execute the `deploy()` method for all packages except for that of the `pkg` recipe. The `--deployer-folder` argument will also affect the output location of this deployment. See the [deploy() method](https://docs.conan.io/2//reference/conanfile/methods/deploy.html.md#reference-conanfile-methods-deploy). If multiple deployed packages deploy to the same location, it is their responsibility to not mutually overwrite their binaries if they have the same filenames. For example if multiple packages `deploy()` a file called “License.txt”, each recipe is responsible for creating an intermediate folder with the package name and/or version that makes it unique, so other recipes `deploy()` method do not overwrite previously deployed “License.txt” files. ## Name, version, user, channel The `conan install` command provides optional arguments for `--name, --version, --user, --channel`. These arguments might not be necessary in the majority of cases. Never for `conanfile.txt` and for `conanfile.py` only in the case that they are not defined in the recipe: ```python from conan import ConanFile from conan.tools.scm import Version class Pkg(ConanFile): name = "mypkg" def requirements(self): if Version(self.version) >= "3.23": self.requires("...") ``` ```text # If we don't specify ``--version``, it will be None and it will fail $ conan install . --version=3.24 ``` ## Lockfiles The `conan install` command has several arguments to load and produce lockfiles. By default, if a `conan.lock` file is located beside the recipe or in the current working directory if no path is provided, will be used as an input lockfile. Lockfiles are strict by default, that means that if there is some `requires` and it cannot find a matching locked reference in the lockfile, it will error and stop. For cases where it is expected that the lockfile will not be complete, as there might be new dependencies, the `--lockfile-partial` argument can be used. By default, `conan install` will not generate an output lockfile, but if the `--lockfile-out` argument is provided, pointing to a filename, like `--lockfile-out=result.lock`, then a lockfile will be generated from the current dependency graph. If `--lockfile-clean` argument is provided, all versions and revisions not used in the current dependency graph will be dropped from the resulting lockfile. Let’s say that we already have a `conan.lock` input lockfile, but we just added a new `requires = "newpkg/1.0"` to a new dependency. We could resolve the dependencies, locking all the previously locked versions, while allowing to resolve the new one, which was not previously present in the lockfile, and store it in a new location, or overwrite the existing lockfile: ```text # --lockfile=conan.lock is the default, not necessary $ conan install . --lockfile=conan.lock --lockfile-partial --lockfile-out=conan.lock ``` Also, it is likely that the majority of lockfile operations are better managed by the `conan lock` command. #### SEE ALSO - [Lockfiles](https://docs.conan.io/2//tutorial/consuming_packages/intro_to_versioning.html.md#tutorial-consuming-packages-versioning-lockfiles). - Read the tutorial about the [local package development flow](https://docs.conan.io/2//tutorial/developing_packages/local_package_development_flow.html.md#local-package-development-flow). ## Update The `conan install` command has an `--update` argument that will force the re-evaluation of the selected items of the dependency graph, allowing for the update of the dependencies to the latest version if using version ranges, or to the latest revision of the same version, when those versions are not locked in the given lockfile. Passing `--update` will check every package in the dependency graph, but it is also possible to pass a package name to the `--update` argument (it can be added to the command more than once with different names), to only update those packages, which avoids the re-evaluation of the whole graph. ```bash $ conan install . --update # Update all packages in the graph $ conan install . --update=openssl # Update only the openssl package $ conan install . --update=openssl --update=boost # Update both openssl and boost packages ``` Note that the `--update` argument will look into all the remotes specified in the command for possible newer versions, and won’t stop at the first newer one found. ## Build modes The `conan install --build=` argument controls the behavior regarding building packages from source. The default behavior is failing if there are no existing binaries, with the “missing binary” error message, except for packages that define a `build_policy = "missing"` policy, but this can be changed with the `--build` argument. The possible values are: ```bash --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. Legacy and discouraged, shouldnt be used in most cases. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. Same as ``--build=![pattern]`` --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=missing:~[pattern] Build from source if a compatible binary does not exist, for packages not matching the pattern. Same as ``--build=missing:![pattern]`` --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) ``` The `--build=never` policy can be used to force never building from source, even for package recipes that define the `build_policy = "missing"` policy. The `--build=compatible:[pattern]` is an **experimental** new mode that allows building missing binaries with a configuration different than the current one. For example if the current profile has `compiler.cppstd=14`, but some package raises an “invalid” configuration error, because it needs at least `compiler.cppstd=17`, and the binary compatibiliy (defined for example in `compatibility.py` plugin) allows that as a compatible binary, then, Conan will build from source that dependency package applying `compiler.cppstd=17`. The `--build=[pattern]` uses a pattern, so it should use something like `--build="zlib/*"` to match any version of the `zlib` package, as doing `--build=zlib` will not work. The `--build=missing:[pattern]` form uses the same kind of package patterns as in [Profile patterns](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profile-patterns) (`fnmatch`-style wildcards, references like `name/version@user/channel`, etc.). Also, you can use the `&` syntax to match the **consumer** conanfile (the root of the graph). That is useful with `conan create .` when you only want to build the package being created if its binary is missing, without retyping its name: `--build=missing:&` (equivalent to `--build=missing:current_pkg/current_version` in the case of `conan create .`). The `--build=missing:[pattern]` also accepts negations like `--build=missing:!dep/* --build=missing:!lib/*` will build all packages except `dep` and `lib` ones. #### NOTE **Best practices** Forcing the rebuild of existing binaries with `--build="*"` or any other `--build="pkg/*"` or similar pattern is not a recommended practice. If a binary is already existing there is no reason to rebuild it from source. CI pipelines should be specially careful to not do this, and in general the `--build=missing` and `--build=missing:[pattern]` are more recommended. The `--build=cascade` mode is partly legacy, and shouldn’t be used in most cases. The `package_id` computation should be the driver to decide what needs to be built. This mode has been left in Conan 2 only for exceptional cases, like recovering from broken systems, but it is not recommended for normal production usage. --- https://docs.conan.io/2/reference/commands/list.html.md --- # conan list ```text $ conan list -h usage: conan list [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-p PACKAGE_QUERY] [-fp FILTER_PROFILE] [-fs FILTER_SETTINGS] [-fo FILTER_OPTIONS] [-r REMOTE] [-c] [-g GRAPH] [-gb GRAPH_BINARIES] [-gr GRAPH_RECIPES] [-gc {build,host,build-only,host-only}] [--lru LRU] [pattern] List existing recipes, revisions, or packages in the cache (by default) or the remotes. positional arguments: pattern A pattern in the form 'pkg/version#revision:package_id#revision', e.g: "zlib/1.2.13:*" means all binaries for zlib/1.2.13. If revision is not specified, it is assumed latest one. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html, compact --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -p PACKAGE_QUERY, --package-query PACKAGE_QUERY List only the packages matching a specific query, e.g, os=Windows AND (arch=x86 OR compiler=gcc) -fp FILTER_PROFILE, --filter-profile FILTER_PROFILE Profiles to filter the binaries -fs FILTER_SETTINGS, --filter-settings FILTER_SETTINGS Settings to filter the binaries -fo FILTER_OPTIONS, --filter-options FILTER_OPTIONS Options to filter the binaries -r REMOTE, --remote REMOTE Remote names. Accepts wildcards ('*' means all the remotes available) -c, --cache Search in the local cache -g GRAPH, --graph GRAPH Graph json file -gb GRAPH_BINARIES, --graph-binaries GRAPH_BINARIES Which binaries are listed -gr GRAPH_RECIPES, --graph-recipes GRAPH_RECIPES Which recipes are listed -gc {build,host,build-only,host-only}, --graph-context {build,host,build-only,host-only} Filter the results by the given context --lru LRU List recipes and binaries that have not been recently used. Use a time limit like --lru=5d (days) or --lru=4w (weeks), h (hours), m(minutes) ``` The `conan list` command can list recipes and packages from the local cache, from the specified remotes or from both. This command uses a *reference pattern* as input. The structure of this pattern is based on a complete Conan reference that looks like: `name/version@user/channel#rrev:pkgid#prev` This pattern supports using `*` as wildcard as well as `#latest` to specify the latest revision (though that might not be necessary in most cases, by default Conan will be listing the latest revisions). Using it you can list: * Recipe references (`name/version@user/channel`). * Recipe revisions (`name/version@user/channel#rrev`). * Package IDs and their configurations (`name/version@user/channel#rrev:pkgids`). * Package revisions (`name/version@user/channel#rrev:pkgids#prev`). Let’s see some examples on how to use this pattern: ## Listing recipe references ```text # Make sure to quote the argument $ conan list Local Cache hello hello/2.26.1@mycompany/testing hello/2.20.2@mycompany/testing hello/1.0.4@mycompany/testing hello/2.3.2@mycompany/stable hello/1.0.4@mycompany/stable string-view-lite string-view-lite/1.6.0 zlib zlib/1.3.1 ``` This command is equivalent to `$ conan list "*"` (make sure to quote the argument), if no argument is provided Conan will list all packages. ```text $ conan list zlib Local Cache zlib zlib/1.3.1 zlib/1.2.12 ``` As we commented, you can also use the `*` wildcard inside the reference you want to search. ```text # Make sure to quote the argument $ conan list "zlib/*" Local Cache zlib zlib/1.3.1 zlib/1.2.12 ``` You can also use version ranges in the version field to define the versions you want: ```text # Make sure to quote the argument $ conan list "zlib/[<1.2.12]" -r=conancenter Local Cache zlib zlib/1.3.1 $ conan list "zlib/[>1.2.11]" -r=conancenter Local Cache zlib zlib/1.2.12 zlib/1.2.13 ``` Use the pattern for searching only references matching a specific channel: ```text $ conan list "*/*@*/stable" Local Cache hello hello/2.3.2@mycompany/stable hello/1.0.4@mycompany/stable ``` Use the `...@` pattern for searching only references that don’t have *user* and *channel*: ```text $ conan list "*/*@" Local Cache string-view-lite string-view-lite/1.6.0 zlib zlib/1.3.1 ``` ## Listing recipe revisions To list recipe revisions the `#` must be used. If we want just the latest revision we can use the `#latest` placeholder: ```text $ conan list zlib/1.3.1#latest Local Cache zlib zlib/1.3.1 revisions ffa77daf83a57094149707928bdce823 (2022-11-02 13:46:53 UTC) ``` To list all recipe revisions use the `*` wildcard: ```text $ conan list "zlib/1.3.1#*" Local Cache zlib zlib/1.3.1 revisions ffa77daf83a57094149707928bdce823 (2022-11-02 13:46:53 UTC) 8b23adc7acd6f1d6e220338a78e3a19e (2022-10-19 09:19:10 UTC) ce3665ce19f82598aa0f7ac0b71ee966 (2022-10-14 11:42:21 UTC) 31ee767cb2828e539c42913a471e821a (2022-10-12 05:49:39 UTC) d77ee68739fcbe5bf37b8a4690eea6ea (2022-08-05 17:17:30 UTC) ``` ## Listing package IDs The shortest way of listing all the package IDs belonging to the latest recipe revision is using `name/version@user/channel:*` as the pattern: ```text # Make sure to quote the argument $ conan list "zlib/1.3.1:*" Local Cache zlib zlib/1.3.1 revisions d77ee68739fcbe5bf37b8a4690eea6ea (2022-08-05 17:17:30 UTC) packages d0599452a426a161e02a297c6e0c5070f99b4909 info settings arch: x86_64 build_type: Release compiler: apple-clang compiler.version: 12.0 os: Macos options fPIC: True shared: False ebec3dc6d7f6b907b3ada0c3d3cdc83613a2b715 info settings arch: x86_64 build_type: Release compiler: gcc compiler.version: 11 os: Linux options fPIC: True shared: False ``` #### NOTE Here the `#latest` for the recipe revision is implicit, i.e., that pattern is equivalent to `zlib/1.3.1#latest:*` To list all the package IDs for all the recipe revisions use the `*` wildcard in the revision `#` part: ```text # Make sure to quote the argument $ conan list "zlib/1.3.1#*:*" Local Cache zlib zlib/1.3.1 revisions d77ee68739fcbe5bf37b8a4690eea6ea (2022-08-05 17:17:30 UTC) packages d0599452a426a161e02a297c6e0c5070f99b4909 info settings arch: x86_64 build_type: Release compiler: apple-clang compiler.version: 12.0 os: Macos options fPIC: True shared: False e4e1703f72ed07c15d73a555ec3a2fa1 (2022-07-04 21:21:45 UTC) packages d0599452a426a161e02a297c6e0c5070f99b4909 info settings arch: x86_64 build_type: Release compiler: apple-clang compiler.version: 12.0 os: Macos options fPIC: True shared: False ``` ## Listing package revisions The shortest way of listing the latest package revision for a specific recipe revision and package ID is using the pattern `name/version@user/channel#rrev:pkgid` ```text $ conan list zlib/1.3.1#8b23adc7acd6f1d6e220338a78e3a19e:fdb823f07bc228621617c6397210a5c6c4c8807b Local Cache zlib zlib/1.3.1 revisions 8b23adc7acd6f1d6e220338a78e3a19e (2022-08-05 17:17:30 UTC) packages fdb823f07bc228621617c6397210a5c6c4c8807b revisions 4834a9b0d050d7cf58c3ab391fe32e25 (2022-11-18 12:33:31 UTC) ``` To list all the package revisions for for the latest recipe revision: ```text # Make sure to quote the argument $ conan list "zlib/1.3.1:*#*" Local Cache zlib zlib/1.3.1 revisions 6a6451bbfcb0e591333827e9784d7dfa (2022-12-29 11:51:39 UTC) packages b1d267f77ddd5d10d06d2ecf5a6bc433fbb7eeed revisions 67bb089d9d968cbc4ef69e657a03de84 (2022-12-29 11:47:36 UTC) 5e196dbea832f1efee1e70e058a7eead (2022-12-29 11:47:26 UTC) 26475a416fa5b61cb962041623748d73 (2022-12-29 11:02:14 UTC) d15c4f81b5de757b13ca26b636246edff7bdbf24 revisions a2eb7f4c8f2243b6e80ec9e7ee0e1b25 (2022-12-29 11:51:40 UTC) ``` #### NOTE Here the `#latest` for the recipe revision is implicit, i.e., that pattern is equivalent to `zlib/1.3.1#latest:*#*` ## Listing graph artifacts When the `conan list --graph=` graph json file is provided, the command will list the binaries in it. By default, it will list all recipes and binaries included in the dependency graph. But the `--graph-recipes=` and `--graph-binaries=` allow specifying what artifacts have to be listed in the final result, some examples: - `conan list --graph=graph.json --graph-binaries=build` list exclusively the recipes and binaries that have been built from sources - `conan list --graph=graph.json --graph-recipes="*"` list exclusively the recipes, all recipes, but no binaries - `conan list --graph=graph.json --graph-binaries=download` list exclusively the binaries that have been downloaded in the last `conan create` or `conan install` Additionally, the `--graph-context` argument allows to filter the output by the context of the package, allowing to list either `build` packages, `host` packages, and `build-only` packages or `host-only` packages when we want to list packages that are \_only_ present in their respective context. ## Filtering packages There are a few ways to filter the packages that are returned by the command: * The `--package-query` option allows to filter the packages that match a specific query, for example `--package-query="os=Windows AND (arch=x86 OR compiler=gcc)"` would match only Windows packages where the architecture is x86 or the compiler is gcc. * You can filter packages by profiles (`--filter-profile`), settings (`--filter-settings`), or options (`--filter-options`). Note that only declared settings and options in the recipe will be considered for filtering, so that if for example a recipe does not declare the `shared` option, its packages will always be returned when using the `--filter-options="*:shared=True"` filter (regardless of the `shared` value used) ```text $ conan list "zlib/1.3.1:*" -fs="os=Macos" -fo="*:shared=True" -r=conancenter conancenter zlib zlib/1.3.1 revisions f52e03ae3d251dec704634230cd806a2 (2024-02-22 09:20:06 UTC) packages 24612164eb0760405fcd237df0102e554ed1cb2f info settings arch: x86_64 build_type: Release compiler: apple-clang compiler.version: 13 os: Macos options shared: True a3c9d80d887539fac38b81ff8cd4585fe42027e0 info settings arch: armv8 build_type: Release compiler: apple-clang compiler.version: 13 os: Macos options shared: True ``` Both ways can be used together, and only the packages that match both filters will be listed ## List json output format #### NOTE **Best practices** The text output in the terminal should never be parsed or relied on for automation, and it is intended for human reading only. For any automation, the recommended way is using the formatted output as *json* The `conan list ... --format=json` will return a json output in `stdout` (which can be redirected to a file) with the following structure: ```text # Make sure to quote the argument $ conan list "zlib/1.3.1:*#*" --format=json { "Local Cache": { "zli/1.0.0": { "revisions": { "b58eeddfe2fd25ac3a105f72836b3360": { "timestamp": "2023-01-10 16:30:27 UTC", "packages": { "9a4eb3c8701508aa9458b1a73d0633783ecc2270": { "revisions": { "d9b1e9044ee265092e81db7028ae10e0": { "timestamp": "2023-01-10 22:45:49 UTC" } }, "info": { "settings": { "os": "Linux" } } }, "ebec3dc6d7f6b907b3ada0c3d3cdc83613a2b715": { "revisions": { "d9b1e9044ee265092e81db7028ae10e0": { "timestamp": "2023-01-10 22:45:49 UTC" } }, "info": { "settings": { "os": "Windows" } } } } } } } } } ``` ## List html output format The `conan list ... --format=html` will return a html output in `stdout` (which can be redirected to a file) with the following structure: ```text $ conan list "zlib/1.2.13#*:*#*" --format=html -c > list.html ``` Here is the rendered generated HTML. ![image](images/conan-list-html.png) ## List compact output format For developers, it can be convenient to use the `--format=compact` output, because it allows to copy and paste full references into other commands (like for example `conan cache path`): ```text $ conan list "zlib/1.2.13:*" -r=conancenter --format=compact conancenter zlib/1.2.13 zlib/1.2.13#97d5730b529b4224045fe7090592d4c1%1692672717.68 (2023-08-22 02:51:57 UTC) zlib/1.2.13#97d5730b529b4224045fe7090592d4c1:d62dff20d86436b9c58ddc0162499d197be9de1e settings: Macos, x86_64, Release, apple-clang, 13 options(diff): fPIC=True, shared=False zlib/1.2.13#97d5730b529b4224045fe7090592d4c1:abe5e2b04ea92ce2ee91bc9834317dbe66628206 settings: Linux, x86_64, Release, gcc, 11 options(diff): shared=True zlib/1.2.13#97d5730b529b4224045fe7090592d4c1:ae9eaf478e918e6470fe64a4d8d4d9552b0b3606 settings: Windows, x86_64, Release, msvc, dynamic, Release, 192 options(diff): shared=True ... ``` The `--format=compact` will show the list of values for `settings`, and it will only show the differences (“diff”) for options, that is, it will compute the common denominator of options for all displayed packages, and will print only those values that deviate from that common denominator. #### SEE ALSO - [Read the “package lists” example usages](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists) --- https://docs.conan.io/2/reference/commands/lock.html.md --- # conan lock The `conan lock` command contains several subcommands. In addition to these commands, most of the Conan commands that compute a graph, like `create`, `install`, `graph`, can both receive lockfiles as input and produce lockfiles as output. - [conan lock add](https://docs.conan.io/2//reference/commands/lock/add.html.md): Manually add items to a lockfile - [conan lock remove](https://docs.conan.io/2//reference/commands/lock/remove.html.md): Manually remove items from a lockfile - [conan lock create](https://docs.conan.io/2//reference/commands/lock/create.html.md): Evaluates a dependency graph and save a lockfile - [conan lock merge](https://docs.conan.io/2//reference/commands/lock/merge.html.md): Merge several existing lockfiles into one - [conan lock update](https://docs.conan.io/2//reference/commands/lock/update.html.md): Manually update items from a lockfile - [conan lock upgrade](https://docs.conan.io/2//reference/commands/lock/upgrade.html.md): (Experimental) Upgrade items from a lockfile - [conan lock upgrade-config](https://docs.conan.io/2//reference/commands/lock/upgrade_config.html.md): (Experimental) Upgrade configuration packages from a lockfile ```text $ conan lock -h usage: conan lock [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] {add,create,merge,remove,update,upgrade,upgrade-config} ... Create or manage lockfiles. positional arguments: {add,create,merge,remove,update,upgrade,upgrade-config} sub-command help add Add requires, build-requires or python-requires to an existing or new lockfile. The resulting lockfile will be ordered, newer versions/revisions first. References can be supplied with and without revisions like "-- requires=pkg/version", but they must be recipe references, including at least the version, and they cannot contain a version range. create Create a lockfile from a conanfile or a reference. merge Merge 2 or more lockfiles. remove Remove requires, build-requires or python-requires from an existing lockfile. References can be supplied with and without revisions like "-- requires=pkg/version", update Update requires, build-requires or python-requires from an existing lockfile. References that matches the arguments package names will be replaced by the arguments. References can be supplied with and without revisions like "--requires=pkg/version", upgrade (Experimental) Upgrade requires, build-requires or python-requires from an existing lockfile given a conanfile or a reference. upgrade-config (Experimental) Upgrade config requires in a lockfile options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` --- https://docs.conan.io/2/reference/commands/new.html.md --- # conan new Create a new recipe (with a conanfile.py and other associated files) from either a predefined or a user-defined template. ## conan new ```text $ conan new -h usage: conan new [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-d DEFINE] [-f] [-o OUTPUT] [template] Create a new example recipe and source files from a template. positional arguments: template Template name, either a predefined built-in or a user- provided one. Available built-in templates: basic, cmake_lib, cmake_exe, header_lib, meson_lib, meson_exe, msbuild_lib, msbuild_exe, bazel_lib, bazel_exe, autotools_lib, autotools_exe, premake_lib, premake_exe, local_recipes_index, workspace. E.g. 'conan new cmake_lib -d name=hello -d version=0.1'. You can define your own templates too by inputting an absolute path as your template, or a path relative to your conan home folder. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -d DEFINE, --define DEFINE Define a template argument as key=value, e.g., -d name=mypkg -f, --force Overwrite file if it already exists -o OUTPUT, --output OUTPUT Output folder for the generated files ``` The `conan new` command creates a new recipe in the current working directory, plus extra example files such as *CMakeLists.txt* or the *test_package* folder (as necessary), to either be used as a basis for your own project or aiding in the debugging process. Note that each template has some required and some [optional] user-defined variables used to customize the resulting files. The available templates are: - *default* (no argument is required): Creates a simple and empty CMake consumer recipe. The use case would be an user having a local CMakeLists.txt and the sources, and want to build them likely using requirements through Conan: Its variables are: name, version, [requires1, requires2, …], [tool_requires1, tool_requires2, …] - **basic**: Creates a simple recipe with some example code and helpful comments, and is a good starting point to avoid writing boilerplate code. Its variables are: [name], [version], [description], [requires1, requires2, …], [tool_requires1, tool_requires2, …] - **alias**: Creates the minimal recipe needed to define an alias to a target recipe Its variables are: name, [version], target - **cmake_lib**: Creates a cmake library target that defines a function called `name`, which will print some information about the compilation environment to stdout. You can add requirements to this template in the form of `conan new cmake_lib -d name=ai -d version=1.0 -d requires=math/3.14 -d requires=magic/0.0` This will add requirements for both `math/3.14` and `magic/0.0` to the requirements() method, will add the necessary `find_package``s in CMake, and add a call to ``math()` and `magic()` inside the generated `ai()` function. Its variables are: name, version, [requires1, requires2, …], [tool_requires1, tool_requires2, …] - **cmake_exe**: Creates a cmake executable target that defines a function called `name`, which will print some information about the compilation environment to stdout. You can add requirements to this template in the form of `conan new cmake_exe -d name=game -d version=1.0 -d requires=math/3.14 -d requires=ai/1.0` This will add requirements for both `math/3.14` and `ai/1.0` to the requirements() method, will add the necessary `find_package``s in CMake, and add a call to ``math()` and `ai()` inside the generated `game()` function. Its variables are: name, version, [requires1, requires2, …], [tool_requires1, tool_requires2, …] - **header_lib** Creates a header-only library that defines a function called `name`, which will print some output to stdout. > You can add requirements to this template in the form of > `conan new header_lib -d name=foo -d version=1.0 -d requires=math/3.14 -d requires=magic/0.0` This will add requirements for both `math/3.14` and `ai/1.0` to the requirements() method, and add a call to `math()` and `ai()` inside the generated `foo()` function. Its variables are: name, version, [requires1, requires2, …] - **autotools_lib**: Creates an Autotools library. Its variables are: `name`, `version` - **autotools_exe**: Creates an Autotools executable Its variables are: `name`, `version` - **bazel_lib**: **Bazel integration BazelDeps, BazelToolchain, Bazel is experimental**. Creates a Bazel library. Its variables are: `name`, `version` - **bazel_exe**: **Bazel integration BazelDeps, BazelToolchain, Bazel is experimental**. Creates a Bazel executable Its variables are: `name`, `version` - **meson_lib**: Creates a Meson library. Its variables are: `name`, `version` - **meson_exe**: Creates a Meson executable Its variables are: `name`, `version` - **msbuild_lib**: Creates a MSBuild library. Its variables are: `name`, `version` - **msbuild_exe**: Creates a MSBuild executable Its variables are: `name`, `version` - **workspace**: Creates a ready-to-use workspace containing three editables: **liba**, **libb** (requires liba) and **app1** (requires libb), plus the top-level `CMakeLists.txt`, `conanws.yml` and `conanws.py` that describe the workspace. You can pass a `requires` variable like `-d requires=mymath/0.1` to add an external dependency to **liba**. By default, all `name` and `version` variables are set to `mypkg` and `0.1`, respectively, if not provided by the user. #### WARNING The output of the predefined built-in templates is **not stable**. It might change in future releases to adapt to the latest tools or good practices. ## Examples ```text $ conan new ``` Generates a simple CMake consumer *conanfile.py*. Notice that neither the CMakeLists.txt nor the sources are created. #### NOTE You could be interested in the [conan require](https://docs.conan.io/2//reference/commands/require.html.md#reference-commands-require) command to add some remote/local requirements to your recipe. ```text $ conan new basic ``` Generates a basic *conanfile.py* that does not implement any custom functionality ```text $ conan new basic -d name=mygame -d requires=math/1.0 -d requires=ai/1.3 ``` Generates a *conanfile.py* for `mygame` that depends on the packages `math/1.0` and `ai/1.3` ```text $ conan new cmake_lib ``` Creates a basic CMake library with default package `name = "mypkg"` and default package version `version = "0.1"` ```text $ conan new cmake_exe -d name=game -d version=1.0 -d requires=math/3.14 -d requires=ai/1.0 ``` Generates the necessary files for a CMake executable target. This will add requirements for both `math/3.14` and `ai/1.0` to the `requirements()` method, will add the necessary `find_package` in CMake, and add a call to `math()` and `ai()` inside the generated `game()` function. ## Custom templates There’s also the possibility of creating your templates. Templates in the Conan home should be located in the `templates/command/new` folder, and each template should have a folder named like the template one. If we create the `templates/command/new/mytemplate` folder, the command will be called with the following: ```bash $ conan new mytemplate ``` As with other files in the Conan home, you can manage these templates with `conan config install `, putting them in a git repo or an http server and sharing them with your team. It is also possible to use templates from any folder, just passing the full path to the template in the `conan new `, but in general it is more convenient to manage them in the Conan home. The folder can contain as many files as desired. Both the filenames and the contents of the files can be templatized using Jinja2 syntax. The command `-d/--define` arguments will define the `key=value` inputs to the templates. The file contents will be like (Jinja2 syntax): ```python # File "templates/command/new/mytemplate/conanfile.py" from conan import ConanFile class Conan(ConanFile): name = "{{name}}" version = "{{version}}" license = "{{license}}" ``` And it will require passing these values: ```bash $ conan new mytemplate -d name=pkg -d version=0.1 -d license=MIT ``` and it will generate in the current folder a file: ```python # File "/conanfile.py" from conan import ConanFile class Conan(ConanFile): name = "pkg" version = "0.1" license = "MIT" ``` There are some special `-d/--defines` names. The `name` one is always mandatory. The `conan_version` definition will always be automatically defined. The `requires` and `tool_requires` definitions, if existing, will be automatically converted to lists. The `package_name` will always be defined, by default equals to `name`. For parametrized filenames, the filenames themselves support Jinja2 syntax. For example if we store a file named literally `{{name}}` with the brackes in the template folder `templates/command/new/mytemplate/`, instead of the `conanfile.py` above: ```python {{contents}} ``` Then, executing ```bash $ conan new mytemplate -d name=file.txt -d contents=hello! ``` will create a file called `file.txt` in the current dir containing the string `hello!`. If there are files in the template not to be rendered with Jinja2, like image files, then their names should be added to a file called `not_templates` inside the template directory, one filename per line. So we could have a folder with: ```text templates/command/new/mytemplate |- not_templates |- conanfile.py |- image.png |- image2.png ``` And the `not_templates` contains the string `*.png`, then `conan new mytemplate ...` will only render the `conanfile.py` through Jinja2, but both images will be copied as-is. --- https://docs.conan.io/2/reference/commands/pkglist.html.md --- # conan pkglist #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. Perform different operations over package lists: - Merge multiple package lists (deep merge) into a single one: `conan pkglist merge` - Find in which remotes packages from the cache can be found: `conan pkglist find-remote` ## conan pkglist merge ```text $ conan pkglist merge -h usage: conan pkglist merge [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LIST] (Experimental) Merge several package lists into a single one options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LIST, --list LIST Package list file ``` The `conan pkglist merge` command can merge multiple package lists into a single one: ```bash $ conan pkglist merge --list=list1.json --list=list2.json --format=json > result.json ``` The merge will be a deep merge, different versions can be added, and within versions multiple revisions can be added, and for every recipe revision multiple package_ids can be also accumulated. ## conan pkglist find-remote ```text $ conan pkglist find-remote -h usage: conan pkglist find-remote [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-r REMOTE] list (Experimental) Find the remotes of a list of packages in the cache positional arguments: list Input package list options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -r REMOTE, --remote REMOTE Remote names. Accepts wildcards ('*' means all the remotes available) ``` The `conan pkglist find-remote` command will take a package list of packages in the cache (key `"Local Cache"`) and look for them in the defined remotes. For every exact occurrence in a remote matching the recipe, version, recipe-revision, etc, an entry in the resulting “package lists” will be added for that specific remote. #### SEE ALSO - [Read the “package lists” example usages](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists) --- https://docs.conan.io/2/reference/commands/profile.html.md --- # conan profile Manage profiles ## conan profile detect ```text $ conan profile detect -h usage: conan profile detect [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--name NAME] [-f] [-e] Generate a profile using auto-detected values. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --name NAME Profile name, 'default' if not specified -f, --force Overwrite if exists -e, --exist-ok If the profile already exist, do not detect a new one ``` #### WARNING The output of `conan profile detect` is **not stable**. It can change at any time in future Conan releases to adapt to latest tools, latest versions, or other changes in the environment. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. You can create a new auto-detected profile for your configuration using: ```text $ conan profile detect Found apple-clang 14.0 apple-clang>=13, using the major as version Detected profile: [settings] arch=x86_64 build_type=Release compiler=apple-clang compiler.cppstd=gnu17 compiler.libcxx=libc++ compiler.version=14 os=Macos WARN: This profile is a guess of your environment, please check it. WARN: Defaulted to cppstd='gnu17' for apple-clang. WARN: The output of this command is not guaranteed to be stable and can change in future Conan versions. WARN: Use your own profile files for stability. Saving detected profile to /Users/barbarians/.conan2/profiles/default ``` Be aware that if the profile already exists you have to use `--force` to overwrite it. Otherwise it will fail ```text $ conan profile detect ERROR: Profile '/Users/carlosz/.conan2/profiles/default' already exists $ conan profile detect --force Found apple-clang 14.0 ... Saving detected profile to /Users/carlosz/.conan2/profiles/default ``` #### NOTE **Best practices** It is not recommended to use `conan profile detect` in production. To guarantee reproducibility, it is recommended to define your own profiles, store them in a git repo or in a zip in a server, and distribute it to your team and CI machines with `conan config install`, together with other configuration like custom settings, custom remotes definition, etc. ## conan profile list ```text $ conan profile list -h usage: conan profile list [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] List all profiles in the cache. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ```text $ conan profile list Profiles found in the cache: default ios_base ios_simulator clang_15 ``` ## conan profile path ```text $ conan profile path -h usage: conan profile path [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] name Show profile path location. positional arguments: name Profile name options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Use to get the profile location in your `[CONAN_HOME]` folder: ```text $ conan profile path default /Users/barbarians/.conan2/profiles/default ``` ## conan profile show ```text $ conan profile show -h usage: conan profile show [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-cx {host,build}] Show aggregated profiles from the passed arguments. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -cx {host,build}, --context {host,build} profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL ``` Use **conan profile show** to compute the resulting build and host profiles from the command line arguments. For example, combining different options and settings with the default profile or with any other profile using the `pr:b` or `pr:h` arguments: ```text $ conan profile show -s:h build_type=Debug -o:h shared=False Host profile: [settings] arch=x86_64 build_type=Debug compiler=apple-clang compiler.cppstd=gnu17 compiler.libcxx=libc++ compiler.version=14 os=Macos [options] shared=False [conf] Build profile: [settings] arch=x86_64 build_type=Release compiler=apple-clang compiler.cppstd=gnu17 compiler.libcxx=libc++ compiler.version=14 os=Macos [conf] ``` It’s also useful to show the result of the evaluation of [jinja2 templates in the profiles](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-rendering). For example, a profile like this: ```text [settings] os = {{ {"Darwin": "Macos"}.get(platform.system(), platform.system()) }} ``` Check the evaluated profile: ```text $ conan profile show -pr:h=myprofile Host profile: [settings] os=Macos [conf] ... ``` The command can also output a json with the results: ```text $ conan profile show --format=json { "host": { "settings": { "arch": "armv8", "build_type": "Release", "compiler": "apple-clang", "compiler.cppstd": "gnu17", "compiler.libcxx": "libc++", "compiler.version": "15", "os": "Macos" }, "package_settings": {}, "options": {}, "tool_requires": {}, "conf": {}, "build_env": "" }, "build": { "settings": { "arch": "armv8", "build_type": "Release", "compiler": "apple-clang", "compiler.cppstd": "gnu17", "compiler.libcxx": "libc++", "compiler.version": "15", "os": "Macos" }, "package_settings": {}, "options": {}, "tool_requires": {}, "conf": {}, "build_env": "" } } ``` #### SEE ALSO - Read more about [profiles](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles) --- https://docs.conan.io/2/reference/commands/remote.html.md --- # conan remote Use this command to add, edit and remove Conan repositories from the Conan remote registry and also manage authentication to those remotes. For more information on how to work with Conan repositories, please check the [dedicated section](https://docs.conan.io/2//tutorial/conan_repositories.html.md#conan-repositories). ```text $ conan remote -h usage: conan remote [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] {add,auth,disable,enable,list,list-users,login,logout,remove,rename,set-user,update} ... Manage the remote list and the users authenticated on them. positional arguments: {add,auth,disable,enable,list,list-users,login,logout,remove,rename,set-user,update} sub-command help add Add a remote. auth Authenticate in the defined remotes. Use CONAN_LOGIN_USERNAME* and CONAN_PASSWORD* variables if available. Ask for username and password interactively in case (re-)authentication is required and there are no CONAN_LOGIN* and CONAN_PASSWORD* variables available which could be used. Usually you'd use this method over conan remote login for scripting which needs to run in CI and locally. By default, this command returns exit code 0 even if authentication fails for some remotes. Use --strict to return exit code 1 if authentication fails for any remote. disable Disable all the remotes matching a pattern. enable Enable all the remotes matching a pattern. list List current remotes. list-users List the users logged into all the remotes. login Login into the specified remotes matching a pattern. logout Clear the existing credentials for the specified remotes matching a pattern. remove Remove remotes. rename Rename a remote. set-user Associate a username with a remote matching a pattern without performing the authentication. update Update a remote. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote add ```text $ conan remote add -h usage: conan remote add [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--insecure] [--index INDEX] [-f] [-ap ALLOWED_PACKAGES] [-t {local-recipes-index}] [--recipes-only] name url Add a remote. positional arguments: name Name of the remote to add url Url of the remote options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --insecure Allow insecure server connections when using SSL --index INDEX Insert the remote at a specific position in the remote list -f, --force Force the definition of the remote even if duplicated -ap ALLOWED_PACKAGES, --allowed-packages ALLOWED_PACKAGES Add recipe reference pattern to list of allowed packages for this remote -t {local-recipes-index}, --type {local-recipes-index} Define the remote type --recipes-only Disallow binary downloads from this remote, only recipes will be downloaded ``` ## conan remote auth ```text $ conan remote auth -h usage: conan remote auth [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--with-user] [--force] [--strict] remote Authenticate in the defined remotes. Use CONAN_LOGIN_USERNAME* and CONAN_PASSWORD* variables if available. Ask for username and password interactively in case (re-)authentication is required and there are no CONAN_LOGIN* and CONAN_PASSWORD* variables available which could be used. Usually you'd use this method over conan remote login for scripting which needs to run in CI and locally. By default, this command returns exit code 0 even if authentication fails for some remotes. Use --strict to return exit code 1 if authentication fails for any remote. positional arguments: remote Pattern or name of the remote/s to authenticate against. The pattern uses 'fnmatch' style wildcards. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --with-user Only try to auth in those remotes that already have a username or a CONAN_LOGIN_USERNAME* env-var defined --force Force authentication for anonymous-enabled repositories. Can be used for force authentication in case your Artifactory instance has anonymous access enabled and Conan would not ask for username and password even for non-anonymous repositories if not yet authenticated. --strict Return exit code 1 if authentication fails for any remote. ``` #### NOTE If a remote which allows anonymous access matches the pattern given to the command, Conan won’t try to authenticate with it by default. If you want to authenticate with a remote that allows anonymous access, you can use the `--force` option. #### NOTE By default, `conan remote auth` exits with code 0 even if some remotes fail to authenticate. Use `--strict` to exit with a non-zero code when any matched remote fails. ## conan remote disable ```text $ conan remote disable -h usage: conan remote disable [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] remote Disable all the remotes matching a pattern. positional arguments: remote Pattern of the remote/s to disable. The pattern uses 'fnmatch' style wildcards. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote enable ```text $ conan remote enable -h usage: conan remote enable [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] remote Enable all the remotes matching a pattern. positional arguments: remote Pattern of the remote/s to enable. The pattern uses 'fnmatch' style wildcards. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote list ```text $ conan remote list -h usage: conan remote list [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] List current remotes. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote list-users ```text $ conan remote list-users -h usage: conan remote list-users [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] List the users logged into all the remotes. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote login ```text $ conan remote login -h usage: conan remote login [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-p [PASSWORD]] remote [username] Login into the specified remotes matching a pattern. positional arguments: remote Pattern or name of the remote to login into. The pattern uses 'fnmatch' style wildcards. username Username options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -p [PASSWORD], --password [PASSWORD] User password. Use double quotes if password with spacing, and escape quotes if existing. If empty, the password is requested interactively (not exposed) ``` ## conan remote logout ```text $ conan remote logout -h usage: conan remote logout [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] remote Clear the existing credentials for the specified remotes matching a pattern. positional arguments: remote Pattern or name of the remote to logout. The pattern uses 'fnmatch' style wildcards. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote remove ```text $ conan remote remove -h usage: conan remote remove [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] remote Remove remotes. positional arguments: remote Name of the remote to remove. Accepts 'fnmatch' style wildcards. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote rename ```text $ conan remote rename -h usage: conan remote rename [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] remote new_name Rename a remote. positional arguments: remote Current name of the remote new_name New name for the remote options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote set-user ```text $ conan remote set-user -h usage: conan remote set-user [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] remote username Associate a username with a remote matching a pattern without performing the authentication. positional arguments: remote Pattern or name of the remote. The pattern uses 'fnmatch' style wildcards. username Username options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan remote update ```text $ conan remote update -h usage: conan remote update [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--url URL] [--secure] [--insecure] [--index INDEX] [-ap ALLOWED_PACKAGES] [--recipes-only [{True,False}]] remote Update a remote. positional arguments: remote Name of the remote to update options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --url URL New url for the remote --secure Don't allow insecure server connections when using SSL --insecure Allow insecure server connections when using SSL --index INDEX Insert the remote at a specific position in the remote list -ap ALLOWED_PACKAGES, --allowed-packages ALLOWED_PACKAGES Add recipe reference pattern to the list of allowed packages for this remote --recipes-only [{True,False}] Disallow binary downloads from this remote, only recipes will be downloaded ``` #### SEE ALSO - [Uploading packages tutorial](https://docs.conan.io/2//tutorial/conan_repositories/uploading_packages.html.md#uploading-packages) - [Working with Conan repositories](https://docs.conan.io/2//tutorial/conan_repositories.html.md#conan-repositories) - [Upload Conan packages to remotes using conan upload command](https://docs.conan.io/2//reference/commands/upload.html.md#reference-commands-upload) --- https://docs.conan.io/2/reference/commands/remove.html.md --- # conan remove ```text $ conan remove -h usage: conan remove [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-c] [-p PACKAGE_QUERY] [-r REMOTE] [-l LIST] [--lru LRU] [--dry-run] [pattern] Remove recipes or packages from local cache or a remote. - If no remote is specified (-r), the removal will be done in the local conan cache. - If a recipe reference is specified, it will remove the recipe and all the packages, unless -p is specified, in that case, only the packages matching the specified query (and not the recipe) will be removed. - If a package reference is specified, it will remove only the package. positional arguments: pattern A pattern in the form 'pkg/version#revision:package_id#revision', e.g: "zlib/1.2.13:*" means all binaries for zlib/1.2.13. If revision is not specified, it is assumed latest one. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -c, --confirm Remove without requesting a confirmation -p PACKAGE_QUERY, --package-query PACKAGE_QUERY Remove all packages (empty) or provide a query: os=Windows AND (arch=x86 OR compiler=gcc) -r REMOTE, --remote REMOTE Will remove from the specified remote -l LIST, --list LIST Package list file --lru LRU Remove recipes and binaries that have not been recently used. Use a time limit like --lru=5d (days) or --lru=4w (weeks), h (hours), m(minutes) --dry-run Do not remove any items, only print those which would be removed ``` The `conan remove` command removes recipes and packages from the local cache or from a specified remote. Depending on the patterns specified as argument, it is possible to remove a complete package, or just remove the binaries, leaving still the recipe available. You can also use the keyword `!latest` in the revision part of the pattern to avoid removing the latest recipe or package revision of a certain Conan package. Use `--dry-run` to avoid performing actual deletions, and instead get a list of the elements that would have been removed. It has 2 possible and mutually exclusive inputs: - The `conan remove ` pattern-based matching of recipes. - The `conan remove --list=` that will remove the artifacts specified in the `pkglist` json file There are other commands like **conan list** (see the patterns documentation there [conan list](https://docs.conan.io/2//reference/commands/list.html.md#reference-commands-list)), **conan upload** and **conan download**, that take the same patterns. To remove recipes and their associated package binaries from the local cache: ```text $ conan remove "*" # Removes everything from the cache $ conan remove "zlib/*"" # Remove all possible versions of zlib, including all recipes, revisions and packages $ conan remove zlib/1.2.11 # Remove zlib/1.2.11, all its revisions and package binaries. Leave other zlib versions $ conan remove "zlib/[<1.2.13]" # Remove zlib/1.2.11 and zlib/1.2.12, all its revisions and package binaries. $ conan remove zlib/1.2.11#latest # Remove zlib/1.2.11, only its latest recipe revision and binaries of that revision # Leave the other zlib/1.2.11 revisions intact $ conan remove zlib/1.2.11#!latest # Remove all the recipe revisions from zlib/1.2.11 but the latest one # Leave the latest zlib/1.2.11 revision intact $ conan remove zlib/1.2.11# # Remove zlib/1.2.11, only its exact and binaries of that revision # Leave the other zlib/1.2.11 revisions intact ``` To remove only package binaries, but leaving the recipes, it is necessary to specify the pattern including the `:` separator of the `package_id`: ```text $ conan remove "zlib/1.2.11:*" # Removes all the zlib/1.2.11 package binaries from all the recipe revisions $ conan remove "zlib/*:*" # Removes all the binaries from all the recipe revisions from all zlib versions $ conan remove "zlib/1.2.11#latest:*" # Removes all the zlib/1.2.11 package binaries only from the latest zlib/1.2.11 recipe revision $ conan remove "zlib/1.2.11#!latest:*" # Removes all the zlib/1.2.11 package binaries from all the recipe revisions but the latest one $ conan remove zlib/1.2.11: # Removes the package binary from all the zlib/1.2.11 recipe revisions $ conan remove zlib/1.2.11:#latest#latest # Removes only the latest package revision of the binary identified with # from the latest recipe revision of zlib/1.2.11 # WARNING: Recall that having more than 1 package revision is a smell and shouldn't happen # in normal situations ``` Note that you can filter which packages will be removed using the `--package-query` argument: ```text $ conan remove zlib/1.2.11:* -p compiler=clang # Removes all the zlib/1.2.11 packages built with Clang compiler ``` You can query packages by both their settings and options, including custom ones. To query for options you need to explicitly add the options. prefix, so that -p options.shared=False will work but -p shared=False won’t. All the above commands, by default, operate in the Conan cache. To remove artifacts from a server, use the `-r=myremote` argument: ```text $ conan remove zlib/1.2.11:* -r=myremote # Removes all the zlib/1.2.11 package binaries from all the recipe revisions in # the remote ``` --- https://docs.conan.io/2/reference/commands/report.html.md --- # conan report The `conan report` command contains subcommands that return information about packages and libraries. ```text $ conan report -h usage: conan report [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] {diff} ... Gets information about the recipe and its sources. positional arguments: {diff} sub-command help diff Get the difference between two recipes with their sources. It can be used to compare two different versions of the same recipe, or two different recipe revisions. Each old/new recipe can be specified by a path to a conanfile.py and a companion reference, or by a reference only. If only a reference is specified, it will be searched in the local cache, or downloaded from the specified remotes. If no revision is specified, the latest revision will be used. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan report diff ```text $ conan report diff -h usage: conan report diff [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-op OLD_PATH] -or OLD_REFERENCE [-np NEW_PATH] -nr NEW_REFERENCE [-r REMOTE] Get the difference between two recipes with their sources. It can be used to compare two different versions of the same recipe, or two different recipe revisions. Each old/new recipe can be specified by a path to a conanfile.py and a companion reference, or by a reference only. If only a reference is specified, it will be searched in the local cache, or downloaded from the specified remotes. If no revision is specified, the latest revision will be used. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -op OLD_PATH, --old-path OLD_PATH Path to the old recipe if comparing a local recipe is desired -or OLD_REFERENCE, --old-reference OLD_REFERENCE Old reference, e.g. 'mylib/1.0'. If used on its own, it can contain a revision, which will be resolved to the latest one if not provided, but it will be ignored if a path is specified. If used with a path, it will be used to create the reference for the recipe to be compared. -np NEW_PATH, --new-path NEW_PATH Path to the new recipe if comparing a local recipe is desired -nr NEW_REFERENCE, --new-reference NEW_REFERENCE New reference, e.g. 'mylib/1.0'. If used on its own, it can contain a revision, which will be resolved to the latest one if not provided, but it will be ignored if a path is specified. If used with a path, it will be used to create the reference for the recipe to be compared. -r REMOTE, --remote REMOTE Look in the specified remote or remotes server ``` The `conan report diff` command gets the differences between two recipes, also comparing their sources. This functionality allows you to compare either two versions of the same recipe or two entirely different recipes. Each recipe (old and new) can be identified in one of two ways: by providing both the path to its `conanfile.py` and its reference, or by specifying just the reference. When only a reference is given, Conan will first search for the recipe in the local cache; if it is not found, it will attempt to download it from the configured remotes. If no revision is explicitly provided, Conan will default to using the latest available revision. ### **Examples** #### Remote Reference vs Remote Reference If we want to compare versions 1.0 and 2.0 of mylib that are available on our my-remote remote, it would be: ```bash $ conan report diff --old-reference="mylib/1.0" --new-reference="mylib/2.0" -r=my-remote ``` #### Remote Reference vs Local Reference Let’s suppose we’re making changes to the recipe or adding a new version, and we want to compare our changes against a version that is in the remote. The version that is not on the remote requires the path to the recipe in order to compare it. If it’s the old version that we’re modifying and it’s not found in the remotes, we would use `--old-path`: ```bash $ conan report diff --old-reference="mylib/1.0" --old-path="path/to/recipe" --new-reference="mylib/2.0" ``` If, on the other hand, it’s the new version that we’re modifying then we would use `--new-path`: ```bash $ conan report diff --old-reference="mylib/1.0" --new-reference="mylib/2.0" --new-path="path/to/recipe" ``` #### Local Reference vs Local Reference Finally, if we’re modifying both versions, we’ll need to provide both paths. They may or may not be the same. ```bash $ conan report diff --old-reference="mylib/1.0" --old-path="path/to/recipe" --new-reference="mylib/2.0" --new-path="path/to/recipe" ``` #### Specifying revision The command allows you to specify the revision of the package you want to compare. By default, it uses the latest revision, but by providing a revision, you can target the exact package you want to compare. This makes it possible to do things like compare two identical versions with different revisions in order to check for differences between them. ```bash $ conan report diff --old-reference="mylib/1.0#oldrev" --new-reference="mylib/1.0#newrev" ``` ### Available formatters #### Text Formatter By default, it displays this format, which is the format provided by a `git diff` between the packages. #### JSON Formatter You can obtain the result in JSON format, providing a structured output that is perfect for consumption by other scripts. ```bash $ conan report diff --old-reference="mylib/1.0" --new-reference="mylib/2.0" --format=json ``` #### HTML Formatter The HTML format generates a small self-contained static web page in a single HTML file. This page lets you conveniently visualize the changes in the recipe as well as the changes in the source files of your libraries. It contains filters to include and exclude keywords and shortcuts to all the changed files. ```bash $ conan report diff --old-reference="zlib/1.3" --new-reference="zlib/1.3.1" --format=html > diff.html ``` [![image](images/conan-report-diff_html.png)](../../_images/conan-report-diff_html.png) --- https://docs.conan.io/2/reference/commands/require.html.md --- # conan require #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan require -h usage: conan require [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] {add,remove} ... Adds/removes requirements to/from your local conanfile. positional arguments: {add,remove} sub-command help add Add a new requirement to your local conanfile as a version range. By default, it will look for the requirement versions remotely. remove Removes a requirement from your local conanfile. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` The **conan require** command helps to add any requirement as a version range or remove it from your *conanfile.py*. #### IMPORTANT This command is only a UX utility. It’s not aimed at replacing editing the conanfile, and it’s not expected to cover all the use cases, i.e., conditional requirements, requirements with different traits, etc. For all those mentioned scenarios, we recommend editing the conanfile.py as usual. ## conan require add ```text $ conan require add -h usage: conan require add [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--folder FOLDER] [-tor TOOL] [-ter TEST] [-r REMOTE | -nr] [requires ...] Add a new requirement to your local conanfile as a version range. By default, it will look for the requirement versions remotely. positional arguments: requires Requirement name. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --folder FOLDER Path to a folder containing a recipe (conanfile.py). Defaults to the current directory -tor TOOL, --tool TOOL Tool requirement name. -ter TEST, --test TEST Test requirement name. -r REMOTE, --remote REMOTE Remote names. Accepts wildcards ('*' means all the remotes available) -nr, --no-remote Do not use remote, resolve exclusively in the cache ``` Add a new requirement to your local *conanfile.py* as a version range. By default, it looks for the recipe name in any of your remotes. When a remote contains any result for the recipe required, the latest version is used and written as a version range between the version found and the next major one (if possible, as versions based on commits do not have that major version): ```bash $ conan require add fmt Connecting to remote 'conancenter' anonymously Found 21 pkg/version recipes matching fmt/* in conancenter Added 'fmt/[>=12.1.0 <13]' as a new requires. ``` It admits several arguments as new requirements: ```bash $ conan require add fmt zlib Connecting to remote 'conancenter' anonymously Found 21 pkg/version recipes matching fmt/* in conancenter Found 5 pkg/version recipes matching zlib/* in conancenter Added 'fmt/[>=12.1.0 <13]' as a new requires. Added 'zlib/[>=1.3.1 <2]' as a new requires. ``` Or even, you can directly put the requirement version: ```bash $ conan require add boost/1.89.0 Added 'boost/[>=1.89.0 <2]' as a new requires. ``` Tool and test requirements are also supported: ```bash $ conan require add --tool cmake --test gtest Connecting to remote 'conancenter' anonymously Found 54 pkg/version recipes matching cmake/* in conancenter Found 10 pkg/version recipes matching gtest/* in conancenter Added 'cmake/[>=4.2.2 <5]' as a new tool_requires. Added 'gtest/cci.20210126' as a new test_requires. ``` Use `--no-remote` to resolve versions only from the local cache: ```bash $ conan require add boost --no-remote Found 2 pkg/version recipes matching boost/* in local cache Added 'boost/[>=1.89.0 <2]' as a new requires. ``` Use `--folder` to point to a different recipe location: ```text $ conan require add fmt --folder=path/to/conanfile.py ``` ## conan require remove ```text $ conan require remove -h usage: conan require remove [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--folder FOLDER] [-tor TOOL] [-ter TEST] [requires ...] Removes a requirement from your local conanfile. positional arguments: requires Requirement name. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --folder FOLDER Path to a folder containing a recipe (conanfile.py). Defaults to the current directory -tor TOOL, --tool TOOL Tool requirement name. -ter TEST, --test TEST Test requirement name. ``` Remove any requirement from your *conanfile.py*: ```bash $ conan require remove fmt zlib Removed fmt dependency as requires. Removed zlib dependency as requires. ``` Tool and test requirements are also supported: ```bash $ conan require remove --tool cmake --test gtest Removed cmake dependency as tool_requires. Removed gtest dependency as test_requires. ``` Use `--folder` to point to a different recipe location: ```text $ conan require remove fmt --folder=path/to/conanfile.py ``` --- https://docs.conan.io/2/reference/commands/run.html.md --- # conan run #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan run -h usage: conan run [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--context {host,build}] [--build-require] [path] command (Experimental) Run a command given a set of requirements from a recipe or from command line. positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given command Command to run options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --context {host,build} Context to use, by default both contexts are activated if not specified --build-require Whether the provided path is a build-require remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan run` command lets you directly execute a binary from a Conan package, automatically resolving and installing all its dependencies. There’s no need to manually activate any environments generated by Conan: just pass the executable to run, and Conan will activate the necessary environments and execute it. The command can receive either a `conanfile.py`/`conanfile.txt` or have the requirements specified directly from the CLI via `--requires` and `--tool-requires` arguments. For example, if we call a specific version of `openssl` we would: ```bash $ conan run "openssl --version" --tool-requires=openssl/3.5.4 Installing and building dependencies, this might take a while... OpenSSL 3.5.4 30 Sep 2025 (Library: OpenSSL 3.5.4 30 Sep 2025) ``` This command is useful when you want to execute some specific binary from any package. #### NOTE This command activates both the `host` and `build` contexts, so that both contexts binaries are made available at once. In case that a package exists in both contexts, the `host` context binaries take precedence. ## Running executables from profile `[tool_requires]` #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. Starting in Conan 2.32, `conan run` can be invoked without a `conanfile` and without `--requires` / `--tool-requires` arguments. In that case, executables provided by the `[tool_requires]` section of the active profile can be executed directly: ```text include(default) [tool_requires] cmake/3.29.3 ``` ```bash $ conan run "cmake --version" -pr:h=myprofile ``` --- https://docs.conan.io/2/reference/commands/search.html.md --- # conan search Search existing recipes in remotes. This command is equivalent to `conan list -r=*`, and is provided for simpler UX. ```text $ conan search -h usage: conan search [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-r REMOTE] reference Search for package recipes in all the remotes (by default), or a remote. positional arguments: reference Recipe reference to search for. It can contain * as wildcard at any reference field. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -r REMOTE, --remote REMOTE Remote names. Accepts wildcards. If not specified it searches in all the remotes ``` ```text $ conan search zlib conancenter zlib zlib/1.2.8 zlib/1.3.1 zlib/1.2.12 zlib/1.2.13 $ conan search zlib -r=conancenter conancenter zlib zlib/1.2.8 zlib/1.3.1 zlib/1.2.12 zlib/1.2.13 $ conan search zlib/1.2.1* -r=conancenter conancenter zlib zlib/1.3.1 zlib/1.2.12 zlib/1.2.13 $ conan search zlib/1.2.1* -r=conancenter --format=json { "conancenter": { "zlib/1.3.1": {}, "zlib/1.2.12": {}, "zlib/1.2.13": {} } } ``` --- https://docs.conan.io/2/reference/commands/source.html.md --- # conan source ```text $ conan source -h usage: conan source [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-l LOCKFILE] [--lockfile-partial] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [path] Call the source() method. positional arguments: path Path to a folder containing a conanfile.py. Defaults to current directory options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile for python-requires resolution. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile ``` #### SEE ALSO - Read the tutorial about the [local package development flow](https://docs.conan.io/2//tutorial/developing_packages/local_package_development_flow.html.md#local-package-development-flow). --- https://docs.conan.io/2/reference/commands/test.html.md --- # conan test ```text $ conan test -h usage: conan test [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [path] reference Test a package from a test_package folder. positional arguments: path Path to a test_package folder containing a conanfile.py. Defaults to a 'test_package' folder in the current directory reference Provide a package reference to test options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan test` command uses the *test_package* folder specified in `path` to tests the package reference specified in `reference`. When using the `cmake_layout()` functionality inside `test_package`, the conf `tools.cmake.cmake_layout:test_folder` can be used to define the location of the build artifacts for the `test_package`. See [cmake_layout() docs](https://docs.conan.io/2//reference/tools/cmake/cmake_layout.html.md#cmake-layout). Likewise, the full path to the build artifacts will be defined by the `self.folders.build_folder_vars` attribute. - **tools.cmake.cmake_layout:test_folder** (*new since Conan 2.2.0*)(*experimental*) uses its value as the base folder of the `conanfile.folders.build` for test_package builds. If that value is `$TMP`, Conan will create and use a temporal folder. #### SEE ALSO - Read the tutorial about [testing Conan packages](https://docs.conan.io/2//tutorial/creating_packages/test_conan_packages.html.md#tutorial-creating-test). --- https://docs.conan.io/2/reference/commands/upload.html.md --- # conan upload Use this command to upload recipes and binaries to Conan repositories. For more information on how to work with Conan repositories, please check the [dedicated section](https://docs.conan.io/2//tutorial/conan_repositories.html.md#conan-repositories). ```text $ conan upload -h usage: conan upload [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-p PACKAGE_QUERY] -r REMOTE [--only-recipe] [--force] [--check] [-c] [--dry-run] [--allow-disabled] [-l LIST] [-m METADATA] [pattern] Upload packages to a remote. By default, all the matching references are uploaded (all revisions). By default, if a recipe reference is specified, it will upload all the revisions for all the binary packages, unless --only-recipe is specified. You can use the "latest" placeholder at the "reference" argument to specify the latest revision of the recipe or the package. positional arguments: pattern A pattern in the form 'pkg/version#revision:package_id#revision', e.g: "zlib/1.2.13:*" means all binaries for zlib/1.2.13. If revision is not specified, it is assumed latest one. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -p PACKAGE_QUERY, --package-query PACKAGE_QUERY Only upload packages matching a specific query. e.g: os=Windows AND (arch=x86 OR compiler=gcc) -r REMOTE, --remote REMOTE Upload to this specific remote --only-recipe Upload only the recipe/s, not the binary packages. --force Force the upload of the artifacts even if the revision already exists in the server --check Perform an integrity check, using the manifests, before upload -c, --confirm Upload all matching recipes without confirmation --dry-run Do not execute the real upload (experimental) --allow-disabled Allow uploading to disabled remote -l LIST, --list LIST Package list file -m METADATA, --metadata METADATA Upload the metadata, even if the package is already in the server and not uploaded ``` The `conan upload` command can upload packages to 1 server repository specified by the `-r=myremote` argument. It has 2 possible and mutually exclusive inputs: - The `conan upload ` pattern-based matching of recipes, with a pattern similar to the `conan list `. - The `conan upload --list=` that will upload the artifacts specified in the `pkglist` json file If the `--format=json` formatter is specified, the result will be a “PackageList”, compatible with other Conan commands, for example the `conan remove` command, so it is possible to concatenate different commands using the generated json file. The resulting “PackageList” also includes the URLs where each file has been or will be uploaded, providing additional context for automation or inspection purposes. See the [Packages Lists examples](https://docs.conan.io/2//examples/commands/pkglists.html.md#examples-commands-pkglists). The `--dry-run` argument will prepare the packages for upload, zip files if necessary, check in the server to see what needs to be uploaded and what is already in the server, but it will not execute the actual upload. #### NOTE The `--dry-run` flag is useful as the resulting package list json can be used to feed a `conan upload --list=` call, allowing for the split of the preparation of artifacts step and the actual upload step, which can be useful in CI pipelines. ```bash # Recipes are loaded and artifacts prepared, but no upload is performed $ conan upload --dry-run -r=myremote -f=json > pkglist.json # Nothing is re-prepared, only the actual upload is performed $ conan upload --list=pkglist.json -r=myremote ``` ## Upload policies and efficient uploads The `conan upload` commmand performs a check in the server to see if the local Conan packages in the cache already exist in the server or not. This is done by comparing the local `recipe-revision` and `package-revision` against the existing server ones. If they already exist in the server, the actual upload can be skipped, as the revision system uses the artifacts checksums, so it is guaranteed that the same artifacts already exist in the server. If for some reason it is desired to force the full transfer of the artifacts from the local filesystem to the server again, and assuming the server has overwrite/delete permissions (necessary for an overwrite), then the `conan upload --force` can be used. That will force a new upload to the server. Uploading an older existing revision to the server with `--force` doesn’t guarantee that such a revision will be made the latest one in the server, that is to update its timestamp to the current time. This behavior might depend on the server configuration. For example in **Artifactory** the default configuration, due to historic reasons and Conan 1.X compatibility the behavior is as follows: - If the `conan upload --force` happens before 60 seconds of the original upload, it is not made latest. - If the `conan upload --force` happens after 60 seconds of the original upload, it is made latest. The time limit can be configured with `artifactory.conan.index.timestamp.override.threshold.millis`, for example, to completely opt-out of this behavior and `conan upload --force` not changing the revision timestamp and consequently never making it the latest, it is possible to define `artifactory.conan.index.timestamp.override.threshold.millis=Long.MAX_VALUE`. #### NOTE In general, the `conan upload --force` argument shouldn’t be used in regular production pipelines. It is more intended for exceptional cases, like fixing some corrupted package. ## Upload configurations There are different configurations and parameters that can affect the uploads: - The recipe `upload_policy = "skip"` attribute is intended to skip the upload of binaries for that package, only the recipe will ever be uploaded. This attribute is used for exceptional cases where a package can only be built in the installation machine, for example “system” package wrappers - `core.scm:local_url`: By default allows to store local folders as remote url, but not upload them. Use ‘allow’ for allowing upload and ‘block’ to completely forbid it. By default `scm` captures that are not reproducible, that is, that point to a local folder, will be blocked at upload time. This configuration can avoid that block, but please note that this is not recommended in the general case, as those packages won’t be able to be reproduce later, as their sources are pointing to a local machine folder that will dissapear. - `core.sources:upload_url`: Remote URL to upload backup sources to. If the “backup-sources” system is configured with this URL, then the `conan upload` command will also upload the associated downloaded sources to this backup-sources repository. - `core.upload:compression_format`: The compression format used when uploading Conan packages. Possible values: ‘zst’, ‘xz’, ‘gz’ (default=gz)\`. Recall that `zst` requires at least Python>=3.14 to work. With this configuration, it is possible to change the compression format for Conan stored artifacts. - `core.upload:parallel`: Number of concurrent threads to upload packages. Using this conf, it is possible to upload packages in parallel. By default, or when set to a value less than `2`, no parallelization will take place, and any other value will be the number of parallel threads to utilize. - `core.upload:retry`: (int, default: 1) Number of retries in case of failure when uploading to Conan server - `core.upload:retry_wait`: (int, default: 5s) Seconds to wait between upload attempts to Conan server #### SEE ALSO - [Uploading packages tutorial](https://docs.conan.io/2//tutorial/conan_repositories/uploading_packages.html.md#uploading-packages) - [Working with Conan repositories](https://docs.conan.io/2//tutorial/conan_repositories.html.md#conan-repositories) - [Managing remotes with conan remote command](https://docs.conan.io/2//reference/commands/remote.html.md#reference-commands-remote) - [Uploading metadata files](https://docs.conan.io/2//devops/metadata.html.md#devops-metadata). --- https://docs.conan.io/2/reference/commands/version.html.md --- # conan version #### NOTE This feature is in **preview**. It means that it is very unlikely to be removed and unlikely to have breaking changes. Maintainers will try as much as possible to not break it, and only do it if very necessary. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan version -h usage: conan version [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] Give information about the Conan client version. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` The **conan version** command shows information about the system and Python environment, including Conan version, Python version, system platform, architecture, release, CPU, and more: * **version**: The Conan version. * **conan_path**: The path to the Conan script. * *python*: A sub-dictionary containing information about the Python environment, including: : * **version**: The version of Python being used. * **sys_version**: The full Python system version. * **sys_executable**: The path to the Python executable. * **is_frozen**: An indicator of whether the Python script is being run as a frozen file (e.g., using py2exe or PyInstaller). * **architecture**: The architecture detected by Python. * *system*: A sub-dictionary containing information about the operating system, including: : * **version**: The version of the operating system. * **platform**: The platform of the system. * **system**: The name of the operating system. * **release**: The release version of the operating system. * **cpu**: Information about the system’s CPU. ```text $ conan version version: 2.0.6 conan_path: /conan/venv/bin/conan python version: 3.10.4 sys_version: 3.10.4 (main, May 17 2022, 10:53:07) [Clang 13.1.6 (clang-1316.0.21.2.3)] sys_executable: /conan/venv/bin/python is_frozen: False architecture: arm64 system version: Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:37 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6031 platform: macOS-14.4.1-arm64-arm-64bit system: Darwin release: 23.4.0 cpu: arm ``` The **conan version --format=json** returns a JSON output format in `stdout` (which can be redirected to a file) with the following structure: ```text $ conan version --format=json { "version": "2.0.6", "conan_path": "/Users/myUser/Documents/GitHub/conan/venv/bin/conan", "python": { "version": "3.10.4", "sys_version": "3.10.4 (main, May 17 2022, 10:53:07) [Clang 13.1.6 (clang-1316.0.21.2.3)]", "sys_executable": "/conan/venv/bin/python", "is_frozen": false, "architecture": "arm64" }, "system": { "version": "Darwin Kernel Version 23.4.0: Fri Mar 15 00:12:37 PDT 2024; root:xnu-10063.101.17~1/RELEASE_ARM64_T6031", "platform": "macOS-14.4.1-arm64-arm-64bit", "system": "Darwin", "release": "23.4.0", "cpu": "arm" } } ``` --- https://docs.conan.io/2/reference/commands/workspace.html.md --- # conan workspace #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. The `conan workspace` command allows to open, add, and remove packages from the current workspace. Check the `conan workspace -h` help and the help of the subcommands to check their usage. ```text $ conan workspace -h usage: conan workspace [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] {add,build,clean,complete,create,info,init,install,open,remove,root,source,super-install} ... Manage Conan workspaces (group of packages in editable mode) positional arguments: {add,build,clean,complete,create,info,init,install,open,remove,root,source,super-install} sub-command help add Add packages to current workspace build Call "conan build" for packages in the workspace, in the right order clean Clean the temporary build folders when possible complete Complete the workspace, opening or adding intermediate packages to it that have requirements to other packages in the workspace. create Call "conan create" for packages in the workspace, in the correct order. Packages will be created in the Conan cache, not locally info Display info for current workspace init Initialize a workspace in the given path, creating an empty conanws.yml and conanws.py if they dont exist. install Call "conan install" for packages in the workspace, in the right order open Open specific references. If no reference is provided, open every package in the current workspace definition whose folder does not yet exist. remove Remove packages from the current workspace root Return the folder containing the conanws.py/conanws.yml workspace file source Call the source() method of packages in the workspace super-install Install the workspace as a monolith, installing only external dependencies to the workspace, generating a single result (generators, etc) for the whole workspace. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` ## conan workspace init ```text $ conan workspace init -h usage: conan workspace init [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [path] Initialize a workspace in the given path, creating an empty conanws.yml and conanws.py if they dont exist. positional arguments: path Path to a folder where the workspace will be initialized. Defaults to the current directory options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` The command `conan workspace init [path]` creates an empty `conanws.yml` file and a minimal `conanws.py` within that path if they don’t exist yet. That path can be relative to your current working directory. ```bash $ conan workspace init myfolder Created empty conanws.yml in myfolder Created minimal conanws.py in myfolder ``` ## conan workspace [add | remove] ```text $ conan workspace add -h usage: conan workspace add [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [--ref REF] [--folder FOLDER] [-of OUTPUT_FOLDER] [-r REMOTE | -nr] [path] Add packages to current workspace positional arguments: path Path to the package folder in the user workspace options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --ref REF Open and add this reference --folder FOLDER Target folder for the opened package, relative to the workspace root. Subfolders are allowed (e.g. libs/mypkg). Only valid together with '--ref' -of OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER The root output folder for generated and build files -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile ``` ```text $ conan workspace remove -h usage: conan workspace remove [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] path Remove packages from the current workspace positional arguments: path Path to the package folder in the user workspace options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Use these commands to add or remove editable packages to the current workspace. The `conan workspace add ` folder must contain a `conanfile.py`. That path can be relative to your current workspace. When adding a package, the reference `conan workspace add --ref ` can be used instead of the individual arguments `--name`, `--version`, etc. Also, the optional `--folder` argument can be used to control the relative path (to the workspace root) where the package will be added. Subfolders are allowed, e.g. `--folder=libs/mypkg`. The `conanws.py` has a default implementation, but it is possible to override the default behavior: ```python import os from conan import Workspace class MyWorkspace(Workspace): def name(self): return "myws" def add(self, ref, path, *args, **kwargs): self.output.info(f"Adding {ref} at {path}") super().add(ref, path, *args, **kwargs) def remove(self, path, *args, **kwargs): self.output.info(f"Removing {path}") return super().remove(path, *args, **kwargs) ``` See [conan workspace complete](#workspace-complete-command) command to open/add multiple packages that are missing in the package to connect different packages already existing in the workspace. ## conan workspace info ```text $ conan workspace info -h usage: conan workspace info [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] Display info for current workspace options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Use this command to show information about the current workspace ```bash $ cd myfolder $ conan new workspace $ conan workspace info WARN: Workspace found WARN: Workspace is a dev-only feature, exclusively for testing name: myfolder folder: /path/to/myfolder packages - path: liba ref: liba/0.1 - path: libb ref: libb/0.1 - path: app1 ref: app1/0.1 ``` ## conan workspace clean ```text $ conan workspace clean -h usage: conan workspace clean [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] Clean the temporary build folders when possible options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` The new `conan workspace clean` command removes by default the `output-folder` of every package in the workspace if it was defined. If it is not defined, it won’t remove anything by default, as removing files in user space is dangerous, and could destroy user changes or files. It would be recommended that users manage that cleaning with `git clean -xdf` or similar strategies. It is also possible to define a custom clean logic by implementing the `clean()` method: ```python class Ws(Workspace): def name(self): return "my_workspace" def clean(self): self.output.info("MY CLEAN!!!!") ``` ## conan workspace open ```text $ conan workspace open -h usage: conan workspace open [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--folder FOLDER] [-r REMOTE | -nr] [reference] Open specific references. If no reference is provided, open every package in the current workspace definition whose folder does not yet exist. positional arguments: reference Open this package source repository. If omitted, open all packages in the current workspace definition options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --folder FOLDER Target folder for the opened package, relative to the workspace root. Subfolders are allowed (e.g. libs/mypkg). Only valid together with a 'reference' argument -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache ``` The new `conan workspace open` command implements a new concept. The packages containing an `scm` information in the `conandata.yml` (with `git.coordinates_to_conandata()`) can be automatically cloned and checkout inside the current workspace from their Conan recipe reference (including recipe revision). The optional `--folder` argument can be used together with an explicit reference to control the relative path (to the workspace root) where the package will be cloned. Subfolders are allowed, e.g. `--folder=libs/mypkg`: ```bash $ conan workspace open mypkg/1.0 --folder=libs/mypkg ``` If `conan workspace open` is called without a reference argument, it will read the current `conanws` file and automatically open every package it defines whose folder doesn’t already exist yet, cloning each one into its workspace-defined path: ```bash $ conan workspace open ``` See [conan workspace complete](#workspace-complete-command) command to open/add multiple packages that are missing in the package to connect different packages already existing in the workspace. ## conan workspace root ```text $ conan workspace root -h usage: conan workspace root [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] Return the folder containing the conanws.py/conanws.yml workspace file options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True ``` Return the folder containing the conanws.py/conanws.yml workspace file. ## conan workspace source ```text $ conan workspace source -h usage: conan workspace source [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--pkg PKG] Call the source() method of packages in the workspace options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --pkg PKG Define specific packages ``` The command `conan workspace source` performs the equivalent of `conan source ` for every `package` defined within the workspace. ## conan workspace install ```text $ conan workspace install -h usage: conan workspace install [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--pkg PKG] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-l LOCKFILE] [--lockfile-partial] Call "conan install" for packages in the workspace, in the right order options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --pkg PKG Define specific packages -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile ``` The command `conan workspace install` performs the equivalent of `conan install ` for every `package` defined within the workspace in the correct order. ## conan workspace build ```text $ conan workspace build -h usage: conan workspace build [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--pkg PKG] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-l LOCKFILE] [--lockfile-partial] Call "conan build" for packages in the workspace, in the right order options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --pkg PKG Define specific packages -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile ``` The command `conan workspace build` performs the equivalent of `conan build ` for every `package` defined within the workspace in the correct order. ## conan workspace create ```text $ conan workspace create -h usage: conan workspace create [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--pkg PKG] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-l LOCKFILE] [--lockfile-partial] Call "conan create" for packages in the workspace, in the correct order. Packages will be created in the Conan cache, not locally options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --pkg PKG Define specific packages -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile ``` The command `conan workspace create` performs the equivalent of `conan create ` for every `package` defined within the workspace in the correct order. They will be created in the Conan cache, not locally. ## conan workspace super-install ```text $ conan workspace super-install -h usage: conan workspace super-install [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--pkg PKG] [-g GENERATOR] [-of OUTPUT_FOLDER] [-d DEPLOYER] [--deployer-folder DEPLOYER_FOLDER] [--deployer-package DEPLOYER_PACKAGE] [--envs-generation {false}] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] Install the workspace as a monolith, installing only external dependencies to the workspace, generating a single result (generators, etc) for the whole workspace. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --pkg PKG Define specific packages -g GENERATOR, --generator GENERATOR Generators to use -of OUTPUT_FOLDER, --output-folder OUTPUT_FOLDER The root output folder for generated and build files -d DEPLOYER, --deployer DEPLOYER Deploy using the provided deployer to the output folder. Built-in deployers: 'full_deploy', 'direct_deploy', 'runtime_deploy' --deployer-folder DEPLOYER_FOLDER Deployer output folder, base build folder by default if not set --deployer-package DEPLOYER_PACKAGE Execute the deploy() method of the packages matching the provided patterns --envs-generation {false} Generation strategy for virtual environment files for the root -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The command `conan workspace super-install` is useful to install and build the current workspace as a monolithic super-project of the editables. By default it uses all the `editable` packages in the workspace. It is possible to select only a subset of them with the `conan workspace super-install --pkg=pkg_name1 --pkg=pkg_name2` optional arguments. Only the subgraph of those packages, including their dependencies and transitive dependencies will be installed. ## conan workspace complete ```text $ conan workspace complete -h usage: conan workspace complete [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [-l LOCKFILE] [--lockfile-partial] Complete the workspace, opening or adding intermediate packages to it that have requirements to other packages in the workspace. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile ``` The `conan workspace complete` command is intended to complete the `conan workspace open/add` commands. When there are packages in a workspace that have dependencies on some packages in the Conan cache, and in turn those cache packages depend on packages that are in the workspace, this creates an undesired and risky situation. Packages in the Conan cache must be reproducible, including their dependencies. Having binaries in the Conan cache that build against headers and libraries in a workspace, that are not really packages yet, and might never be, is a dangerous situation. It means that it is very easy to have Conan packages in the cache that build and link against code and binaries that never exist in Conan, that are never uploaded as packages. When the cache packages are uploaded and later deployed to production they will link and/or run with different packages, which can cause different issues, from compile or link problems to very difficult to debug and understand runtime errors. So when a Conan `workspace` command detects this situation, it will raise an error like: ```default ERROR: Workspace definition error. Package mypkg/version in the Conan cache has dependencies to packages in the workspace: ["dep1/1.0", "dep2/0.2"] Try the 'conan workspace complete' to open/add intermediate packages ``` This could be solved by manually doing a `conan workspace open/add ` for the missing packages, and add them to the workspace, then repeat the previous command until the error is gone. The `conan workspace complete` command is basically a helper to do this process automatically, detecting what are the missing packages and adding all of them to the workspace. #### SEE ALSO - Read the [Workspace tutorial](https://docs.conan.io/2//tutorial/developing_packages/workspaces.html.md#tutorial-workspaces) section. - Read the [conan new workspace](https://docs.conan.io/2//reference/commands/new.html.md#reference-commands-new) command section. --- https://docs.conan.io/2/reference/commands/formatters/graph_info_json_formatter.html.md --- # Formatter: Graph-info JSON This section is aimed to show one example of the JSON format output when using any of these commands: > * `conan graph info xxxx --format=json` > * `conan create xxxx --format=json` > * `conan install xxxx --format=json` > * `conan export-pkg xxxx --format=json` The output shows the graph information processed by Conan in each command. The JSON output generated by **conan graph info --require=zlib/1.2.11 -r=conancenter --format=json > graph.json** for instance: ```json { "graph": { "nodes": { "0": { "ref": "conanfile", "id": "0", "recipe": "Cli", "package_id": null, "prev": null, "rrev": null, "rrev_timestamp": null, "prev_timestamp": null, "remote": null, "binary_remote": null, "build_id": null, "binary": null, "invalid_build": false, "info_invalid": null, "name": null, "user": null, "channel": null, "url": null, "license": null, "author": null, "description": null, "homepage": null, "build_policy": null, "upload_policy": null, "revision_mode": "hash", "provides": null, "deprecated": null, "win_bash": null, "win_bash_run": null, "default_options": null, "options_description": null, "version": null, "topics": null, "package_type": "unknown", "settings": { "os": "Macos", "arch": "x86_64", "compiler": "apple-clang", "compiler.cppstd": "gnu17", "compiler.libcxx": "libc++", "compiler.version": "12.0", "build_type": "Release" }, "options": {}, "options_definitions": {}, "generators": [], "python_requires": null, "system_requires": {}, "recipe_folder": null, "source_folder": null, "build_folder": null, "generators_folder": null, "package_folder": null, "cpp_info": { "root": { "includedirs": [ "include" ], "srcdirs": null, "libdirs": [ "lib" ], "resdirs": null, "bindirs": [ "bin" ], "builddirs": null, "frameworkdirs": null, "system_libs": null, "frameworks": null, "libs": null, "defines": null, "cflags": null, "cxxflags": null, "sharedlinkflags": null, "exelinkflags": null, "objects": null, "sysroot": null, "requires": null, "properties": null } }, "conf_info": {}, "label": "cli", "dependencies": { "1": { "ref": "zlib/1.2.11", "run": false, "libs": true, "skip": false, "test": false, "force": false, "direct": true, "build": false, "transitive_headers": null, "transitive_libs": null, "headers": true, "package_id_mode": null, "visible": true } }, "context": "host", "test": false }, "1": { "ref": "zlib/1.2.11#ffa77daf83a57094149707928bdce823", "id": "1", "recipe": "Cache", "package_id": "d0599452a426a161e02a297c6e0c5070f99b4909", "prev": "1440f4f447208c8e6808936b4c6ff282", "rrev": "dc0e384f0551386cd76dc29cc964c95e", "rrev_timestamp": 1703667991.3458598, "prev_timestamp": 1703668372.8517942, "remote": null, "binary_remote": null, "build_id": null, "binary": "Missing", "invalid_build": false, "info_invalid": null, "name": "zlib", "user": null, "channel": null, "url": "https://github.com/conan-io/conan-center-index", "license": "Zlib", "author": null, "description": "A Massively Spiffy Yet Delicately Unobtrusive Compression Library (Also Free, Not to Mention Unencumbered by Patents)", "homepage": "https://zlib.net", "build_policy": null, "upload_policy": null, "revision_mode": "hash", "provides": null, "deprecated": null, "win_bash": null, "win_bash_run": null, "default_options": { "shared": false, "fPIC": true }, "options_description": null, "version": "1.2.11", "topics": [ "zlib", "compression" ], "package_type": "static-library", "settings": { "os": "Macos", "arch": "x86_64", "compiler": "apple-clang", "compiler.cppstd": "gnu17", "compiler.libcxx": "libc++", "compiler.version": "12.0", "build_type": "Release" }, "options": { "fPIC": "True", "shared": "False" }, "options_definitions": { "shared": [ "True", "False" ], "fPIC": [ "True", "False" ] }, "generators": [], "python_requires": null, "system_requires": {}, "recipe_folder": "/Users/franchuti/.conan2/p/zlib774aa77541f8b/e", "source_folder": null, "build_folder": null, "generators_folder": null, "package_folder": null, "cpp_info": { "root": { "includedirs": [ "include" ], "srcdirs": null, "libdirs": [ "lib" ], "resdirs": null, "bindirs": [ "bin" ], "builddirs": null, "frameworkdirs": null, "system_libs": null, "frameworks": null, "libs": null, "defines": null, "cflags": null, "cxxflags": null, "sharedlinkflags": null, "exelinkflags": null, "objects": null, "sysroot": null, "requires": null, "properties": null } }, "conf_info": {}, "label": "zlib/1.2.11", "info": { "settings": { "os": "Macos", "arch": "x86_64", "compiler": "apple-clang", "compiler.cppstd": "gnu17", "compiler.libcxx": "libc++", "compiler.version": "12.0", "build_type": "Release" }, "options": { "fPIC": "True", "shared": "False" } }, "vendor": false, "conandata": { "patches": { "1.2.11": [ { "patch_description": "separate static/shared builds, disable debug suffix, disable building examples", "patch_file": "patches/1.2.x/0001-fix-cmake.patch", "patch_type": "conan" }, { "patch_description": "fix condition for WIDECHAR usage", "patch_file": "patches/1.2.x/0003-gzguts-fix-widechar-condition.patch", "patch_source": "https://github.com/madler/zlib/issues/268", "patch_type": "portability" } ] }, "sources": { "1.2.11": { "sha256": "c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1", "url": "https://zlib.net/fossils/zlib-1.2.11.tar.gz" } } }, "dependencies": {}, "context": "host", "test": false } }, "root": { "0": "None" }, "overrides": {}, "resolved_ranges": {}, "replaced_requires": {} } } ``` --- https://docs.conan.io/2/reference/commands/graph/build_order.html.md --- # conan graph build-order ```text $ conan graph build-order -h usage: conan graph build-order [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--order-by {recipe,configuration}] [--reduce] [path] Compute the build order of a dependency graph. positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --order-by {recipe,configuration} Select how to order the output, "recipe" by default if not set. --reduce Reduce the build order, output only those to build. Use this only if the result will not be merged later with other build-order remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan graph build-order` command computes the build order of the dependency graph for the recipe specified in `path` or in `--requires/--tool-requires`. There are 2 important arguments that affect how this build order is computed: - The `--order-by` argument can take 2 values `recipe` and `configuration`, depending how we want to structure and parallelize our CI. - The `--reduce` argument will strip all packages in the order that doesn’t need to be built from source. By default, the `conan graph build-order` will return the order for the full dependency graph, and it will annotate in each element what needs to be done, for example `"binary": "Cache"` if the binary is already in the Conan Cache and it doesn’t need to be built from source, and `"binary": "Build"`, if it needs to be built from source. Having the full order is necessary if we want to `conan graph build-order-merge` several build-orders into a single one later, because having the full information allows to preserve the relative order that would otherwise be lost and broken. Consequently, the `--reduce` argument should only be used when we are directly going to use the result to do the build, but not if we plan to later do a merge of the resulting build-order with other ones. Let’s consider installing libpng and wanting to see the build order for this requirement ordered by recipe: #### WARNING Please be aware that starting with Conan 2.1.0, using the –order-by argument is recommended, and its absence is deprecated. This argument will be removed in the near future. It is maintained for backward compatibility. Note that the JSON output will differ if you use the –order-by argument, changing from a simple list to a dictionary with extended information. ```text $ conan graph build-order --requires=libpng/1.5.30 --format=json --order-by=recipe ... ======== Computing the build order ======== { "order_by": "recipe", "reduced": false, "order": [ [ { "ref": "zlib/1.3#06023034579559bb64357db3a53f88a4", "depends": [], "packages": [ [ { "package_id": "d62dff20d86436b9c58ddc0162499d197be9de1e", "prev": "54b9c3efd9ddd25eb6a8cbf01860b499", "context": "host", "binary": "Cache", "options": [], "filenames": [], "depends": [], "overrides": {}, "build_args": null } ] ] } ], [ { "ref": "libpng/1.5.30#ed8593b3f837c6c9aa766f231c917a5b", "depends": [ "zlib/1.3#06023034579559bb64357db3a53f88a4" ], "packages": [ [ { "package_id": "60778dfa43503cdcda3636d15124c19bf6546ae3", "prev": "ad092d2e4aebcd9d48a5b1f3fd51ba9a", "context": "host", "binary": "Download", "options": [], "filenames": [], "depends": [], "overrides": {}, "build_args": null } ] ] } ] ], "profiles": { "self": { "args": "" } } } ``` Firstly, we can see the `zlib` package, as `libpng` depends on it. The output is sorted by recipes as we passed with the –order-by argument; however, we might prefer to see it sorted by configurations instead. For that purpose use the –order-by argument with value configuration. At the end of the json, after the `order` field, we see a `profiles` field, which contains the profile related command line arguments for the current “build-order”. As in this case we didn’t provide any arguments, it is empty. But if we used something like `conan graph build-order ... -pr=default -s build_type=Debug > bo.json`, the `args` will contain those arguments (with json character escaping): `"args": "-pr:h=\"default\" -s:h=\"build_type=Debug\""` Using `--order-by=configuration` we will get a different build-order format: ```text $ conan graph build-order --requires=libpng/1.5.30 --format=json --order-by=configuration ... ======== Computing the build order ======== { "order_by": "configuration", "reduced": false, "order": [ [ { "ref": "zlib/1.3#06023034579559bb64357db3a53f88a4", "pref": "zlib/1.3#06023034579559bb64357db3a53f88a4:d62dff20d86436b9c58ddc0162499d197be9de1e#54b9c3efd9ddd25eb6a8cbf01860b499", "package_id": "d62dff20d86436b9c58ddc0162499d197be9de1e", "prev": "54b9c3efd9ddd25eb6a8cbf01860b499", "context": "host", "binary": "Cache", "options": [], "filenames": [], "depends": [], "overrides": {}, "build_args": null } ], [ { "ref": "libpng/1.5.30#ed8593b3f837c6c9aa766f231c917a5b", "pref": "libpng/1.5.30#ed8593b3f837c6c9aa766f231c917a5b:60778dfa43503cdcda3636d15124c19bf6546ae3#ad092d2e4aebcd9d48a5b1f3fd51ba9a", "package_id": "60778dfa43503cdcda3636d15124c19bf6546ae3", "prev": "ad092d2e4aebcd9d48a5b1f3fd51ba9a", "context": "host", "binary": "Download", "options": [], "filenames": [], "depends": [ "zlib/1.3#06023034579559bb64357db3a53f88a4:d62dff20d86436b9c58ddc0162499d197be9de1e#54b9c3efd9ddd25eb6a8cbf01860b499" ], "overrides": {}, "build_args": null } ] ] } ``` If we now apply the `--reduce`: ```text $ conan graph build-order --requires=libpng/1.5.30 --reduce --format=json --order-by=configuration ... ======== Computing the build order ======== { "order_by": "configuration", "reduced": false, "order": [] } ``` As there are no binaries to build here, all binaries already exist. If we explicitly force to build some, the result would be only those that are going to be built: ```text $ conan graph build-order --requires=libpng/1.5.30 --build="libpng/*" --reduce --format=json --order-by=configuration ... ======== Computing the build order ======== { "order_by": "configuration", "reduced": false, "order": [ [ { "ref": "libpng/1.5.30#ed8593b3f837c6c9aa766f231c917a5b", "pref": "libpng/1.5.30#ed8593b3f837c6c9aa766f231c917a5b:60778dfa43503cdcda3636d15124c19bf6546ae3#ad092d2e4aebcd9d48a5b1f3fd51ba9a", "package_id": "60778dfa43503cdcda3636d15124c19bf6546ae3", "prev": null, "context": "host", "binary": "Build", "options": [], "filenames": [], "depends": [], "overrides": {}, "build_args": "--require=libpng/1.5.30 --build=libpng/1.5.30" } ] ] } ``` Then it will contain exclusively the `binary=Build` nodes, but not the rest. Note that it will also provide a `build_args` field with the arguments needed for a `conan install ` to fire the build of this package in the CI agent. **Getting a visual representation of the Build Order** You can obtain a visual representation of the build order by using the HTML formatter. For example: ```text $ conan graph build-order --requires=opencv/4.9.0 --order-by=recipe --build=missing --format=html > build-order.html ``` ![image](images/conan-build-order-html.png) --- https://docs.conan.io/2/reference/commands/graph/build_order_merge.html.md --- # conan graph build-order-merge ```text $ conan graph build-order-merge -h usage: conan graph build-order-merge [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--file [FILE]] [--reduce] Merge more than 1 build-order file. options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json, html --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --file [FILE] Files to be merged --reduce Reduce the build order, output only those to build. Use this only if the result will not be merged later with other build-order ``` As described in the `conan graph build-order` command, there are 2 types of order `recipe` and `configuration`. Only build-orders of the same type can be merged together, otherwise the command will return an error. Note that only build-orders that haven’t been reduced with `--reduce` can be merged. The result of merging the different input files can be also reduced with the `conan graph build-order-merge --reduce` argument, and the behavior will be the same, leave only the elements that need to be built from source. When 2 or more “build-order” files are merged, the resulting merge contains a `profiles` section like: ```json "profiles": { "build_order_win": { "args": "-pr:h=\"profile1\" -s:h=\"os=Windows\" ..." }, "build_order_nix": { "args": "-pr:h=\"profile2\" -s:h=\"os=Linux\" ..." } } ``` With the `build_order_win` and `build_order_nix` being the “build-order” filenames that were used as inputs to the merge, and which will be referenced in the `filenames` field of every `package` in the build order. This way, it is easier to obtain the necessary command line arguments to build a specific package binary in the build-order when building multiple configurations. Note that when a merged build order containing multilpe `filenames` something like: ```json { "package_id": "efa83b160a55b033c4ea706ddb980cd708e3ba1b", "context": "build", "binary": "Build", "filenames": [ "build_order_win", "build_order_nix" ], "build_args": "--tool-requires=dep/0.1 --build=dep/0.1", "info": { "settings": { "build_type": "Release" } } } "profiles": { "build_order_win": { "args": "-pr:h=\"profile1\" -s:h=\"os=Windows\" ..." }, "build_order_nix": { "args": "-pr:h=\"profile2\" -s:h=\"os=Linux\" ..." } } ``` Then, the `filename` to be used is the first one, in this case `build_order_win`, because the `context` and `build_args` arguments matches this profile information. The other filenames are provided as a reference to which other individual build-order files had this `package_id` listed for build. --- https://docs.conan.io/2/reference/commands/graph/explain.html.md --- # conan graph explain ```text $ conan graph explain -h usage: conan graph explain [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--check-updates] [--build-require] [--missing [MISSING]] [path] Explain what is wrong with the dependency graph, like report missing binaries closest alternatives, trying to explain why the existing binaries do not match positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --check-updates Check if there are recipe updates --build-require Whether the provided reference is a build-require --missing [MISSING] A pattern in the form 'pkg/version#revision:package_id#revision', e.g: "zlib/1.2.13:*" means all binaries for zlib/1.2.13. If revision is not specified, it is assumed latest one. remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan graph explain` tries to give a more detailed explanation for a package that might be missing with the configuration provided and show the differences between the expected binary package and the available ones. It helps to understand what is missing from the package requested, whether it is different options, different settings or different dependencies. **Example**: Imagine that we want to install the lib/1.0.0 that depends on dep/2.0.0 but we don’t have a binary yet, as the latest CI run only generated a binary for lib/1.0.0 using the previous version of dep. When we try to install the refere lib/1.0.0 it says: ```text $ conan install --requires=lib/1.0.0 ... ERROR: Missing prebuilt package for 'lib/1.0.0' ``` Now we can try to find a explanation for this: ```text $ conan graph explain --requires=lib/1.0.0 requires: dep/1.Y.Z diff dependencies expected: dep/2.Y.Z existing: dep/1.Y.Z explanation: This binary has same settings and options, but different dependencies ``` In the same way, it can report when a package has a different option value and the output is also available in JSON format: ```text $conan graph explain --requires=lib/1.0.0 -o lib/*:shared=True --format=json ... { "closest_binaries": { "lib/1.0.0": { "revisions": { "dc0e384f0551386cd76dc29cc964c95e": { "timestamp": 1692672717.68, "packages": { "b647c43bfefae3f830561ca202b6cfd935b56205": { "info": { "settings": { "arch": "x86_64", "build_type": "Release", "compiler": "gcc", "compiler.version": "11", "os": "Linux" }, "options": { "shared": "False" } }, "diff": { "platform": {}, "options": { "expected": [ "shared=True" ], "existing": [ "shared=False" ] }, "settings": {}, "dependencies": {}, "explanation": "This binary was built with same settings but different options." }, "remote": "conancenter" } } } } } } } ``` --- https://docs.conan.io/2/reference/commands/graph/info.html.md --- # conan graph info ```text $ conan graph info -h usage: conan graph info [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--check-updates] [--filter FILTER] [--package-filter PACKAGE_FILTER] [-d DEPLOYER] [-df DEPLOYER_FOLDER] [--build-require] [path] Compute the dependency graph and show information about it. positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: html, json, dot --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --check-updates Check if there are recipe updates --filter FILTER Show only the specified fields --package-filter PACKAGE_FILTER Print information only for packages that match the patterns -d DEPLOYER, --deployer DEPLOYER Deploy using the provided deployer to the output folder. Built-in deployers: 'full_deploy', 'direct_deploy'. Deployers will only deploy recipes, as 'conan graph info' do not retrieve binaries -df DEPLOYER_FOLDER, --deployer-folder DEPLOYER_FOLDER Deployer output folder, base build folder by default if not set --build-require Whether the provided reference is a build-require remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan graph info` command shows information about the dependency graph for the recipe specified in `path`. **Examples**: ```bash $ conan graph info . $ conan graph info myproject_folder $ conan graph info myproject_folder/conanfile.py $ conan graph info --requires=hello/1.0@user/channel ``` The output will look like: ```text $ conan graph info --require=binutils/2.38 -r=conancenter ... ======== Basic graph information ======== conanfile: ref: conanfile id: 0 recipe: Cli package_id: None prev: None build_id: None binary: None invalid_build: False info_invalid: None revision_mode: hash package_type: unknown settings: os: Macos arch: armv8 compiler: apple-clang compiler.cppstd: gnu17 compiler.libcxx: libc++ compiler.version: 14 build_type: Release options: system_requires: recipe_folder: None source_folder: None build_folder: None generators_folder: None package_folder: None cpp_info: root: includedirs: ['include'] srcdirs: None libdirs: ['lib'] resdirs: None bindirs: ['bin'] builddirs: None frameworkdirs: None system_libs: None frameworks: None libs: None defines: None cflags: None cxxflags: None sharedlinkflags: None exelinkflags: None objects: None sysroot: None requires: None properties: None label: cli context: host test: False requires: 1: binutils/2.38#0dc90586530d3e194d01d17cb70d9461 binutils/2.38#0dc90586530d3e194d01d17cb70d9461: ref: binutils/2.38#0dc90586530d3e194d01d17cb70d9461 id: 1 recipe: Downloaded package_id: 5350e016ee8d04f418b50b7be75f5d8be9d79547 prev: None build_id: None binary: Invalid invalid_build: False info_invalid: cci does not support building binutils for Macos since binutils is degraded there (no as/ld + armv8 does not build) url: https://github.com/conan-io/conan-center-index/ license: GPL-2.0-or-later description: The GNU Binutils are a collection of binary tools. topics: ('gnu', 'ld', 'linker', 'as', 'assembler', 'objcopy', 'objdump') homepage: https://www.gnu.org/software/binutils revision_mode: hash package_type: application settings: os: Macos arch: armv8 compiler: apple-clang compiler.version: 14 build_type: Release options: multilib: True prefix: aarch64-apple-darwin- target_arch: armv8 target_os: Macos target_triplet: aarch64-apple-darwin with_libquadmath: True system_requires: recipe_folder: /Users/barbarian/.conan2/p/binut53bd9b3ee9490/e source_folder: None build_folder: None generators_folder: None package_folder: None cpp_info: root: includedirs: ['include'] srcdirs: None libdirs: ['lib'] resdirs: None bindirs: ['bin'] builddirs: None frameworkdirs: None system_libs: None frameworks: None libs: None defines: None cflags: None cxxflags: None sharedlinkflags: None exelinkflags: None objects: None sysroot: None requires: None properties: None label: binutils/2.38 context: host test: False requires: 2: zlib/1.2.13#416618fa04d433c6bd94279ed2e93638 zlib/1.2.13#416618fa04d433c6bd94279ed2e93638: ref: zlib/1.2.13#416618fa04d433c6bd94279ed2e93638 id: 2 recipe: Cache package_id: 76f7d863f21b130b4e6527af3b1d430f7f8edbea prev: 866f53e31e2d9b04d49d0bb18606e88e build_id: None binary: Skip invalid_build: False info_invalid: None url: https://github.com/conan-io/conan-center-index license: Zlib description: A Massively Spiffy Yet Delicately Unobtrusive Compression Library (Also Free, Not to Mention Unencumbered by Patents) topics: ('zlib', 'compression') homepage: https://zlib.net revision_mode: hash package_type: static-library settings: os: Macos arch: armv8 compiler: apple-clang compiler.version: 14 build_type: Release options: fPIC: True shared: False system_requires: recipe_folder: /Users/barbarian/.conan2/p/zlibbcf9063fcc882/e source_folder: None build_folder: None generators_folder: None package_folder: None cpp_info: root: includedirs: ['include'] srcdirs: None libdirs: ['lib'] resdirs: None bindirs: ['bin'] builddirs: None frameworkdirs: None system_libs: None frameworks: None libs: None defines: None cflags: None cxxflags: None sharedlinkflags: None exelinkflags: None objects: None sysroot: None requires: None properties: None label: zlib/1.2.13 context: host test: False requires: ``` **conan graph info** builds the complete dependency graph, like **conan install** does. The main difference is that it doesn’t try to install or build the binaries, but the package recipes will be retrieved from remotes if necessary. It is very important to note that the **conan graph info** command outputs the dependency graph for a given configuration (settings, options), as the dependency graph can be different for different configurations. This means that the input to the **conan graph info** command is the same as **conan install**, the configuration can be specified directly with settings and options, or using profiles,and querying the graph of a specific recipe is possible by using the `--requires` flag as shown above. You can additionally filter the output, both by filtering by fields (`--filter`) and by package (`--filter-package`). For example, to get the options of zlib, the following command could be run: ```text $ conan graph info --require=binutils/2.38 -r=conancenter --filter=options --package-filter="zlib*" ... ======== Basic graph information ======== zlib/1.2.13#13c96f538b52e1600c40b88994de240f: ref: zlib/1.2.13#13c96f538b52e1600c40b88994de240f options: fPIC: True shared: False ``` The `--package-filter` accepts the `&` placeholder as `--package-filter="&""` to refer to the current “consumer” recipes, without needing to explictly type its package name. ## Available formatters ### json formatter For the documentation about the JSON formatter, please check the [dedicated section](https://docs.conan.io/2//reference/commands/formatters/graph_info_json_formatter.html.md#reference-commands-graph-info-json-format). ### dot formatter To use the DOT format, execute the following command: ```bash $ conan graph info --require=binutils/2.38 -r=conancenter --format=dot > graph.dot ``` This command generates a DOT file with the following content: ```dot digraph { "cli" -> "binutils/2.38" "binutils/2.38" -> "zlib/1.2.13" } ``` To visualize this graph, you can render it using Graphviz or any compatible tool. ### html formatter The HTML formatter provides a visual representation of the dependency graph that is both interactive and user-friendly. ```bash $ conan graph info --require=tensorflow-lite/2.12.0 -r=conancenter --format=html > graph.html ``` The HTML output displays an interactive graph of your project’s dependencies, featuring nodes for packages with versions, directional arrows for dependencies, and color-coded labels for dependency types. You can interact with the graph to filter visibility of dependencies and access package details and status. [![image](images/conan-graph-info-html.png)](../../../_images/conan-graph-info-html.png) #### NOTE When using `format=html`, the generated HTML contains links to a third-party resource: the [vis-network](https://github.com/visjs/vis-network) library trough the *vis-network.min.js* file. By default, this file is retrieved from Cloudflare. However, for environments without an internet connection, you will need to create a template for the file and place it in `CONAN_HOME/templates/graph.html` to point to a local version of [the remote vis-network.min.js file](https://cdnjs.cloudflare.com/ajax/libs/vis-network/9.1.9/standalone/umd/vis-network.min.js) Use the template located in `/conan/cli/formatters/graph/info_graph_html.py` as a starting point for your own. #### SEE ALSO - Check the [JSON format output](https://docs.conan.io/2//reference/commands/formatters/graph_info_json_formatter.html.md#reference-commands-graph-info-json-format) for this command. --- https://docs.conan.io/2/reference/commands/graph/outdated.html.md --- # conan graph outdated ```text $ conan graph outdated -h usage: conan graph outdated [-h] [-f FORMAT] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--check-updates] [--build-require] [path] List the dependencies in the graph and it's newer versions in the remote positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit -f FORMAT, --format FORMAT Select the output format: json --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --check-updates Check if there are recipe updates --build-require Whether the provided reference is a build-require remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan graph outdated` command provides details on libraries for which a newer version is available in a remote repository. This command helps users in identifying outdated libraries by displaying the latest version available in the remote repository and indicating which specific remote repository it was found in. Additionally, it presents information on the versions currently stored in the local cache and specifies the version ranges for each library. It will display the information for every library on the dependency graph it is run on. For example if running the command with an older version of `libcurl` it will display: ```bash $ conan graph outdated --requires=libcurl/[*] ``` ```text ======== Computing dependency graph ======== Graph root cli Requirements libcurl/8.5.0#95279f20d2443016907657f081a79261 - Cache openssl/3.2.1#edbeabd3bfc383d2cca3858aa2a78a0d - Cache zlib/1.3.1#f52e03ae3d251dec704634230cd806a2 - Cache Build requirements nasm/2.15.05#058c93b2214a49ca1cfe9f8f26205568 - Cache strawberryperl/5.32.1.1#8f83d05a60363a422f9033e52d106b47 - Cache Resolved version ranges libcurl/[*]: libcurl/8.5.0 openssl/[>=1.1 <4]: openssl/3.2.1 zlib/[>=1.2.11 <2]: zlib/1.3.1 ======== Checking remotes ======== Found 35 pkg/version recipes matching libcurl in conancenter Found 46 pkg/version recipes matching openssl in conancenter Found 6 pkg/version recipes matching zlib in conancenter Found 5 pkg/version recipes matching nasm in conancenter Found 3 pkg/version recipes matching strawberryperl in conancenter ======== Outdated dependencies ======== libcurl Current versions: libcurl/8.5.0 Latest in remote(s): libcurl/8.6.0 - conancenter Version ranges: libcurl/[*] nasm Current versions: nasm/2.15.05 Latest in remote(s): nasm/2.16.01 - conancenter ``` --- https://docs.conan.io/2/reference/commands/lock/add.html.md --- # conan lock add ```text $ conan lock add -h usage: conan lock add [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--requires REQUIRES] [--build-requires BUILD_REQUIRES] [--python-requires PYTHON_REQUIRES] [--config-requires CONFIG_REQUIRES] [--lockfile-out LOCKFILE_OUT] [--lockfile LOCKFILE] Add requires, build-requires or python-requires to an existing or new lockfile. The resulting lockfile will be ordered, newer versions/revisions first. References can be supplied with and without revisions like "-- requires=pkg/version", but they must be recipe references, including at least the version, and they cannot contain a version range. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --requires REQUIRES Add references to lockfile. --build-requires BUILD_REQUIRES Add build-requires to lockfile --python-requires PYTHON_REQUIRES Add python-requires to lockfile --config-requires CONFIG_REQUIRES Add config-requires to lockfile --lockfile-out LOCKFILE_OUT Filename of the created lockfile --lockfile LOCKFILE Filename of the input lockfile ``` The `conan lock add` command is able to add a package version to an existing or new lockfile `requires`, `build_requires`, `python_requires` or `config_requires`. For example, the following is able to create a lockfile (by default, named `conan.lock`): ```bash $ conan lock add --requires=pkg/1.1 --build-requires=tool/2.2 --python-requires=mypytool/3.3 Generated lockfile: ...conan.lock $cat conan.lock { "version": "0.5", "requires": [ "pkg/1.1" ], "build_requires": [ "tool/2.2" ], "python_requires": [ "mypytool/3.3" ] } ``` The `conan lock add` command also allows to provide an existing lockfile as an input, and it will add the arguments to the existing lockfile, maintaining the package versions sorted: ```bash $ conan lock add --build-requires=tool/2.3 --lockfile=conan.lock Using lockfile: '.../conan.lock' Generated lockfile: .../conan.lock $ cat conan.lock { "version": "0.5", "requires": [ "pkg/1.1" ], "build_requires": [ "tool/2.3", "tool/2.2" ], "python_requires": [ "mypytool/3.3" ] } ``` The `conan lock add` command does not perform any checking on the lockfile, the packages, the existence of packages, the existence of package versions, or the existence of those packages in a given dependency graph, it is a basic manipulation of the json information. When that lockfile is applied to resolve a dependency graph, it is possible that the added versions do not exist, or do not resolve for the `conanfile.py` recipes defined version ranges. Moreover, the list of versions is still sorted. Adding an older version like `tool/2.1` to the previous lockfile won’t make that version being used automatically if the recipes contain the version range `tool/[>=2.0 <3]`, because the `tool/2.2` version is listed there and the range will resolve to it, not to the older `tool/2.1`. Note that a lockfile created with `conan lock add` can be incomplete and not contain all necessary locked versions that a full dependency graph would need. For those cases, recall that the `--lockfile-partial` argument can be applied. Note also that if a `conan.lock` file exist in the current folder, Conan commands like `conan install` will automatically use it. Please have a look to the [lockfiles tutorial](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles). If explicitly adding revisions, please recall that the revisions are timestamp sorted. If more than one revision exists in the lockfile, it is mandatory to provide the timestamps of those revisions, so the sorting makes sense, which can be done with: ```bash $ conan lock add --requires=pkg/1.1#revision%timestamp ``` #### WARNING - It is forbidden to manually manipulate a Conan lockfile, changing the strict sorting of references, and that could result in any arbitrary undefined behavior. - Recall that it is not possible to `conan lock add` a version range. The version might be not fully complete (like not providing the revision), but it must be an exact version. #### NOTE **Best practices** This command will not be necessary in many situations. The existing `conan install`, `conan create`, `conan lock`, `conan export`, `conan graph` commands can directly update or produce new lockfiles with the new information of the packages they are creating, and those new or updated lockfiles can be used to continue with the processing. --- https://docs.conan.io/2/reference/commands/lock/create.html.md --- # conan lock create ```text $ conan lock create -h usage: conan lock create [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--build-require] [path] Create a lockfile from a conanfile or a reference. positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --build-require Whether the provided reference is a build-require remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan lock create` command creates a lockfile for the recipe or reference specified in `path` or `--requires`. This command will compute the dependency graph, evaluate which binaries do exist or need to be built, but it will not try to install or build from source those binaries. In that regard, it is equivalent to the `conan graph info` command. Most of the arguments accepted by this command are the same as `conan graph info` (and `conan install`, `conan create`), because the `conan lock create` creates or update a lockfile for a given configuration. A lockfile can be created from scratch, computing a new dependency graph from a local conanfile, or from requires, for example for this `conanfile.txt`: ```text [requires] fmt/9.0.0 [tool_requires] cmake/3.23.5 ``` We can run: ```bash $ conan lock create . $ cat conan.lock { "version": "0.5", "requires": [ "fmt/9.0.0#ca4ae2047ef0ccd7d2210d8d91bd0e02%1675126491.773" ], "build_requires": [ "cmake/3.23.5#5f184bc602682bcea668356d75e7563b%1676913225.027" ], "python_requires": [] } ``` `conan lock create` accepts a `--lockfile` input lockfile (if a `conan.lock` default one is found, it will be automatically used), and then it will add new information in the `--lockfile-out` (by default, also `conan.lock`). For example if we change the above `conanfile.txt`, removing the `tool_requires`, updating `fmt` to `9.1.0` and adding a new dependency to `zlib/1.2.13`: ```text [requires] fmt/9.1.0 zlib/1.2.13 [tool_requires] ``` We will see how `conan lock create` **extends** the existing lockfile with the new configuration, but it doesn’t remove unused versions or packages from it: ```bash $ conan lock create . # will use the existing conan.lock as base, and rewrite it # use --lockfile and --lockfile-out to change that behavior $ cat conan.lock { "version": "0.5", "requires": [ "zlib/1.2.13#13c96f538b52e1600c40b88994de240f%1667396813.733", "fmt/9.1.0#e747928f85b03f48aaf227ff897d9634%1675126490.952", "fmt/9.0.0#ca4ae2047ef0ccd7d2210d8d91bd0e02%1675126491.773" ], "build_requires": [ "cmake/3.23.5#5f184bc602682bcea668356d75e7563b%1676913225.027" ], "python_requires": [] } ``` This behavior is very important to be able to capture multiple different configurations (Linux/Windows, shared/static, Debug/Release, etc) that might have different dependency graphs. See the [lockfiles tutorial](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles), to read more about lockfiles for multiple configurations. If we want to trim unused versions and packages we can force it with the `--lockfile-clean` argument: ```bash $ conan lock create . --lockfile-clean # will use the existing conan.lock as base, and rewrite it, cleaning unused versions $ cat conan.lock { "version": "0.5", "requires": [ "zlib/1.2.13#13c96f538b52e1600c40b88994de240f%1667396813.733", "fmt/9.1.0#e747928f85b03f48aaf227ff897d9634%1675126490.952" ], "build_requires": [], "python_requires": [] } ``` #### SEE ALSO The [lockfiles tutorial section](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles) has more examples and hands on explanations of lockfiles. --- https://docs.conan.io/2/reference/commands/lock/merge.html.md --- # conan lock merge ```text $ conan lock merge -h usage: conan lock merge [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--lockfile LOCKFILE] [--lockfile-out LOCKFILE_OUT] Merge 2 or more lockfiles. options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --lockfile LOCKFILE Path to lockfile to be merged --lockfile-out LOCKFILE_OUT Filename of the created lockfile ``` The `conan lock merge` command takes 2 or more lockfiles and aggregate them, producing one final lockfile. For example, if we have 2 lockfiles `lock1.lock` and `lock2.lock`, we can merge both in a final `conan.lock` one: ```bash # we have 2 lockfiles lock1.lock and lock2.lock $ conan lock add --requires=pkg/1.1 --lockfile-out=lock1.lock $ cat lock1.lock { "version": "0.5", "requires": [ "pkg/1.1", ], "build_requires": [], "python_requires": [] } $ conan lock add --requires=other/2.1 --build-requires=tool/3.2 --lockfile-out=lock2.lock $ cat lock2.lock { "version": "0.5", "requires": [ "other/2.1" ], "build_requires": [ "tool/3.2" ], "python_requires": [] } # we can merge both $ conan lock merge --lockfile=lock1.lock --lockfile=lock2.lock $ cat conan.lock { "version": "0.5", "requires": [ "pkg/1.1", "other/2.1" ], "build_requires": [ "tool/3.2" ], "python_requires": [] } ``` Similar to the `conan lock add` command, the `conan lock merge`: - Does keep strict sorting of the lists of versions - It does not perform any kind of validation if the packages or versions exist or not, or if they belong to a given dependency graph - It is a basic processing of the json files, aggregating them. - It doesn’t guarantee that the lockfile will be complete, might require `--lockfile-partial` if not - Recipe revisions, if defined, must contain the timestamp to be sorted correctly. #### WARNING - It is forbidden to manually manipulate a Conan lockfile, changing the strict sorting of references, and that could result in any arbitrary undefined behavior. - Recall that it is not possible to `conan lock add` a version range. The version might be not fully complete (like not providing the revision), but it must be an exact version. #### SEE ALSO To better understand `conan lock merge`, it is recommended to first understand lockfiles in general, visit the [lockfiles tutorial](https://docs.conan.io/2//tutorial/versioning/lockfiles.html.md#tutorial-versioning-lockfiles) for a practical introduction to lockfiles. This `conan lock merge` command can be useful to consolidate in a single lockfile when for some reasons there are several lockfiles that have diverged. A use case would be to create a multi-configuration lockfile that contains all necessary locked versions for all OSs (Linux, Windows, etc), even if there are conditional dependencies in the graph for the different OSs. At some point when testing a new dependency version, for example, `pkg/3.4` new version, when previously `pkg/3.3` was already in the graph, we might want to have such a new lockfile cleaning the previous `pkg/3.3`. If we apply the `--lockfile-clean` argument that will remove the non-used versions in the lockfile, but that will also remove the OS-dependant dependencies. So something like this could be done: lets say that we have this lockfile (simplified, removed revisions for simplicity) as the result of testing a new `pkgb/0.2` version for our main product `app1/0.1`: ```json { "version": "0.5", "requires": [ "pkgb/0.2", "pkgb/0.1", "pkgawin/0.1", "pkganix/0.1", "app1/0.1" ] } ``` The `pkgawin` and `pkganix` are dependencies that exist exclusively in Windows and Linux respectively. Everything looks good, `pkgb/0.2` new version works fine with our app, and we want to clean the unused things from the lockfile: ```bash $ conan lock create --requires=app1/0.1 --lockfile=app.lock --lockfile-out=win.lock -s os=Windows --lockfile-clean # Note how both pkgb/0.1 and pkganix are gone $ cat win.lock { "version": "0.5", "requires": [ "pkgb/0.2", "pkgawin/0.1", "app1/0.1" ] } $ conan lock create --requires=app1/0.1 --lockfile=app.lock --lockfile-out=nix.lock -s os=Linux --lockfile-clean # Note how both pkgb/0.1 and pkgawin are gone $ cat win.lock { "version": "0.5", "requires": [ "pkgb/0.2", "pkganix/0.1", "app1/0.1" ] } # Finally, merge the 2 clean lockfiles, for keeping just 1 for next iteration $ conan lock merge --lockfile=win.lock --lockfile=nix.lock --lockfile-out=final.lock $ cat final.lock { "version": "0.5", "requires": [ "pkgb/0.2", "pkgawin/0.1", "pkganix/0.1", "app1/0.1" ] } ``` --- https://docs.conan.io/2/reference/commands/lock/remove.html.md --- # conan lock remove ```text $ conan lock remove -h usage: conan lock remove [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--requires REQUIRES] [--build-requires BUILD_REQUIRES] [--python-requires PYTHON_REQUIRES] [--config-requires CONFIG_REQUIRES] [--lockfile-out LOCKFILE_OUT] [--lockfile LOCKFILE] Remove requires, build-requires or python-requires from an existing lockfile. References can be supplied with and without revisions like "-- requires=pkg/version", options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --requires REQUIRES Remove references to lockfile. --build-requires BUILD_REQUIRES Remove build-requires from lockfile --python-requires PYTHON_REQUIRES Remove python-requires from lockfile --config-requires CONFIG_REQUIRES Remove config-requires from lockfile --lockfile-out LOCKFILE_OUT Filename of the created lockfile --lockfile LOCKFILE Filename of the input lockfile ``` The `conan lock remove` command is able to remove `requires`, `build_requires`, `python_requires` or `config_requires` items from an existing lockfile. For example, if we have the following `conan.lock`: ```bash $ cat conan.lock { "version": "0.5", "requires": [ "math/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", "engine/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "build_requires": [ "cmake/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", "ninja/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "python_requires": [ "mytool/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", "othertool/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ] } ``` The `conan lock remove` command: ```bash $ conan lock remove --requires="math/*" --build-requires=cmake/1.0 --python-requires="*tool/*" ``` Will result in the following `conan.lock`: ```bash $ cat conan.lock { "version": "0.5", "requires": [ "engine/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "build_requires": [ "ninja/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "python_requires": [ ] } ``` It is possible to specify different patterns: - Remove by version-ranges with expressions like `--requires="math/[>=1.0 <2]"`, and also - Remove a specific revision: `--requires=math/1.0#revision` - Remove locked dependencies for a given “team” user `--requires=*/*@team*` The `conan lock remove` can be useful for: - In combination with `conan lock add`, it can be used to force the downgrade of a locked version to an older one. As `conan lock add` always adds and sorts the order, resulting in newer versions with high priority, it is not possible to force going back to an older version with just `add`. But first using `conan lock remove`, then `conan lock add`, it is possible to do so. - `conan lock remove` can unlock certain dependencies, resulting in an incomplete lockfile, that can be used with `--lockfile-partial` to resolve to the latest available versions for the unlocked dependencies, while keeping locked the rest. --- https://docs.conan.io/2/reference/commands/lock/update.html.md --- # conan lock update ```text $ conan lock update -h usage: conan lock update [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [--requires REQUIRES] [--build-requires BUILD_REQUIRES] [--python-requires PYTHON_REQUIRES] [--config-requires CONFIG_REQUIRES] [--lockfile-out LOCKFILE_OUT] [--lockfile LOCKFILE] Update requires, build-requires or python-requires from an existing lockfile. References that matches the arguments package names will be replaced by the arguments. References can be supplied with and without revisions like "-- requires=pkg/version", options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True --requires REQUIRES Update references to lockfile. --build-requires BUILD_REQUIRES Update build-requires from lockfile --python-requires PYTHON_REQUIRES Update python-requires from lockfile --config-requires CONFIG_REQUIRES Update config-requires from lockfile --lockfile-out LOCKFILE_OUT Filename of the created lockfile --lockfile LOCKFILE Filename of the input lockfile ``` The `conan lock update` command is able to update `requires`, `build_requires`, `python_requires` or `config_requires` items from an existing lockfile. For example, if we have the following `conan.lock`: ```bash $ cat conan.lock { "version": "0.5", "requires": [ "math/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", "engine/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "build_requires": [ "cmake/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", "ninja/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "python_requires": [ "mytool/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", "othertool/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ] } ``` The `conan lock update` command: ```bash $ conan lock update --requires=math/1.1 --build-requires=cmake/1.1 ``` Will result in the following `conan.lock`: ```bash $ cat conan.lock { "version": "0.5", "requires": [ "math/1.1", "engine/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "build_requires": [ "cmake/1.1", "ninja/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ], "python_requires": [ "mytool/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", "othertool/1.0#fd2b006646a54397c16a1478ac4111ac%1702683583.3544693" ] } ``` The command will replace existing locked references that matches the same package name with the provided argument values. If the provided references does not exist in the lockfile, they will be added (same as `conan lock add` command). This command is similar to do a `conan lock remove` followed by a `conan lock add` command. --- https://docs.conan.io/2/reference/commands/lock/upgrade.html.md --- # conan lock upgrade #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan lock upgrade -h usage: conan lock upgrade [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [--name NAME] [--version VERSION] [--user USER] [--channel CHANNEL] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [-ur UPDATE_REQUIRES] [-ubr UPDATE_BUILD_REQUIRES] [-upr UPDATE_PYTHON_REQUIRES] [--build-require] [path] (Experimental) Upgrade requires, build-requires or python-requires from an existing lockfile given a conanfile or a reference. positional arguments: path Path to a folder containing a recipe (conanfile.py or conanfile.txt) or to a recipe file. e.g., ./my_project/conanfile.txt. Defaults to the current directory when no --requires or --tool-requires is given options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile -ur UPDATE_REQUIRES, --update-requires UPDATE_REQUIRES Update requires from lockfile -ubr UPDATE_BUILD_REQUIRES, --update-build-requires UPDATE_BUILD_REQUIRES Update build-requires from lockfile -upr UPDATE_PYTHON_REQUIRES, --update-python-requires UPDATE_PYTHON_REQUIRES Update python-requires from lockfile --build-require Whether the provided reference is a build-require remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL reference arguments: --name NAME Provide a package name if not specified in conanfile --version VERSION Provide a package version if not specified in conanfile --user USER Provide a user if not specified in conanfile --channel CHANNEL Provide a channel if not specified in conanfile lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan lock upgrade` command is able to upgrade `requires`, `build_requires`, `python_requires` items from an existing lockfile. For example, if we have the following `conan.lock`: ```bash $ cat conan.lock { "version": "0.5", "requires": [ "package/1.0#b0546195fd5bf19a0e6742510fff8855%1740472377.653885" ], "build_requires": [ "cmake/1.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", ] } ``` And these packages available in the cache: ```bash $ conan list "*" --format=compact Found 9 pkg/version recipes matching * in local cache Local Cache package/1.0 package/1.9 cmake/3.29.0 cmake/3.30.5 ``` Using the `conan lock upgrade` command with the appropiate `--update-**` arguments: ```bash $ conan lock upgrade --requires=package/[>=1.0 <2] --update-requires=package/[*] ``` Will result in the following `conan.lock`: ```bash $ cat conan.lock { "version": "0.5", "requires": [ "package/1.9#b0546195fd5bf19a0e6742510fff8855%1740484122.108484" ], "build_requires": [ "cmake/3.29.0#85d927a4a067a531b1a9c7619522c015%1702683583.3411012", ] } ``` The same can be done for `build_requires` and `python_requires`. The command will upgrade existing locked references that match the same package name with versions that match the version ranges provided by required arguments. The `conan lock upgrade` command may also be able to upgrade `requires`, `build_requires`, `python_requires` from a conanfile. This use case enhances the functionality of version ranges. Let’s consider the following conanfile: ```python from conan import ConanFile class HelloConan(ConanFile): requires = ("math/[>=1.0 <2]") tool_requires = "ninja/[>=1.0]" ``` ```bash $ conan list "*" --format=compact Found 9 pkg/version recipes matching * in local cache Local Cache math/1.0 math/2.0 ninja/1.0 ninja/1.1 ``` Starting from the same environment and `conan.lock` file from previous example. Running the following command: ```bash $ conan lock upgrade . --update-requires=math/1.0 --update-build-requires=ninja/[*] ``` Will result in the following `conan.lock`: ```bash { "version": "0.5", "requires": [ "math/1.0#b0546195fd5bf19a0e6742510fff8855%1740488410.356828" ], "build_requires": [ "ninja/1.1#dc77a17d3e566df710241e3b1f380b8c%1740488410.371875" ] } ``` `math` package have not been updated due to the version range specified in the conanfile, but `ninja` has been updated to the latest version available in the cache. If a dependency is updated and in the new revision, a transitive dependency is added, the `lock upgrade` command will reflect the new transitive dependency in the lockfile. E.g. - `liba/1.0` depends on `libb/1.0` - `libb/1.0` depends on `libc/1.0` If `libb/2.0` depends also on `libd/1.0`: ```bash $ conan lock upgrade --requires=libb/[>=2] --update-requires=libb/* ``` The resulting lockfile will contain both `libc/1.0` and `libd/1.0`. #### NOTE Updating transitive dependencies is not supported yet. This is an experimental feature and it may change in the future. --- https://docs.conan.io/2/reference/commands/lock/upgrade_config.html.md --- # conan lock upgrade-config #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. ```text $ conan lock upgrade-config -h usage: conan lock upgrade-config [-h] [--out-file OUT_FILE] [-v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}]] [-cc CORE_CONF] [-b BUILD] [-r REMOTE | -nr] [-u [UPDATE]] [-pr PROFILE] [-pr:b PROFILE_BUILD] [-pr:h PROFILE_HOST] [-pr:a PROFILE_ALL] [-o OPTIONS] [-o:b OPTIONS_BUILD] [-o:h OPTIONS_HOST] [-o:a OPTIONS_ALL] [-s SETTINGS] [-s:b SETTINGS_BUILD] [-s:h SETTINGS_HOST] [-s:a SETTINGS_ALL] [-c CONF] [-c:b CONF_BUILD] [-c:h CONF_HOST] [-c:a CONF_ALL] [--requires REQUIRES] [--tool-requires TOOL_REQUIRES] [-l LOCKFILE] [--lockfile-partial] [--lockfile-out LOCKFILE_OUT] [--lockfile-clean] [--lockfile-overrides LOCKFILE_OVERRIDES] [--update-config-requires UPDATE_CONFIG_REQUIRES] [path] (Experimental) Upgrade config requires in a lockfile positional arguments: path Path to a conanconfig.yml file (defaults to current directory) options: -h, --help show this help message and exit --out-file OUT_FILE Write the output of the command to the specified file instead of stdout. -v [{quiet,error,warning,notice,status,verbose,debug,v,trace,vv}] Level of detail of the output. Valid options from less verbose to more verbose: -vquiet, -verror, -vwarning, -vnotice, -vstatus, -v or -vverbose, -vv or -vdebug, -vvv or -vtrace -cc CORE_CONF, --core-conf CORE_CONF Define core configuration, overwriting global.conf values. E.g.: -cc core:non_interactive=True -b BUILD, --build BUILD Optional, specify which packages to build from source. Combining multiple '--build' options on one command line is allowed. Possible values: --build=never Disallow build for all packages, use binary packages or fail if a binary package is not found, it cannot be combined with other '--build' options. --build=missing Build packages from source whose binary package is not found. --build=cascade Build packages from source that have at least one dependency being built from source. --build=[pattern] Build packages from source whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards, so '--build="*"' will build everything from source. --build=~[pattern] Excluded packages, which will not be built from the source, whose package reference matches the pattern. The pattern uses 'fnmatch' style wildcards. --build=missing:[pattern] Build from source if a compatible binary does not exist, only for packages matching pattern. --build=compatible:[pattern] (Experimental) Build from source if a compatible binary does not exist, and the requested package is invalid, the closest package binary following the defined compatibility policies (method and compatibility.py) --requires REQUIRES Directly provide requires instead of a conanfile --tool-requires TOOL_REQUIRES Directly provide tool-requires instead of a conanfile --update-config-requires UPDATE_CONFIG_REQUIRES Update config-requires from lockfile remote arguments: -r REMOTE, --remote REMOTE Look in the specified remote or remotes server -nr, --no-remote Do not use remote, resolve exclusively in the cache -u [UPDATE], --update [UPDATE] Will install newer versions and/or revisions in the local cache for the given references whose name matches the given pattern, or all references in the graph if no argument is supplied. When using version ranges, it will install the latest version that satisfies the range. It will update to the latest revision for the resolved version range. The consumer pattern (&) has no effect, and users should not specify versions. profile arguments: -pr PROFILE, --profile PROFILE Apply the specified profile. By default, or if specifying -pr:h (--profile:host), it applies to the host context. Use -pr:b (--profile:build) to specify the build context, or -pr:a (--profile:all) to specify both contexts at once -pr:b PROFILE_BUILD, --profile:build PROFILE_BUILD -pr:h PROFILE_HOST, --profile:host PROFILE_HOST -pr:a PROFILE_ALL, --profile:all PROFILE_ALL -o OPTIONS, --options OPTIONS Apply the specified options. By default, or if specifying -o:h (--options:host), it applies to the host context. Use -o:b (--options:build) to specify the build context, or -o:a (--options:all) to specify both contexts at once. Example: -o="pkg/*:with_qt=True" -o:b OPTIONS_BUILD, --options:build OPTIONS_BUILD -o:h OPTIONS_HOST, --options:host OPTIONS_HOST -o:a OPTIONS_ALL, --options:all OPTIONS_ALL -s SETTINGS, --settings SETTINGS Apply the specified settings. By default, or if specifying -s:h (--settings:host), it applies to the host context. Use -s:b (--settings:build) to specify the build context, or -s:a (--settings:all) to specify both contexts at once. Example: -s="compiler=gcc" -s:b SETTINGS_BUILD, --settings:build SETTINGS_BUILD -s:h SETTINGS_HOST, --settings:host SETTINGS_HOST -s:a SETTINGS_ALL, --settings:all SETTINGS_ALL -c CONF, --conf CONF Apply the specified conf. By default, or if specifying -c:h (--conf:host), it applies to the host context. Use -c:b (--conf:build) to specify the build context, or -c:a (--conf:all) to specify both contexts at once. Example: -c="tools.cmake.cmaketoolchain:generator=Xcode" -c:b CONF_BUILD, --conf:build CONF_BUILD -c:h CONF_HOST, --conf:host CONF_HOST -c:a CONF_ALL, --conf:all CONF_ALL lockfile arguments: -l LOCKFILE, --lockfile LOCKFILE Path to a lockfile. Use --lockfile="" to avoid automatic use of existing 'conan.lock' file --lockfile-partial Do not raise an error if some dependency is not found in lockfile --lockfile-out LOCKFILE_OUT Filename of the updated lockfile --lockfile-clean Remove unused entries from the lockfile --lockfile-overrides LOCKFILE_OVERRIDES Overwrite lockfile overrides ``` The `conan lock upgrade-config` command is equivalent to the previous `conan lock upgrade`, but tailored specifically to upgrade the `config-requires` packages that can be installed with `conan config install-pkg`. The upgrade can be done over individual requirements passed on the command line: ```bash $ conan lock upgrade-config --requires=config/[*] --update-config-requires=config/* ``` Note that it is important to specify which packages are to be updated with `--update-config-requires`, because it is possible that the lockfile contains more than one configuration package. Also note that the upgrade of the lockfile doesn’t change yet or install the configuration. Until a `conan config install-pkg` happens, the active and current configuration will not be updated. It is also possible to use a `conanconfig.yml` file as an input to the command, by passing the path to its containing folder: ```bash $ conan lock upgrade-config . --update-config-requires=config/1.0 ``` #### IMPORTANT The `path` argument must point to a folder containing a `conanconfig.yml` file (typically the folder where `conan config install-pkg` is executed), not to a `conanfile.py` or `conanfile.txt` recipe. Use `--requires` or `--tool-requires` to define recipe references directly on the command line. #### SEE ALSO - See the [conan config install-pkg](https://docs.conan.io/2//reference/commands/config.html.md#reference-commands-conan-config-install-pkg) command. --- https://docs.conan.io/2/reference/conanfile/attributes.html.md --- # Attributes > * [Package reference](#package-reference) > * [name](#name) > * [version](#version) > * [user](#user) > * [channel](#channel) > * [Metadata](#metadata) > * [description](#description) > * [license](#license) > * [author](#author) > * [topics](#topics) > * [homepage](#homepage) > * [url](#url) > * [Requirements](#requirements) > * [requires](#requires) > * [tool_requires](#tool-requires) > * [build_requires](#build-requires) > * [test_requires](#test-requires) > * [python_requires](#python-requires) > * [python_requires_extend](#python-requires-extend) > * [Sources](#sources) > * [exports](#exports) > * [exports_sources](#exports-sources) > * [conan_data](#conan-data) > * [source_buildenv](#source-buildenv) > * [Binary model](#binary-model) > * [package_type](#package-type) > * [settings](#settings) > * [options](#options) > * [default_options](#default-options) > * [default_build_options](#default-build-options) > * [options_description](#options-description) > * [languages](#languages) > * [info](#info) > * [package_id_{embed,non_embed,python,unknown}_mode, build_mode](#package-id-embed-non-embed-python-unknown-mode-build-mode) > * [package_id_abi_options](#package-id-abi-options) > * [context](#context) > * [Build](#build) > * [generators](#generators) > * [build_policy](#build-policy) > * [win_bash](#win-bash) > * [win_bash_run](#win-bash-run) > * [Folders and layout](#folders-and-layout) > * [source_folder](#source-folder) > * [export_sources_folder](#export-sources-folder) > * [build_folder](#build-folder) > * [generators_folder](#generators-folder) > * [package_folder](#package-folder) > * [recipe_folder](#recipe-folder) > * [recipe_metadata_folder](#recipe-metadata-folder) > * [package_metadata_folder](#package-metadata-folder) > * [no_copy_source](#no-copy-source) > * [test_package_folder](#test-package-folder) > * [Layout](#layout) > * [folders](#folders) > * [cpp](#cpp) > * [layouts](#layouts) > * [Package information for consumers](#package-information-for-consumers) > * [cpp_info](#cpp-info) > * [buildenv_info](#buildenv-info) > * [runenv_info](#runenv-info) > * [conf_info](#conf-info) > * [generator_info](#generator-info) > * [deprecated](#deprecated) > * [provides](#provides) > * [package_type_traits](#package-type-traits) > * [Other](#other) > * [dependencies](#dependencies) > * [subgraph](#subgraph) > * [conf](#conf) > * [Output](#output) > * [Output contents](#output-contents) > * [revision_mode](#revision-mode) > * [upload_policy](#upload-policy) > * [required_conan_version](#required-conan-version) > * [implements](#implements) > * [alias](#alias) > * [extension_properties](#extension-properties) ## Package reference Recipe attributes that can define the main `pkg/version@user/channel` package reference. ### name The name of the package. A valid name is all lowercase and has: - A minimum of 2 and a maximum of 101 characters (though shorter names are recommended). - Matches the following regex `^[a-z0-9_][a-z0-9_+.-]{1,100}$`: so starts with alphanumeric or `_`, : then from 1 to 100 characters between alphanumeric, `_`, `+`, `.` or `-`. The name is only necessary for `export`-ing the recipe into the local cache (`export`, `export-pkg` : and `create` commands), if they are not defined in the command line with `--name=`. ### version The version of the package. A valid version follows the same rules than the `name` attribute. In case the version follows semantic versioning in the form `X.Y.Z-pre1+build2`, that value might be used for requiring this package through version ranges instead of exact versions. The version is only strictly necessary for `export`-ing the recipe into the local cache (`export`, `export-pkg` and `create` commands), if they are not defined in the command line with `--version=` The `version` can be dynamically defined in the command line, and also programmatically in the recipe with the [set_version() method](https://docs.conan.io/2//reference/conanfile/methods/set_version.html.md#reference-conanfile-methods-set-version). ### user A valid string for the `user` field follows the same rules than the `name` attribute. This is an optional attribute. It can be used to identify your own packages with `pkg/version@user/channel`, where `user` could be the name of your team, org or company. ConanCenter recipes don’t have `user/channel`, so they are in the form of `pkg/version` only. You can also name your packages without user and channel, or using only the user as `pkg/version@user`. The user can be specified in the command line with `--user=` ### channel A valid string for the `channel` field follows the same rules than the `name` attribute. This is an optional attribute. It is sometimes used to identify a maturity of the package (“stable”, “testing”…), but in general this is not necessary, and the maturity of packages is better managed by putting them in different server repositories. The channel can be specified in the command line with `--channel=`. If a channel is specified, a user must also be specified, so the package reference is always complete as `pkg/version@user/channel`. ## Metadata Optional metadata, like license, description, author, etc. Not necessary for most cases, but can be useful to have. ### description This is an optional, but recommended text field, containing the description of the package, and any information that might be useful for the consumers. The first line might be used as a short description of the package. ```python class HelloConan(ConanFile): name = "hello" version = "0.1" description = """This is a Hello World library. A fully featured, portable, C++ library to say Hello World in the stdout, with incredible iostreams performance""" ``` ### license License of the **target** source code and binaries, i.e. the code that is being packaged, not the `conanfile.py` itself. Can contain several, comma separated licenses. It is a text string, so it can contain any text, but it is strongly recommended that recipes of Open Source projects use [SPDX](https://spdx.dev) identifiers from the [SPDX license list](https://spdx.org/licenses/) This will help people wanting to automate license compatibility checks, like consumers of your package, or you if your package has Open-Source dependencies. ```python class Pkg(ConanFile): license = "MIT" ``` ### author Main maintainer/responsible for the package, any format. This is an optional attribute. ```python class HelloConan(ConanFile): author = "John J. Smith (john.smith@company.com)" ``` ### topics Tags to group related packages together and describe what the code is about. Used as a search filter in ConanCenter. Optional attribute. It should be a tuple of strings. ```python class ProtocInstallerConan(ConanFile): name = "protoc_installer" version = "0.1" topics = ("protocol-buffers", "protocol-compiler", "serialization", "rpc") ``` ### homepage The home web page of the library being packaged. Used to link the recipe to further explanations of the library itself like an overview of its features, documentation, FAQ as well as other related information. ```python class EigenConan(ConanFile): name = "eigen" version = "3.3.4" homepage = "http://eigen.tuxfamily.org" ``` ### url URL of the package repository, i.e. not necessarily of the original source code. Recommended, but not mandatory attribute. ```python class HelloConan(ConanFile): name = "hello" version = "0.1" url = "https://github.com/conan-io/libhello.git" ``` ## Requirements Attribute form of the dependencies simple declarations, like `requires`, `tool_requires`. For more advanced way to define requirements, use the `requirements()`, `build_requirements()` methods instead. ### requires List or tuple of strings for regular dependencies in the host context, like a library. ```python class MyLibConan(ConanFile): requires = "hello/1.0", "otherlib/2.1@otheruser/testing" ``` You can specify version ranges, the syntax is using brackets: ```python class HelloConan(ConanFile): requires = "pkg/[>1.0 <1.8]" ``` Accepted expressions would be: | Expression | Versions in range | Versions outside of range | |--------------|--------------------------|-----------------------------| | [>=1.0 <2] | 1.0.0, 1.0.1, 1.1, 1.2.3 | 0.2, 2.0, 2.1, 3.0 | | [<3.2.1] | 0.1, 1.2, 2.4, 3.1.1 | 3.2.2 | | [>2.0] | 2.1, 2.2, 3.1, 14.2 | 1.1, 1.2, 2.0 | The caret `^` and tilde `~` operators are basically compact representations of lower and upper bounds: - The `[~2.5.1]` range could be written as `[>=2.5.1 <2.6.0]` - The `[^1.2.3]` range could be written as `[>=1.2.3 <2.0.0]` In general, it is recommended to use the full expression `[>=lower =1.0 <2] | 1.0.0-pre.1, 1.0.0, 1.0.1, 1.1, 1.2.3 | 0.2, 2.0-pre.1, 2.0, 2.1, 3.0 | | [<3.2.1] | 0.1, 1.2, 1.8-beta.1, 2.0-alpha.2, 2.4, 3.1.1 | 3.2.1-pre.1, 3.2.1, 3.2.2, 3.3 | | [>2.0] | 2.1-pre.1, 2.1, 2.2, 3.1, 14.2 | 1.1, 1.2, 2.0-pre.1, 2.0 | #### SEE ALSO - Check [Range expressions](https://docs.conan.io/2//tutorial/versioning/version_ranges.html.md#tutorial-version-ranges-expressions) version_ranges tutorial section - Check [requirements()](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-methods-requirements) method docs ### tool_requires List or tuple of strings for dependencies. Represents a build tool like “cmake”. If there is an existing pre-compiled binary for the current package, the binaries for the tool_require won’t be retrieved. They cannot conflict. ```python class MyPkg(ConanFile): tool_requires = "tool_a/0.2", "tool_b/0.2@user/testing" ``` This is the declarative way to add `tool_requires`. Check the [tool_requires()](https://docs.conan.io/2//reference/conanfile/methods/build_requirements.html.md#reference-conanfile-methods-build-requirements-tool-requires) conanfile.py method to learn a more flexible way to add them. ### build_requires #### WARNING Deprecated since Conan 2.28. Please use `tool_requires` instead of `build_requires`. build_requires are used in Conan 2 to provide compatibility with the Conan 1.X syntax, but their use is discouraged in Conan 2 and will be deprecated in future 2.X releases. Please use tool_requires instead of build_requires in your Conan 2 recipes. ### test_requires List or tuple of strings for dependencies in the host context only. Represents a test tool like “gtest”. Used when the current package is built from sources. They don’t propagate information to the downstream consumers. If there is an existing pre-compiled binary for the current package, the binaries for the test_require won’t be retrieved. They cannot conflict. ```python class MyPkg(ConanFile): name = "mypkg" test_requires = "gtest/1.17.0", "other_test_tool/0.2@user/testing" ``` Note that `test_requires` are private (`visible=False`), only the recipe that declares them has visibility and can use them. The consumers of `MyPkg` will not see or know about the existence of `gtest` or `other_test_tool`. Consequently, they cannot be affected by consumers `options` values definitions, it doesn’t matter that a consumer of `mypkg` defines options like `gtest*:some_option=somevalue`, because `gtest` will never receive that value. This is the declarative way to add `test_requires`. Check the [test_requires() method](https://docs.conan.io/2//reference/conanfile/methods/build_requirements.html.md#reference-conanfile-methods-build-requirements-test-requires) to learn a more flexible way to add them. ### python_requires This class attribute allows to define a dependency to another Conan recipe and reuse its code. Its basic syntax is: ```python from conan import ConanFile class Pkg(ConanFile): python_requires = "pyreq/0.1@user/channel" # recipe to reuse code from def build(self): self.python_requires["pyreq"].module # access to the whole conanfile.py module self.python_requires["pyreq"].module.myvar # access to a variable self.python_requires["pyreq"].module.myfunct() # access to a global function self.python_requires["pyreq"].path # access to the folder where the reused file is ``` Read more about this attribute in [Python requires](https://docs.conan.io/2//reference/extensions/python_requires.html.md#reference-extensions-python-requires) ### python_requires_extend This class attribute defines one or more classes that will be injected in runtime as base classes of the recipe class. Syntax for each of these classes should be a string like `pyreq.MyConanfileBase` where the `pyreq` is the name of a `python_requires` and `MyConanfileBase` is the name of the class to use. ```python from conan import ConanFile class Pkg(ConanFile): python_requires = "pyreq/0.1@user/channel", "utils/0.1@user/channel" python_requires_extend = "pyreq.MyConanfileBase", "utils.UtilsBase" # class/es to inject ``` ## Sources ### exports List or tuple of strings with file names or [fnmatch](https://docs.python.org/3/library/fnmatch.html) patterns that should be exported and stored side by side with the *conanfile.py* file to make the recipe work: other python files that the recipe will import, some text file with data to read,… For example, if we have some python code that we want the recipe to use in a `helpers.py` file, and have some text file *info.txt* we want to read and display during the recipe evaluation we would do something like: ```python exports = "helpers.py", "info.txt" ``` Exclude patterns are also possible, with the `!` prefix: ```python exports = "*.py", "!*tmp.py" ``` #### SEE ALSO - [Check the export() conanfile.py method](https://docs.conan.io/2//reference/conanfile/methods/export.html.md#reference-conanfile-methods-export). ### exports_sources List or tuple of strings with file names or [fnmatch](https://docs.python.org/3/library/fnmatch.html) patterns that should be exported and will be available to generate the package. Unlike the `exports` attribute, these files shouldn’t be used by the `conanfile.py` Python code, but to compile the library or generate the final package. And, due to its purpose, these files will only be retrieved if requested binaries are not available or the user forces Conan to compile from sources. This is an alternative to getting the sources with the `source()` method. Used when we are not packaging a third party library and we have together the recipe and the C/C++ project: ```python exports_sources = "include*", "src*" ``` Exclude patterns are also possible, with the `!` prefix: ```python exports_sources = "include*", "src*", "!src/build/*" ``` Note, if the recipe defines the `layout()` method and specifies a `self.folders.source = "src"` it won’t affect where the files (from the `exports_sources`) are copied. They will be copied to the base source folder. So, if you want to replace some file that got into the `source()` method, you need to explicitly copy it from the parent folder or even better, from `self.export_sources_folder`. ```python import os, shutil from conan import ConanFile from conan.tools.files import save, load class Pkg(ConanFile): ... exports_sources = "CMakeLists.txt" def layout(self): self.folders.source = "src" self.folders.build = "build" def source(self): # emulate a download from web site save(self, "CMakeLists.txt", "MISTAKE: Very old CMakeLists to be replaced") # Now I fix it with one of the exported files shutil.copy("../CMakeLists.txt", ".") shutil.copy(os.path.join(self.export_sources_folder, "CMakeLists.txt"), ".") ``` #### SEE ALSO - [Check the export_sources() conanfile.py method](https://docs.conan.io/2//reference/conanfile/methods/export_sources.html.md#reference-conanfile-methods-export-sources). ### conan_data Read only attribute with a dictionary with the keys and values provided in a [conandata.yml](https://docs.conan.io/2//tutorial/creating_packages/handle_sources_in_packages.html.md#creating-packages-handle-sources-in-packages-conandata) file format placed next to the *conanfile.py*. This YAML file is automatically exported with the recipe and automatically loaded with it too. You can declare information in the *conandata.yml* file and then access it inside any of the methods of the recipe. For example, a *conandata.yml* with information about sources that looks like this: ```YAML sources: "1.1.0": url: "https://www.url.org/source/mylib-1.0.0.tar.gz" sha256: "8c48baf3babe0d505d16cfc0cf272589c66d3624264098213db0fb00034728e9" "1.1.1": url: "https://www.url.org/source/mylib-1.0.1.tar.gz" sha256: "15b6393c20030aab02c8e2fe0243cb1d1d18062f6c095d67bca91871dc7f324a" ``` ```python def source(self): get(self, **self.conan_data["sources"][self.version]) ``` ### source_buildenv Boolean attribute to opt-in injecting the [VirtualBuildEnv](https://docs.conan.io/2//reference/tools/env/virtualbuildenv.html.md#conan-tools-env-virtualbuildenv) generated environment while running the source() method. Setting this attribute to True (default value False) will inject the `VirtualBuildEnv` generated environment from tool requires when executing the source() method. ```python class MyConan: name = "mylib" version = "1.0.0" source_buildenv = True tool_requires = "7zip/1.2.0" def source(self): get(self, **self.conan_data["sources"][self.version]) self.run("7z x *.zip -o*") ## Can run 7z in the source method ``` ## Binary model Important attributes that define the package binaries model, which settings, options, package type, etc. affect the final packaged binaries. ### package_type Optional, but very strongly recommended. Declaring the `package_type` will help Conan: - To choose better the default `package_id_mode` for each dependency, that is, how a change in a dependency should affect the `package_id` to the current package. - Which information from the dependencies should be propagated to the consumers, like headers, libraries, runtime information. See [here](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-package-type-trait-inferring) to see what traits are propagated based on the `package_type` information. The valid values are: - **application**: The package is an application. - **library**: The package is a generic library. It will try to determine the type of library (from `shared-library`, `static-library`, `header-library`) reading the `self.options.shared` (if declared) and the `self.options.header_only` - **shared-library**: The package is a shared library. - **static-library**: The package is a static library. - **header-library**: The package is a header only library. - **build-scripts**: The package only contains build scripts. - **python-require**: The package is a python require. - **unknown**: The type of the package is unknown. Note that relationships between packages might not always be defined and can lead to errors, for example, `build-scripts` cannot have regular `requires` dependencies to compiled libraries, and it is not known how these should be propagated through something that is intended to be used as a `tool_requires`. If some package want to use both some build scripts and link with a given library should define a `tool_requires()` to the `build-scripts` package and a regular `requires()` to the compiled library. #### IMPORTANT The `package_type` defines how different information of C and C++ packages is propagated down the dependency graph: visibility of headers, linkage requirements, etc. It is very recommended to define it, and it should be defined in most cases. #### NOTE The runtime propagation implied by `package_type` can be overridden by declaring `"run": True` inside [package_type_traits](#conan-conanfile-attributes-package-type-traits) attribute. This is useful, for example, for a `static-library` that also ships a shared library that consumers need available at runtime, which would otherwise not be exposed, as `static-library` implies `run=False`. #### NOTE The `package_type` attribute can also be computed dynamically in both the `config_options()` and `configure()` methods, for example, a recipe might not support building shared libraries in a specific platform. This can be defined as: ```python package_type = "library" options = {"shared": [True, False]} def config_options(self): if self.settings.os == "Windows": del self.options.shared self.package_type = "static-library" ``` where care should be taken when accessing the `shared` option, as it will be removed for Windows, so the `self.options.get_safe("shared")` accessor should be used as appropiate. ### settings List of strings with the first level settings (from [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md#reference-config-files-settings-yml)) that the recipe needs, because: - They are read for building (e.g: `if self.settings.compiler == "gcc"`) - They affect the `package_id`. If a value of the declared setting changes, the `package_id` has to be different. The most common is to declare: ```python settings = "os", "compiler", "build_type", "arch" ``` Once the recipe is loaded by Conan, the `settings` are processed and they can be read in the recipe, also the sub-settings: ```python settings = "os", "arch" def build(self): if self.settings.compiler == "gcc": if self.settings.compiler.cppstd == "gnu20": # do some special build commands ``` If you try to access some setting that doesn’t exist, like `self.settings.compiler.libcxx` for the `msvc` setting, Conan will fail telling that `libcxx` does not exist for that compiler. If you want to do a safe check of settings values, you could use the `get_safe()` method: ```python def build(self): # Will be None if doesn't exist (not declared) arch = self.settings.get_safe("arch") # Will be None if doesn't exist (doesn't exist for the current compiler) compiler_version = self.settings.get_safe("compiler.version") # Will be the default version if the return is None build_type = self.settings.get_safe("build_type", default="Release") ``` The `get_safe()` method returns `None` if that setting or sub-setting doesn’t exist and there is no default value assigned. It’s also feasible to check the possible values defined in [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md#reference-config-files-settings-yml) using the `possible_values()` method: ```python def generate(self): # Print if Android exists as OS in the whole settings.yml is_android = "Android" in self.settings.possible_values()["os"] self.output.info(f"Android in settings.yml: {is_android}") # Print the available versions for the compiler used by the HOST profile compiler_versions = self.settings.compiler.version.possible_values() self.output.info(f"[HOST] Versions for {str(self.settings.compiler)}: {', '.join(compiler_versions)}") # Print the available versions for the compiler used by the BUILD profile compiler_versions = self.settings_build.compiler.version.possible_values() self.output.info(f"[BUILD] Versions for {str(self.settings_build.compiler)}: {', '.join(compiler_versions)}") ``` As you can see above, doing `self.settings.possible_values()` returns the whole [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md#reference-config-files-settings-yml) as a Python dict-like object, and doing `self.settings.compiler.version.possible_values()` for instance returns the available versions for the compiler used by the consumer. If you want to do a safe deletion of settings, you could use the `rm_safe()` method. For example, in the `configure()` method a typical pattern for a C library would be: ```python def configure(self): self.settings.rm_safe("compiler.libcxx") self.settings.rm_safe("compiler.cppstd") ``` #### SEE ALSO - [settings.yml](https://docs.conan.io/2//reference/config_files/settings.html.md#reference-config-files-settings-yml). - [Removing settings in the package_id() method](https://docs.conan.io/2//reference/conanfile/methods/package_id.html.md#reference-conanfile-methods-package-id-clear). - [Creating universal binaries using CMakeToolchain](https://docs.conan.io/2//reference/tools/cmake/cmaketoolchain.html.md#conan-tools-cmaketoolchain-universal-binaries). ### options Dictionary with traits that affects only the current recipe, where the key is the option name and the value is a list of different values that the option can take. By default any value change in an option, changes the `package_id`. Check the `default_options` and `default_build_options` fields to define default values for the options. Values for each option can be typed or plain strings (`"value"`, `True`, `42`,…). There are two special values: - `None`: Allow the option to have a `None` value (not specified) without erroring. - `"ANY"`: For options that can take any value, not restricted to a set. ```python class MyPkg(ConanFile): ... options = { "shared": [True, False], "option1": ["value1", "value2"], "option2": ["ANY"], "option3": [None, "value1", "value2"], "option4": [True, False, "value"], } ``` Once the recipe is loaded by Conan, the `options` are processed and they can be read in the recipe. You can also use the method `.get_safe()` (see [settings attribute](#conan-conanfile-properties-settings)) to avoid Conan raising an Exception if the option doesn’t exist: ```python class MyPkg(ConanFile): options = {"shared": [True, False]} def build(self): if self.options.shared: # build the shared library if self.options.get_safe("foo", True): pass ``` In boolean expressions, like `if self.options.shared`: - equals `True` for the values `True`, `"True"` and `"true"`, and any other value that would be evaluated the same way in Python code. - equals `False` for the values `False`, `"False"` and `"false"`, also for the empty string and for `0` and `"0"` as expected. Notice that a comparison using `is` is always `False` because the types would be different as it is encapsulated inside a Python class. If you want to do a safe deletion of options, you could use the `rm_safe()` method. For example, in the `config_options()` method a typical pattern for Windows library would be: ```python def config_options(self): if self.settings.os == "Windows": self.options.rm_safe("fPIC") ``` #### WARNING Some names are not allowed as option names because they conflict with existing `Options` class methods. Some of them are already documented or available methods: - `update`: used by `self.options.update()` to extend options from a `python_requires` base class. See the [init() method](https://docs.conan.io/2//reference/conanfile/methods/init.html.md#reference-conanfile-methods-init). - `clear`: used internally to clear all options, e.g. for header-only packages. - `items`: used to iterate over option name/value pairs. - The `get_safe` and `rm_safe` operations. But there can be also other private methods that could eventually collide (Conan will try to reduce them, but at the moment they are still there and could shadow user definitions): - Some verbs related to storage and serialization: `loads`, `dumps` and `serialize`. - The `possible_values` access - Anything that is private (starts with `_` underscore, or starts with `conan`) Using any of these names as option keys will cause the option value to be shadowed by the corresponding method, leading to unexpected behavior. #### SEE ALSO - Read the [Getting started, creating packages](https://docs.conan.io/2//tutorial/creating_packages/create_your_first_package.html.md#creating-packages-create-your-first-conan-package) to know how to declare and how to define a value to an option. - [Removing options in the package_id() method](https://docs.conan.io/2//reference/conanfile/methods/package_id.html.md#reference-conanfile-methods-package-id-clear). - Read [how the package_type attribute behaves when a shared option is declared](#reference-conanfile-attributes-package-type). ### default_options The attribute `default_options` defines the default values for the options, both for the current recipe and for any requirement. This attribute should be defined as a python dictionary. ```python class MyPkg(ConanFile): ... requires = "zlib/1.2.8", "zwave/2.0" options = {"build_tests": [True, False], "option2": "ANY"} default_options = {"build_tests": True, "option1": 42, "z*:shared": True} ``` You can also assign default values for options of your requirements using “: option_name”, being a valid `reference_pattern` a `name/version` or any pattern with `*` like the example above. #### WARNING Defining options values for dependencies in recipes does not have strong guarantees, please check [this FAQ about options values for dependencies](https://docs.conan.io/2//knowledge/faq.html.md#faq-different-options-values). The recommended way to define `default_options` values for dependencies is in **profile files**. You can also set the options conditionally to a final value with `configure()` instead of using `default_options`: ```python class OtherPkg(ConanFile): settings = "os", "arch", "compiler", "build_type" options = {"some_option": [True, False]} # Do NOT declare 'default_options', use 'config_options()' def configure(self): if self.options.some_option == None: if self.settings.os == 'Android': self.options.some_option = True else: self.options.some_option = False ``` Take into account that if a value is assigned in the `configure()` method it cannot be overridden. #### SEE ALSO - [config_options() method](https://docs.conan.io/2//reference/conanfile/methods/config_options.html.md#reference-conanfile-methods-config-options). There are 2 different ways that a recipe can try to define options values for its dependencies. Using `default_options = {"mypkg/*:myoption", 123}` the current recipe can define the `123` value to the dependency `mypkg` `myoption`. This way of defining options for dependencies has some limitations: - Any other downstream user of the current recipe that defines the same option for `mypkg` will have precedence, overwriting the current recipe `123` value. Also any definition in the profile or command line will also have precedence. The recipe `default_options` have the least precedence. If a recipe will not work at all with some dependencies options, then recipes can check and raise `ConanInvalidConfiguration` errors accordingly. - Any *sibling* package that depends on `mypkg` will also define its options and it will be the only one being taken into account. In other words, the first time `mypkg` is required by any other package will “freeze” its currently assigned options values. Any other package that depends later on `mypkg`, closing the diamond structures in the dependency graph will not have any influence on the `mypkg` options. Only the first one requiring it will. The second way to define the options values is defining them as `important!`. #### WARNING The `important!` syntax is experimental and can be changed or removed at any time. A recipe can define its dependencies options as `important!` with the syntax `default_options = {"mypkg/*:myoption!", 123}`. That means that the `mypkg` `myoption` will not be overriden by other downstream packages, profile or command line doing regular definition of options (like `-o *:myoption=234`). But there are 2 cases in which this will still not define the final value of the dependency: - If any downstream recipe, command line or profile also uses the `myoption!` syntax, that will also have precedence and override the value upstream - If there is any other package that requires first `mypkg`, the values defined at that moment will still have precedence. In general the recommendation for defining options values is to do it in `profile` files, not in recipes, as in-recipe definition can be more complicated specially for complex dependency graphs. ### default_build_options The attribute `default_build_options` defines the default values for the options in the build context and is typically used for defining options for `tool_requires`. ```python from conan import ConanFile class Consumer(ConanFile): default_options = {"protobuf/*:shared": True} default_build_options = {"protobuf/*:shared": False} def requirements(self): self.requires("protobuf/1.0") def build_requirements(self): self.tool_requires("protobuf/1.0") ``` ### options_description The `options_description` attribute is an optional attribute that can be defined in the form of a dictionary where the key is the option name and the value is a description of the option in text format. This attribute is useful for providing additional information about the functionality and purpose of each option, particularly when the option is not self-explanatory or has complex or special behavior. The format for each dictionary entry should be: - Key: Option name. Must be a string and must match one of the keys in the `options` dictionary. - Value: Description of the option. Must be a string and can be as long as necessary. For example: ```python class MyPkg(ConanFile): ... options = {"option1": [True, False], "option2": "ANY"} options_description = { "option1": "Describe the purpose and functionality of 'option1'. ", "option2": "Describe the purpose and functionality of 'option2'. ", } ``` ### languages #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. From Conan 2.4, the `conanfile.py` recipe attribute `languages` can be used to define the programming languages involved in this package. At the moment the `C` and `C++` languages are the possible values. For example a pure C package would define something as: ```python class ZLib(ConanFile): languages = "C" ``` It is possible to define more than one language, for example `languages = "C", "C++"` is the correct definition when a package is built from both C and C++ sources. Regarding `languages` definition, the following will happen: - If no `languages` is defined or `C` is not a declared language, `compiler.cstd` subsetting will be automatically removed at package `configure()` time (to achieve backward compatibility). - If `languages` is defined, but it doesn’t contain `C++`, `compiler.cppstd` and `compiler.libcxx` subsettings will be automatically removed at package `configure()` time. ### info Object used exclusively in `package_id()` method: - The :ref:package_id method to control the unique ID for a package: > ```python > def package_id(self): > self.info.clear() > ``` The `self.info.clear()` method removes all the settings, options, requirements (`requires`, `tool_requires`, `python_requires`) and configuration (`conf`) from the `package_id` computation, so the `package_id` will always result in the same binary, irrespective of all those things. This would be the typical case of a header-only library, in which the packaged artifacts (files) are always identical. ### package_id_{embed,non_embed,python,unknown}_mode, build_mode The `package_id_embed_mode, package_id_non_embed_mode, package_id_python_mode, package_id_unknown_mode` are class attributes that can be defined in recipes to define the effect they have on their consumers’ `package_id`, when they are consumed as `requires`. The `build_mode` (experimental) is a class attribute that affects the package consumers when these consumers use it as `tool_requires`. Can be declared as: ```python from conan import ConanFile class Pkg(ConanFile): name = "pkg" version = "1.0.0" # They are not mandatory, and it is not necessary to define all package_id_embed_mode = "full_mode" package_id_non_embed_mode = "patch_mode" package_id_unknown_mode = "minor_mode" package_id_python_mode = "major_mode" build_mode = "patch_mode" # (experimental) when used as tool_requires ``` In general, the Conan defaults are good ones, and allow providing users good control over when the consumers need to be re-built from source or not. Also, the Conan defaults can be changed globally in the `global.conf` file (they should be changed globally for all users, CI, etc.) via the `core.package_id:xxxx` configurations. The in-recipe attribute definition is useful to define behavior that deviates from the defaults. Possible values are (following the semver definition of MAJOR.MINOR.PATCH, with an extra MICRO digit for versioning schemes with 4 digits): - `patch_mode`: New patches, minors, and major releases of the package will require a new binary (new `package_id`) of the consumers. New recipe revisions will not require new binaries of the consumers. For example if we create a new `pkg/1.0.1` version and some consumer has `requires = "pkg/[>=1.0 <2.0]"`, such a consumer will build a new binary against this specific new `1.0.1` version. But if we just change the recipe, producing a new `recipe_revision`, the consumers will not require building a new binary. - `micro_mode`: (Available since Conan 2.31). Similar to `patch_mode` but factoring in a 4th `MICRO` digit for versioning schemes that use `MAJOR.MINOR.PATCH.MICRO`. New micro, patch, minor and major releases will require a new binary of the consumers, but new recipe revisions will not. Any additional digits beyond the 4th are ignored. Missing digits default to `0` (a dependency version `1.2.3` will be represented as `1.2.3.0`). - `minor_mode`: New minor and major releases of this package will require a new binary of the consumers. New patches and new revisions will not require new binaries of the consumers. This is the default for the “non-embed-mode”, as it allows fine control by the users to decide when to rebuild things or not. - `major_mode`: Only new major releases will require new binaries. Any other modifications and new versions will not require new binaries from the consumers. - `full_mode`: The full identifier of this package, including `pkgname/version@user/channel#recipe_revision:package_id` will be used in the consumers `package_id`, then requiring to build a new binary of the consumer for every change of this package (as any change either in source or configuration will produce a different `recipe_revision` or `package_id` respectively). This is the default for the “embed-mode”. - `unrelated_mode`: No change in this package will ever produce a new binary in the consumer. - `revision_mode`: Uses the `pkgname/version@user/channel#recipe_revision` in the consumers’ `package_id`, that is the full reference except the `package_id` of the dependency. - `semver_mode`: Equivalent to `major_mode` if the version is `>=1.0`, or equivalent to `patch_mode` (or the full version if it has more than 3 digits) if the version is `<1.0`. The 4 different attributes are: - `package_id_embed_mode`: Define the mode for “embedding” cases, that is, a shared library linking a static library, an application linking a static library, an application or a library linking a header-only library. The default for this mode is `full_mode` - `package_id_non_embed_mode`. Define the mode for “non-embedding” cases, that is, a shared library linking another shared library, a static library linking another static library, an application executable linking a shared library. The default for this mode is `minor_mode`. - `package_id_unknown_mode`: Define the mode when the relationship between packages is unknown. If it is not possible to deduce the package type, because there are no `shared` or `header_only` options defined, or because `package_type` is not defined, then, this mode will be used. The default for this mode is `semver_mode` (similar to Conan 1.X behavior). - `package_id_python_mode`: Define the mode for consumers of `python_requires`. By default it will be `minor_mode`, and it is strongly recommended to use this default, and not define the `package_id_python_mode`. This attribute is provided for completeness and exceptional cases like temporary migrations. - `build_mode`: (Experimental) Define the mode for consumers using this dependency as `tool_requires`. By default is `None`, which means that the `tool_requires` does not affect directly the `package_id` of their consumers. Enabling this `build_mode` introduces a harder dependency to the `tool_requires` that will be needed to resolve the `package_id` of the consumers in more cases. #### SEE ALSO Read the [binary model reference](https://docs.conan.io/2//reference/binary_model.html.md#reference-binary-model) for a full view of the Conan binary model. ### package_id_abi_options There are some scenarios when it might be desired to make the value of a given option to influence the `package_id` of the binaries consuming this package. This is generally not necessary in most of the cases, as the default binary model is good for the majority of scenarios. For example, in all `embed` modes, the full dependency reference, including its `package_id`, that already encodes the dependency options, are already factored in into the consumer `package_id`. So for that case, the dependency’s options already have this effect on the consumer `package_id`. But there might be some cases for `non_embed`, like a static library that could be linking a dependency sometimes as a static library and sometimes as a shared library. In platforms such as Linux or Mac, the linkage doesn’t really change the consumer. But this case for Windows `msvc` compiler, when the dependency is conditionally defining `dllimport` in their headers, the calling convention changes, and the binary of the consumer is different. For shared libraries in Windows, it is common to find this idiom: ```cpp #ifdef WIN32 #define HELLO_EXPORT __declspec(dllexport) #else #define HELLO_EXPORT #endif HELLO_EXPORT void hello(); ``` To export the `hello()` symbol into the shared library, as in Windows MSVC the symbols are not exported by default. This is not an issue, as the consumer packages and callers of `hello()` will not change its linkage. But in some cases, some libraries might decide to define something like: ```cpp #ifdef WIN32 #ifdef libhello_EXPORTS /* We are building this library */ #define HELLO_EXPORT __declspec(dllexport) #else /* We are using this library */ #define HELLO_EXPORT __declspec(dllimport) #endif #else #define HELLO_EXPORT #endif HELLO_EXPORT void hello(); ``` And control via `libhello_EXPORTS` if the package is being built or consumed. In this case, the consumer will have a different linkage when linking this shared library with the `dllimport`, than when linking this library as a static library. For those case, the package recipe can define which of its own options affect the consumers `package_id`, irrespective of the `non_embed` mode, so they can still generate different binaries for the different linkages, without necessarily resorting to a full `embed` mode that will require unnecessary rebuilds of binaries from source. This can be defined with: ```python from conan import ConanFile class Pkg(ConanFile): name = "pkg" version = "1.0.0" options = {"shared": [False, True]} package_id_abi_options = ["shared"] ``` And that will make all the consumers of `pkg/1.0.0` to automatically factor the `pkg/*:shared=True/False` value in their own `package_id`. ### context #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. The `conanfile.py` recipe attribute `context` will contain either the “build” or “host” value to represent the context where the current package instance is being evaluated. Recall that it is possible that some recipes might exist both in the “build” and “host” contexts, depending on the usage. This attribute shouldn’t be necessary for the vast majority of cases, so it is recommended to avoid using it. One potential exception for this recommendation would be to break otherwise infinite dependency cycles, defining some conditional dependency as: ```python def requirements(self): if self.context == "host": self.tool_requires("mytool/1.0") ``` ## Build ### generators List or tuple of strings with names of generators. ```python class MyLibConan(ConanFile): generators = "CMakeDeps", "CMakeToolchain" ``` The generators can also be instantiated explicitly in the [generate() method](https://docs.conan.io/2//reference/conanfile/methods/generate.html.md#reference-conanfile-methods-generate). ```python from conan.tools.cmake import CMakeToolchain class MyLibConan(ConanFile): ... def generate(self): tc = CMakeToolchain(self) tc.generate() ``` ### build_policy Controls when the current package is built during a `conan install`. The allowed values are: - `"missing"`: Conan builds it from source if there is no binary available. - `"never"`: This package cannot be built from sources, it is always created with `conan export-pkg` - `None` (default value): This package won’t be built unless the policy is specified in the command line (e.g `--build=foo*`) > ```python > class PocoTimerConan(ConanFile): > build_policy = "missing" > ``` ### win_bash When `True` it enables the new run in a subsystem bash in Windows mechanism. ```python from conan import ConanFile class FooRecipe(ConanFile): ... win_bash = True ``` It can also be declared as a `property` based on any condition: ```python from conan import ConanFile class FooRecipe(ConanFile): ... @property def win_bash(self): return self.settings.arch == "armv8" ``` ### win_bash_run When `True` it enables running commands in the `"run"` scope, to run them inside a bash shell. ```python from conan import ConanFile class FooRecipe(ConanFile): ... win_bash_run = True def build(self): self.run(cmd, scope="run") # will run inside bash ``` ## Folders and layout ### source_folder The folder in which the source code lives. The path is built joining the base directory (a cache directory when running in the cache or the `output folder` when running locally) with the value of `folders.source` if declared in the `layout()` method. Note that the base directory for the `source_folder` when running in the cache will point to the base folder of the build unless [no_copy_source](#conan-conanfile-properties-no-copy-source) is set to `True`. But anyway it will always point to the correct folder where the source code is. ### export_sources_folder The value depends on the method you access it: - At `source(self)`: Points to the base source folder (that means self.source_folder but without taking into account the `folders.source` declared in the `layout()` method). The declared exports_sources are copied to that base source folder always. - At `exports_sources(self)`: Points to the folder in the cache where the export sources have to be copied. #### SEE ALSO - [Read about the export_sources() method](https://docs.conan.io/2//reference/conanfile/methods/export_sources.html.md#reference-conanfile-methods-export-sources). - [Read about the source() method](https://docs.conan.io/2//reference/conanfile/methods/source.html.md#reference-conanfile-methods-source). ### build_folder The folder used to build the source code. The path is built joining the base directory (a cache directory when running in the cache or the `output folder` when running locally) with the value of `folders.build` if declared in the `layout()` method. ### generators_folder The folder where the files in the `generate()` method should be generated. The path is built from the layout’s `self.folders.generators` attribute. ### package_folder The folder to copy the final artifacts for the binary package. In the local cache a package folder is created for every different package ID. The most common usage of `self.package_folder` is to `copy` the files at the [package() method](https://docs.conan.io/2//reference/conanfile/methods/package.html.md#reference-conanfile-methods-package): ```python import os from conan import ConanFile from conan.tools.files import copy class MyRecipe(ConanFile): ... def package(self): copy(self, "*.so", self.build_folder, os.path.join(self.package_folder, "lib")) ... ``` ### recipe_folder The folder where the recipe *conanfile.py* is stored, either in the local folder or in the cache. This is useful in order to access files that are exported along with the recipe, or the origin folder when exporting files in `export(self)` and `export_sources(self)` methods. The most common usage of `self.recipe_folder` is in the `export(self)` and `export_sources(self)` methods, as the folder from where we copy the files: ```python from conan import ConanFile from conan.tools.files import copy class MethodConan(ConanFile): exports = "file.txt" def export(self): copy(self, "LICENSE.md", self.recipe_folder, self.export_folder) ``` ### recipe_metadata_folder The `self.recipe_metadata_folder` (**experimental**) can be used in the `export()` and `export_sources()` and `source()` methods to save or copy **recipe** metadata files. See [metadata section](https://docs.conan.io/2//devops/metadata.html.md#devops-metadata) for more information. ### package_metadata_folder The `self.package_metadata_folder` (**experimental**) can be used in the `generate()`, `build()` and `package()` methods to save or copy **package** metadata files. See [metadata section](https://docs.conan.io/2//devops/metadata.html.md#devops-metadata) for more information. ### no_copy_source The attribute `no_copy_source` tells the recipe that the source code will not be copied from the `source_folder` to the `build_folder`. This is mostly an optimization for packages with large source codebases or header-only, to avoid extra copies. If you activate `no_copy_source=True`, it is **mandatory** that the source code must not be modified at all by the configure or build scripts, as the source code will be shared among all builds. The recipes should always use `self.source_folder` attribute, which will point to the `build` folder when `no_copy_source=False` and will point to the `source` folder when `no_copy_source=True`. #### SEE ALSO Read [header-only packages section](https://docs.conan.io/2//tutorial/creating_packages/other_types_of_packages/header_only_packages.html.md#creating-packages-other-header-only) for an example using `no_copy_source` attribute. ### test_package_folder The `test_package_folder` class attribute allows defining in recipe a different default `test_package` folder for `conan create` commands. When a `conan create` runs, after the package is created in the cache, it will look for a `test_package` folder, or for the folder specified in the `--test-folder=xxx` argument, and launch the package test. This attribute allows to change that default name: ```python import os from conan import ConanFile class Pkg(ConanFile): test_package_folder = "my/test/folder" ``` It allows to define any folder, always relative to the location of the `conanfile.py`. ## Layout ### folders The `folders` attribute has to be set only in the `layout()` method. Please check the [layout() method documentation](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md#layout-folders-reference) to learn more about this attribute. ### cpp Object storing all the information needed by the consumers of a package: include directories, library names, library paths… Both for editable and regular packages in the cache. It is only available at the `layout()` method. - `self.cpp.package`: For a regular package being used from the Conan cache. Same as declaring `self.cpp_info` at the `package_info()` method. - `self.cpp.source`: For “editable” packages, to describe the artifacts under `self.source_folder` - `self.cpp.build`: For “editable” packages, to describe the artifacts under `self.build_folder`. The `cpp` attribute has to be set only in the `layout()` method. Please check the [layout() method documentation](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md#layout-cpp-reference) to learn more about this attribute. ### layouts The `layouts` attribute has to be set only in the `layout()` method. Please check the [layout() method documentation](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md#layout-cpp-reference) to learn more about this attribute. The `layouts` attribute contains information about environment variables and `conf` that would be path-dependent, and as a result it would contain a different value when the package is in editable mode, or when the package is in the cache. The `layouts` sub-attributes are: - `self.layouts.build`: information related to the relative `self.folders.build` - `self.layouts.source`: information related to the relative `self.folders.source` - `self.layouts.package`: information related to the final `package_folder` Each one of those will contain: - `buildenv_info`: environment variables build information for consumers (equivalent to `self.buildenv_info` in `package_info()`) - `runenv_info`: environment variables run information for consumers (equivalent to `self.runenv_info` in `package_info()`) - `conf_info`: configuration information for consumers (equivalent to `self.conf_info` in `package_info()`). Note this is only automatically propagated to `self.conf` of consumers when this package is a direct `tool_require`. For example, if we had an `androidndk` recipe that contains the AndroidNDK, and we want to have that recipe in “editable” mode, it is necessary where the androidndk will be locally, before being in the created package: ```python import os from conan import ConanFile from conan.tools.files import copy class AndroidNDK(ConanFile): def layout(self): # When developing in user space it is in a "mybuild" folder (relative to current dir) self.layouts.build.conf_info.define_path("tools.android:ndk_path", "mybuild") # but when packaged it will be in a "mypkg" folder (inside the cache package folder) self.layouts.package.conf_info.define_path("tools.android:ndk_path", "mypkg") def package(self): copy(self, "*", src=os.path.join(self.build_folder, "mybuild"), dst=os.path.join(self.package_folder, "mypkg")) ``` ## Package information for consumers ### cpp_info Same as using `self.cpp.package` in the `layout()` method. Use it if you need to read the `package_folder` to locate the already located artifacts. #### SEE ALSO - [CppInfo](https://docs.conan.io/2//reference/conanfile/methods/package_info.html.md#conan-conanfile-model-cppinfo) model. #### IMPORTANT This attribute is only defined inside `package_info()` method being None elsewhere. ### buildenv_info For the dependant recipes, the declared environment variables will be present during the build process. Should be only filled in the `package_info()` method. #### IMPORTANT This attribute is only defined inside `package_info()` method being None elsewhere. ```python def package_info(self): self.buildenv_info.append_path("PATH", self.package_folder) ``` #### SEE ALSO Check the reference of the [Environment](https://docs.conan.io/2//reference/tools/env/environment.html.md#conan-tools-env-environment-model) object to know how to fill the `self.buildenv_info`. ### runenv_info For the dependant recipes, the declared environment variables will be present at runtime. Should be only filled in the `package_info()` method. #### IMPORTANT This attribute is only defined inside `package_info()` method being None elsewhere. ```python def package_info(self): self.runenv_info.define_path("RUNTIME_VAR", "c:/path/to/exe") ``` #### SEE ALSO Check the reference of the [Environment](https://docs.conan.io/2//reference/tools/env/environment.html.md#conan-tools-env-environment-model) object to know how to fill the `self.runenv_info`. ### conf_info Configuration variables to be passed to the dependant recipes. Should be only filled in the `package_info()` method. ```python class Pkg(ConanFile): name = "pkg" def package_info(self): self.conf_info.define("tools.build:verbosity", "debug") self.conf_info.get("tools.build:verbosity") # == "debug" self.conf_info.append("user.myconf.build:ldflags", "--flag3") # == ["--flag1", "--flag2", "--flag3"] self.conf_info.update("tools.microsoft.msbuildtoolchain:compile_options", {"ExpandAttributedSource": "false"}) self.conf_info.unset("tools.microsoft.msbuildtoolchain:compile_options") self.conf_info.remove("user.myconf.build:ldflags", "--flag1") # == ["--flag0", "--flag2", "--flag3"] self.conf_info.pop("tools.system.package_manager:sudo") ``` #### SEE ALSO Read here [the complete reference of self.conf_info](https://docs.conan.io/2//reference/conanfile/methods/package_info.html.md#conan-conanfile-model-conf-info). ### generator_info #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. Generators to be passed to the dependant recipes. Should be only filled in the `package_info()` method, `None` by default. #### SEE ALSO See [an example usage here](https://docs.conan.io/2//reference/extensions/custom_generators.html.md#reference-commands-custom-generators-tool-requires) and [the complete reference of self.generator_info](https://docs.conan.io/2//reference/conanfile/methods/package_info.html.md#conan-conanfile-model-generator-info). ### deprecated This attribute declares that the recipe is deprecated, causing a user-friendly warning message to be emitted whenever it is used For example, the following code: ```python from conan import ConanFile class Pkg(ConanFile): name = "cpp-taskflow" version = "1.0" deprecated = True ``` may emit a `risk` warning like: ```bash Deprecated cpp-taskflow/1.0 WARN: risk: There are deprecated packages in the graph ``` Optionally, the attribute may specify the name of the suggested replacement: ```python from conan import ConanFile class Pkg(ConanFile): name = "cpp-taskflow" version = "1.0" deprecated = "Not secure, use better taskflow>1.2.3" ``` This will emit a `risk` warning like: ```bash Deprecated cpp-taskflow/1.0: Not secure, use better taskflow>1.2.3 WARN: risk: There are deprecated packages in the graph ``` If the value of the attribute evaluates to `False`, no warning is printed. ### provides This attribute declares that the recipe provides the same functionality as other recipe(s). The attribute is usually needed if two or more libraries implement the same API to prevent link-time and run-time conflicts (ODR violations). One typical situation is forked libraries. Some examples are: - [LibreSSL](https://www.libressl.org/), [BoringSSL](https://boringssl.googlesource.com/boringssl/) and [OpenSSL](https://www.openssl.org/) - [libav](https://en.wikipedia.org/wiki/Libav) and [ffmpeg](https://ffmpeg.org/) - [MariaDB client](https://downloads.mariadb.org/client-native) and [MySQL client](https://dev.mysql.com/downloads/c-api/) If Conan encounters two or more libraries providing the same functionality within a single graph, it raises an error: ```bash At least two recipes provides the same functionality: - 'libjpeg' provided by 'libjpeg/9d', 'libjpeg-turbo/2.0.5' ``` The attribute value should be a string with a recipe name or a tuple of such recipe names. For example, to declare that `libjpeg-turbo` recipe offers the same functionality as `libjpeg` recipe, the following code could be used: ```python from conan import ConanFile class LibJpegTurbo(ConanFile): name = "libjpeg-turbo" version = "1.0" provides = "libjpeg" ``` To declare that a recipe provides the functionality of several different recipes at the same time, the following code could be used: ```python from conan import ConanFile class OpenBLAS(ConanFile): name = "openblas" version = "1.0" provides = "cblas", "lapack" ``` If the attribute is omitted, the value of the attribute is assumed to be equal to the current package name. Thus, it’s redundant for `libjpeg` recipe to declare that it provides `libjpeg`, it’s already implicitly assumed by Conan. ### package_type_traits This attribute declares that the package has runtime artifacts that consumers should be aware of. This is useful for `package_type="static-library"` recipes that nevertheless also contain shared libraries, or by `package_type="header-library"` that have some kind of resource that library needs at runtime, so that at runtime their folders are exposed to the consumers. It is important to still declare the `package_type` that best describes the package for linkage and `package_id` purposes (see [the effect of dependencies on package_id](https://docs.conan.io/2//reference/binary_model/dependencies.html.md#reference-binary-model-dependencies) and [package_type trait inferring](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-package-type-trait-inferring)), and use `package_type_traits` only to fix the specific trait that `package_type` got wrong, instead of changing the `package_type` itself. For example, a package that is fundamentally a static library, meant to be embedded and to force a rebuild of its direct consumers like any other static library, should keep `package_type = "static-library"`, even if it also happens to ship a shared library or some other resource needed at runtime. Declaring it instead as `package_type = "shared-library"` would also change the `package_id` computation mode and the linkage information propagated to consumers, when the only thing that actually needs fixing is the `run` trait. By default, a `static-library` dependency gets the `run` requirement trait set to `False` (see [package_type trait inferring](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-package-type-trait-inferring)), so its binary can be skipped when only linked transitively, and its folders are not added to the runtime environment by generators like [VirtualRunEnv](https://docs.conan.io/2//reference/tools/env/virtualrunenv.html.md#conan-tools-env-virtualrunenv), nor collected by deployers like [runtime_deploy](https://docs.conan.io/2//reference/extensions/deployers.html.md#reference-extensions-deployer-runtime-deploy). Declaring `package_type_traits = {"run": True}` forces `run=True` for every consumer of the package, regardless of its `package_type`: ```python from conan import ConanFile class Pkg(ConanFile): name = "mypkg" version = "1.0" # This is a static library, but it also ships a shared library (e.g. a plugin) that # consumers need available at runtime package_type = "static-library" package_type_traits = {"run": True} ``` #### NOTE At the moment, `run` is the only key read from `package_type_traits`, and `True` is the only value that has an effect. Setting any other trait or value currently does nothing, so it shouldn’t be relied upon: unsupported keys are silently ignored today, but might be validated, or start having an effect, in future Conan versions. #### SEE ALSO - [The run requirement trait](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-methods-requirements). - [How package_type infers the run trait](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-package-type-trait-inferring). ## Other ### dependencies Conan recipes provide access to their dependencies via the `self.dependencies` attribute. ```python class Pkg(ConanFile): requires = "openssl/0.1" def generate(self): openssl = self.dependencies["openssl"] # access to members openssl.ref.version openssl.ref.revision # recipe revision openssl.options openssl.settings ``` #### SEE ALSO Read here [the complete reference of self.dependencies](https://docs.conan.io/2//reference/conanfile/methods/generate.html.md#conan-conanfile-model-dependencies). ### subgraph (Experimental) A read-only dependency graph of the recipe. The `dependencies` attribute should be used to access the dependencies of the recipe, as this attribute is intended to be passed to other Conan APIs and exposed for advanced usages like [SBOM generation](https://docs.conan.io/2//reference/tools/sbom.html.md#conan-tools-sbom). ### conf In the `self.conf` attribute we can find all the conf entries declared in the [[conf]](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-conf) section of the profiles. in addition of the declared [self.conf_info](https://docs.conan.io/2//reference/conanfile/methods/package_info.html.md#conan-conanfile-model-conf-info) entries from the first level tool requirements. The profile entries have priority. ```python from conan import ConanFile class MyConsumer(ConanFile): tool_requires = "my_android_ndk/1.0" def generate(self): # This is declared in the tool_requires self.output.info("NDK host: %s" % self.conf.get("tools.android:ndk_path")) # This is declared in the profile at [conf] section self.output.info("Custom var1: %s" % self.conf.get("user.custom.var1")) ``` #### NOTE The `conf` attribute is a **read-only** attribute. It can only be defined in profiles and command lines, but it should never be set by recipes. Recipes can only read its value via `self.conf.get()` method. ### Output ### Output contents Use the `self.output` attribute to print contents to the output. ```python self.output.success("This is good, should be green") self.output.info("This is neutral, should be white") self.output.warning("This is a warning, should be yellow") self.output.error("Error, should be red") ``` Additional output methods are available and you can produce different outputs with different colors. See [the output documentation](https://docs.conan.io/2//reference/conanfile/running_and_output.html.md#reference-conanfile-output) for the list of available output methods. ### revision_mode This attribute allow each recipe to declare how the revision for the recipe itself should be computed. It can take three different values: - `"hash"` (by default): Conan will use the checksum hash of the recipe manifest to compute the revision for the recipe. - `"scm"`: if the project is inside a Git repository the commit ID will be used as the recipe revision. If there is no repository it will raise an error. - `"scm_folder"`: This configuration applies when you have a mono-repository project, but still want to use *scm* revisions. In this scenario, the revision of the exported conanfile.py will correspond to the commit ID of the folder where it’s located. This approach allows multiple conanfile.py files to exist within the same Git repository, with each file exported under its distinct revision. When `scm` or `scm_folder` is selected, the Git commit will be used, but by default the repository must be clean, otherwise it would be very likely that there are uncommitted changes and the build wouldn’t be reproducible. So if there are dirty files, Conan will raise an error. If there are files that can be dirty in the repo, but do not belong at all to the recipe or the package, then it is possible to exclude them from the check with the `revision_mode_excluded` recipe attribute or the `core.scm:excluded` configuration, which is a list of patterns (fnmatch) to exclude. ```python from conan import ConanFile class MyConsumer(ConanFile): revision_mode = "scm" # the .tmp files are excluded from revision and dirty check revision_mode_excluded = ["*.tmp"] ``` ### upload_policy Controls when the current package built binaries are uploaded or not - `"skip"`: The precompiled binaries are not uploaded. This is useful for “installer” packages that just download and unzip something heavy (e.g. android-ndk), and is useful together with the `build_policy = "missing"` > ```python > class Pkg(ConanFile): > upload_policy = "skip" > ``` ### required_conan_version Recipes can define a module level `required_conan_version` that defines a valid version range of Conan versions that can load and understand the current `conanfile.py`. The syntax is: ```python from conan import ConanFile required_conan_version = ">=2.0" class Pkg(ConanFile): pass ``` Version ranges as in `requires` are allowed. Also there is a `global.conf` file `core:required_conan_version` configuration that can define a global minimum, maximum or exact Conan version to run, which can be very convenient to maintain teams of developers and CI machines to use the desired range of versions. ### implements A list is used to define a series of option configurations that Conan will handle automatically. This is especially handy for avoiding boilerplate code that tends to repeat in most of the recipes. The syntax is as follows: ```python from conan import ConanFile class Pkg(ConanFile): implements = ["auto_shared_fpic", "auto_header_only", ...] ``` Currently these are the automatic implementations provided by Conan: - `"auto_shared_fpic"`: automatically manages `fPIC` and `shared` options. Adding this implementation will have both effect in the [configure](https://docs.conan.io/2//reference/conanfile/methods/configure.html.md#reference-conanfile-methods-configure-implementations) and [config_options](https://docs.conan.io/2//reference/conanfile/methods/config_options.html.md#reference-conanfile-methods-config-options-implementations) steps when those methods are not explicitly defined in the recipe. - `"auto_header_only"`: automatically manages the package ID clearing settings. Adding this implementation will have effect in the [package_id](https://docs.conan.io/2//reference/conanfile/methods/package_id.html.md#reference-conanfile-methods-package-id-implementations) step when the method is not explicitly defined in the recipe. #### WARNING This is a 2.0-only feature, and it will not work in 1.X ### alias #### WARNING While aliases can technically still be used in Conan 2, their usage is not recommended and they may be fully removed in future releases. Users are encouraged to adapt to the [newer versioning features](https://docs.conan.io/2//devops/versioning/versioning.html.md#devops-versioning) for a more standardized and efficient package management experience. In Conan 2, the `alias` attribute remains a part of the recipe, allowing users to define an alias for a package version. Normally, you would create one using the `conan new` command with the `alias` template and the exporting the recipe with conan export: ```shell $ conan new alias -d name=mypkg -d version=latest -d target=1.0 $ conan export . ``` Note that when requiring the alias, you must place the version in parentheses `()` to explicitly declare the use of an alias as a requirement: ```python class Consumer(ConanFile): ... requires = "mypkg/(latest)" ... ``` ### extension_properties The `extensions_properties` attribute is a dictionary intended to define and pass information from the recipes to the Conan extensions. At the moment, the only defined properties are `compatibility_cppstd` and `compatibility_cstd`, that allows disabling the behavior of [the default compatibility.py extension](https://docs.conan.io/2//reference/extensions/binary_compatibility.html.md#reference-extensions-binary-compatibility), that considers binaries built with different `compiler.cppstd` and `compiler.cstd` values ABI-compatible among them. To disable this behavior for the current package, it is possible to do it with: ```python class Pkg(ConanFile): extension_properties = {"compatibility_cppstd": False} ``` If it is necessary to do it conditionally, it is also possible to define its value inside recipe `compatibility()` method: ```python class Pkg(ConanFile): def compatibility(self): self.extension_properties = {"compatibility_cppstd": False} ``` #### NOTE The value of `extension_properties` is not transitive from the dependencies to the consumers by default, but can be propagated manually by iterating the `self.dependencies` and checking the desired values of their `extension_properties`. --- https://docs.conan.io/2/reference/conanfile/methods.html.md --- # Methods What follows is a list of methods that you can define in your recipes to customize the package creation & consumption processes: - [build()](https://docs.conan.io/2//reference/conanfile/methods/build.html.md): Contains the build instructions to build a package from source - [build_id()](https://docs.conan.io/2//reference/conanfile/methods/build_id.html.md): Allows reusing the same build to create different package binaries - [build_requirements()](https://docs.conan.io/2//reference/conanfile/methods/build_requirements.html.md): Defines `tool_requires` and `test_requires` - [build_system_requirements()](https://docs.conan.io/2//reference/conanfile/methods/build_system_requirements.html.md): Installs system packages when building from source (uses build arch) - [compatibility()](https://docs.conan.io/2//reference/conanfile/methods/compatibility.html.md): Defines binary compatibility at the recipe level - [configure()](https://docs.conan.io/2//reference/conanfile/methods/configure.html.md): Allows configuring settings and options while computing dependencies - [config_options()](https://docs.conan.io/2//reference/conanfile/methods/config_options.html.md): Configure options while computing dependency graph - [deploy()](https://docs.conan.io/2//reference/conanfile/methods/deploy.html.md): Deploys (copy from package to user folder) the desired artifacts - [export()](https://docs.conan.io/2//reference/conanfile/methods/export.html.md): Copies files that are part of the recipe - [export_sources()](https://docs.conan.io/2//reference/conanfile/methods/export_sources.html.md): Copies files that are part of the recipe sources - [finalize()](https://docs.conan.io/2//reference/conanfile/methods/finalize.html.md): Customizes the package for using it in the running machine without affecting the original package - [generate()](https://docs.conan.io/2//reference/conanfile/methods/generate.html.md): Generates the files that are necessary for building the package - [init()](https://docs.conan.io/2//reference/conanfile/methods/init.html.md): Special initialization of recipe when extending from `python_requires` - [layout()](https://docs.conan.io/2//reference/conanfile/methods/layout.html.md): Defines the relative project layout, source folders, build folders, etc. - [package()](https://docs.conan.io/2//reference/conanfile/methods/package.html.md): Copies files from build folder to the package folder. - [package_id()](https://docs.conan.io/2//reference/conanfile/methods/package_id.html.md): Defines special logic for computing the binary `package_id` identifier - [package_info()](https://docs.conan.io/2//reference/conanfile/methods/package_info.html.md): Provide information for consumers of this package about libraries, folders, etc. - [requirements()](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md): Define the dependencies of the package - [set_name()](https://docs.conan.io/2//reference/conanfile/methods/set_name.html.md): Dynamically define the name of a package - [set_version()](https://docs.conan.io/2//reference/conanfile/methods/set_version.html.md): Dynamically define the version of a package. - [source()](https://docs.conan.io/2//reference/conanfile/methods/source.html.md): Contains the commands to obtain the source code used to build - [system_requirements()](https://docs.conan.io/2//reference/conanfile/methods/system_requirements.html.md): Call system package managers like Apt to install system packages - [test()](https://docs.conan.io/2//reference/conanfile/methods/test.html.md): Run some simple package test (exclusive of `test_package`) - [validate()](https://docs.conan.io/2//reference/conanfile/methods/validate.html.md): Define if the current package is invalid (cannot work) with the current configuration. - [validate_build()](https://docs.conan.io/2//reference/conanfile/methods/validate_build.html.md): Define if the current package cannot be created with the current configuration. --- https://docs.conan.io/2/reference/conanfile/running_and_output.html.md --- # Running and output ## Output text from recipes Use the `self.output` attribute to output text from the recipes. Do **not** use Python’s `print()` function. ### error(self, msg: str, error_type: str = None) Indicates that a serious issue has occurred that prevents the system or application from continuing to function correctly. Typically, this represents a failure in the normal flow of execution, such as a service crash or a critical exception. Notice that if the user has set the `core:warnings_as_errors` configuration, this will raise an exception when the output is printed, so that the error does not pass unnoticed. ### warning(self, msg: str, warn_tag: str = None) Highlights a potential issue that, while not stopping the system, could cause problems in the future or under certain conditions. Warnings signal abnormal situations that should be reviewed but don’t necessarily cause an immediate halt in operations. Notice that if the tag matches the pattern in the `core:warnings_as_errors` configuration, and is not skipped, this will be upgraded to an error, and raise an exception when the output is printed, so that the error does not pass unnoticed. ### success(self, msg: str) Shows that an operation has been completed successfully. This type of message is useful to confirm that key processes or tasks have finished correctly, which is essential for good application monitoring. ### highlight(self, msg: str) Marks or emphasizes important events or processes that need to stand out but don’t necessarily indicate success or error. These messages draw attention to key points that may be relevant for the user or administrator. ### info(self, msg: str, fg: str = None, bg: str = None, newline: bool = True) Provides general information about the system or ongoing operations. Info messages are basic and used to inform about common events, like the start or completion of processes, without implying specific problems or achievements. ### status(self, msg: str, fg: str = None, bg: str = None, newline: bool = True) Provides general information about the system or ongoing operations. Info messages are basic and used to inform about common events, like the start or completion of processes, without implying specific problems or achievements. The following three methods are not shown by default and are usually reserved for scenarios that require a higher level of verbosity. You can display them using the arguments `-v`, `-vv`, and `-vvv` respectively. ### verbose(self, msg: str, fg: str = None, bg: str = None) Displays additional and detailed information that, while not critical, can be useful for better understanding how the system is working. This message won’t be printed unless the user has set the log level to verbose (e.g., using the `-v` option in the command line). It’s appropriate for gaining more context without overloading the logs with excessive detail. Useful when more clarity is needed than a simple info. ### debug(self, msg: str, fg: str = '\\x1b[35m', bg: str = None) With a high level of detail, it is mainly used for debugging code. This message won’t be printed unless the user has set the log level to debug (e.g., using the `-vv` option in the command line). These messages provide useful information for developers, such as variable values or execution flow details, to trace errors or analyze the program’s behavior. ### trace(self, msg: str) This is the most extreme level of detail. Trace messages log every little step the system takes, including function entries and exits, variable changes, and other very specific events. This message won’t be printed unless the user has set the log level to trace (e.g., using the `-vvv` option in the command line). It’s used when full visibility of everything happening in the system is required, but should be used carefully due to the large amount of information it can generate. These output functions will only output if the verbosity level with which Conan was launched is the same or higher than the message, so running with `-vwarning` will output calls to `warning()` and `error()`, but not `info()` (Additionally, the `highlight()` and `success()` methods have a `-vnotice` verbosity level) Note that these methods return the output object again, so that you can chain output calls if needed. Using the `core:warnings_as_errors` conf, you can make Conan raise an exception when either errors or a tagged warning matching any of the given patterns is printed. This is useful to make sure that recipes are not printing unexpected warnings or errors. Additionally, you can skip which warnings trigger an exception [with the core:skip_warnings conf](https://docs.conan.io/2//reference/config_files/global_conf.html.md#reference-config-files-global-conf-skip-warnings). ```text # Raise an exception if any warning or error is printed core:warnings_as_errors=['*'] # But skip the deprecation warnings core:skip_warnings=['deprecated'] ``` Both confs accept a list of patterns to match against the warning tags. A special `unknown` value can be used to match any warning without a tag. To tag a warning, use the `warn_tag` argument of the `warning()` method in your recipes: ```python self.output.warning("Extra warning", warn_tag="custom_tag") ``` #### NOTE Custom commands and tools are free to instantiate their own `ConanOutput` object. Some methods have optional `fg` and `bg` arguments, these are colour codes for the foreground and background of the text, available in the `conan.api.output.Color` class. ```python self.output.info("This is a message", fg=Color.BLUE, bg=Color.YELLOW) ``` ## Running commands Recipes and helpers can use the `self.run()` method to run system commands while injecting the calls to activate the appropriate environment, and throw exceptions when errors occur so that command errors do not pass unnoticed. It also wraps the commands with the results of the [command wrapper plugin](https://docs.conan.io/2//reference/extensions/command_wrapper.html.md#reference-extensions-command-wrapper). ### run(self, command: str, stdout=None, cwd=None, ignore_errors=False, env='', quiet=False, shell=True, scope='build', stderr=None) Run a command in the current package context. * **Parameters:** * **command** – The command to run formatted as a plain string * **stdout** – The output stream to write the command output. If `None`, it defaults to the standard output stream. * **stderr** – The error output stream to write the command error output. If `None`, it defaults to the standard error stream. * **cwd** – The current working directory to run the command in. * **ignore_errors** – If `True`, do not raise an error if the command returns a non-zero exit code. * **env** – The environment file to use. If empty, it defaults to `"conanbuild"` for when `scope` is `build` or `"conanrun"` for `run`. If set to `None` explicitly, no environment file will be applied, which is useful for commands that do not require any environment. * **quiet** – If `True`, suppress the output of the command. * **shell** – If `True`, run the command in a shell. This is passed to the underlying `Popen` function. If set to `False`, `env` parameter should be set to `None` (a shell is needed in order to source files) * **scope** – The scope of the command, either `"build"` or `"run"`. Use the `stdout` and `stderr` arguments to redirect the output of the command to a file-like object instead of the console. ```python # Redirect stdout to a file with open("ninja_stdout.log", "w") as stdout: # Redirect stderr to a StringIO object to be able to read it later stderr = StringIO() self.run("ninja ...", stdout=stdout, stderr=stderr) ``` --- https://docs.conan.io/2/reference/conanfile/methods/build.html.md --- # build() The `build()` method is used to define the build from source of the package. In practice this means calling some build system, which could be done explicitly or using any of the build helpers provided by Conan: ```python from conan.tools.cmake import CMake class Pkg(ConanFile): def build(self): # Either using some of the Conan built-in helpers cmake = CMake(self) cmake.configure() # equivalent to self.run("cmake . ") cmake.build() # equivalent to self.run("cmake --build . ") cmake.test() # equivalent to self.run("cmake --target=RUN_TESTS") # Or it could run your own build system or scripts self.run("mybuildsystem . --configure") self.run("mybuildsystem . --build") ``` For more information about the existing built-in build system integrations, visit [Recipe tools](https://docs.conan.io/2//reference/tools.html.md#conan-tools). The `build()` method should be as simple as possible, just wrapping the command line invocations that a developer would do in the simplest possible way. The `generate()` method is the one responsible for preparing the build, creating toolchain files, CMake presets, or any other files which are necessary so developers could easily call the build system by hand. This allows for much better integrations with IDEs and improves the developer experience. The result is that in practice the `build()` method should be relatively simple. The `build()` method runs once per unique configuration, so if there are some source operations like applying patches that are done conditionally to different configurations, they could be also applied in the `build()` method, before the actual build. It is important to note that in this case the [no_copy_source](https://docs.conan.io/2//reference/conanfile/attributes.html.md#conan-conanfile-properties-no-copy-source) attribute cannot be set to `True`. The `build()` method is the right place to build and run unit tests, before packaging, and raising errors if those tests fail, interrupting the process, and not even packaging the final binaries. The built-in helpers will skip the unit tests if the `tools.build:skip_test` configuration is defined. For custom integrations, it is expected that the method checks this `conf` value in order to skip building and running tests, which can be useful for some CI scenarios. **Running Tests in Cross-Building Scenarios**: There may be some cases where you want to build tests but cannot run them, such as in cross-building scenarios. For these rare situations, you can use the [conan.tools.build.can_run](https://docs.conan.io/2//reference/tools/build.html.md#conan-tools-build-can-run) tool as follows: ```python ... def build(self): cmake = CMake(self) cmake.configure() cmake.build() if can_run(self): cmake.test() ``` #### NOTE **Best practices** - The `build()` method should be as simple as possible, the heavy lifting of preparing the build should happen in the `generate()` method in order to achieve a good developer experience that can easily build locally with just `conan install .`, plus directly calling the build system or opening their IDE. #### SEE ALSO Follow the [tutorial about building packages](https://docs.conan.io/2//tutorial/creating_packages/build_packages.html.md#tutorial-creating-build) for more information about building from sources. --- https://docs.conan.io/2/reference/conanfile/methods/build_id.html.md --- # build_id() The `build_id()` method allows you to **reuse a single build** to create multiple binary packages in the Conan cache, saving time by avoiding unnecessary rebuilds. It is primarily an optimization tool for situations where **building each configuration separately isn’t feasible**. There are a couple of scenarios where this could be useful, for example, when a package build: * **Generates multiple configurations in a single build run**: Some build scripts always produce both Debug and Release artifacts together, without a way to build them separately. * **Produces one configuration but different sets of artifacts**: The build could generate the main library plus some test executables, and you want to create: * one package with just the library (for general use), and * another package that includes both the library and the test binaries (for compliance, debugging, or reproducibility). In these scenarios, **reusing the same build folder avoids recompiling the same sources multiple times** just because you need slightly different packaging. ## How does the build folder relate to the package ID and the build ID? By default, Conan creates **one build folder per unique package ID**, where: * Generally, the **package ID** depends on the combination of settings, options, and dependencies. * Each different **package ID** triggers a separate `build()` execution and generates a separate build folder. When you define the `build_id()` method, you can **force different package IDs to share the same build folder** by customizing self.info_build: * `self.info_build` is like `self.info`, but it only affects the computation of the **build ID**, not the final package ID. * Any package IDs with the same build ID will reuse the same build folder and the same build step. ### Example: sharing the build for Debug and Release ```python settings = "os", "compiler", "arch", "build_type" def build_id(self): self.info_build.settings.build_type = "Any" ``` * With this recipe, Debug and Release will each produce their own package IDs (and thus their own binary packages), but they will **share the same build folder**, because the build ID ignores the `build_type` setting. * **However, you still need to run one** **conan create** **command per configuration** (e.g., once for Debug, once for Release). Conan will check if the build folder already exists (based on the shared build ID) and skip the actual compilation if it’s already been built, only executing package() to create the corresponding package. Example workflow: ```bash # First build: creates the build folder + packages the Debug package $ conan create . -s build_type=Debug # Second build: reuses the previous build folder + packages the Release package without rebuilding $ conan create . -s build_type=Release ``` This way, although we called **conan create** twice (once per package ID), the actual build will only happen once. #### NOTE You can also customize `build_id()` based on options: ```python def build_id(self): self.info_build.options.myoption = "MyValue" self.info_build.options.fullsource = "Always" ``` ## Conditional usage of the build ID If the `build_id()` method does not modify the `self.info_build` data, and produces the same build ID as the package ID, then the standard behavior will be applied. For example: ```python settings = "os", "compiler", "arch", "build_type" def build_id(self): if self.settings.os == "Windows": self.info_build.settings.build_type = "Any" ``` This will only produce a different **build ID** if the package is for Windows, so it will only run the `build()` method once for all the `build_type` values. For any other OS, Conan will behave as usual (as if the `build_id()` method was not defined), running the `build()` method for every `build_type` configuration. #### NOTE **Best practices** The goal of the `build_id()` method is to deal with legacy build scripts that cannot easily be changed to compile one configuration at a time. We strongly recommend to just package **one package binary per package ID** for each different configuration. --- https://docs.conan.io/2/reference/conanfile/methods/build_requirements.html.md --- # build_requirements() The `build_requirements()` method is functionally equivalent to the `requirements()` one, it is executed just after it. It is not strictly necessary, in theory everything that is inside this method, could be done in the end of the `requirements()` one. Still, `build_requirements()` is good for having a dedicated place to define `tool_requires` and `test_requires`: ```python def build_requirements(self): self.tool_requires("cmake/3.23.5") self.test_requires("gtest/1.13.0") ``` For simple cases the attribute syntax can be enough, like `tool_requires = "cmake/3.23.5"` and `test_requires = "gtest/1.13.0"`. The method form can be necessary for conditional or parameterized requirements. The `tool_requires` and `test_requires` methods are just a specialized instance of `requires` with some predefined trait values. See the [requires() reference](https://docs.conan.io/2//reference/conanfile/methods/requirements.html.md#reference-conanfile-methods-requirements) for more information about traits. There are 2 **experimental** `confs` that can be used to avoid the expansion of these types of requirements: - `tools.graph:skip_build` allows to skip `tool_requires` dependencies completely. This can be done if two conditions are met: the packages requiring these tools do not need to be built from sources, and the tool requirements do not affect the consumers `package_id`. If this happens, Conan will raise an error. - `tools.graph:skip_test` allows to skip `test_requires` dependencies completely. If these dependencies are skipped, but then some package needs to be built from source and `tools.build:skip_test` was not activated, it will fail to locate the `test_requires`. So in most cases, the `tools.build:skip_test` should also be defined. Note that if tool and/or test requirements are skipped they will not be part of the dependency graph, and they will not become part of possible generated lockfiles or package lists, with a potential impact on future reproducibility. Also, in most cases, Conan is able to mark tool and test requirements as unnecessary (`Skip`), avoiding the download of the heavy binaries, just downloading the recipe which is usually very fast. That means that in most cases these `confs` are not necessary and the Conan defaults are good, please use them being aware of the tradeoffs. ## tool_requires() The `tool_requires` is equivalent to `requires()` with the following traits: - `build=True`. This dependency is in the “build” context, being necessary at build time, but not at application runtime, and will receive the “build” profile and configuration. - `visible=False`. The dependency to a tool requirement is not propagated downstream. For example, one package can call `tool_requires("cmake/3.23.5")`, but that doesn’t mean that the consumer packages also use `cmake`, they could even use a different build system, or a different version, without causing conflicts. - `run=True`. This dependency has some executables or runtime that needs to be ran at build time. - `headers=False` A tool requirement does not have headers. - `libs=False`: A tool requirement does not have libraries to be linked by the consumer (if it had libraries they would be in the “build” context and could be incompatible with the “host” context of the consumer package). Recall that `tool_requires` are intended exclusively for depending on tools like `cmake` or `ninja`, which run in the “build” context, but not for library-like dependencies that would be linked into binaries. For libraries or library-like dependencies, use `requires` or `test_requires`. ### #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. This syntax is useful when you’re using the same package recipe as a *requires* and as a *tool_requires* and you want to avoid version mismatches if any user decides to override the original *requires* version in the *host* context, i.e., the user could end up with two different versions in the host and build contexts of the same dependency. In a nutshell, the `` specifier allows us to ensure that the version resolved for the *tool_requires* always matches the one for the host requirement. For instance, let’s show a simple recipe using *protobuf*: ```python from conan import ConanFile class mylibRecipe(ConanFile): name = "mylib" version = "0.1" def requirements(self): self.requires("protobuf/3.18.1") def build_requirements(self): self.tool_requires("protobuf/") ``` Then, if any user wants to use *mylib/0.1*, but another version of *protobuf*, there shouldn’t be any problems overriding it: ```python from conan import ConanFile class myappRecipe(ConanFile): name = "myapp" version = "0.1" def requirements(self): self.requires("protobuf/3.21.9", override=True) self.requires("mylib/0.1") ``` The `` defined upstream is ensuring that the host and build contexts are using the same version of that requirement. Additionally, the syntax `` can be used to specify the name of the package to be tracked, should the *requires* and *tool_requires* have different names. For instance: ```python from conan import ConanFile class mylibRecipe(ConanFile): name = "mylib" version = "0.1" def requirements(self): self.requires("gettext/2.31") def build_requirements(self): self.tool_requires("libgettext/") ``` #### WARNING It’s important to note that the reference match is only performed over the package name, not the full reference, so variations on the `user` and `channel` fields are allowed, for example, having `self.requires("protobuf/3.18.1@mycompany/fork")` and `self.tool_requires("protobuf/")` will work and look for a `protobuf/3.18.1` package in the build context, without `user` nor `channel` fields. If we want to also keep the same `user` and `channel` fields, we’d need to specify it in the tool requirements reference as well, i.e., `self.tool_requires("protobuf/@mycompany/fork")`. The `` feature also works when the requirement is replaced using the [[replace_requires]](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-replace-requires) section in your profile, so that the replaced version would be used in both contexts at once. #### NOTE If your `[replace_requires]` is replacing not only the version, but also the `user`/`channel` fields, (so for example replacing `protobuf/*: protobuf/3.18.1@mycompany/fork`) and you would like to also use the same `user` and `channel` fields in the build context, you should use the [[replace_tool_requires]](https://docs.conan.io/2//reference/config_files/profiles.html.md#reference-config-files-profiles-replace-tool-requires) to replace it in the build context as well, otherwise the `` will look for `protobuf/3.18.1` without the `user` and `channel` fields in the build context as explained in the previous warning, which could lead to unexpected results. ## test_requires The `test_requires` is equivalent to `requires()` with the following traits: - `test=True`. This dependency is a “test” dependency, existing in the “host” context, but not aiming to be part of the final product. - `visible=False`. The dependency to a test requirement is not propagated downstream. For example, one package can call `self.test_requires("gtest/1.13.0")`, but that doesn’t mean that the consumer packages also use `gtest`, they could even use a different test framework, or the same `gtest` with a different version, without causing conflicts. #### WARNING As the `test_requires` defines a `visible=False` trait, care must be taken to avoid having transitive dependencies with a normal requirement to the same packages used in the `test_requires`. This is because having direct `visible=False` requirements can create conflicts if a transitive dependency has a `visible=True` requirement to the same package that the current recipe is requiring as a test dependency. In these cases where different visibility rules reach the same package, the visible transitive dependency will be used and propagated downstream. It is possible to further modify individual traits of `tool_requires()` and `test_requires()` if necessary, for example: ```python def build_requirements(self): self.tool_requires("cmake/3.23.5", options={"shared": False}) ``` #### WARNING Defining options values for dependencies in recipes does not have strong guarantees, please check [this FAQ about options values for dependencies](https://docs.conan.io/2//knowledge/faq.html.md#faq-different-options-values). The recommended way to define options values for dependencies is in **profile files**. For the `tool_requires/test_requires` defining the `options` trait is more feasible than with regular requires, because they are not visible and not propagated, but don’t apply `options` trait to regular requires if possible, and use **profile files** instead. Still, both `tool_requires` and `test_requires` are private (`visible=False`), only the recipe that declares them has visibility and can use them. The consumers of the package will not see or know about their existence. Consequently, they cannot be affected by consumers `options``values definitions, it doesn't matter that a consumer of the package defines options like ``cmake*:some_option=somevalue`, because `cmake` is `visible=False` and it will never receive that value from downstream consumers. The `test_requires()` allows the `force=True` trait in case there are transitive test requirements with conflicting versions, and likewise `tool_requires()` support the `override=True` trait, for overriding possible transitive dependencies of the direct tool requirements. #### NOTE **Best practices** - `tool_requires` are exclusively for build time **tools**, not for libraries that would be included and linked into the consumer package. For libraries with some special characteristics, use a `requires()` with custom trait values. - The `self.test_requires()` and `self.tool_requires()` methods should exclusively be used in the `build_requirements()` method, with the only possible exception being the `requirements()` method. Using them in any other method is forbidden. To access information about dependencies when necessary in some methods, the [self.dependencies](https://docs.conan.io/2//reference/conanfile/methods/generate.html.md#conan-conanfile-model-dependencies) attribute should be used. #### SEE ALSO - Follow the [tutorial about consuming Conan packages as tools](https://docs.conan.io/2//tutorial/consuming_packages/use_tools_as_conan_packages.html.md#consuming-packages-tool-requires). - Read the [tutorial about creating tool_requires packages](https://docs.conan.io/2//tutorial/creating_packages/other_types_of_packages/tool_requires_packages.html.md#tutorial-other-tool-requires-packages). - [Using the same requirement as a requires and as a tool_requires](https://docs.conan.io/2//examples/graph/tool_requires/using_protobuf.html.md#examples-graph-tool-requires-protobuf) --- https://docs.conan.io/2/reference/conanfile/methods/build_system_requirements.html.md --- # build_system_requirements() #### WARNING This feature is experimental and subject to breaking changes. See [the Conan stability](https://docs.conan.io/2//introduction.html.md#stability) section for more information. The `build_system_requirements()` method is a companion to `system_requirements()` intended specifically for system packages that are only needed when **building from source** (i.e., when the package binary is being compiled). It is not called when a pre-built binary is retrieved from a server or cache. The key difference from `system_requirements()` is that `build_system_requirements()` installs packages using the **build machine architecture** (`settings_build.arch`) rather than the host architecture. This is especially important in cross-compilation scenarios where the build and host machines have different architectures. Then, these requirements are intended to be “tools”, executables used at build time, but not libraries that would be linked in the consumers libraries or applications. ```python from conan import ConanFile from conan.tools.system.package_manager import Apt class MyPkg(ConanFile): name = "mypkg" version = "1.0" settings = "os", "arch" def build_system_requirements(self): # Installed using build machine arch (settings_build.arch), # only when building from source apt = Apt(self) apt.install(["build-essential", "pkg-config"]) def system_requirements(self): # Installed using host arch (settings.arch), always apt = Apt(self) apt.install(["libssl-dev"]) ``` #### NOTE `build_system_requirements()` is only invoked when the package is being built from source. If the binary is already available in the cache or a remote, this method is skipped. #### SEE ALSO - [system_requirements()](https://docs.conan.io/2//reference/conanfile/methods/system_requirements.html.md#reference-conanfile-methods-system-requirements) - [conan.tools.system.package_manager](https://docs.conan.io/2//reference/tools/system/package_manager.html.md#conan-tools-system-package-manager) --- https://docs.conan.io/2/reference/conanfile/methods/compatibility.html.md --- # compatibility() #### WARNING This is a **preview** feature The `compatibility()` method implements the same binary compatibility mechanism than the [compatibility plugin](https://docs.conan.io/2//reference/extensions/binary_compatibility.html.md#reference-extensions-binary-compatibility), but at the recipe level. In general, the global compatibility plugin should be good for most cases, and only require the recipe method for exceptional cases. This method can be used in a *conanfile.py* to define packages that are compatible between each other. If there are no binaries available for the requested settings and options, this mechanism will retrieve the compatible package’s binaries if they exist. This method should return a list of compatible configurations. For example, if we want that binaries built with gcc versions 4.8, 4.7 and 4.6 to be considered compatible with the ones compiled with 4.9 we could declare a `compatibility()` method like this: ```python def compatibility(self): if self.settings.compiler == "gcc" and self.settings.compiler.version == "4.9": return [{"settings": [("compiler.version", v)]} for v in ("4.8", "4.7", "4.6")] ``` The format of the list returned is as shown below: ```python [ { "settings": [(, ), (, ), ...], "options": [(