<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Conan C/C++ Package Manager Blog</title>
    <description>Blog for the team behind the Fully Open Source, MIT licensed, C/C++ Package Manager.</description>
    <link>https://blog.conan.io/</link>
    <atom:link href="https://blog.conan.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 14 May 2026 08:50:37 +0000</pubDate>
    <lastBuildDate>Thu, 14 May 2026 08:50:37 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Introducing conan-py-build: Build Python Wheels with Conan</title>
        <description>&lt;p&gt;Packaging Python extensions that contain native C or C++ code has come a long
way. &lt;a href=&quot;https://peps.python.org/pep-0517/&quot;&gt;PEP 517&lt;/a&gt; defined a contract between
Python build frontends (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uv&lt;/code&gt;) and the build backend
that produces the wheel. That standard is what makes it possible today to
connect a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pyproject.toml&lt;/code&gt;, declare a backend, and let
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip wheel .&lt;/code&gt; drive the build.&lt;/p&gt;

&lt;p&gt;The C/C++ dependency layer is a different story. Somewhere between
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pyproject.toml&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt;, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find_package(OpenSSL)&lt;/code&gt; has to resolve.
In practice, most projects solve that outside the wheel build: through system
packages, vendored source trees, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;FetchContent&lt;/code&gt; or a separate native package
manager install step. That means a separate step to manage before the Python
build, often duplicated across CI configurations and developer setups.&lt;/p&gt;

&lt;p&gt;Today, we are happy to introduce
&lt;strong&gt;&lt;a href=&quot;https://github.com/conan-io/conan-py-build&quot;&gt;conan-py-build&lt;/a&gt;&lt;/strong&gt;, a PEP 517
build backend that brings Conan’s C/C++ dependency management directly into the
Python wheel build.&lt;/p&gt;

&lt;p&gt;The project is currently in beta and under active development. We are releasing
it now to gather early feedback, and we would love for you to try it and tell
us what you think.&lt;/p&gt;

&lt;h2 id=&quot;what-is-conan-py-build&quot;&gt;What is conan-py-build?&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan-py-build&lt;/code&gt; is a build backend for Python packages that contain native
C/C++ extensions. You declare it in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pyproject.toml&lt;/code&gt;, provide a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanfile.py&lt;/code&gt;
that describes the C/C++ build and its dependencies, and build wheels through
standard Python packaging commands such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip wheel .&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a build runs, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan-py-build&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Resolves the C/C++ dependency graph through Conan, downloading precompiled
binaries where available and building the rest from source&lt;/li&gt;
  &lt;li&gt;Prepares the build toolchain through the corresponding Conan generators&lt;/li&gt;
  &lt;li&gt;Builds the extension using your project’s build system&lt;/li&gt;
  &lt;li&gt;When the extension links against shared libraries, copies those runtime
dependencies next to the extension module and patches RPATH on Linux and
macOS where applicable&lt;/li&gt;
  &lt;li&gt;Packages the result into a standard Python wheel&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Because it is a PEP 517 backend, it plugs into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uv&lt;/code&gt;
directly, and fits into &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cibuildwheel&lt;/code&gt;-based CI workflows for multi-platform
builds.&lt;/p&gt;

&lt;h2 id=&quot;a-minimal-example&quot;&gt;A minimal example&lt;/h2&gt;

&lt;p&gt;Let’s build a tiny Python package that exposes a single function, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greet(name)&lt;/code&gt;,
which prints a colored greeting to the terminal. We’ll use CMake for the native
build, &lt;a href=&quot;https://github.com/pybind/pybind11&quot;&gt;pybind11&lt;/a&gt; for the Python bindings,
and &lt;a href=&quot;https://fmt.dev&quot;&gt;{fmt}&lt;/a&gt; as a dependency pulled in through Conan. The same
setup extends to other build systems like Meson or Autotools.&lt;/p&gt;

&lt;p&gt;The project layout:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;mypackage/
├── pyproject.toml
├── conanfile.py
├── CMakeLists.txt
└── src/
    ├── mypackage/
    │   └── __init__.py
    └── mypackage.cpp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pyproject.toml&lt;/code&gt; declares the build backend and the project metadata:&lt;/p&gt;

&lt;div class=&quot;language-toml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[build-system]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;requires&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;[&quot;conan-py-build&quot;]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;build-backend&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;conan_py_build.build&quot;&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[project]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;mypackage&quot;&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;0.1.0&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanfile.py&lt;/code&gt; describes the C/C++ side: its dependencies (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pybind11&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmt&lt;/code&gt;)
and how they are built and packaged.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;conan&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConanFile&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;conan.tools.cmake&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CMake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmake_layout&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MyPackageConan&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConanFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;os&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;compiler&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;build_type&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;arch&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;generators&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;CMakeToolchain&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;CMakeDeps&quot;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;layout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmake_layout&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;requirements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;requires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;pybind11/3.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;requires&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;fmt/12.1.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmake&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CMake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configure&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmake&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;CMake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmake&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; builds the extension against pybind11 and fmt and installs
the resulting module into the Python package directory so the backend picks it
up when assembling the wheel:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cmake_minimum_required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;VERSION 3.15&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;mypackage LANGUAGES CXX&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;PYBIND11_FINDPYTHON ON&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;find_package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;pybind11 CONFIG REQUIRED&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;find_package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;fmt CONFIG REQUIRED&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nf&quot;&gt;pybind11_add_module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;_core src/mypackage.cpp&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;_core PRIVATE fmt::fmt&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;TARGETS _core DESTINATION mypackage&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The C++ source defines &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;greet(name)&lt;/code&gt; using fmt’s color support and exposes it
as a compiled &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_core&lt;/code&gt; module:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;string&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;pybind11/pybind11.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;fmt/color.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;green&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hello, {}!&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\n&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;PYBIND11_MODULE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_core&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;m&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;src/mypackage/__init__.py&lt;/code&gt; re-exports it so callers see &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mypackage.greet&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;mypackage._core&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greet&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;__all__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;greet&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With that in place, building the wheel is the standard Python packaging
command:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip wheel &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-w&lt;/span&gt; dist/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Conan resolves &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pybind11&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;fmt&lt;/code&gt; from Conan Center Index, CMake compiles the
extension against them, and you get a platform-specific wheel in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dist/&lt;/code&gt;.
Install it and try it:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;pip &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;dist/mypackage-&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.whl
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;python &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;import mypackage; mypackage.greet(&apos;world&apos;)&quot;&lt;/span&gt;
Hello, world!
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You should see &lt;code style=&quot;color: #008000;&quot;&gt;Hello, world!&lt;/code&gt; printed in green.&lt;/p&gt;

&lt;div style=&quot;border-left: 3px solid #e0e0e0; padding: 0.4em 1em; color: #555; font-size: 0.95em; margin: 1.5em 0;&quot;&gt;
&lt;strong&gt;More examples:&lt;/strong&gt; the &lt;a href=&quot;https://github.com/conan-io/conan-py-build/tree/main/examples&quot;&gt;repo&lt;/a&gt; has nanobind bindings, shared library dependencies, C++ sources fetched at build time, and a full multi-platform &lt;a href=&quot;https://github.com/conan-io/conan-py-build/tree/main/examples/cibw-example&quot;&gt;cibuildwheel&lt;/a&gt; setup for Linux, macOS, and Windows.
&lt;/div&gt;

&lt;h2 id=&quot;what-conan-py-build-brings&quot;&gt;What conan-py-build brings&lt;/h2&gt;

&lt;p&gt;Some of the advantages of bringing Conan into the wheel build:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;One build entry point.&lt;/strong&gt; The usual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;pip wheel .&lt;/code&gt; command can drive both the
Python packaging step and the native C/C++ dependency/build step.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Conan Center.&lt;/strong&gt; A large catalog of C/C++ libraries with recipes tested
across a broad compiler and OS matrix.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Binary caching.&lt;/strong&gt; Compiled dependencies are reused across builds and CI
runs via the Conan cache or a shared remote, rebuilt only when settings
change.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Profiles and lockfiles.&lt;/strong&gt; Profiles define the native build configuration of
each wheel (compiler, architecture, C++ standard, dependency options), and
lockfiles pin the graph for reproducible builds.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Shared library handling.&lt;/strong&gt; Conan-managed runtime libraries are deployed
next to the extension module, and RPATH is adjusted on Linux and macOS where
applicable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan-py-build&lt;/code&gt; pulls the C/C++ dependency layer inside the PEP 517 build so
the Python build and the C/C++ build are one problem, not two. If you have been
maintaining a separate dependency step alongside your Python packaging, it is
worth a look.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href=&quot;https://conan-py-build.conan.io&quot;&gt;documentation&lt;/a&gt; and browse the
&lt;a href=&quot;https://github.com/conan-io/conan-py-build/tree/main/examples&quot;&gt;examples&lt;/a&gt;.
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan-py-build&lt;/code&gt; is still in &lt;strong&gt;beta&lt;/strong&gt; and available on
&lt;a href=&quot;https://pypi.org/project/conan-py-build/&quot;&gt;PyPI&lt;/a&gt;. If something does not work, or
there is a workflow you want supported, please open an issue on
&lt;a href=&quot;https://github.com/conan-io/conan-py-build/issues&quot;&gt;GitHub&lt;/a&gt; and let us know
where it fits, or where it does not yet.&lt;/p&gt;

&lt;p&gt;Looking forward to your feedback.&lt;/p&gt;
</description>
        <pubDate>Tue, 05 May 2026 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/cpp/conan/python/2026/05/05/Introducing-conan-py-build.html</link>
        <guid isPermaLink="true">https://blog.conan.io/cpp/conan/python/2026/05/05/Introducing-conan-py-build.html</guid>
        
        
        <category>cpp</category>
        
        <category>conan</category>
        
        <category>python</category>
        
      </item>
    
      <item>
        <title>Reproducible and traceable configuration for Conan C and C++ package manager</title>
        <description>&lt;p&gt;The Conan C and C++ package manager has many powerful customization and extensibility capabilities. It is possible to configure the remote servers that are being used, define custom settings to model different binaries using user-defined logic, use custom profiles, use custom Conan commands for automation, there are hooks for automating different tasks, extensions like plugins to define rules for profile checking or binary compatibility, and many more.&lt;/p&gt;

&lt;p&gt;Conan has provided for some time the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan config install&lt;/code&gt; command, that could use a git repository or a zip file in an http server to install all of the above configuration files. This has proven a &lt;strong&gt;simple and convenient way to distribute and share the Conan configuration&lt;/strong&gt;, so all the CI machines and developer machines could use the same configuration. But this approach still had some challenges, things like being able to reproduce the same configuration that was used to build something in the past was complicated.&lt;/p&gt;

&lt;p&gt;With the recent introduction of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan config install-pkg&lt;/code&gt;, configuration management has effectively turned into a first-class citizen. You can now &lt;strong&gt;package all your custom configuration, remotes,  profiles, hooks, custom settings, etc. as standard Conan packages and manage them with the same rigor you apply to your C++ libraries&lt;/strong&gt;, enjoying all the versioning capabilities like version ranges and lockfiles to get a new level of extensibility, reproducibility, and traceability.&lt;/p&gt;

&lt;p&gt;Using the new Conan configuration packages and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan config install-pkg&lt;/code&gt; has several advantages:&lt;/p&gt;

&lt;h2 id=&quot;improved-versioning-easier-updates&quot;&gt;Improved versioning, easier updates&lt;/h2&gt;

&lt;p&gt;As Conan packages are versioned, putting the configuration inside a Conan package automatically leverages all the versioning capabilities. For example, to install a specific version from a Conan package:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan config install-pkg my_conf/1.2
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Instead of the previous &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan config install&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan config &lt;span class=&quot;nb&quot;&gt;install &lt;/span&gt;git@github.com/myorg/repo/my_conf.git &lt;span class=&quot;nt&quot;&gt;--args&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;-b 1.2&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Furthermore, it is also possible to use version ranges for installation, and for updating to the latest version within the defined range:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan config install-pkg &lt;span class=&quot;s2&quot;&gt;&quot;mycompany_conf/[&amp;gt;=1.0 &amp;lt;2]&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;simple-to-create-and-maintain&quot;&gt;Simple to create and maintain&lt;/h2&gt;

&lt;p&gt;Creating a Conan package for configuration uses a very simple recipe with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package_type = “configuration”&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;conan&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConanFile&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;conan.tools.files&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConanFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;myconf&quot;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1.2&quot;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;package_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;configuration&quot;&lt;/span&gt;

   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*.conf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the package can be created and uploaded to the server with the standard commands:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan export-pkg &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt;
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan upload &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;default &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, when this package is installed with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan config install-pkg myconf/1.2 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;the configuration process will copy the contents of the package’s internal “package folder” to the current Conan home.&lt;/p&gt;

&lt;h2 id=&quot;can-use-different-configurations-per-platform&quot;&gt;Can use different configurations per platform&lt;/h2&gt;

&lt;p&gt;One of the advantages of using Conan packages is that in the same way Conan package binaries will be different based on the current profile (OS, compiler, architecture, etc), it is possible to have different configurations for different platforms. Adding &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;settings = “os”&lt;/code&gt; to the recipe above and conditioning the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;copy()&lt;/code&gt;, we could have it:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;os&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;conan&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ConanFile&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;conan.tools.files&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Conf&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ConanFile&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;myconf&quot;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;version&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;1.2&quot;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;os&quot;&lt;/span&gt;
   &lt;span class=&quot;n&quot;&gt;package_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;configuration&quot;&lt;/span&gt;

   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;win&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;settings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Windows&quot;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;nix&quot;&lt;/span&gt;
       &lt;span class=&quot;n&quot;&gt;copy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;*.conf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dst&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;package_folder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The different configuration packages can be created with:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan export-pkg &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Windows
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan export-pkg &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Linux
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan upload &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;default &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And then, when &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan config install-pkg myconf/1.2&lt;/code&gt; is done, it will automatically install the Windows or Linux configuration files based on the current platform.&lt;/p&gt;

&lt;h2 id=&quot;same-infrastructure-and-processes&quot;&gt;Same infrastructure and processes&lt;/h2&gt;

&lt;p&gt;Another advantage of Conan configuration packages is that it is possible to use the same server-side repositories that store regular Conan packages to store them. Then, it is not necessary to establish or configure new repositories or credentials to access the configuration, as it will be the same one of the regular packages.&lt;/p&gt;

&lt;p&gt;Likewise, it is possible to use the same development and release conventions than other packages, like running promotions between different server repositories to control maturity of the configuration itself, similar to the promotions used in the CI tutorial in https://docs.conan.io/2/ci_tutorial/tutorial.html&lt;/p&gt;

&lt;h2 id=&quot;easy-bootstrap-with-conanconfigyml&quot;&gt;Easy bootstrap with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanconfig.yml&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;Besides the command line syntax, it is also possible to define a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanconfig.yml&lt;/code&gt; file that can contain one or more configuration packages references like:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;myconf_a/0.1&lt;/span&gt;
   &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;myconf_b/0.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanconfig.yml&lt;/code&gt; file can also define version-ranges and possible URLs of the repositories to download them for the first time, like:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;packages&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;myconf_a/[&amp;gt;=1 &amp;lt;2]&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;urls&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://myserver/url/api/conan/conanrepo&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That means that if a source repository contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanconfig.yml&lt;/code&gt; file, it is enough to do a simple:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan config install-pkg  &lt;span class=&quot;c&quot;&gt;# No arguments at all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And that will read the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanconfig.yml&lt;/code&gt; in the source repo and install all the configuration from it.&lt;/p&gt;

&lt;p&gt;Together with the usage of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.conanrc&lt;/code&gt; file that can define a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan_home&lt;/code&gt; for the current folder, this is a powerful mechanism to achieve full isolation and reproducibility of configuration for different projects.&lt;/p&gt;

&lt;h2 id=&quot;reproducibility-and-lockfiles&quot;&gt;Reproducibility and lockfiles&lt;/h2&gt;

&lt;p&gt;When you generate a lockfile for your project, Conan can now record exactly which version and revision of the configuration packages was used. If you need to reproduce a bug from a build that happened three months ago, the lockfile ensures you aren’t just using the right library versions, but also the exact same configuration, profiles, remotes, custom settings, hooks, etc that were present during the original build.&lt;/p&gt;

&lt;p&gt;Lockfiles work well with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanconfig.yml&lt;/code&gt; files too. The files can contain a valid version range &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;myconf_a/[&amp;gt;=1 &amp;lt;2]&lt;/code&gt; while the lockfile can guarantee the reproducibility of a specific version and recipe revision in that range.&lt;/p&gt;

&lt;h2 id=&quot;effect-on-package_id&quot;&gt;Effect on package_id&lt;/h2&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;core.package_id:config_mode&lt;/code&gt; configuration entry allows you to include configuration packages in the package ID calculation for every package built or consumed under that configuration. For example, you can define this in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;global.conf&lt;/code&gt; as follows:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# in your global.conf
&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;core.package_id:&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;config_mode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;minor_mode&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And we install the following configuration package:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan config install-pkg my_conf/1.2.0
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Consequently, all package binaries will include &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_conf/1.2.Z&lt;/code&gt; in their &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package_id&lt;/code&gt; calculation. This ensures that minor updates, such as installing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_conf/1.2.1&lt;/code&gt;, will not trigger new builds. However, moving to a version like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;my_conf/1.3.0&lt;/code&gt; will require rebuilding all packages.&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;this feature should be used with caution&lt;/strong&gt;.  The Conan’s binary model of settings, options and dependencies has proved to be the most efficient way to avoid unnecessary rebuilds. However, if the model is still not sufficient, as a last resort, using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;core.package_id:config_mode&lt;/code&gt; could be a valid approach to provide safer guarantees and better traceability for the specific configuration used to build each package binary.&lt;/p&gt;

&lt;h2 id=&quot;easier-to-manage-multiple-configurations&quot;&gt;Easier to manage multiple configurations&lt;/h2&gt;

&lt;p&gt;Sometimes, there are scenarios where there are different configurations to be used. For example a large company could have some main remote repositories that everyone in the organization should be using, while specific projects or teams could have their own specific configuration for that project.&lt;/p&gt;

&lt;p&gt;As we have seen in the above &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanconfig.yml&lt;/code&gt; file, it is possible and easier to manage such scenario, as multiple Conan configuration packages can be installed, and Conan can still use the above guarantees, like applying lockfiles to guarantee reproducibility for all of them, to make all of them part of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;package_id&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;conclusions&quot;&gt;Conclusions&lt;/h2&gt;

&lt;p&gt;If you are managing a Conan project that has some user configurations, like defining different remotes, custom profiles, custom settings, custom commands, hooks or plugins extensions, etc, using Conan configuration packages and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan config install-pkg&lt;/code&gt; would make easier to maintain, distribute and manage such a configuration across CI and developer machines. Furthermore, the usage of Conan configuration packages can achieve better reproducibility and traceability, something that is more challenging with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan config install&lt;/code&gt; command using git repositories, and the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;core.package_id:config_mode&lt;/code&gt; can improve the modelling of binary compatibility in advanced scenarios.&lt;/p&gt;

&lt;p&gt;Check out the official documentation for &lt;a href=&quot;https://docs.conan.io/2/reference/commands/config.html#conan-config-install-pkg&quot;&gt;config install-pkg&lt;/a&gt; and the &lt;a href=&quot;https://docs.conan.io/2/reference/commands/config.html#conanconfig-yml&quot;&gt;conanconfig.yml&lt;/a&gt; spec, and if you have any questions or feedback, please let us know in &lt;a href=&quot;https://github.com/conan-io/conan/issues&quot;&gt;Github issues&lt;/a&gt;.&lt;/p&gt;
</description>
        <pubDate>Tue, 17 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/cpp/conan/configuration/reproducibility/lockfile/2026/02/17/Reproducible-Configuration-Conan.html</link>
        <guid isPermaLink="true">https://blog.conan.io/cpp/conan/configuration/reproducibility/lockfile/2026/02/17/Reproducible-Configuration-Conan.html</guid>
        
        
        <category>cpp</category>
        
        <category>conan</category>
        
        <category>configuration</category>
        
        <category>reproducibility</category>
        
        <category>lockfile</category>
        
      </item>
    
      <item>
        <title>Conan 2 Essentials and Advanced Training Now Complete on JFrog Academy</title>
        <description>&lt;p&gt;We are happy to announce that the &lt;strong&gt;complete Conan 2 training&lt;/strong&gt; is now available
for free on &lt;a href=&quot;https://academy.jfrog.com/&quot;&gt;&lt;strong&gt;JFrog Academy&lt;/strong&gt;&lt;/a&gt;. You can take it at
your own pace through two learning paths, each organized into modules so you can
progress step by step:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;➡️ &lt;a href=&quot;https://academy.jfrog.com/path/conan-cc-package-manager&quot;&gt;&lt;strong&gt;Conan 2 Essentials&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;➡️ &lt;a href=&quot;https://academy.jfrog.com/path/conan-2-advanced&quot;&gt;&lt;strong&gt;Conan 2 Advanced&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The training is made up of &lt;strong&gt;29 video lessons&lt;/strong&gt; in total, split across &lt;strong&gt;7
modules&lt;/strong&gt;: Essentials has 16 lessons across 3 modules, and Advanced has 13
lessons across 4 modules. Both paths are &lt;strong&gt;self-paced&lt;/strong&gt; and &lt;strong&gt;free&lt;/strong&gt;.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;a href=&quot;https://academy.jfrog.com/path/conan-cc-package-manager&quot;&gt;
    &lt;img src=&quot;/assets/post_images/2026-02-03/conan-training-full.png&quot; width=&quot;80%&quot; alt=&quot;Conan 2 Essentials and Advanced courses on JFrog Academy&quot; /&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;h2 id=&quot;what-youll-learn&quot;&gt;What you’ll learn&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://academy.jfrog.com/path/conan-cc-package-manager&quot;&gt;Conan 2 Essentials&lt;/a&gt;&lt;/strong&gt; —
Fundamentals of using and creating packages with Conan 2, for developers with
little or no Conan experience.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Build C++ projects with Conan and CMake, cross-compile with host/build
profiles, and scan dependencies with &lt;a href=&quot;https://audit.conan.io/register&quot;&gt;&lt;strong&gt;Conan Audit&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Go through the Conan package creation flow in detail: writing recipes,
testing packages, and uploading packages to Conan repositories&lt;/li&gt;
  &lt;li&gt;Package &lt;strong&gt;header-only&lt;/strong&gt; libraries, &lt;strong&gt;prebuilt binaries&lt;/strong&gt;, and &lt;strong&gt;build tools&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href=&quot;https://academy.jfrog.com/path/conan-2-advanced&quot;&gt;Conan 2 Advanced&lt;/a&gt;&lt;/strong&gt; — For
users who already know Conan 2 basics.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Develop packages locally with &lt;strong&gt;editable mode&lt;/strong&gt;; understand &lt;strong&gt;package types&lt;/strong&gt;,
&lt;strong&gt;test_requires&lt;/strong&gt;, &lt;strong&gt;lockfiles&lt;/strong&gt;, and advanced versioning&lt;/li&gt;
  &lt;li&gt;Extend Conan with &lt;strong&gt;deployers&lt;/strong&gt;, &lt;strong&gt;custom commands&lt;/strong&gt;, &lt;strong&gt;hooks&lt;/strong&gt;, and
&lt;strong&gt;python_requires&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;Extend the binary model and define &lt;strong&gt;custom binary compatibility&lt;/strong&gt; rules&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;start-learning-today&quot;&gt;Start Learning Today&lt;/h2&gt;

&lt;p&gt;Both paths are &lt;strong&gt;free&lt;/strong&gt;, &lt;strong&gt;self-paced&lt;/strong&gt;, and available on JFrog Academy.&lt;/p&gt;

&lt;p&gt;➡️ &lt;a href=&quot;https://academy.jfrog.com/path/conan-cc-package-manager&quot;&gt;&lt;strong&gt;Enroll in Conan 2 Essentials&lt;/strong&gt;&lt;/a&gt;&lt;br /&gt;
➡️ &lt;a href=&quot;https://academy.jfrog.com/path/conan-2-advanced&quot;&gt;&lt;strong&gt;Enroll in Conan 2 Advanced&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The examples in the training use the &lt;a href=&quot;https://github.com/conan-io/conan-training2&quot;&gt;Conan Training 2 GitHub
repository&lt;/a&gt;. If you have questions
or feedback about the courses, or if you run into any issues with the code
examples, feel free to open an issue there.&lt;/p&gt;

&lt;p&gt;We hope you enjoy the full training and find it useful for your day-to-day work
with Conan 2.&lt;/p&gt;
</description>
        <pubDate>Tue, 03 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/2026/02/03/Conan-2-Essentials-and-Advanced-trainings-on-JFrog-Academy.html</link>
        <guid isPermaLink="true">https://blog.conan.io/2026/02/03/Conan-2-Essentials-and-Advanced-trainings-on-JFrog-Academy.html</guid>
        
        
      </item>
    
      <item>
        <title>ML in C++: The libtorch package is now available in Conan Center Index</title>
        <description>&lt;p&gt;Over the years, one of the most requested ML libraries that users wanted to see available
in Conan Center has been &lt;strong&gt;libtorch&lt;/strong&gt;, and we’re now happy to announce that we have added experimental support for the recipe.&lt;/p&gt;

&lt;p&gt;Having this recipe packaged in Conan Center will allow developers to execute their PyTorch workflows
as easily as any other Conan recipe, without manual downloads or custom integration steps.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;what-is-libtorch&quot;&gt;What is libtorch&lt;/h2&gt;
&lt;p&gt;Libtorch is the core C++ component behind the popular PyTorch library.
It provides multidimensional tensors, automatic differentiation, neural network layers, optimizers,
and model serialization, all implemented in C++.&lt;/p&gt;

&lt;p&gt;Internally, libtorch is built on the ATen tensor library and PyTorch’s dynamic computation graph engine,
enabling imperative, eager-execution code with a tape-based autograd system.
The API closely follows PyTorch’s Python interface, making it easy to translate models and workflows between Python and C++.&lt;/p&gt;

&lt;p&gt;Libtorch is typically used in environments where Python is not suitable,
such as performance-critical applications, real-time inference pipelines, embedded systems, or large C++ codebases.&lt;/p&gt;

&lt;h2 id=&quot;example-usage&quot;&gt;Example usage&lt;/h2&gt;

&lt;p&gt;To show how easy the new recipe makes integrating libtorch in your project,
let’s use the upstream regression example from pytorch.
You can follow along by cloning the contents of the regression folder in
&lt;a href=&quot;https://github.com/pytorch/examples/tree/main/cpp/regression&quot;&gt;https://github.com/pytorch/examples/tree/main/cpp/regression&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once we have this, with modern Conan integrations, using libtorch is as easy as adding a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanfile.txt&lt;/code&gt; to your project,
with contents that look something like:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[requires]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;libtorch/&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;[*]&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[layout]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;cmake_layout&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[generators]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;CMakeDeps&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;CMakeToolchain&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then running Conan to ensure the package is available locally:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;missing
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And now, we can build the example using CMake as we would normally do.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Note that for Windows, the following configure preset name should be replaced by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan-default&lt;/code&gt; (using the same &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan-release&lt;/code&gt; for the build preset.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cmake &lt;span class=&quot;nt&quot;&gt;--preset&lt;/span&gt; conan-release
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;cmake &lt;span class=&quot;nt&quot;&gt;--build&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--preset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;conan-release
&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;./build/Release/regression
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2026-01-20/blogpost-run.gif&quot; alt=&quot;Regression example output&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;We can now see that the example correctly compiled, and it successfully found our target polynomial,
and as the default error is set to quite a small value in the code, the plotted polynomials have quite the overlap.&lt;/p&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2026-01-20/function_comparison.png&quot; alt=&quot;Libtorch regression example output&quot; /&gt;
&lt;/div&gt;

&lt;p&gt;Even though we have seen a simple usage of the library,
this same approach will work for your local project using libtorch, so feel free to explore using it in your projects!&lt;/p&gt;

&lt;h2 id=&quot;wed-love-to-hear-your-feedback&quot;&gt;We’d love to hear your feedback&lt;/h2&gt;

&lt;p&gt;As always, we would love to hear your feedback with the recipe,
so do feel free to contact us in &lt;a href=&quot;https://github.com/conan-io/conan-center-index/issues&quot;&gt;https://github.com/conan-io/conan-center-index/issues&lt;/a&gt;,
either for general feedback on the usage of the recipe, 
or if you would like to see the recipe support new features for the library.
Happy coding!&lt;/p&gt;
</description>
        <pubDate>Tue, 20 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/cpp/ml/ai/conan/gpu/tensor/neural-network/2026/01/20/Libtorch-Available-In-Conancenter.html</link>
        <guid isPermaLink="true">https://blog.conan.io/cpp/ml/ai/conan/gpu/tensor/neural-network/2026/01/20/Libtorch-Available-In-Conancenter.html</guid>
        
        
        <category>cpp</category>
        
        <category>ml</category>
        
        <category>ai</category>
        
        <category>conan</category>
        
        <category>gpu</category>
        
        <category>tensor</category>
        
        <category>neural-network</category>
        
      </item>
    
      <item>
        <title>Taking Your Raylib C/C++ Game to Android with Conan and Android Studio</title>
        <description>&lt;p&gt;In our &lt;a href=&quot;/cpp/gamedev/clion/conan/raylib/2025/05/13/GameDev-Raylib-CLion.html&quot;&gt;previous post&lt;/a&gt;,
we built a fun 2D runner game using &lt;strong&gt;Raylib&lt;/strong&gt; and &lt;strong&gt;CLion&lt;/strong&gt;.
Now it’s time to take one step ahead and run that game on mobile!
In this post, we’ll show you how to build the same “Jump to Survive” game for Android using &lt;strong&gt;Android Studio&lt;/strong&gt;,
the &lt;strong&gt;Android NDK&lt;/strong&gt;, and &lt;strong&gt;Conan&lt;/strong&gt; for dependency management.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you’ll have your Raylib game running on Android devices with touch controls.&lt;/p&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-10/game_running.gif&quot; alt=&quot;Jump to Survive on Android&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Before we begin, make sure you have &lt;a href=&quot;https://developer.android.com/studio&quot;&gt;Android Studio&lt;/a&gt; installed on your machine.&lt;/p&gt;

&lt;p&gt;Also, the example code for this post is available on &lt;a href=&quot;https://github.com/conan-io/examples2/tree/main/examples/cross_build/android/raylib/&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;creating-the-android-project&quot;&gt;Creating the Android Project&lt;/h2&gt;

&lt;p&gt;In order to run our Raylib game on Android, we need to create a new Android project with native C++ support.&lt;/p&gt;

&lt;h3 id=&quot;set-up-a-new-native-c-project&quot;&gt;Set Up a New Native C++ Project&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Open Android Studio and create a &lt;strong&gt;New Project&lt;/strong&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Select &lt;strong&gt;Native C++&lt;/strong&gt; from the templates&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-10/new_project.png&quot; alt=&quot;New Native C++ Project in Android Studio&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Name your application (e.g., “RaylibRunner”)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Set the &lt;strong&gt;Minimum SDK&lt;/strong&gt; to API level 27 or higher (remember this value for the Conan profile)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Choose &lt;strong&gt;Groovy DSL&lt;/strong&gt; for the build configuration language&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-10/project_name.png&quot; alt=&quot;New Native C++ Project in Android Studio&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Next, select &lt;strong&gt;C++17&lt;/strong&gt; as the C++ Standard (we’ll match this in our Conan profile)&lt;/li&gt;
&lt;/ul&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-10/project_cppstd.png&quot; alt=&quot;New Native C++ Project in Android Studio&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;In the end, we will have a basic Android project set up with C++ support.
The project structure should look like this:&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;├── app
│   ├── build.gradle
│   ├── libs
│   └── src
│       ├── main
│       │   ├── AndroidManifest.xml
│       │   ├── cpp
│       │   │   ├── CMakeLists.txt
│       │   │   ├── conanfile.txt
│       │   │   └── native-lib.cpp
│       │   ├── java
│       │   └── res
│       └── test
├── build.gradle
├── gradle.properties
├── local.properties
└── settings.gradle
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpp&lt;/code&gt; folder contains a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;native-lib.cpp&lt;/code&gt; file. This is where our game code will live.&lt;/p&gt;

&lt;h3 id=&quot;update-the-raylib-example-code&quot;&gt;Update the Raylib Example Code&lt;/h3&gt;

&lt;p&gt;Now that we have the template C++ file, we will re-use the previous example, but adapted for Android. The key differences from the desktop version are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Touch input&lt;/strong&gt; instead of keyboard (using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetTouchPointCount()&lt;/code&gt;)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Back button handling&lt;/strong&gt; with double-press to exit&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Disabled exit key&lt;/strong&gt; to prevent accidental app closure&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;details&gt;

  &lt;summary&gt;Here’s the complete and updated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;native-lib.cpp&lt;/code&gt; file content (click to show).&lt;/summary&gt;

  &lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;jni.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;android/log.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;android/native_activity.h&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&quot;raylib.h&quot;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;vector&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;extern&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// --- Initialization ---&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;800&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;450&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;InitWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;screenW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenH&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Jump to Survive!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;SetExitKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Disable back button from closing app automatically&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// --- Player Setup ---&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;Rectangle&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gravity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1000.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jumpImpulse&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;450.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// --- Ground Definition ---&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groundY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// --- Obstacle Management ---&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;vector&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Rectangle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawnTimer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawnInterval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obstacleSpeed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;300.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;minSpawnInterval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.8&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxSpawnInterval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.6&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;minObsWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxObsWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;120&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// --- Game State Variables ---&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gameOver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;// --- Back button double press logic ---&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backPressTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;bool&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doublePressInterval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.5&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 0.5 seconds&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;SetTargetFPS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;60&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;WindowShouldClose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dt&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetFrameTime&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// --- Back button exit logic ---&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;backPressTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backPressTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doublePressInterval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsKeyPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KEY_BACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Exit game&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;backPressTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gameOver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Jump logic - using touch instead of keyboard&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetTouchPointCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groundY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;vy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jumpImpulse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Apply gravity&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;vy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gravity&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;vy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Ground collision&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groundY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groundY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;vy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Spawn obstacles with random width &amp;amp; interval&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;spawnTimer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;spawnTimer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;spawnInterval&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;spawnTimer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;spawnInterval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetRandomValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minSpawnInterval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                              &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;maxSpawnInterval&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;100.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;w&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetRandomValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;minObsWidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maxObsWidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;push_back&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;screenW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;groundY&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt;
                                     &lt;span class=&quot;kt&quot;&gt;float&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;w&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;40.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Move &amp;amp; collide obstacles&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obstacleSpeed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;dt&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;CheckCollisionRecs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                    &lt;span class=&quot;n&quot;&gt;gameOver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

            &lt;span class=&quot;c1&quot;&gt;// Remove off-screen obstacles &amp;amp; increment score&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;empty&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;front&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;front&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;erase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;begin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;());&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;c1&quot;&gt;// Accepting restart&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetTouchPointCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// Reset everything&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;80&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;vy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;spawnTimer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;spawnInterval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.2&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;gameOver&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;c1&quot;&gt;// --- Drawing ---&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BeginDrawing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;ClearBackground&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;RAYWHITE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;DrawRectangle&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groundY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenW&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DARKGRAY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;DrawRectangleRec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLUE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;auto&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obstacles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DrawRectangleRec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RED&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;DrawText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;TextFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Score: %d&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gameOver&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;DrawText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;GAME OVER! Tap to restart&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MAROON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Press back again to exit&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textWidth&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MeasureText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;DrawText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;screenW&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;textWidth&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;screenH&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;420&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;BLACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

        &lt;span class=&quot;n&quot;&gt;EndDrawing&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;CloseWindow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// extern &quot;C&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;  &lt;/div&gt;

&lt;/details&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;As you can see, most of the game logic remains unchanged. Let’s highlight the important changes for Android:&lt;/p&gt;

&lt;p&gt;Instead of checking for spacebar presses, we use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetTouchPointCount()&lt;/code&gt; to detect screen touches:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GetTouchPointCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;y&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;height&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;groundY&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;vy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jumpImpulse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Android users expect the back button to work, but we don’t want accidental exits. We implement a double-press mechanism:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;IsKeyPressed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KEY_BACK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// Exit game&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;backPressedOnce&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;backPressTime&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.0&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using this code, the game should be fully functional on Android devices. Next, we need to set up Conan to manage our Raylib dependency.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;configuring-conan-for-android&quot;&gt;Configuring Conan for Android&lt;/h2&gt;

&lt;p&gt;As we did in the previous post, we will use Conan to handle the Raylib dependency. However, since we are targeting Android, we will consider this example as a cross-compilation scenario. Now we need to set up a Conan profile for Android and adjust our build process accordingly.&lt;/p&gt;

&lt;h3 id=&quot;prepare-a-conan-file-with-raylib-as-a-dependency&quot;&gt;Prepare a Conan File with Raylib as a Dependency&lt;/h3&gt;

&lt;p&gt;Create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanfile.txt&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpp&lt;/code&gt; folder with the Raylib dependency. It did not change from the previous example:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[requires]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;raylib/5.0&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[generators]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;CMakeToolchain&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;CMakeDeps&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[layout]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;cmake_layout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;set-up-the-android-profile&quot;&gt;Set Up the Android Profile&lt;/h3&gt;

&lt;p&gt;To be able to build for Android, we will be using a &lt;a href=&quot;https://docs.conan.io/2/reference/config_files/profiles.html&quot;&gt;Conan profile&lt;/a&gt; to define the cross-compilation settings. Create a file called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android&lt;/code&gt; with the following content:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# &amp;lt;conan_home&amp;gt;/profiles/android
&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;[settings]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;armv8&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;build_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Release&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Android&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;os.api_level&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;27&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;clang&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler.version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;18&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler.libcxx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;c++_static&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler.cppstd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;17&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[conf]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;tools.android:&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;ndk_path&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;lt;/path/to/your/system/ndk&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s important to match the listed settings with the configuration you selected when creating the Android project:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;os.api_level&lt;/code&gt;: Match the Minimum SDK you selected in the wizard;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compiler.version&lt;/code&gt;: Check your Clang version installed in your NDK (usually in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;sdk_path&amp;gt;/ndk/&amp;lt;version&amp;gt;/toolchains/llvm/prebuilt/&amp;lt;tripet&amp;gt;/bin/&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compiler.cppstd&lt;/code&gt;: Match the C++ standard you selected (17 in our case)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tools.android:ndk_path&lt;/code&gt;: Point to your Android NDK installation (usually in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;sdk_path&amp;gt;/ndk/&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Alternatively, you can use the Conan NDK package from Conan Center to manage the NDK installation instead of manually setting the path.
In that case, your profile would look like this:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[tool_requires]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;*:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;android-ndk/r27&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;automate-conan-installation&quot;&gt;Automate Conan Installation&lt;/h3&gt;

&lt;p&gt;Instead of manually running &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan install&lt;/code&gt; every time we build the project, we can automate this process by adding a custom Gradle task.
As a result, every time we build the project using the IDE, Conan will ensure that the dependencies are installed for all architectures.&lt;/p&gt;

&lt;p&gt;Open the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.gradle&lt;/code&gt; file in your app module and add the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanInstall&lt;/code&gt; task after the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;plugins&lt;/code&gt; block:&lt;/p&gt;

&lt;div class=&quot;language-gradle highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;plugins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;task&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conanInstall&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conanExecutable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;conan&quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// define the path to your conan installation&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buildDir&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;app/build&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;buildDir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mkdirs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Debug&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Release&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;build_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;armv8&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;conanExecutable&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot; install &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
                      &lt;span class=&quot;s2&quot;&gt;&quot;../src/main/cpp --profile android -s build_type=&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;build_type&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; -s arch=&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
                      &lt;span class=&quot;s2&quot;&gt;&quot; --build missing -c tools.cmake.cmake_layout:build_folder_vars=[&apos;settings.arch&apos;]&quot;&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&amp;gt;&amp;gt; ${cmd} \n&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

            &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sout&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serr&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;StringBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cmd&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;execute&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buildDir&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;consumeProcessOutput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sout&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;serr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;waitFor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;$sout $serr&quot;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;proc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;exitValue&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;out&amp;gt; $sout err&amp;gt; $serr&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;\nCommand: ${cmd}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;android&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// ... rest of your android configuration&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This task will automatically run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan install&lt;/code&gt; for all listed build configurations before building your app.
The current example only includes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;armv8&lt;/code&gt;, but you can add more architectures like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;armv7&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt; as needed.
In case your Conan client is not in your system PATH, make sure to provide the full path to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan&lt;/code&gt; executable in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanExecutable&lt;/code&gt; variable.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;configuring-cmake&quot;&gt;Configuring CMake&lt;/h2&gt;

&lt;p&gt;Now that Conan is set up to install Raylib for Android, we need to configure CMake to use the Conan generated toolchain and dependency files.&lt;/p&gt;

&lt;p&gt;In order to use the correct architecture, we will create a small CMake wrapper that selects the appropriate one based on the Android ABI being built.
Create a file called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan_android_toolchain.cmake&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpp&lt;/code&gt; folder:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; NOT ANDROID_ABI OR NOT CMAKE_BUILD_TYPE &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;return&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ANDROID_ABI&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; STREQUAL &lt;span class=&quot;s2&quot;&gt;&quot;x86_64&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_CURRENT_LIST_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/build/x86_64/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/generators/conan_toolchain.cmake&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;elseif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ANDROID_ABI&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; STREQUAL &lt;span class=&quot;s2&quot;&gt;&quot;x86&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_CURRENT_LIST_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/build/x86/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/generators/conan_toolchain.cmake&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;elseif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ANDROID_ABI&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; STREQUAL &lt;span class=&quot;s2&quot;&gt;&quot;arm64-v8a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_CURRENT_LIST_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/build/armv8/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/generators/conan_toolchain.cmake&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;elseif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ANDROID_ABI&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; STREQUAL &lt;span class=&quot;s2&quot;&gt;&quot;armeabi-v7a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_CURRENT_LIST_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/build/armv7/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/generators/conan_toolchain.cmake&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;FATAL_ERROR &lt;span class=&quot;s2&quot;&gt;&quot;Not supported configuration: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ANDROID_ABI&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;endif&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The expected file path structure is based on the Conan CMake layout.
This wrapper will be later referenced in our Gradle configuration to ensure the correct toolchain is used during the build.&lt;/p&gt;

&lt;h3 id=&quot;update-cmakeliststxt&quot;&gt;Update CMakeLists.txt&lt;/h3&gt;

&lt;p&gt;The folder &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpp&lt;/code&gt; contains a default &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; file generated by Android Studio.
We need to modify it to link against Raylib and use the Conan toolchain.
To do this, replace the contents of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMakeLists.txt&lt;/code&gt; in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpp&lt;/code&gt; folder:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cmake_minimum_required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;VERSION 3.22.1&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;raylibexample&quot;&lt;/span&gt; LANGUAGES C CXX&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;NATIVE_APP_GLUE_DIR &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;ANDROID_NDK&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/sources/android/native_app_glue&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;find_package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;raylib CONFIG REQUIRED&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;add_library&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; SHARED&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;target_sources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; PRIVATE
    &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;NATIVE_APP_GLUE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;/android_native_app_glue.c
    native-lib.cpp&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;target_include_directories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; PRIVATE
    &lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;NATIVE_APP_GLUE_DIR&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;CMAKE_PROJECT_NAME&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt; PRIVATE
    android
    log
    EGL
    GLESv2
    OpenSLES
    m
    raylib&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This CMake file has been updated in order to work for our scenario, and may have some differences compared to a regular desktop CMakeLists.txt:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;We include &lt;a href=&quot;https://developer.android.com/reference/games/game-activity/group/android-native-app-glue&quot;&gt;native_app_glue&lt;/a&gt; from the NDK to handle Android app lifecycle events. Without this, our app would not respond correctly to system events.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;We link against Android specific libraries like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;log&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EGL&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GLESv2&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;OpenSLES&lt;/code&gt; which are required for graphics and audio on Android. These libraries are provided by the NDK itself.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The Raylib Conan package is found using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find_package(raylib CONFIG REQUIRED)&lt;/code&gt;, which relies on the &lt;a href=&quot;https://docs.conan.io/2/reference/tools/cmake/cmakedeps.html&quot;&gt;Conan CMakeDeps generator&lt;/a&gt; to provide the necessary configuration files. The Raylib project project the CMake target &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;raylib&lt;/code&gt; that we link against.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;configure-the-toolchain-in-gradle&quot;&gt;Configure the Toolchain in Gradle&lt;/h3&gt;

&lt;p&gt;Now it’s time to tell Gradle to use our &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan_android_toolchain.cmake&lt;/code&gt; file during the CMake build process.
In your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.gradle&lt;/code&gt;, add the CMake toolchain file path in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;android.defaultConfig.externalNativeBuild.cmake:arguments&lt;/code&gt; section:&lt;/p&gt;

&lt;div class=&quot;language-gradle highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;android&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;externalNativeBuild&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cmake&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;arguments&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;-DCMAKE_TOOLCHAIN_FILE=conan_android_toolchain.cmake&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;building-and-running&quot;&gt;Building and Running&lt;/h2&gt;

&lt;p&gt;Now that everything is set up, it’s time to build and run our Raylib game on Android!&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Click &lt;strong&gt;Build -&amp;gt; Assemble ‘app’ Run Configuration&lt;/strong&gt; in Android Studio&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;You’ll see Conan installing Raylib for all listed architectures. This may take a few minutes the first time.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Once complete, CMake will build your native shared library&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, you can run the app on an Android device or emulator:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Connect an Android device or start an emulator&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Click the &lt;strong&gt;Run -&amp;gt; Run ‘app’&lt;/strong&gt; button on Android Studio.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Your game should launch on the device! Use touch to make the rectangle jump over obstacles.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;troubleshooting&quot;&gt;Troubleshooting&lt;/h2&gt;

&lt;p&gt;Besides the usual Android development issues, here are some common pitfalls specific to this setup:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can Not Install The Example App&lt;/strong&gt;: Make sure you have enabled &lt;a href=&quot;https://developer.android.com/studio/debug/dev-options&quot;&gt;Developer Options&lt;/a&gt; and &lt;a href=&quot;https://developer.android.com/studio/debug/dev-options#Enable-debugging&quot;&gt;USB Debugging&lt;/a&gt; on your Android device. Those settings are required to install and run apps from Android Studio.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NDK Not Found&lt;/strong&gt;: Make sure the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tools.android:ndk_path&lt;/code&gt; in your profile points to the correct NDK installation. You can find SDK at Android Studio under &lt;strong&gt;Tools -&amp;gt; SDK Manager -&amp;gt; Android SDK Location&lt;/strong&gt;, that path usually contains the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ndk&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conan Install Fails&lt;/strong&gt;: Verify your profile settings match your project configuration (API level, C++ standard, compiler version).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Build Errors&lt;/strong&gt;: Check that the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan_android_toolchain.cmake&lt;/code&gt; file is in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cpp&lt;/code&gt; folder and that the path in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build.gradle&lt;/code&gt; is correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Touch Not Working&lt;/strong&gt;: Make sure you’re testing on a device or emulator with touch support. The emulator’s mouse clicks should register as touches.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Congratulations! You’ve successfully ported a Raylib game to Android using Android Studio and Conan.
This workflow makes it easy to manage C++ dependencies and build cross-platform games.
The combination of Raylib, Conan, and Android Studio gives you everything you need to create mobile games.&lt;/p&gt;

&lt;p&gt;Happy mobile game development! 🎮📱&lt;/p&gt;
</description>
        <pubDate>Wed, 10 Dec 2025 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/cpp/gamedev/android/conan/raylib/2025/12/10/GameDev-Raylib-Android.html</link>
        <guid isPermaLink="true">https://blog.conan.io/cpp/gamedev/android/conan/raylib/2025/12/10/GameDev-Raylib-Android.html</guid>
        
        
        <category>cpp</category>
        
        <category>gamedev</category>
        
        <category>android</category>
        
        <category>conan</category>
        
        <category>raylib</category>
        
      </item>
    
      <item>
        <title>From Zero to Package in Seconds: the new Conan MCP Server</title>
        <description>&lt;p&gt;MCP (Model Context Protocol) is an &lt;a href=&quot;https://modelcontextprotocol.io/docs/getting-started/intro&quot;&gt;open-source standard&lt;/a&gt; that allows language models and AI applications like ChatGPT, 
Claude, or Grok to connect with other systems, enabling them to access data sources such as local files or databases, 
workflows like specific prompts, and tools, such as, in our case, the Conan client.&lt;/p&gt;

&lt;h2 id=&quot;why-should-i-use-it&quot;&gt;Why should I use it?&lt;/h2&gt;
&lt;p&gt;The Conan MCP Server offers several compelling advantages, particularly for developers working 
with C and C++ dependencies and AI development tools:&lt;/p&gt;

&lt;h3 id=&quot;enhanced-automation-and-efficiency&quot;&gt;Enhanced Automation and Efficiency&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Easier Packaging Workflow&lt;/strong&gt;: The MCP server allows the language model to run Conan commands directly. This makes it 
possible to generate the basic structure of a C++ project, add dependencies in natural language, and prepare the project by 
installing the Conan dependencies it needs.
It can also run security scans on your dependencies and list their declared licenses. All of this happens through simple natural 
language prompts, using your preferred LLM.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Reduced Context Switching&lt;/strong&gt;: Developers no longer need to jump between their development environment, command line, 
and documentation to manage dependencies. The AI acts as an intelligent intermediary, handling complex Conan tasks 
in the background.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;easy-dependency-management-and-auditing&quot;&gt;Easy Dependency Management and Auditing&lt;/h3&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Natural Language Package Search&lt;/strong&gt;: Thanks to the Conan MCP Server, you can search for the exact package you need from your 
remotes by specifying the operating system, architecture, compiled binary options, or even complex version range 
filters, all without resorting to command line syntax.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Simplified Dependency Definition&lt;/strong&gt;: Leveraging the power of natural language processing through MCP, developers can 
define their required C/C++ dependencies without needing to memorize specific Conan syntax for creating recipe files.
For instance, a simple request like “I need the latest version of Boost for my project, 
compiled with C++17 support” is translated by the AI agent into the necessary Conan commands and configuration.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Proactive Auditing and Security&lt;/strong&gt;: The AI agent can proactively audit dependencies as they are installed, automatically
checking for known vulnerabilities (CVEs) and verifying license compliance against project policies, giving immediate 
feedback in natural language.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;lets-dive-into-real-examples&quot;&gt;Let’s dive into real examples&lt;/h2&gt;
&lt;h3 id=&quot;bootstrapping-new-conan-projects&quot;&gt;Bootstrapping new Conan projects&lt;/h3&gt;
&lt;p&gt;Let’s move on to one of the highlights of the MCP server: initial project setup using prompts. Suppose we want to start a project of a library 
that uses CMake, with dependencies on fmt and OpenSSL. We can let Conan MCP create the entire project scaffolding and 
install the dependencies.&lt;/p&gt;
&lt;div style=&quot;background-color: #f5f5f5; border-left: 4px solid #007bff; padding: 15px 20px; margin: 20px 0; border-radius: 4px; font-style: italic; color: #333;&quot;&gt;
  &quot;Create a project for a CMake library using Conan, with dependencies on the latest versions of fmt and OpenSSL. Install the dependencies of the project.&quot;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-04/gif3-Create-project-x6.gif&quot; alt=&quot;Create project gif example&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;auditing-project-and-checking-licenses&quot;&gt;Auditing project and checking licenses&lt;/h3&gt;
&lt;p&gt;One of the most powerful features is how easily the Conan MCP server helps you check vulnerabilities and list dependency licenses. Using the previous 
project as a base, let’s ask the language model to ensure that the resolved versions have no vulnerabilities and that 
all the licenses used by our dependencies are suitable for commercial use.&lt;/p&gt;
&lt;div style=&quot;background-color: #f5f5f5; border-left: 4px solid #007bff; padding: 15px 20px; margin: 20px 0; border-radius: 4px; font-style: italic; color: #333;&quot;&gt;
  &quot;Ensure my project&apos;s third-party libraries are secure and licensed for commercial use.&quot;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-04/gif4-Verify-x10.gif&quot; alt=&quot;Verify project gif example&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;listing-packages&quot;&gt;Listing packages&lt;/h3&gt;
&lt;p&gt;Let’s see a simpler one: we’re going to try to search for the compiled packages on ConanCenter for a library, 
such as zlib, with some options, including the architecture being arm and the shared option set to false, and have it tell 
us which versions we have packages for.&lt;/p&gt;
&lt;div style=&quot;background-color: #f5f5f5; border-left: 4px solid #007bff; padding: 15px 20px; margin: 20px 0; border-radius: 4px; font-style: italic; color: #333;&quot;&gt;
  &quot;Tell me which versions of zlib packages are available with armv8 architecture and statically linked&quot;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-04/gif1-List-versions-x6.gif&quot; alt=&quot;List versions gif example&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;h3 id=&quot;manage-existing-profiles&quot;&gt;Manage existing profiles&lt;/h3&gt;
&lt;p&gt;The Conan MCP Server can also access the list of profiles and is able to query it, so that, for example, if you want to check which 
C++ version my Windows profile with MSVC 193 is configured for, you can simply ask:&lt;/p&gt;
&lt;div style=&quot;background-color: #f5f5f5; border-left: 4px solid #007bff; padding: 15px 20px; margin: 20px 0; border-radius: 4px; font-style: italic; color: #333;&quot;&gt;
  &quot;Check my Conan profiles and tell me which cppstd is configured in the Windows profile that uses compiler version 193.&quot;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-12-04/gif2-profile-x6.gif&quot; alt=&quot;Search profile gif example&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;
It will list the profiles using a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan profile list&lt;/code&gt; command and then use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan profile show&lt;/code&gt; with the selected profile 
to obtain the required information. For this type of functionality to work correctly, we recommend maintaining a proper 
order when naming your Conan profiles.&lt;/p&gt;

&lt;h2 id=&quot;installing-the-conan-mcp-server&quot;&gt;Installing the Conan MCP Server&lt;/h2&gt;
&lt;p&gt;To install the Conan MCP Server, the first thing you need is an MCP client. You can use for example LibreChat or 
Cursor. Then, simply add to your MCP configuration.
This assumes you have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uv&lt;/code&gt; installed on your machine. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uv&lt;/code&gt; has become a common way to run MCP servers. You can find installation instructions here: &lt;a href=&quot;https://docs.astral.sh/uv/getting-started/installation/&quot;&gt;uv installation guide&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;s2&quot;&gt;&quot;mcpServers&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;conan&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;s2&quot;&gt;&quot;command&quot;&lt;/span&gt;: &lt;span class=&quot;s2&quot;&gt;&quot;uvx&quot;&lt;/span&gt;,
      &lt;span class=&quot;s2&quot;&gt;&quot;args&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;conan-mcp&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;what-is-next&quot;&gt;What is next?&lt;/h2&gt;
&lt;p&gt;The Conan MCP Server is still in an early stage, with a strong focus on the most critical developer workflows, and we are gradually
expanding support for more Conan features. We would love to hear your feedback about what you are missing or which 
workflows you would like to see supported next.&lt;/p&gt;

&lt;p&gt;We have prioritized the features most critical for the developer workflow: powerful &lt;strong&gt;package search&lt;/strong&gt; and filtering, 
seamless &lt;strong&gt;project creation&lt;/strong&gt; and dependency installation, profile checking, and the most essential: &lt;strong&gt;vulnerability 
scanning and license listing&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We would love to hear your ideas. Feel free to share your thoughts in our &lt;a href=&quot;https://github.com/conan-io/conan-mcp&quot;&gt;repository&lt;/a&gt;!
If you have any suggestions for new features you would like to see addressed by the Conan MCP Server, or even if you wish to 
contribute code to the project, don’t hesitate to do so! 
Your feedback and contributions are invaluable in shaping the future of this tool.&lt;/p&gt;

&lt;p&gt;Happy prompting with the Conan MCP Server!&lt;/p&gt;

</description>
        <pubDate>Thu, 04 Dec 2025 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/mcp/ai/gpt/conan/conan-mcp/2025/12/04/From-Zero-to-Package-in-Seconds-the-new-Conan-MCP.html</link>
        <guid isPermaLink="true">https://blog.conan.io/mcp/ai/gpt/conan/conan-mcp/2025/12/04/From-Zero-to-Package-in-Seconds-the-new-Conan-MCP.html</guid>
        
        
        <category>MCP</category>
        
        <category>AI</category>
        
        <category>GPT</category>
        
        <category>conan</category>
        
        <category>conan-mcp</category>
        
      </item>
    
      <item>
        <title>How to Use Compiler Sanitizers in Your Conan C/C++ Workflow</title>
        <description>&lt;p&gt;Modern C and C++ projects may grow fast, and be developed in parallel. Keeping them correct and safe is a huge challenge
when releasing to production and serving several users.&lt;/p&gt;

&lt;p&gt;In order to enlighten the dark corners of undefined behavior, memory corruption, and data races, compiler sanitizers are invaluable tools, but they can also introduce complexity and confusion if not managed properly.&lt;/p&gt;

&lt;p&gt;Using Conan to manage your C/C++ dependencies and builds can help in terms of consistency and reproducibility, and integrating sanitizers into a Conan workflow can be straightforward and effective.&lt;/p&gt;

&lt;p&gt;Let’s explore how to do this effectively, traceably, and safely.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;tldr---key-takeaways&quot;&gt;TL;DR - Key Takeaways&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Sanitizers are runtime tools&lt;/strong&gt; that detect memory errors, undefined behavior, and data races in C/C++ code&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Start with ASan + UBSan&lt;/strong&gt; for general debugging; use TSan for threading issues, MSan for uninitialized memory&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Model sanitizers as Conan settings&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compiler.sanitizer&lt;/code&gt;) to ensure ABI compatibility across your dependency graph&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Use Conan profiles&lt;/strong&gt; to configure sanitizer flags and environment variables in one place&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Expect performance overhead:&lt;/strong&gt; ASan adds ~2-3x slowdown, TSan ~5-15x, MSan ~3x&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Never ship sanitized builds to production&lt;/strong&gt; - they’re for development and testing only&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Build all dependencies with sanitizers&lt;/strong&gt; when using MSan to avoid false positives&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;what-are-compiler-sanitizers-and-why-should-you-care&quot;&gt;What Are Compiler Sanitizers (and Why Should You Care)?&lt;/h2&gt;

&lt;p&gt;Compiler sanitizers are runtime instrumentation tools built into your toolchain. These checks, along with a special runtime library, can detect many common programming mistakes such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Buffer overflows:&lt;/strong&gt; When a program tries to write data beyond the allocated space in memory.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Use-after-free:&lt;/strong&gt; When a program tries to use memory that has already been released.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Data races:&lt;/strong&gt; When multiple parts of a program try to access and modify the same data at the same time, leading to unpredictable results.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Memory leaks:&lt;/strong&gt; When a program allocates memory but fails to free it, leading to a gradual consumption of available memory.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Undefined behavior:&lt;/strong&gt; When a program performs an operation that the C++ standard doesn’t define, which can lead to unexpected and often buggy behavior.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nowadays, most compilers support a suite of sanitizers that can be enabled via simple command-line flags. The most commonly used sanitizers include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;AddressSanitizer (ASan):&lt;/strong&gt; Detects memory errors such as buffer overflows and use-after-free.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;UndefinedBehaviorSanitizer (UBSan):&lt;/strong&gt; Catches undefined behavior like integer overflows and invalid casts.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ThreadSanitizer (TSan):&lt;/strong&gt; Identifies data races in multithreaded programs.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;MemorySanitizer (MSan):&lt;/strong&gt; Detects uninitialized memory reads.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;LeakSanitizer (LSan):&lt;/strong&gt; Finds memory leaks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You don’t have to use every sanitizer at once. Here’s a quick decision guide:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;If you’re &lt;strong&gt;starting from zero:&lt;/strong&gt; Use &lt;strong&gt;ASan + UBSan&lt;/strong&gt; as a baseline.&lt;/li&gt;
  &lt;li&gt;If you suspect &lt;strong&gt;race conditions:&lt;/strong&gt; Use &lt;strong&gt;TSan&lt;/strong&gt;.&lt;/li&gt;
  &lt;li&gt;If you suspect &lt;strong&gt;uninitialized memory:&lt;/strong&gt; Use &lt;strong&gt;MSan&lt;/strong&gt;, consider rebuilding everything with it to avoid false positives.&lt;/li&gt;
  &lt;li&gt;If you want &lt;strong&gt;leak checks:&lt;/strong&gt; Use &lt;strong&gt;LSan&lt;/strong&gt;, but is usually bundled with ASan.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under the hood, sanitizers rewrite your code to insert checks, like replacing memory access instructions with instrumented versions that validate the access. When an error is detected, the sanitizer runtime reports it, often with a stack trace and detailed information about the violation.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;⚠️ &lt;strong&gt;Warning:&lt;/strong&gt; Do &lt;strong&gt;NOT&lt;/strong&gt; use sanitizer builds for production binaries, especially ones with elevated privileges (e.g., SUID). Sanitizer runtimes rely on environment variables and can enable privilege escalation. Use them for development and testing only.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As very basic illustration, compiling with ASan on GCC/Clang looks like this:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;g++ &lt;span class=&quot;nt&quot;&gt;-fsanitize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;address &lt;span class=&quot;nt&quot;&gt;-g&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; my_sanitized_program my_program.cpp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As a side note, MSVC also supports AddressSanitizer on x86, x64 and ARM64 with a similar flag: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/fsanitize=address&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also, sanitizers introduce runtime overhead, with typical slowdowns ranging from minimal for LSan and UBSan (~1.2x) to significant for TSan (5-15x), while ASan offers a good balance at 2-3x slowdown and memory overhead. MSan also results about a 3x slowdown and minimal memory overhead but requires a full rebuild of dependencies. Note that all these performance figures are approximate, varying with code patterns.&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;abi-compatibility-and-the-dependency-graph&quot;&gt;ABI Compatibility and the Dependency Graph&lt;/h3&gt;

&lt;p&gt;Sanitizers don’t just add a couple of checks in your binaries; they can change several aspects of your program’s behavior and ABI.
As a result, when using sanitizers, you need to be aware of how they affect your entire dependency graph to avoid issues like crashes or false positives/negatives. Some of the aspects that sanitizers can affect include: memory layout, function behavior, and ABI.&lt;/p&gt;

&lt;p&gt;In some cases, non-instrumented code may not interoperate correctly with instrumented code (e.g. MemorySanitizer), but in some other cases (e.g. AddressSanitizer) it might work enough for basic functionality.&lt;/p&gt;

&lt;p&gt;Also, some sanitizers can be combined (e.g. ASan + UBSan), while others cannot (e.g. ASan + MSan). For example, AddressSanitizer and MemorySanitizer are incompatible because they both modify memory access behavior in conflicting ways. The compiler will usually emit an error if you try to combine incompatible sanitizers.&lt;/p&gt;

&lt;p&gt;Here’s a compatibility matrix for common sanitizer combinations:&lt;/p&gt;

&lt;div class=&quot;table-responsive&quot;&gt;
  &lt;table class=&quot;table table-bordered table-striped table-hover mb-3 align-middle border-top&quot;&gt;
    &lt;thead class=&quot;table-light&quot;&gt;
      &lt;tr&gt;
        &lt;th scope=&quot;col&quot; class=&quot;fw-semibold text-nowrap&quot;&gt;Combination&lt;/th&gt;
        &lt;th scope=&quot;col&quot; class=&quot;fw-semibold text-nowrap&quot;&gt;Compatible?&lt;/th&gt;
        &lt;th scope=&quot;col&quot; class=&quot;fw-semibold&quot;&gt;Notes&lt;/th&gt;
      &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
      &lt;tr&gt;
        &lt;td&gt;ASan + UBSan&lt;/td&gt;
        &lt;td&gt;Yes&lt;/td&gt;
        &lt;td&gt;Recommended baseline combination&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;ASan + LSan&lt;/td&gt;
        &lt;td&gt;Yes&lt;/td&gt;
        &lt;td&gt;LSan is typically included with ASan&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;TSan + UBSan&lt;/td&gt;
        &lt;td&gt;Yes&lt;/td&gt;
        &lt;td&gt;Good for multithreaded code&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;ASan + TSan&lt;/td&gt;
        &lt;td&gt;No&lt;/td&gt;
        &lt;td&gt;Conflicting memory instrumentation&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;ASan + MSan&lt;/td&gt;
        &lt;td&gt;No&lt;/td&gt;
        &lt;td&gt;Conflicting memory tracking&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
        &lt;td&gt;TSan + MSan&lt;/td&gt;
        &lt;td&gt;No&lt;/td&gt;
        &lt;td&gt;Incompatible runtime requirements&lt;/td&gt;
      &lt;/tr&gt;
    &lt;/tbody&gt;
  &lt;/table&gt;
&lt;/div&gt;

&lt;p&gt;As a result, the produced binaries have a different ABI and behavior depending on the sanitizer configuration used during compilation.&lt;/p&gt;

&lt;p&gt;When using Conan to manage your C/C++ projects, it is crucial to ensure that all dependencies are mapped to ensure ABI compatibility across the entire dependency graph. This means that if you are building your main application with a specific sanitizer configuration, all its dependencies must also be built with a compatible configuration to avoid runtime issues.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;model-sanitizers-as-conan-settings-so-conan-can-track-them&quot;&gt;Model Sanitizers as Conan Settings (So Conan Can Track Them)&lt;/h2&gt;

&lt;p&gt;Conan generates unique &lt;a href=&quot;https://docs.conan.io/2/reference/binary_model/package_id.html&quot;&gt;package ID&lt;/a&gt; for each combination of settings, options and dependencies. If we want “Debug + ASan” to be a different binary than “Debug + no sanitizer”, we should make sanitizers part of the settings.&lt;/p&gt;

&lt;p&gt;Instead of modifying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;settings.yml&lt;/code&gt;, you can define custom sub‑settings in your own &lt;a href=&quot;https://docs.conan.io/2/examples/config_files/settings/settings_user.html&quot;&gt;settings_user.yml&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# settings_user.yml&lt;/span&gt;

&lt;span class=&quot;na&quot;&gt;compiler&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
 &lt;span class=&quot;na&quot;&gt;clang&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;na&quot;&gt;sanitizer&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Leak&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Memory&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UndefinedBehavior&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
               &lt;span class=&quot;nv&quot;&gt;HardwareAssistanceAddress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;KernelAddress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
               &lt;span class=&quot;nv&quot;&gt;AddressUndefinedBehavior&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ThreadUndefinedBehavior&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
 &lt;span class=&quot;na&quot;&gt;gcc&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;na&quot;&gt;sanitizer&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Leak&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;UndefinedBehavior&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt;
               &lt;span class=&quot;nv&quot;&gt;KernelAddress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;AddressUndefinedBehavior&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;ThreadUndefinedBehavior&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
 &lt;span class=&quot;na&quot;&gt;msvc&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
   &lt;span class=&quot;na&quot;&gt;sanitizer&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;Address&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;KernelAddress&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Conan will now understand &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compiler.sanitizer&lt;/code&gt; as part of the build configuration, but will not configure any flags or behavior by itself.&lt;/p&gt;

&lt;p&gt;Also, in order to combine more than one sanitizer (e.g., ASan + UBSan), we provide combined tags like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AddressUndefinedBehavior&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now, using Conan profiles, you can create configurations that include sanitizers flags and settings. For example, you can have a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcc_asan&lt;/code&gt; profile for GCC Debug + ASan builds:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# gcc_asan
&lt;/span&gt;
&lt;span class=&quot;nn&quot;&gt;[settings]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;x86_64&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Linux&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;build_type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Debug&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;gcc&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler.cppstd&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;gnu20&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler.libcxx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;libstdc++11&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler.version&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;15&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;compiler.sanitizer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Address&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[conf]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;tools.build:cflags+=&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;[&quot;-fsanitize=address&quot;, &quot;-fno-omit-frame-pointer&quot;]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;tools.build:cxxflags+=&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;[&quot;-fsanitize=address&quot;, &quot;-fno-omit-frame-pointer&quot;]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;tools.build:exelinkflags+=&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;[&quot;-fsanitize=address&quot;]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;tools.build:sharedlinkflags+=&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;[&quot;-fsanitize=address&quot;]&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[runenv]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;ASAN_OPTIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;halt_on_error=1:detect_leaks=1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This profile not only sets &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compiler.sanitizer=Address&lt;/code&gt;, but also injects the necessary flags to enable ASan instrumentation during compilation and linking. Additionally, it configures the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ASAN_OPTIONS&lt;/code&gt; environment variable to stop on the first error and enable leak detection at runtime.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;building-and-using-sanitized-packages-with-conan&quot;&gt;Building and Using Sanitized Packages with Conan&lt;/h2&gt;

&lt;p&gt;With the sanitizer profiles defined, building and using sanitized packages becomes a matter of selecting the appropriate profile during the Conan install step. In order to exercise the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcc_asan&lt;/code&gt; profile, let’s visit a &lt;a href=&quot;https://github.com/boostorg/json/issues/1047&quot;&gt;known bug in Boost.JSON 1.86.0&lt;/a&gt; that ASan can catch. The issue was fixed in later versions, but serves as a good example.&lt;/p&gt;

&lt;p&gt;First, create a simple application that uses Boost.JSON and has the buffer overflow bug:&lt;/p&gt;

&lt;div class=&quot;language-cpp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;boost/json/parse_into.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
#include&lt;/span&gt; &lt;span class=&quot;cpf&quot;&gt;&amp;lt;boost/describe/class.hpp&amp;gt;&lt;/span&gt;&lt;span class=&quot;cp&quot;&gt;
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Test&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;BOOST_DESCRIBE_STRUCT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;arr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;Test&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{};&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error_code&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

 &lt;span class=&quot;n&quot;&gt;std&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;R&quot;({&quot;arr&quot;:[977,775500052916,9216,77552916,9216]})&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
 &lt;span class=&quot;n&quot;&gt;boost&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse_into&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ec&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

 &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, let’s add a CMakeLists.txt to build it:&lt;/p&gt;

&lt;div class=&quot;language-cmake highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;cmake_minimum_required&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;VERSION 3.15&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;project&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;BoostJsonAsanExample LANGUAGES CXX&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;find_package&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;Boost REQUIRED COMPONENTS json&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;nb&quot;&gt;add_executable&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;example main.cpp&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;target_link_libraries&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;example PRIVATE Boost::json&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;target_compile_features&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;example PRIVATE cxx_std_11&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conanfile.txt&lt;/code&gt; to declare the dependency:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[requires]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;boost/1.86.0&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[generators]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;CMakeToolchain&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;CMakeDeps&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[layout]&lt;/span&gt;
&lt;span class=&quot;err&quot;&gt;cmake_layout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, with all files in place, let’s install the dependencies, setup the project, and build it:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;conan &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-pr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;gcc_asan &lt;span class=&quot;nt&quot;&gt;-b&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;missing
cmake &lt;span class=&quot;nt&quot;&gt;--preset&lt;/span&gt; conan-debug &lt;span class=&quot;nt&quot;&gt;-DCMAKE_VERBOSE_MAKEFILE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;ON
cmake &lt;span class=&quot;nt&quot;&gt;--build&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--preset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;conan-debug
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-pr=gcc_asan&lt;/code&gt; flag tells Conan to use the ASan profile we defined earlier, ensuring that both our application and its dependencies (Boost.JSON in this case) are built with ASan instrumentation. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-b=missing&lt;/code&gt; flag instructs Conan to build any missing packages from source, which is necessary here to ensure Boost.JSON is built with the correct sanitizer settings. Using Conan to &lt;a href=&quot;https://docs.conan.io/2/examples/tools/cmake/cmake_toolchain/build_project_cmake_presets.html&quot;&gt;build with CMake Presets&lt;/a&gt; requires CMake +3.23, but greatly simplifies the build commands. Also, enabling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CMAKE_VERBOSE_MAKEFILE&lt;/code&gt; helps to see the actual compiler commands being executed, including the sanitizer flags that we expect to see. Those flags are injected by Conan, coming from the CMake toolchain generated from the profile, so we do not need to add them to the CMakeLists.txt either.&lt;/p&gt;

&lt;p&gt;Finally, run the application:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;build/Debug/example
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This example used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Unix Makefiles&lt;/code&gt; generator with CMake, and the output binary is located in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;build/Debug/example&lt;/code&gt; according to the CMake presets layout. But may vary depending on your generator and configuration.&lt;/p&gt;

&lt;p&gt;The test application will run the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;boost::json::parse_into()&lt;/code&gt; function, which will reach a buffer overflow. When running the application, ASan should detect the error and report it:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;=================================================================&lt;/span&gt;
&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;1445592&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;ERROR: AddressSanitizer: stack-buffer-overflow on address 0x6c78e4600038 at pc 0x5eefa6ad15a3 bp 0x7fff46dfd010 sp 0x7fff46dfd008
WRITE of size 8 at 0x6c78e4600038 thread T0
...
Address 0x6c78e4600038 is located &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;stack of thread T0 at offset 56 &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;frame
   &lt;span class=&quot;c&quot;&gt;#0 0x5eefa6aaf037 in main /tmp/tmp.BHxNAL5bpn/main.cpp:14&lt;/span&gt;

 This frame has 6 object&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;s&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:
   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;32, 56&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;object&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;line 16&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &amp;lt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; Memory access at offset 56 overflows this variable
   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;96, 112&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;ec&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;line 17&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;128, 152&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;data&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;line 19&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;192, 208&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;agg.tmp&apos;&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;224, 240&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;ref.tmp&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;line 20&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
   &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;256, 280&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;ref.tmp37&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;line 23&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
HINT: this may be a &lt;span class=&quot;nb&quot;&gt;false &lt;/span&gt;positive &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;your program uses some custom stack unwind mechanism, swapcontext or vfork
     &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;longjmp and C++ exceptions &lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;are&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt; supported&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
SUMMARY: AddressSanitizer: stack-buffer-overflow /home/conan/.conan2/p/b/boost6d3a53bf84abe/p/include/boost/json/detail/parse_into.hpp:567:21 &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;boost::json::detail::converting_handler&amp;lt;boost::json::detail::sequence_conversion_tag, std::__1::array&amp;lt;long, 3ul&amp;gt;, boost::json::detail::converting_handler&amp;lt;boost::json::detail::described_class_conversion_tag, Test, boost::json::detail::into_handler&amp;lt;Test&amp;gt;&amp;gt;&amp;gt;::signal_value&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can see, ASan successfully detected the buffer overflow and provided a detailed report. All of this was achieved seamlessly within the Conan workflow, demonstrating how to effectively build and use sanitized packages. Still, the produced Boost/1.86.0 package will be listed and identified separately thanks to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compiler.sanitizer&lt;/code&gt; setting:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;conan list &lt;span class=&quot;s2&quot;&gt;&quot;boost/1.86.0#latest:*&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-f&lt;/span&gt; compact
Local Cache
 boost/1.86.0
   boost/1.86.0#514cca6b72ee8e0da1318a177e5d6c06%1763450148.1475632 &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;2025-11-18 07:15:48 UTC&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
     boost/1.86.0#514cca6b72ee8e0da1318a177e5d6c06:6db083a153294679253acd9ba3d4af3727bbb6ea
       settings: Linux, x86_64, Debug, clang, gnu17, libc++, Address, 20
       options&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;diff&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;:
       requires: bzip2/1.0.Z, libbacktrace/cci, zlib/1.3.Z
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Fortunately, the Boost/1.87.0 package has that bug fixed, so you can use a newer version to avoid the issue altogether.
To install the latest version of Boost available in Conan Center, just run:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;conan &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; conancenter &lt;span class=&quot;nt&quot;&gt;--requires&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;boost/[*]&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;common-pitfalls-and-practical-tips&quot;&gt;Common Pitfalls and Practical Tips&lt;/h2&gt;

&lt;p&gt;Even with proper configuration, you may encounter some challenges when using sanitizers. Here are solutions to common problems and best practices:&lt;/p&gt;

&lt;h3 id=&quot;third-party-libraries-that-cant-be-rebuilt&quot;&gt;Third-Party Libraries That Can’t Be Rebuilt&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; You depend on a prebuilt binary library that wasn’t compiled with sanitizers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;For ASan/UBSan: This often works fine, though you won’t get error detection in that library&lt;/li&gt;
  &lt;li&gt;For MSan: You &lt;strong&gt;should&lt;/strong&gt; rebuild the library or you’ll get false positives&lt;/li&gt;
  &lt;li&gt;For TSan: Mixed instrumentation can lead to false positives; try to rebuild if possible&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;dealing-with-false-positives&quot;&gt;Dealing with False Positives&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Sanitizers report errors in code you know is correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Use suppression files (see below) to ignore specific known issues&lt;/li&gt;
  &lt;li&gt;For MSan: Ensure &lt;strong&gt;all&lt;/strong&gt; code is instrumented, including system libraries&lt;/li&gt;
  &lt;li&gt;Verify the error isn’t actually a real bug that happens to be “working” by accident&lt;/li&gt;
  &lt;li&gt;In last case, check if there are reports about the issue in the sanitizer’s issue tracker&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;slow-build-times&quot;&gt;Slow Build Times&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Building all dependencies with sanitizers takes too long.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Cache sanitizer-enabled packages in your Conan remote Artifactory repository&lt;/li&gt;
  &lt;li&gt;Use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan install --build=missing&lt;/code&gt; to only rebuild what’s necessary&lt;/li&gt;
  &lt;li&gt;For local development, consider using ASan only on your code and not all dependencies (except for MSan)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;using-suppression-files&quot;&gt;Using Suppression Files&lt;/h3&gt;

&lt;p&gt;Some libraries may trigger false positives with sanitizers. You can create suppression files to ignore specific known issues. For example, for ASan, you can create a file named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;MyASan.supp&lt;/code&gt; with content like:&lt;/p&gt;

&lt;p&gt;Suppress known false positive in some_library for NameOfCFunctionToSuppress method&lt;/p&gt;

&lt;div class=&quot;language-text highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Suppress known false positive in some_library for NameOfCFunctionToSuppress method
interceptor_via_fun:NameOfCFunctionToSuppress
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, set the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ASAN_OPTIONS&lt;/code&gt; environment variable to include the suppression file:&lt;/p&gt;

&lt;div class=&quot;language-ini highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[runenv]&lt;/span&gt;
&lt;span class=&quot;py&quot;&gt;ASAN_OPTIONS&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;suppressions=MyASan.supp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;additional-best-practices&quot;&gt;Additional Best Practices&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Build All Dependencies with Sanitizers When Needed:&lt;/strong&gt; To avoid compatibility issues, ensure that all dependencies are built with the same sanitizer settings. This is most critical when using MemorySanitizer, which requires all code to be instrumented. Use Conan’s –build=missing option to build any missing packages from source with the correct configuration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Debug Builds:&lt;/strong&gt; Sanitizers work best with debug builds, as they provide more information for error reporting. Ensure your Conan settings use build_type=Debug.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;conclusion-sanitizers-without-the-chaos&quot;&gt;Conclusion: Sanitizers Without the Chaos&lt;/h2&gt;

&lt;p&gt;Compiler sanitizers are incredibly powerful, but in a large C/C++ codebase with many dependencies, they can feel intimidating.
Conan helps bring order to that chaos:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;By modeling sanitizers as part of the compiler settings (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;compiler.sanitizer&lt;/code&gt;), Conan can keep sanitized and non‑sanitized binaries cleanly separated.&lt;/li&gt;
  &lt;li&gt;By using profiles, you get all in a single configuration file: settings, flags, and runtime environment.&lt;/li&gt;
  &lt;li&gt;With proper flags, environment configuration, and occasional suppressions, sanitizer runs become a reliable debug tool rather than a wall of noise.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can obtain more information about sanitizers integration with Conan in the official documentation: &lt;a href=&quot;https://docs.conan.io/2/security/sanitizers.html&quot;&gt;C, C++ Compiler Sanitizers&lt;/a&gt;.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;try-it-yourself&quot;&gt;Try It Yourself&lt;/h2&gt;

&lt;p&gt;Ready to add sanitizers to your project? Here’s what to do next:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Create a sanitizer profile&lt;/strong&gt; for your compiler (use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcc_asan&lt;/code&gt; example above as a template)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;settings_user.yml&lt;/code&gt;&lt;/strong&gt; to your Conan configuration with the sanitizer settings&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Start a new Conan project&lt;/strong&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan new cmake_lib&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Build your project and run its tests&lt;/strong&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;conan create . -pr=&amp;lt;your_sanitizer_profile&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can find a complete working example in our &lt;a href=&quot;https://github.com/conan-io/examples2/tree/main/examples/security/sanitizers&quot;&gt;GitHub Examples repository&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;related-resources&quot;&gt;Related Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://docs.conan.io/2/security/sanitizers.html&quot;&gt;Conan Documentation: Sanitizers&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/google/sanitizers/wiki&quot;&gt;Google Sanitizers Wiki&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://clang.llvm.org/docs/index.html&quot;&gt;Clang Sanitizer Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html&quot;&gt;GCC Instrumentation Options&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/cpp/sanitizers/&quot;&gt;Microsoft C/C++ Sanitizers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Happy debugging - and stay safe out there in UndefinedBehavior land.&lt;/p&gt;
</description>
        <pubDate>Tue, 25 Nov 2025 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/sanitizers/toolchain/tools/conan/2025/11/25/How-to-use-sanitizers-in-your-conan-workflow.html</link>
        <guid isPermaLink="true">https://blog.conan.io/sanitizers/toolchain/tools/conan/2025/11/25/How-to-use-sanitizers-in-your-conan-workflow.html</guid>
        
        
        <category>sanitizers</category>
        
        <category>toolchain</category>
        
        <category>tools</category>
        
        <category>conan</category>
        
      </item>
    
      <item>
        <title>Windows ARM64 builds now enabled in Conan Center</title>
        <description>&lt;p&gt;ARM-powered devices continue to gain significant traction across a number of platforms. Last year marked a pivotal 
moment with Microsoft’s release of new Surface products as well as laptops from multiple vendors featuring Snapdragon X 
CPUs. This commitment is further reinforced by Qualcomm’s recent announcement of the Snapdragon X2 Elite, further 
enabling developer workflows on native devices.&lt;/p&gt;

&lt;p&gt;Conan has been platform-agnostic since its inception, already enabling teams to target various operating systems and CPU
architectures using the same recipes and commands (e.g., macOS Apple Silicon, Android, iOS, FreeBSD, …). Windows ARM64 
is no exception.&lt;/p&gt;

&lt;p&gt;But up until now, the conancenter remote lacked binaries for this evergrowing platform, that’s why we’re thrilled to 
announce improved support for Windows ARM64 in Conan Center recipes! We’ve been working 
hard to streamline the development experience for this platform, and the latest improvements are now rolling out.&lt;/p&gt;

&lt;h2 id=&quot;whats-new-and-improved&quot;&gt;What’s New and Improved?&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Native Installer and Self-Contained Executable:&lt;/strong&gt; While Conan is typically installed by developers locally using pip, 
we also provide standalone installers that don’t require a Python distribution. Starting with the 
&lt;strong&gt;Conan 2.21.0 release&lt;/strong&gt;, we are now providing a &lt;a href=&quot;https://github.com/conan-io/conan/releases/download/2.21.0/conan-2.21.0-windows-arm64-installer.exe&quot;&gt;native ARM64 Windows installer&lt;/a&gt; as well as &lt;a href=&quot;https://github.com/conan-io/conan/releases/download/2.21.0/conan-2.21.0-windows-arm64.zip&quot;&gt;a self-contained executable&lt;/a&gt; 
for Conan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validated recipes for native development:&lt;/strong&gt; We understand that a package manager is only as good as the packages it 
provides. We’ve dedicated significant effort to validating a subset of the most popular Conan Center recipes to ensure 
they build and run natively on Windows ARM64. This includes over 350+ recipes in Conan Center (and counting!), including 
the most popular ones such as Boost, OpenCV, Qt, ffmpeg, Protocol buffers, gRPC, and many more!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Improved fallbacks for build tools that don’t yet support ARM64:&lt;/strong&gt; Some recipes require build tools that currently only 
run with x86_64 emulation, like Autotools on msys2 and strawberry perl. We have improved the recipes so that compatible
binaries are transparently fetched from Conan Center without manual tweaks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Availability of Windows ARM64 binaries in Conan Center:&lt;/strong&gt; To further simplify your development workflow, Conan Center 
CI will now actively build and publish Windows ARM64 binaries for already validated recipes. This means that for an ever 
growing list of libraries, you won’t need to build from source on your ARM64 machine if your profile matches the 
available binaries, saving you time and resources. This is an ongoing process and we aim to publish Windows ARM64 
binaries for every recipe that supports it. You can check if binaries are available in the Conan Center package 
explorer, example: &lt;a href=&quot;https://conan.io/center/recipes/fmt&quot;&gt;https://conan.io/center/recipes/fmt&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;your-feedback-fuels-our-progress&quot;&gt;Your Feedback Fuels Our Progress!&lt;/h3&gt;

&lt;p&gt;This is an ongoing effort, and your feedback is invaluable. As you begin to develop on Windows ARM64 with Conan, we 
strongly encourage you to share your experiences, report any issues, and suggest additional recipes you’d like to see 
natively supported. Your contributions help us prioritize and expand our ARM64 coverage, ensuring Conan Center remains 
a powerful resource for all developers.&lt;/p&gt;

&lt;h2 id=&quot;getting-started-with-conan-for-native-arm64-windows-development&quot;&gt;Getting started with Conan for native ARM64 Windows Development&lt;/h2&gt;

&lt;p&gt;To get started with native Windows ARM64 development, you’ll need the right tools. Here’s a quick guide to the essential
components:&lt;/p&gt;

&lt;h3 id=&quot;conan&quot;&gt;Conan&lt;/h3&gt;

&lt;p&gt;Download the latest 
&lt;a href=&quot;https://github.com/conan-io/conan/releases/download/2.21.0/conan-2.21.0-windows-arm64-installer.exe&quot;&gt;installer&lt;/a&gt; 
(does &lt;em&gt;NOT&lt;/em&gt; require a separate Python installation) and follow the instructions in the installation wizard.&lt;/p&gt;

&lt;h3 id=&quot;cmake&quot;&gt;CMake&lt;/h3&gt;

&lt;p&gt;Now you will need CMake, which you can download from the official &lt;a href=&quot;https://cmake.org/download/&quot;&gt;website&lt;/a&gt;. Don’t forget to 
add it to the system PATH.&lt;/p&gt;

&lt;p&gt;The current release at time of writing is 4.1.1 
(download &lt;a href=&quot;https://github.com/Kitware/CMake/releases/download/v4.1.1/cmake-4.1.1-windows-arm64.msi&quot;&gt;installer&lt;/a&gt;).&lt;/p&gt;

&lt;h3 id=&quot;visual-studio&quot;&gt;Visual Studio&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Install Visual Studio 2022 (Version 17.4 or later): This is the first version of Visual Studio that offers native ARM64 
support. You can download it from the official &lt;a href=&quot;https://visualstudio.microsoft.com/downloads/&quot;&gt;Visual Studio website&lt;/a&gt;. 
Please ensure you are using the correct license.&lt;/li&gt;
  &lt;li&gt;Select the “Desktop development with C++” Workload: During the Visual Studio installation process, ensure you select this workload.&lt;/li&gt;
&lt;/ul&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-10-01/visual-studio-desktop-development.png&quot; alt=&quot;conan report diff web interface&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;That’s it! Now let’s get this to work.
In a terminal window, first run the following command:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; conan profile detect&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;The result should be:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;Detected profile:
&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;settings]
&lt;span class=&quot;nb&quot;&gt;arch&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;armv8
&lt;span class=&quot;nv&quot;&gt;build_type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Release
&lt;span class=&quot;nv&quot;&gt;compiler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;msvc
compiler.cppstd&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;17
compiler.runtime&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;dynamic
compiler.version&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;194
&lt;span class=&quot;nv&quot;&gt;os&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;Windows&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;⚠️ Ensure the detected architecture is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arch=armv8&lt;/code&gt;. If you get &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;x86_64&lt;/code&gt;, you may be running a non-native installation of Python or Conan. This will still work, but you will need to modify the generated profile to reflect the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;arm=armv8&lt;/code&gt; architecture.&lt;/p&gt;

&lt;h2 id=&quot;build-a-sample-project&quot;&gt;Build a sample project&lt;/h2&gt;

&lt;p&gt;We can now use Conan as we are already used to natively on any platform. For example one of the toy projects in the 
examples repo:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; git clone https://github.com/conan-io/examples2.git
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;cd &lt;/span&gt;examples2/examples/libraries/raylib/introduction
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; conan &lt;span class=&quot;nb&quot;&gt;install&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;.&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-s&lt;/span&gt; compiler.cppstd&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;17
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; cmake &lt;span class=&quot;nt&quot;&gt;--preset&lt;/span&gt; conan-default
&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; cmake &lt;span class=&quot;nt&quot;&gt;--build&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--preset&lt;/span&gt; conan-release
.&lt;span class=&quot;se&quot;&gt;\b&lt;/span&gt;uild&lt;span class=&quot;se&quot;&gt;\R&lt;/span&gt;elease&lt;span class=&quot;se&quot;&gt;\r&lt;/span&gt;unner_game.exe&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-10-01/raylib-image-example.png&quot; alt=&quot;conan report diff web interface&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Dependencies will be downloaded from Conan Center and the app will build and run natively on Windows ARM64.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;
</description>
        <pubDate>Wed, 01 Oct 2025 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/armv8/arm64/windows/conan/2025/10/01/Windows-arm64-builds-now-enabled-in-Conan-Center.html</link>
        <guid isPermaLink="true">https://blog.conan.io/armv8/arm64/windows/conan/2025/10/01/Windows-arm64-builds-now-enabled-in-Conan-Center.html</guid>
        
        
        <category>armv8</category>
        
        <category>arm64</category>
        
        <category>windows</category>
        
        <category>conan</category>
        
      </item>
    
      <item>
        <title>New Free Hands-On Video Course: Conan 2 Essentials</title>
        <description>&lt;p&gt;After months of dedicated work, we are thrilled to launch the new &lt;a href=&quot;https://academy.jfrog.com/conan-2-essentials&quot;&gt;&lt;strong&gt;Conan 2
Essentials&lt;/strong&gt;&lt;/a&gt; course, which is now
fully available.&lt;/p&gt;

&lt;p&gt;This new course has been created from the ground up to cover the fundamental
features and best practices of &lt;strong&gt;Conan 2&lt;/strong&gt;. It will provide you with the
essential knowledge needed to start working with the tool effectively, whether
you are a new user or migrating from a previous version.&lt;/p&gt;

&lt;h2 id=&quot;a-hands-on-free-and-self-paced-course&quot;&gt;A Hands-On, Free, and Self-Paced Course&lt;/h2&gt;

&lt;p&gt;This course is designed to be a practical learning experience. There’s a
dedicated &lt;a href=&quot;https://github.com/conan-io/conan-training2&quot;&gt;GitHub repository&lt;/a&gt; with
the source code that you will use throughout the lessons to apply the concepts
with &lt;strong&gt;hands-on examples&lt;/strong&gt;, allowing you to experiment firsthand with the
features of Conan 2.&lt;/p&gt;

&lt;p&gt;The course is &lt;strong&gt;completely free&lt;/strong&gt; and available for you to take at your own
pace, with no schedules or deadlines.&lt;/p&gt;

&lt;p style=&quot;text-align: center;&quot;&gt;
  &lt;a href=&quot;https://academy.jfrog.com/conan-2-essentials&quot;&gt;
    &lt;img src=&quot;/assets/post_images/2025-07-14/course-icon.png&quot; width=&quot;80%&quot; alt=&quot;Conan Series on JFrog Academy&quot; /&gt;
  &lt;/a&gt;
&lt;/p&gt;

&lt;h2 id=&quot;what-will-you-learn-in-conan-2-essentials&quot;&gt;What Will You Learn in ‘Conan 2 Essentials’?&lt;/h2&gt;

&lt;p&gt;The course consists of &lt;strong&gt;16 video lessons&lt;/strong&gt;, totaling &lt;strong&gt;over two hours
of content&lt;/strong&gt;. It follows a logical progression, starting with the
most common scenario: &lt;strong&gt;consuming packages&lt;/strong&gt; to build a simple application with
CMake. From there, you’ll explore the basic anatomy of a &lt;strong&gt;conanfile.py&lt;/strong&gt; and
other fundamental topics like &lt;strong&gt;settings,&lt;/strong&gt; &lt;strong&gt;options,&lt;/strong&gt; &lt;strong&gt;profiles,&lt;/strong&gt; Conan’s
&lt;strong&gt;PackageID&lt;/strong&gt; system, and even &lt;strong&gt;cross-compilation&lt;/strong&gt;. The journey then continues into
the core of &lt;strong&gt;package creation&lt;/strong&gt;, where you’ll build your own libraries, &lt;strong&gt;manage
dependencies&lt;/strong&gt;, and finally learn how to &lt;strong&gt;use and upload your packages to an
Artifactory repository&lt;/strong&gt;, giving you enough hands-on experience to startworking
with Conan as part of your daily development process.&lt;/p&gt;

&lt;h2 id=&quot;start-learning-today&quot;&gt;Start Learning Today!&lt;/h2&gt;

&lt;p&gt;Don’t wait any longer to modernize your C++ dependency management skills. The
course is complete and waiting for you.&lt;/p&gt;

&lt;p&gt;➡️ &lt;a href=&quot;https://academy.jfrog.com/conan-2-essentials&quot;&gt;&lt;strong&gt;Register for free for the ‘Conan 2 Essentials’ course on JFrog
Academy&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;whats-next-the-advanced-course-is-on-its-way&quot;&gt;What’s Next? The Advanced Course is on its Way&lt;/h2&gt;

&lt;p&gt;While our focus today is on the “Essentials” course launch, we want to let you
know that we are already working on the next chapter: &lt;strong&gt;Conan 2 Advanced&lt;/strong&gt;. This
course will explore more complex scenarios and advanced features. You will
learn to streamline local development workflows with &lt;strong&gt;editable packages&lt;/strong&gt;, master
&lt;strong&gt;advanced versioning and lockfiles&lt;/strong&gt;, and unlock Conan’s full potential through its
&lt;strong&gt;extensibility and customization features&lt;/strong&gt;. We will be releasing lessons
incrementally over the coming months, aiming to have the full course ready by
the &lt;strong&gt;end of this year&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As always, your feedback is crucial to us. If you have any questions or
suggestions during the course, please don’t hesitate to open an issue in the
&lt;a href=&quot;https://github.com/conan-io/conan-training2&quot;&gt;Conan Training GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We hope you enjoy the new content!&lt;/p&gt;
</description>
        <pubDate>Mon, 14 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/2025/07/14/New-conan2-training-series.html</link>
        <guid isPermaLink="true">https://blog.conan.io/2025/07/14/New-conan2-training-series.html</guid>
        
        
      </item>
    
      <item>
        <title>What&apos;s new in your dependencies? Advanced Recipe and Source Diffing in Conan</title>
        <description>&lt;h2 id=&quot;what-has-changed-in-my-package&quot;&gt;What has changed in my package?&lt;/h2&gt;

&lt;p&gt;In modern software development, &lt;strong&gt;understanding what has changed&lt;/strong&gt; between different versions of 
your dependencies is crucial. However, many real-world workflows often raise questions that 
are not easy to answer:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;What differences exist between the recipe in my &lt;strong&gt;local&lt;/strong&gt; cache and the one published on a &lt;strong&gt;shared remote&lt;/strong&gt;?&lt;/li&gt;
  &lt;li&gt;What has changed in the packaged sources between &lt;strong&gt;two versions&lt;/strong&gt; of a package?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the daily work of development teams, CI/CD pipelines, and repository maintainers, these 
questions typically arise in scenarios such as:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Compliance reviews&lt;/strong&gt;: when it’s necessary to verify what changes have been introduced in a specific 
package and their impact.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Debugging issues&lt;/strong&gt;: when investigating why a binary behaves differently between different versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;why-existing-solutions-fall-short&quot;&gt;Why existing solutions fall short&lt;/h2&gt;

&lt;p&gt;Until now, addressing these problems has usually meant relying on &lt;strong&gt;manual, time-consuming&lt;/strong&gt; processes: 
if you’re lucky and your sources are hosted in a version control repository that provides a &lt;strong&gt;change 
viewer&lt;/strong&gt;, that might help. But what if the library you’re using does not have one? Or worse – what if 
there are so many changes between versions that the tool provided by your version control system can’t 
even load all of them?&lt;/p&gt;

&lt;p&gt;Just as critical, though often overlooked, is the need to inspect &lt;strong&gt;changes in the recipes&lt;/strong&gt; themselves. 
Yet, up until now there’s been no easy way to view changes in both the packaged sources and the 
packaging code side by side. No existing tools offer a unified diff that spans both areas.&lt;/p&gt;

&lt;p&gt;Moreover, there’s the challenge of knowing exactly what changes exist in the version you have on 
your remote. Sometimes &lt;strong&gt;versions get retagged&lt;/strong&gt;, and in those cases, you lose the ability to see 
those changes reliably. Or, if you want to compare the exact differences between two specific 
revisions of your recipes, none of those tools can help you do it accurately.&lt;/p&gt;

&lt;p&gt;This can get even more complicated when &lt;strong&gt;patches&lt;/strong&gt; have been applied to our code, introducing an entirely 
new dimension that also needs to be tracked and verified.&lt;/p&gt;

&lt;p&gt;The process we usually end up following is downloading packages, extracting recipes, sources, and 
patches, applying these patches, and finally using external tools (such as diff or git diff) to 
compare them. This approach not only requires time but also leaves room for &lt;strong&gt;human errors&lt;/strong&gt; and makes 
automation more challenging.&lt;/p&gt;

&lt;h2 id=&quot;a-new-command-to-compare-recipes-and-sources&quot;&gt;A new command to compare recipes and sources&lt;/h2&gt;

&lt;p&gt;To solve this problem, we’ve created a new Conan command, the &lt;strong&gt;conan report diff&lt;/strong&gt; that acts 
like a &lt;em&gt;git diff wrapper&lt;/em&gt;, but for packages and recipes stored in remotes or local caches. 
With this command, you can &lt;strong&gt;compare two recipes with their sources&lt;/strong&gt; (including patches) and see 
exactly what has changed, not only between tagged versions, but even between revisions.&lt;/p&gt;

&lt;p&gt;It’s very simple to use. For example, if we want to check the differences between “zlib/1.3” and
“zlib/1.3.1” and see if there are any changes to the recipe, and the difference between their sources,
we can use the command like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan report diff &lt;span class=&quot;nt&quot;&gt;--old-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3 &lt;span class=&quot;nt&quot;&gt;--new-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3.1&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This command will take the latest revision of each version. If Conan finds the package in the cache, 
it will take that; if not, it will search in all available remotes, or the ones passed using the 
&lt;em&gt;–remote&lt;/em&gt; argument&lt;/p&gt;

&lt;p&gt;If you prefer a fine-grained search, &lt;strong&gt;specifying the revision&lt;/strong&gt;, you can simply add it to the reference 
like this:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan report diff &lt;span class=&quot;nt&quot;&gt;--old-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3 &lt;span class=&quot;nt&quot;&gt;--new-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3.1#b8bc2603263cf7eccbd6e17e66b0ed76&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Another typical case is when we have a new version that we are testing locally, and we need to compare 
these changes. In this case, we can add the path to the new recipe to the command. Here’s an example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan report diff &lt;span class=&quot;nt&quot;&gt;--old-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3 &lt;span class=&quot;nt&quot;&gt;--new-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3.1 &lt;span class=&quot;nt&quot;&gt;--new-path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;path/to/new/recipe&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This can also be done for the old reference if you need to specify its location directly too with the 
&lt;em&gt;–old-path&lt;/em&gt; argument.&lt;/p&gt;

&lt;h2 id=&quot;output-formats&quot;&gt;Output Formats&lt;/h2&gt;

&lt;p&gt;The new command provides three formats for the output, which can be selected using the &lt;em&gt;–format&lt;/em&gt; attribute.&lt;/p&gt;

&lt;p&gt;The first one, &lt;strong&gt;“html”&lt;/strong&gt; format, generates a self-contained &lt;strong&gt;static website&lt;/strong&gt;. In this 
web output, &lt;strong&gt;functionality takes priority&lt;/strong&gt;: it includes a small index listing the changed files, 
a search bar to look for files, and another to exclude files from view.&lt;/p&gt;

&lt;div style=&quot;text-align: center;&quot;&gt;
  &lt;img src=&quot;/assets/post_images/2025-07-07/conan-report-diff-web.png&quot; alt=&quot;conan report diff web interface&quot; /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;Next, we have the &lt;strong&gt;“text”&lt;/strong&gt; format, it is the default format, and it displays the differences in the classic 
&lt;strong&gt;git diff format&lt;/strong&gt;. You can use this to pipe its &lt;strong&gt;output to any diff tool&lt;/strong&gt; of your liking. Here’s an example:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan report diff &lt;span class=&quot;nt&quot;&gt;--old-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3 &lt;span class=&quot;nt&quot;&gt;--new-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3.1

...

diff &lt;span class=&quot;nt&quot;&gt;--git&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml
index 1531782fc4..aee6ff7660 100644
&lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml
+++ &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml
@@ &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;,12 +1,11 @@
 patches:
-  &lt;span class=&quot;s1&quot;&gt;&apos;1.3&apos;&lt;/span&gt;:
-  - patch_description: separate static/shared builds, disable debug suffix, disable
-      building examples
-    patch_file: patches/1.3/0001-fix-cmake.patch
+  1.3.1:
+  - patch_description: separate static/shared builds, disable debug suffix
+    patch_file: patches/1.3.1/0001-fix-cmake.patch
     patch_type: conan
 sources:
-  &lt;span class=&quot;s1&quot;&gt;&apos;1.3&apos;&lt;/span&gt;:
-    sha256: ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e
+  1.3.1:
+    sha256: 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23
     url:
-    - https://zlib.net/fossils/zlib-1.3.tar.gz
-    - https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz
+    - https://zlib.net/fossils/zlib-1.3.1.tar.gz
+    - https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz
diff &lt;span class=&quot;nt&quot;&gt;--git&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt
index 1698be4430..98bd55b280 100644
&lt;span class=&quot;nt&quot;&gt;---&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;==&lt;/span&gt;/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt
+++ &lt;span class=&quot;nv&quot;&gt;emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt
@@ &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;,4 +1,4 @@
 1733936230
&lt;span class=&quot;nt&quot;&gt;-conandata&lt;/span&gt;.yml: f273879c230e45f27a54d0a4676fda02
+conandata.yml: 7388d3b9c983326938e00bcdaadb8533
 conanfile.py: 01438040394b477d740d8c84f58cf682
&lt;span class=&quot;nt&quot;&gt;-export_source&lt;/span&gt;/patches/1.3/0001-fix-cmake.patch: 133be1fe5e1ccd96b8da0f43ef0314f3
+export_source/patches/1.3.1/0001-fix-cmake.patch: 258ad7382f40ea5933cd48a5501f843d

...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Finally, we have the &lt;strong&gt;“json”&lt;/strong&gt; format, which returns the diff in a &lt;strong&gt;simple structured representation&lt;/strong&gt;, 
so that it can be consumed by other scripts. This is perfect if you want to extract the specific diff 
of a file and feed it into some kind of pipeline.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;conan report diff &lt;span class=&quot;nt&quot;&gt;--old-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3 &lt;span class=&quot;nt&quot;&gt;--new-reference&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;zlib/1.3.1 &lt;span class=&quot;nt&quot;&gt;--format&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;json

&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
...
&lt;span class=&quot;s2&quot;&gt;&quot;/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;diff --git emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;index 1531782fc4..aee6ff7660 100644&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;--- emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conandata.yml&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+++ emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conandata.yml&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;@@ -1,12 +1,11 @@&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot; patches:&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-  &apos;1.3&apos;:&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-  - patch_description: separate static/shared builds, disable debug suffix, disable&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-      building examples&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-    patch_file: patches/1.3/0001-fix-cmake.patch&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+  1.3.1:&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+  - patch_description: separate static/shared builds, disable debug suffix&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+    patch_file: patches/1.3.1/0001-fix-cmake.patch&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;     patch_type: conan&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot; sources:&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-  &apos;1.3&apos;:&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-    sha256: ff0ba4c292013dbc27530b3a81e1f9a813cd39de01ca5e0f8bf355702efa593e&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+  1.3.1:&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+    sha256: 9a93b2b7dfdac77ceba5a558a580e74667dd6fede4585b91eefb60f03b72df23&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;     url:&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-    - https://zlib.net/fossils/zlib-1.3.tar.gz&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-    - https://github.com/madler/zlib/releases/download/v1.3/zlib-1.3.tar.gz&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+    - https://zlib.net/fossils/zlib-1.3.1.tar.gz&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+    - https://github.com/madler/zlib/releases/download/v1.3.1/zlib-1.3.1.tar.gz&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
  &lt;span class=&quot;s2&quot;&gt;&quot;/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt&quot;&lt;/span&gt;: &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;diff --git emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;index 1698be4430..98bd55b280 100644&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;--- emxpYi8xLjMuMSNiOGJjMjYwMzI2M2NmN2VjY2JkNmUxN2U2NmIwZWQ3Ng==/Users/ernesto/.conan2/p/zlib7a26308608ec9/e/conanmanifest.txt&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+++ emxpYi8xLjMjYjNiNzFiZmU4ZGQwN2FiYzdiODJmZjJiZDBlYWMwMjE=/Users/ernesto/.conan2/p/zlib204752602052d/e/conanmanifest.txt&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;@@ -1,4 +1,4 @@&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot; 1733936230&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-conandata.yml: f273879c230e45f27a54d0a4676fda02&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+conandata.yml: 7388d3b9c983326938e00bcdaadb8533&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot; conanfile.py: 01438040394b477d740d8c84f58cf682&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;-export_source/patches/1.3/0001-fix-cmake.patch: 133be1fe5e1ccd96b8da0f43ef0314f3&quot;&lt;/span&gt;,
    &lt;span class=&quot;s2&quot;&gt;&quot;+export_source/patches/1.3.1/0001-fix-cmake.patch: 258ad7382f40ea5933cd48a5501f843d&quot;&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;,
...
&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;whats-next&quot;&gt;What’s next&lt;/h2&gt;

&lt;p&gt;We’re excited to share this new feature with the community, but this is just the beginning! We’d love to hear 
how you use &lt;strong&gt;conan report diff&lt;/strong&gt; in your workflows. Your feedback, ideas, and suggestions are key to improving
and shaping the future of this tool.&lt;/p&gt;

&lt;p&gt;You can always &lt;a href=&quot;https://github.com/conan-io/conan/issues&quot;&gt;submit feedback here.&lt;/a&gt;&lt;/p&gt;
</description>
        <pubDate>Mon, 07 Jul 2025 00:00:00 +0000</pubDate>
        <link>https://blog.conan.io/cpp/diff/report/conan/2025/07/07/What-is-in-your-dependencies-updates.html</link>
        <guid isPermaLink="true">https://blog.conan.io/cpp/diff/report/conan/2025/07/07/What-is-in-your-dependencies-updates.html</guid>
        
        
        <category>cpp</category>
        
        <category>diff</category>
        
        <category>report</category>
        
        <category>conan</category>
        
      </item>
    
  </channel>
</rss>
