conan-flake
The conan-flake module bridges the gap between Nix and the Conan C/C++ Package Manager, supporting a declarative configuration style and common development workflows.
For a user profile configuration like the following:
[settings]
build_type=Debug
compiler.cppstd=14
[platform_tool_requires]
cmake/X.Y.Z
There correspond the following options:
{
profiles.default = {
settings.build_type = "Debug";
settings."compiler.cppstd" = "14";
platformToolRequires = {
cmake = pkgs.cmake.version;
};
};
devShell = {
# Programs you want to make available in the shell:
tools = { inherit (pkgs) cmake; };
};
}
The conan-flake module works with plain Nix (no flakes), Nix flakes,
flake-parts, or as a devenv
module.
Where to go next
- Getting started takes an empty directory to a working Conan configuration, using one of the templates.
- flake-parts covers the
flake-partsintegration. - devenv covers the devenv integration, both through devenv’s own
languages.cplusplus.conanoption and with conan-flake used directly as a devenv module. - Standalone covers plain Nix usage, with and without flakes.
- Toolchains covers the LLVM/libc++ and CUDA scenarios.
- The option reference lists
every option of the module, generated from the module itself, along with
initial setup instructions for
flake-partsscenarios.
The source lives at codeberg.org/tarcisio/conan-flake, where issues and pull requests are welcome; see Contributing for the development environment, and the Changelog for the revision history.
Getting started
Every example of this site is a runnable project, collected under examples in the source repository, and each one is also exposed as a flake template. The quickest way from an empty directory to a working Conan configuration is to instantiate one of them:
mkdir -p hello-conan && cd hello-conan
git init
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.devenv-module-recipe
That template is the devenv example featuring a
local-recipe-index remote; it carries a complete C++ project — a
conanfile.py recipe, its sources and a test package — alongside the Conan
configuration itself, which is the devenv.nix shown in the
devenv chapter.
The shell can be activated with direnv:
direnv allow .
It can take a while before completing. After that, the conan command is
available in the path, with the profile and the other Conan settings already in
place, so the Conan package defined by the recipe can be built and tested with a
call to conan create:
conan create . --build=missing
Whose output can be used to validate if the configuration was applied successfully:
hello-world: Hello World Release!
hello-world: __x86_64__ defined
hello-world: _GLIBCXX_USE_CXX11_ABI 1
hello-world: __cplusplus201703
hello-world: __GNUC__15
hello-world: __GNUC_MINOR__2
example/0.0.1 test_package
Warning
Depending when this page is being accessed, the devenv integration may still be pending approval upstream. The devenv samples here can still be tested nonetheless, by overriding devenv itself with the version from our upstream PR. See examples/devenv-module-recipe and devenv.yaml therein for more details. The flake-parts and standalone templates are unaffected.
Working from a clone
It’s also possible to interact directly with the example projects from a clone of this repository:1
git clone ssh://git@codeberg.org/tarcisio/conan-flake.git
cd conan-flake
The example above is on the examples/devenv-module-recipe directory:
cd examples/devenv-module-recipe
direnv allow .
And the same conan create call applies from there.
Where to go next
- The option reference lists
every option of the module, and carries the initial setup instructions for
flake-partsscenarios. - The templates chapter lists the remaining templates, one per integration style.
- The flake-parts, devenv and standalone chapters walk through each of those styles.
-
Or, via https:
↩git clone https://codeberg.org/tarcisio/conan-flake.git cd conan-flake
flake-parts
The flake-parts integration requires conan-flake and
infuse to be added to the flake
inputs:
# file: examples/flake-parts/flake.nix
{
inputs = {
nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling";
flake-parts.url = "github:hercules-ci/flake-parts";
treefmt-nix.url = "github:numtide/treefmt-nix";
# Add these two:
conan-flake.url = "git+https://codeberg.org/tarcisio/conan-flake";
infuse = {
url = "git+https://codeberg.org/amjoseph/infuse.nix?rev=364ea18b5611b5fd6a6acd7151411b430a70e194";
flake = false;
};
};
# ...
}
After importing inputs.conan-flake.flakeModule, it’s possible to use the
options from
perSystem.conan
to configure a suitable Conan profile:
# file: examples/flake-parts/flake.nix
{
# ...
outputs = inputs@{ self, nixpkgs, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = nixpkgs.lib.systems.flakeExposed;
imports = [
inputs.conan-flake.flakeModule # Import this module
inputs.treefmt-nix.flakeModule
];
perSystem = { pkgs, config, ... }: {
# A suitable Conan profile:
conan = {
profiles.default = {
settings.build_type = "Release";
settings."compiler.cppstd" = "23";
};
};
devShells.default = pkgs.mkShell {
inputsFrom = [
# conan-flake computes a devShell that can be used directly or
# appended to the `inputsFrom` option of another devShell as a
# means to compose with other devShell modules:
config.conan.outputs.devShell
config.treefmt.build.devShell
];
packages = [ pkgs.just ];
}; # devShells
treefmt.config = {
projectRoot = self;
projectRootFile = "README.md";
programs = {
cmake-format.enable = true;
};
};
};
};
}
The example above can be found in the examples/flake-parts directory:
cd examples/flake-parts
direnv allow .
It can take a while before completing. After that, the conan command should be
available in the path, and the required profile and other Conan settings already
in place:
conan profile show
A Release, C++23 profile is expected:
Host profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=23
compiler.libcxx=libstdc++11
compiler.version=15.3.0
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
Build profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=23
compiler.libcxx=libstdc++11
compiler.version=15.3.0
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
Note
By default, conan-flake sets both CMake and the configured
stdenv.cccompiler asdevShell.tools. Also, whatever CMake version, if any, ends up being in thedevShell.toolsis also set, by default, as aprofiles.<name>.platformToolRequiresof every profile.
The resulting default devShell defined above is a composition — it
merges config.conan.outputs.devShell and config.treefmt.build.devShell, and
appends pkgs.just to the resulting devShell’s package list for its own
sake:
devShells.default = pkgs.mkShell {
inputsFrom = [
# conan-flake computes a devShell that can be used directly or
# appended to the `inputsFrom` option of another devShell as a
# means to compose with other devShell modules:
config.conan.outputs.devShell
config.treefmt.build.devShell
];
packages = [ pkgs.just ];
}; # devShells
A possible sanity check could be to find the corresponding commands available in the path:
cmake --version
conan --version
treefmt --version
echo
just --version
Also, CMake’s version should match the one listed in the
[platform_tool_requires] section of the conan profile show command’s output
above:
cmake version 4.3.4
CMake suite maintained and supported by Kitware (kitware.com/cmake).
Conan version 2.32.0-dev
treefmt v2.5.0
just 1.57.0
The complete list of the options available under perSystem.conan, along with
the initial setup instructions for flake-parts scenarios, is in the
option reference.
devenv
There are two ways of using conan-flake with devenv: the
languages.cplusplus.conan option, which devenv itself provides and which
carries conan-flake’s own options under languages.cplusplus.conan.config, and
a devenv shell that takes conan-flake’s computed devShell directly.
The languages.cplusplus.conan option
Configure Conan in any devenv shell with the supported integration:
# file: examples/devenv-module-recipe/devenv.nix
languages.cplusplus = {
enable = true;
conan = {
enable = true;
install.enable = true;
config = {
profiles.default = {
settings.build_type = "Release";
settings."compiler.cppstd" = "17";
};
# It's possible to specify Conan remotes explicitly, including
# local-recipe-index remotes, in which case the `url` is taken as a
# relative path to the root of the configuration:
remotes.local = {
url = "./repo";
local = true;
allowedPackages = [
"hello-world/0.0.1.cci.20260428"
];
};
# Enable only local remotes (i.e., only of local-recipe-index type):
offline = true;
};
};
}; # languages.cplusplus
Note
See how to setup Conan in devenv for further details. As can be seen from the above example, the devenv integration automatically takes care of the CMake part by default, and the
profiles.<name>.platformToolRequiresanddevShell.toolsoptions are not required to be set explicitly in thelanguages.cplusplus.conan.confignamespace.
Warning
Depending when this page is being accessed, the devenv integration may still be pending approval upstream and the above links to the devenv docs may be missing. The devenv samples here can still be tested nonetheless, by overriding devenv itself with the version from our upstream PR. See examples/devenv-module-recipe and devenv.yaml therein for more details.
The example above is on the examples/devenv-module-recipe directory, and the Getting started chapter walks through it. A variant without the local-recipe-index remote is on examples/devenv-module; its profile settings, and the Conan profile they produce, are the pair shown on the front page.
A devenv shell taking conan-flake’s devShell
Where devenv shells are declared through
flake-parts, conan-flake can be used without the
languages.cplusplus option at all: importing inputs.conan-flake.flakeModule
next to inputs.devenv.flakeModule makes config.conan.outputs.devShell
available, which composes into a devenv shell the same way it composes into a
pkgs.mkShell:
devenv = {
shells.default = {
name = "conan-flake-dev";
inputsFrom = [
# conan-flake exposes a `configuration` devShell by default that
# can be used directly, or passed in the inputsFrom option as a
# means to compose with other devShell modules.
config.conan.outputs.devShell
];
packages = [ pkgs.just ];
treefmt = {
enable = true;
config = {
programs = {
nixpkgs-fmt.enable = true;
cmake-format.enable = true;
};
};
};
};
}; # devenv
That example is on the
examples/devenv
directory, whose Conan configuration is written with the same
perSystem.conan
options the flake-parts chapter describes:
cd examples/devenv
direnv allow .
Either way, the options being set are conan-flake’s own, and the complete list
of them is in the
option reference — under
perSystem.conan for the flake-parts spelling, and under
languages.cplusplus.conan.config for the devenv one.
Standalone
Although conan-flake is presented as a flake-parts module,
there is a subset of its options that can be imported independently, directly
into any Nix code. This use case is supported by two helper functions, exposed
in the lib namespace of the flake defined by this repository:
evalConanConfig and
submoduleWith.
To use these functions, add conan-flake to your flake inputs:
{
inputs = {
nixpkgs.url = "github:cachix/devenv-nixpkgs/rolling";
# Add this:
conan-flake.url = "git+https://codeberg.org/tarcisio/conan-flake";
};
# ...
}
Now conan-flake.lib.evalConanConfig can be used to configure, for each system
supported, a Conan configuration and output a devShell and a check command.
With this schema in place:
{
# ...
outputs = { self, nixpkgs, conan-flake, ... }:
let
eachSystem = nixpkgs.lib.genAttrs nixpkgs.lib.systems.flakeExposed;
# See below for the actual `perSystem` function definition:
perSystem = system:
let
# ...
configuration = conan-flake.lib.evalConanConfig pkgs (
# ...
);
in
{
devShells = {
# ...
};
checks = {
# ...
};
};
systemOutputs = eachSystem perSystem;
in
{
devShells = nixpkgs.lib.mapAttrs (_: s: s.devShells) systemOutputs;
checks = nixpkgs.lib.mapAttrs (_: s: s.checks) systemOutputs;
};
}
The two chapters that follow fill in the perSystem function, one with each
helper:
conan-flake.lib.evalConanConfigevaluates a configuration directly.conan-flake.lib.submoduleWithembeds the same options as a submodule of a larger option tree — including, with no flakes at all, from a plaindefault.nix.
Warning
There’s still no support for the automatic nixification of
conanfile.pypackage definitions;1 the conan-flake module is about the Conan configuration side of things, that is: profiles, settings, remotes…
The options accepted by both helpers are the ones documented in the
option reference (the
perSystem.conan.* entries, minus their perSystem.conan prefix).
-
Or even of
conanfile.txt, for that matter. ↩
evalConanConfig
This example can be found in the standalone-eval-conan-config directory:
cd examples/standalone-eval-conan-config
Where the actual perSystem function — the one left out of the
schema of the previous chapter — is used to configure a
Release, C++17 profile:
# file: examples/standalone-eval-conan-config/flake.nix
{
# ...
perSystem = system:
let
pkgs = nixpkgs.legacyPackages.${system};
configuration = conan-flake.lib.evalConanConfig pkgs (
{ pkgs, config, ... }: {
configRoot = self;
profiles.default = {
settings.build_type = "Release";
settings."compiler.cppstd" = "17";
};
remotes.local = {
url = "./repo";
local = true;
allowedPackages = [ "hello-world/0.0.1.cci.20260428" ];
};
offline = true;
checks.example = {
enable = true;
drv =
conan-flake.lib.runCommandWithInSimulatedShell pkgs config.stdenv config.outputs.devShell
config.info.configRoot "./config"
"standalone-eval-conan-config-example-conan-create"
{ }
''
(
set -x
conan create . --build=missing 2>&1 | grep -F "example/0.0.1"
touch $out
)
''; # checks.example
};
}
);
in
{
devShells.default = configuration.config.outputs.devShell;
checks = configuration.config.outputs.checks;
};
# ...
}
This configuration now can be used to set a developer environment with
direnv:
direnv allow .
But even a plain nix develop would suffice:
nix develop .
From within this shell, the following command can be used to obtain the resulting profile:
conan profile show
To the profiles.default.settings.build_type and
profiles.default.settings."compiler.cppstd" conan-flake options correspond,
respectively, the build_type and compiler.cppstd entries in its output:
Host profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=17
compiler.libcxx=libstdc++11
compiler.version=15.3.0
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
Build profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=17
compiler.libcxx=libstdc++11
compiler.version=15.3.0
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
In the
standalone-eval-conan-config
directory, the
conanfile.py
recipe file defines a C++ package — example/0.0.1 — it’s possible
to call conan create on it, and export this package into the local Conan
cache:
conan create . --build=missing
The above command is going to install the dependencies and then build the example/0.0.1 package. Then export it to the local Conan cache and test it afterwards against standalone-eval-conan-config/test_package. If everything goes well, the last lines from the previous command would be the test package’s output:
hello-world: Hello World Release!
hello-world: __x86_64__ defined
hello-world: _GLIBCXX_USE_CXX11_ABI 1
hello-world: __cplusplus201703
hello-world: __GNUC__15
hello-world: __GNUC_MINOR__2
example/0.0.1 test_package
There’s also a check example function defined along with each default
devShell:
checks.example = {
enable = true;
drv =
conan-flake.lib.runCommandWithInSimulatedShell pkgs config.stdenv config.outputs.devShell
config.info.configRoot "./config"
"standalone-eval-conan-config-example-conan-create"
{ }
''
(
set -x
conan create . --build=missing 2>&1 | grep -F "example/0.0.1"
touch $out
)
''; # checks.example
Run the check via nix flake check:
nix flake check .
submoduleWith
This example can be found in the examples/standalone-submodule-with directory:
cd examples/standalone-submodule-with
Where the actual perSystem function is used to configure a Debug, C++14
profile:
# file: examples/standalone-submodule-with/flake.nix
{
# ...
perSystem =
system:
let
pkgs = nixpkgs.legacyPackages.${system};
lib = pkgs.lib;
conanSubmodule = conan-flake.lib.submoduleWith lib {
modules = [
{
options.pkgs = lib.mkOption {
default = pkgs;
defaultText = lib.literalExpression "pkgs";
};
config.configRoot = self;
}
];
};
conanModule = {
options = {
conan = lib.mkOption {
type = conanSubmodule;
description = "Conan configuration";
default = { };
};
};
}; # conanModule
conanModuleConfig =
(lib.evalModules {
modules = [
({ config, ... }: {
imports = [ conanModule ];
conan = {
profiles.default = {
settings.build_type = "Debug";
settings."compiler.cppstd" = "14";
};
devShell = {
tools = { inherit (pkgs) just; };
};
remotes.local = {
url = "./repo";
local = true;
allowedPackages = [ "hello-world/0.0.1.cci.20260428" ];
};
offline = true;
checks.example = {
enable = true;
drv =
conan-flake.lib.runCommandWithInSimulatedShell pkgs config.conan.stdenv config.conan.outputs.devShell
config.conan.info.configRoot "./config"
"standalone-submodule-with-example-conan-create"
{ }
''
(
set -x
conan create . --build=missing 2>&1 | grep -F "example/0.0.1"
touch $out
)
''; # checks.example
};
};
})
];
}).config.conan; # conanModuleConfig
in
{
devShells.default = conanModuleConfig.outputs.devShell;
checks = conanModuleConfig.outputs.checks;
};
# ...
}
Differently from the example in the previous chapter, here the options are loaded apart:
conanSubmodule = conan-flake.lib.submoduleWith lib {
And integrated as a submodule of a larger configuration:
conanModule = {
options = {
conan = lib.mkOption {
type = conanSubmodule;
description = "Conan configuration";
default = { };
};
};
}; # conanModule
And the final configuration can be obtained with lib.evalModules:
conanModuleConfig =
(lib.evalModules {
modules = [
({ config, ... }: {
imports = [ conanModule ];
conan = {
profiles.default = {
settings.build_type = "Debug";
settings."compiler.cppstd" = "14";
};
devShell = {
tools = { inherit (pkgs) just; };
};
remotes.local = {
url = "./repo";
local = true;
allowedPackages = [ "hello-world/0.0.1.cci.20260428" ];
};
offline = true;
checks.example = {
enable = true;
drv =
conan-flake.lib.runCommandWithInSimulatedShell pkgs config.conan.stdenv config.conan.outputs.devShell
config.conan.info.configRoot "./config"
"standalone-submodule-with-example-conan-create"
{ }
''
(
set -x
conan create . --build=missing 2>&1 | grep -F "example/0.0.1"
touch $out
)
''; # checks.example
};
};
})
];
}).config.conan; # conanModuleConfig
Apart from that, all the other commands and considerations from the previous chapter also apply here.1
Without flakes
To make this difference clearer, the
standalone-submodule-with/default.nix
file defines and configures a conan option using only a fetched conan-flake
module:
# file: examples/standalone-submodule-with/default.nix
{
lib,
pkgs,
inputs,
...
}:
let
conan-flake = (
fetchGit {
url = "https://codeberg.org/tarcisio/conan-flake";
name = "conan-flake";
ref = "refs/branches/main";
rev = "55a3e4025974d01980f637e37e636d7a43a22a91";
shallow = true;
}
);
conanSubmodule =
(import "${conan-flake}/nix/lib/lib.nix" { inherit inputs; }).conanFlakeLib.submoduleWith lib
{
modules = [
{
options.pkgs = lib.mkOption {
default = pkgs;
defaultText = lib.literalExpression "pkgs";
};
config.configRoot = ./.;
}
];
};
in
{
options = {
conan = lib.mkOption {
type = conanSubmodule;
description = "Conan configuration";
default = { };
};
};
config = {
conan = {
profiles.default = {
settings.build_type = "Debug";
settings."compiler.cppstd" = "14";
};
devShell = {
tools = { inherit (pkgs) just; };
};
remotes.local = {
url = "./repo";
local = true;
allowedPackages = [ "hello-world/0.0.1.cci.20260428" ];
};
offline = true;
};
};
}
To validate this setup, the standalone-submodule-with/eval.nix file can be used to evaluate the previous definitions:
# file: examples/standalone-submodule-with/eval.nix
let
pkgs = import <nixpkgs> { };
in
pkgs.lib.evalModules {
modules = [
({ ... }: { config._module.args = { inherit pkgs; }; })
./default.nix
# ./infuse.nix
];
}
To put these together, the following command instantiate the Nix files and print the resulting expression at a given attribute path:
nix-instantiate --eval eval.nix -A config.conan.profiles.default.text.text
The retuned value is that of the resulting default profile:
"[settings]\narch=x86_64\nbuild_type=Debug\ncompiler=gcc\ncompiler.cppstd=14\ncompiler.libcxx=libstdc++11\ncompiler.version=15.3.0\nos=Linux\n\n[options]\n\n\n[tool_requires]\n\n\n[buildenv]\n\n\n[runenv]\n\n\n[conf]\n\n\n[replace_requires]\n\n\n[replace_tool_requires]\n\n\n[platform_requires]\n\n\n[platform_tool_requires]\ncmake/4.3.4\n"
Which can be compared with the one already generated:
cat .conan2/profiles/default
Both outputs match, but for the \n propper printing:
[settings]
arch=x86_64
build_type=Debug
compiler=gcc
compiler.cppstd=14
compiler.libcxx=libstdc++11
compiler.version=15.3.0
os=Linux
[options]
[tool_requires]
[buildenv]
[runenv]
[conf]
[replace_requires]
[replace_tool_requires]
[platform_requires]
[platform_tool_requires]
cmake/4.3.4
-
The definitions of the two methods:
conan-flake.lib.evalConanConfigandconan-flake.lib.submoduleWithtry to mimictreefmt-nix’s related design. Cf. theirdefault.nixto compare definitions. ↩
Toolchains
A common way to support C and C++ packages in Nix is to
integrate their build system and expose a specialized stdenv derivation
responsible to bring in all of the necessary tools required to consistently
generate, configure, build and link those, and related, packages. The stdenv
derivation is a special derivation, defined in
Nixpkgs, and can be regarded as a kind of a
pattern as well — see its reference:
The Standard Environment,
on the
Nixpkgs Reference Manual. For an
introduction to the stdenv as a pattern, see
19. Fundamentals of Stdenv,
from the Nix Pills series.
conan-flake is parameterized by a
stdenv
option (defaulting to pkgs.stdenv), driving this complexity away from this
module, which can then be regarded as its interface with the compile
infrastructure of the Nix system. It’s used to extract mainly compiler related
information and, together with the other options, compute the final
configuration, which is exposed as a devShell output.
The two scenarios this project demonstrates are:
- LLVM — a
stdenvin which all dependencies come from the LLVM project, and thecompiler.libcxxsetting that goes with it. - CUDA — the
NVIDIA toolchain, linking against the CUDA
libraries available in
pkgs.cudaPackages.
LLVM
The way LLVM is packaged in Nix is an example of the stdenv pattern
described in the previous chapter. To integrate with the LLVM
compiler infrastructure, there is a pkgs.llvmPackages.libcxxStdenv derivation
— however this will not provide a pure llvm stdenv in which all
dependencies come from the LLVM project and none from GCC.1 A different
approach would be something like this:
stdenv = pkgs.overrideCC
(
pkgs.llvmPackages.libcxxStdenv.override {
targetPlatform.useLLVM = true;
targetPlatform.linker = "lld";
}
)
pkgs.llvmPackages.clangUseLLVM
That stdenv is what the
stdenv
option is given, and the devShell conan-flake computes from it can then be
appended to an inputsFrom option for composition:
# file: examples/llvm-flake-parts/flake.nix
{
outputs = inputs@{ nixpkgs, flake-parts, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = nixpkgs.lib.systems.flakeExposed;
imports = [
inputs.conan-flake.flakeModule
];
perSystem = { pkgs, config, ... }:
{
conan = {
profiles.default = {
settings = {
build_type = "Release";
"compiler.cppstd" = "23";
};
};
stdenv = pkgs.overrideCC
(
pkgs.llvmPackages.libcxxStdenv.override {
targetPlatform.useLLVM = true;
targetPlatform.linker = "lld";
}
)
pkgs.llvmPackages.clangUseLLVM;
};
devShells.default = pkgs.mkShell {
inputsFrom = [
config.conan.outputs.devShell
];
};
};
};
}
The above example is on the examples/llvm-flake-parts directory:
cd examples/llvm-flake-parts
direnv allow .
By default, conan-flake sets defaults.profiles.settings."compiler.libcxx" to
"libstdc++11", which would result in the wrong choice for
compiler.libcxx
— with the LLVM stdenv above it is detected as libc++ instead:
conan profile show
To the conan.profiles.default.settings.build_type and
conan.profiles.default.settings."compiler.cppstd" options correspond,
respectivelly, the build_type and compiler.cppstd entries in the command
output:
Host profile:
[settings]
arch=x86_64
build_type=Release
compiler=clang
compiler.cppstd=23
compiler.libcxx=libc++
compiler.version=21.1.8
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
tools.build:compiler_executables={'c': '/nix/store/va889lnfilh11sjb1rcnrdvp813jpg03-clang-wrapper-21.1.8/bin/clang', 'cpp': '/nix/store/va889lnfilh11sjb1rcnrdvp813jpg03-clang-wrapper-21.1.8/bin/clang++'}
Build profile:
[settings]
arch=x86_64
build_type=Release
compiler=clang
compiler.cppstd=23
compiler.libcxx=libc++
compiler.version=21.1.8
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
tools.build:compiler_executables={'c': '/nix/store/va889lnfilh11sjb1rcnrdvp813jpg03-clang-wrapper-21.1.8/bin/clang', 'cpp': '/nix/store/va889lnfilh11sjb1rcnrdvp813jpg03-clang-wrapper-21.1.8/bin/clang++'}
The package defined in the examples/llvm-flake-parts/conanfile.py recipe — example/0.0.1 — can be created in order to validate these settings:
conan create . --build=missing
Lines from its output correspond to entries from the Conan profile and, ultimately, to the conan-flake options:
hello-conan: Hello World Release!
hello-conan: __x86_64__ defined
hello-conan: __cplusplus202302
hello-conan: __GNUC__4
hello-conan: __GNUC_MINOR__2
hello-conan: __clang_major__21
hello-conan: __clang_minor__1
example/0.0.1 test_package
-
See this question, or this issue, for further details on how to create a LLVM-based
stdenvfor C++ development. ↩
CUDA
The pkgs.cudaPackages.backendStdenv derivation helps integrate the
NVIDIA and the host compilers while making it
possible to link against the CUDA libraries
available in pkgs.cudaPackages.1
Nixpkgs parametrization can affect the compatibility and availability of CUDA packages:
_module.args.pkgs = import inputs.nixpkgs {
inherit system;
config.allowUnfree = true;
config.allowUnsupportedSystem = false;
config.cudaForwardCompat = true;
config.cudaSupport = true;
}; # _module.args.pkgs
The configuration can be done entirely with
perSystem.conan
options:
# file: examples/cuda-flake-parts/flake.nix
conan = {
stdenv = pkgs.cudaPackages_13_2.backendStdenv;
devShell = {
tools = {
inherit (pkgs.cudaPackages_13_2)
cuda_nvcc
cuda_cccl
cuda_cudart
cuda_nvrtc
cuda_nvtx
cuda_profiler_api
cuda_cuxxfilt
libcublas
libnvfatbin
libnvptxcompiler;
};
env = {
LD_LIBRARY_PATH = "/usr/lib/wsl/lib";
MESA_D3D12_DEFAULT_ADAPTER_NAME = "NVIDIA";
GALLIUM_DRIVER = "d3d12";
};
};
profiles.default = {
settings = {
build_type = "Release";
"compiler.cppstd" = "20";
};
runEnv = [
{
name = "LD_LIBRARY_PATH";
op = "+=(path)";
value = "/usr/lib/wsl/lib";
}
{
name = "MESA_D3D12_DEFAULT_ADAPTER_NAME";
op = "=";
value = "NVIDIA";
}
{
name = "GALLIUM_DRIVER";
op = "=";
value = "d3d12";
}
];
};
remotes.local = {
url = "./repo";
local = true;
allowedPackages = [ "hello-world/0.0.1.cci.20260428" ];
};
}; # conan }
The above example is on the examples/cuda-flake-parts directory:
cd examples/cuda-flake-parts
direnv allow .
And it can be validated with a call to conan create:
conan create . --build=missing
Which returns the result of the program defined in the src/modified_cuda_samples/matrixMulCUBLAS/matrixMulCUBLAS.cpp source file, on the examples/cuda-flake-parts directory:2
[Matrix Multiply CUBLAS] - Starting...
Using CUDA device NVIDIA GeForce RTX 3060 Laptop GPU (having device ID 0)
GPU Device 0: "NVIDIA GeForce RTX 3060 Laptop GPU" with compute capability 8.6
MatrixA(640,480), MatrixB(480,320), MatrixC(640,320)
Computing result using CUBLAS... done.
Performance= 4266.67 GFlop/s, Time= 0.046 msec, Size= 196608000 Ops
Computing result using host CPU... done.
CUBLAS Matrix Multiply is close enough to CPU results: Yes
SUCCESS
-
See CUDA Modules for an overview on how CUDA packages are structured in Nixpkgs. ↩
-
The source files src/modified_cuda_samples/matrixMulCUBLAS/matrixMulCUBLAS.cpp and src/common.hpp are taken from the examples of the cuda-api-wrappers project — examples/modified_cuda_samples/matrixMulCUBLAS/matrixMulCUBLAS.cpp and examples/common.hpp, respectively. ↩
Templates
Every example of this project is also a flake template, so each one can be
instantiated into an empty directory with nix flake init. The
Getting started chapter walks through the first steps
with one of them.
Simple conan-flake project with only a flake-parts-based configuration
This template will get you only the flake.nix, .envrc and .gitignore
files.
mkdir -p default && cd default
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"
C++ conan-flake, flake-parts-based project
Alongside the files from the previous item, this template will provide you also with a complete sample Conan-based C++ project.
mkdir -p example && cd example
git init
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.example
direnv allow .
After this initial setup is complete, test if everything is working:
conan create . --build=missing
The remaining templates in this chapter can be initialized and validated in a similar manner.
LLVM-based C++ conan-flake project
This template is also flake-parts-based; see the
LLVM chapter.
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.llvm
C++ conan-flake, “devenv with flake-parts”-based project
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.devenv
C++ conan-flake, devenv-based project
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.devenv-module
C++ conan-flake, devenv-based project featuring a local-recipe-index remote
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.devenv-module-recipe
C++ conan-flake standalone Nix module project
See the Standalone chapter.
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.standalone
C++ conan-flake, flake-parts-based project demonstrating CUDA integration
See the CUDA chapter.
nix flake init -t "git+https://codeberg.org/tarcisio/conan-flake"#templates.cuda
Contributing
The development environment
To get started, clone this repository and allow devenv to set up the
environment with the configuration from the ./dev directory:
git clone ssh://git@codeberg.org/tarcisio/conan-flake.git
cd conan-flake
devenv --from path:dev allow
It will complain that conan-flake is not available:
error: To use 'conan', run the following command:
$ devenv inputs add conan-flake git+https://codeberg.org/tarcisio/conan-flake
Add the conan-flake input pointing to the local checkout (the root of this
repository) and activate devenv shell:
devenv inputs add conan-flake path:"$PWD"
devenv shell
Check that a default Conan profile was configured successfully:
conan profile show
Host profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++11
compiler.version=15.3.0
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
Build profile:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++11
compiler.version=15.3.0
os=Linux
[platform_tool_requires]
cmake/4.3.4
[conf]
Commands can also be run without entering the shell interactively, by prefixing
them with devenv shell --. To pick a different secretspec provider when
activating it:
devenv inputs add conan-flake path:"$PWD"
devenv --secretspec-provider dotenv shell
Running the checks
The justfile
recipes all point nix at ./dev and override the conan-flake input with the
local checkout:
just show # nix flake show ./dev
just check # nix flake check ./dev
just repl # nix repl ./dev
just ci # the full local CI, via `vira`
just vira <args> # `vira` with arbitrary arguments
just search <query> # conan search "<query>" (defaults to "*")
just show and just check also accept a path or flake reference, so a single
scenario can be targeted:
just check ./examples/flake-parts
Each directory under examples and test is an independent flake, and can be validated in isolation against the local checkout:
nix flake check ./examples/flake-parts --override-input conan-flake . --show-trace --no-pure-eval
Most examples define a checks.test derivation that runs conan install and
conan build inside a simulated shell, so nix flake check is the whole test
runner — there is no separate one.
vira.hs
is the source of truth for which example and test flakes CI exercises: a new
scenario under examples/ or test/ has to be added to its build.flakes list
to be checked. The pipelines themselves are in
.woodpecker:
checks.yml runs nix flake check ./dev, then vira ci -b, then a build of
flake.parts-website against this repository, which is what publishes the
option reference; release.yml
runs vira ci -b again on release events.
Note
Option documentation is generated from the module options’ own
descriptionandexampleattributes, so an option is documented by writing those — never by transcribing them into this site, which would silently go stale. The generated result is the option reference this site links to throughout.
The documentation site
The sources of this site are the Markdown files under docs, rendered by mdBook. From the development shell:
just docs # build the site, exactly as CI builds it
just docs-serve # serve it locally, reloading on every source change
A new page has to be listed in docs/src/SUMMARY.md; mdBook renders nothing that the summary does not name.
just docs builds through Nix, from a filtered copy of the sources, and its
output carries the site alone. just docs-serve runs mdbook serve over the
checkout instead, so it follows the docs/src/.examples symbolic link described
below: the preview publishes that link and mdBook watches the whole examples
tree, including whatever an example run left behind there. That is a property of
the local preview only, never of the built site.
How the generated blocks are refreshed
Code samples are never written into the Markdown sources by hand. Each one is
declared by an embedmd marker naming
the example file and the region to take, and the fenced block below the marker
is rewritten from that file:
[embedmd]:# (./.examples/flake-parts/flake.nix nix !/.*{ inputs/ !/.*inputs }/ s/# // dedent)
embedmd resolves the path relative to the Markdown file and refuses to leave
that directory, which is why the site’s markers go through docs/src/.examples,
a symbolic link to the examples directory at the root of the repository.
Running embedmd over the sources rewrites every such block in place:
embedmd README.md docs/src/*.md
That same command runs as a pre-commit hook and as a treefmt formatter, so
in practice the blocks are refreshed on commit, and a sample that no longer
matches its example project fails the authoring.EMBEDDING.2 check in CI —
the checks over the site are named after the requirement each one proves.
Note
Only
nixandiniblocks are guarded that way. The fewtextblocks that transcribe a command’s output without anmdshblock above them — theconan createoutputs, mostly — are hand-maintained, and have to be updated by hand when the example they came from changes.
Command-output blocks are generated the same way, by
mdsh: the command that produces the output
is recorded next to the block, either visibly —
```sh > text $
conan profile show
```
<!-- BEGIN mdsh -->
```text
…output…
```
<!-- END mdsh -->
— or hidden, when the command is scaffolding rather than something the reader would type:
<!-- > $
echo '```text'
cd "$(git rev-parse --show-toplevel)/examples/flake-parts"
nix develop --command bash -c "profile-show-wrapper 2>/dev/null"
echo '```'
-->
mdsh runs each block from the directory of the Markdown file that carries it,
which is why the site’s blocks cd to the repository root first. Running it
replaces the block that follows with the command’s current output:
mdsh --inputs docs/src/*.md
The sources of the site are the whole of that list: README.md is a pointer at
this site and carries no command-output block, so it is off
programs.mdsh.includes in
dev/treefmt.nix.
It does keep one embedded sample, which is why it is still named in the
embedmd command above.
Warning
Those commands run the
examples/*projects, and those resolve conan-flake from the published upstream rather than from the checkout. Between a breaking option change and the release that publishes it, the examples fail to evaluate andmdshwrites back empty blocks, deleting committed content. For the duration of that window, setprograms.mdsh.excludes = [ "docs/src/*.md" ]in dev/treefmt.nix — the same listprograms.mdsh.includescarries there, somdshis then pointed at zero files, which turns it off without unwiring it and leaves the committed blocks untouched. Clear the exclude once the release is onmain.embedmdis unaffected either way.
Publishing the site
This site is a Codeberg Page of
this repository: the content of its pages branch is served at
https://tarcisio.codeberg.page/conan-flake/. One command builds the site and
updates that branch from the build:
just docs-publish
It runs
scripts/publish-pages.sh,
which is also what CI runs, so what a contributor publishes and what a pipeline
publishes are produced by the same code. It needs no credential beyond the one
that already pushes to this repository: the push goes through the checkout’s own
origin.
What it does, and why it does it that way:
- the site is built first, and nothing else happens if that build fails, so a broken build cannot leave a half-published branch behind;
- the branch is updated through a temporary git worktree, never by switching this checkout, so the branch that was checked out stays checked out and the working tree is not touched — including when the run fails;
pagesis created as an orphan branch: it carries no source of the repository and its history starts at a root commit of its own;- everything the branch carried is dropped before the new build is copied in, so a page removed from the site stops being served;
- the build output is copied out of the Nix store dereferencing symbolic links and without the store’s permissions, since a store path is read-only and its links point back into a store no visitor has. What lands on the branch is the output of the site’s derivation, whole: the server builds nothing.
The pipeline that runs the same script from main is
.woodpecker/pages.yml.
A push to main that touches the sources the site is built from publishes it,
and the pipeline can still be run on demand, which is how the site is
republished without a commit. The checklist below is how that was set up.
When two publications race, the second push loses: its run fails on a rejected push, and the site goes on carrying the other run’s build until the next change or a manual run.
Switching publication on
These steps need administration rights on the Codeberg repository and on its
Woodpecker project, so they cannot be done from a checkout. All of them have
been taken here: the webhook and the codeberg_token secret are registered,
https://tarcisio.codeberg.page/conan-flake/ serves this site from the pages
branch, and CI publishes it on every change to its sources on main. They are
kept because they are what a fork, or a move to another forge, has to repeat
— and a fork has to repeat them before its pages workflow runs at all:
the publishing step names codeberg_token, and a workflow whose secret
Woodpecker cannot resolve fails to compile rather than reporting that nothing
was published.
Important
Order matters between the fourth step and the last one. Woodpecker resolves a
from_secret:while it compiles the workflow, so a run whose event the secret does not list fails before any step starts.codeberg_tokentherefore has to be available at thepushevent before the commit that makes thepagesstep run on a push — otherwise that very push is the run that fails.
- Register the webhook. Repository settings → Webhooks → Add
webhook → type Forgejo, with
Target URL
https://tarcisio.codeberg.page/conan-flake/— which doubles as the address the site is served from — and Branch filterpages. This is what tells git-pages to pull the branch when it is pushed. - Do not read a failed test delivery as a broken setup. The “Test delivery” button fails by design; Codeberg’s own documentation says so. Verify by pushing the branch and loading the site instead.
- Create the push credential. A Codeberg access token with write access
to this repository, belonging to the account the pipeline pushes as
(
tarcisio, or whateverPAGES_USERinscripts/publish-pages-ci.shnames), stored as a secret named exactlycodeberg_tokenon this repository’s Woodpecker project..woodpecker/pages.ymlreads it, and publishes nothing while it is empty. - Allow that secret at both events the pipeline runs on. Open the secret
and tick
pushandmanualunder “Available at the following events”. Woodpecker offers a secret only to a run whose event the secret lists, and a new secret listspush,taganddeployment— somanualhas to be added, andpushhas to be left ticked. It resolves secrets while compiling the workflow, before anything runs, so a missing event does not fail a step: it fails the whole run, withsecret "codeberg_token" is not allowed to be used with pipeline event "push"(or"manual"). This is the one step of this checklist that cannot be taken from a checkout, and the one to take before the commit that turns publishing on, or that very push is the run that fails. - Publish once, with
just docs-publishfrom a checkout. That first run is what creates thepagesbranch, and it uses your own push credentials rather than the secret. - Publish from CI on demand. Once
codeberg_tokenexists and allowsmanual, run thepagespipeline of themainbranch from Woodpecker’s interface: that publishes the site, with no commit to make. This is still how the site is republished when the sources did not change. - Let CI publish on every change.
.woodpecker/pages.ymlhas a single step,pages, which runs on- event: [push, manual]: a push tomaintouching the paths the workflow filters on publishes the site, and so does a run started by hand. There is no second, tokenless step beside it — on a push that one would run the publishing wrapper again without a credential and announce that nothing was published next to a successful publication. What keeps unrelated pushes from publishing is the workflow’s ownwhen, which was already filtering onmainand on the site’s sources. The ordering matters: thecodeberg_tokensecret has to allow thepushevent before the commit that makes this change lands, or that push is compiled with a secret it may not read and fails before it starts. - Verify. Load https://tarcisio.codeberg.page/conan-flake/; content
can take a few minutes to refresh. If it does not appear, ask git-pages
what it deployed, with
curl https://tarcisio.codeberg.page/conan-flake/.git-pages/manifest.json— the manifest names the repository, the branch and the commit it served the site from.
A path the site does not carry is answered with the site’s own 404.html, which
mdBook generates at the root of the output and links back into the sub-path the
site is built for (site-url in docs/book.toml).
Note
.domainsfiles are obsolete: git-pages authorises custom domains through DNSTXTrecords instead, and acodeberg.pagesub-path site needs neither.
References
Projects
This project is heavily based on
haskell-flake, from which it takes
its overall structure.
It’s also influenced, indebted by the following projects in a number of ways:
- devenv (GitHub):
- Among other things, the way it handles the developer environment — see devshell.nix;
treefmt-nix:- Integration with the bare Nix module system — see default.nix.
cuda-api-wrappers- A CUDA example of matrix multiplication using libcublas: src/modified_cuda_samples/matrixMulCUBLAS/matrixMulCUBLAS.cpp
It goes without saying that these proejects don’t have anything to do with conan-flake — all wrong design decisions taken on the present scope are on our own account.
Tutorials
A good overview of the Nix module system is on nix.dev:
specially the second part:
As for the standard environment, it’s worth emphasizing the already mentioned:
Docs
A good source of information is Nixpkgs Reference Manual:
The conan-flake options themselves are published, generated from the module, at the conan-flake option reference — see also the Conan documentation for the configuration files those options render.
Revision history for conan-flake
0.11.0 (Aug 18, 2026)
Documentation
-
The project’s documentation is now a site, published at https://tarcisio.codeberg.page/conan-flake/ and written in mdBook under
docs/: a chapter per integration style (getting started,flake-parts, devenv, standalone withevalConanConfigandsubmoduleWith, LLVM/CUDA toolchains), plus templates, contributing, references and this revision history. It is built byconan-flake.lib.packages.docs(just docs,just docs-serve), asserted over by one check per requirement innix flake check ./dev, and published to Codeberg Pages byscripts/publish-pages.sh(just docs-publish,.woodpecker/pages.yml). -
README.mdis now a pointer at that site: what conan-flake is, one embedded configuration example, how to instantiate a template, a link per chapter, and the option reference. Every topic it used to carry is on the site; nothing was dropped. Its command-output blocks moved there with the prose, somdshis pointed at the site’s sources alone and no longer runs overREADME.md(embedmdstill does, for the one sample it kept). -
The site is now published by CI on every change to its sources on
main: thepagesstep of.woodpecker/pages.ymlruns on a push as well as on demand, and the tokenless step that used to keep such a push green while announcing that nothing was published is gone. The workflow’s existing branch and path filters are what keep unrelated pushes from publishing, and a manual run still republishes the site without a commit. Thecodeberg_tokensecret has to be available at Woodpecker’spushevent for this, since secrets are resolved while the workflow is compiled; the activation checklist in the contributing chapter says so. For the same reason a fork now has to work through that checklist before its ownpagesworkflow compiles at all, rather than getting a green run that announces that nothing was published.
0.10.0 (Aug 13, 2026)
Bug Fixes
-
profiles.<name>.buildEnvandprofiles.<name>.runEnvare now merged with the conan-flake defaults and rendered from the final profile state, like every other profile section. They were the only two sections rendered straight from the profile’s own values, which silently exempted them from the defaults merging and from thenull-removal marker. Added the matchingdefaults.profiles.buildEnvanddefaults.profiles.runEnvoptions (empty by default). An entry replaces the default entry carrying the samename, and setting itsvaluetonullremoves that default entry; the merged defaults keep their relative order and come first. Rendered profiles are unchanged for configurations that set no environment defaults. -
Removed references to
proactivefromclaude.code.agents.*(this property is going to be deprecated).
Improvements
- Updated default Conan package to 2.31.2 version
- Added
profiles.<name>.options,profiles.<name>.toolRequires,profiles.<name>.replaceRequires,profiles.<name>.replaceToolRequiresandprofiles.<name>.platformRequiresoptions, rendering the Conan profile[options],[tool_requires],[replace_requires],[replace_tool_requires]and[platform_requires]sections. - Added the matching
defaults.profiles.*options (empty by default), so every profile section can be given configuration-wide defaults and removed per profile by assigningnullto an entry.
Breaking Changes
-
Flattened the Conan profile
[settings]section into a single attribute set, removing thecompiler/_split:profiles.<name>.settings.compiler.*andprofiles.<name>.settings._.*becomeprofiles.<name>.settings.*;final.profiles.<name>.settings.compiler.*andfinal.profiles.<name>.settings._.*becomefinal.profiles.<name>.settings.*;defaults.profiles.settings.compiler.*anddefaults.profiles.settings._.*becomedefaults.profiles.settings.*.
There is no alias and no deprecation period: the new
settingsoption is a free-form attribute set that must accept an entry literally namedcompiler, so the old declaredcompilersub-option cannot coexist with it at the same path. To migrate, merge the two sets into one, keeping the entry names exactly as Conan spells them (compiler,compiler.cppstd,compiler.libcxx,compiler.version,arch,build_type,os, …).nullstill removes the corresponding default. For example,settings.compiler."compiler.cppstd" = "17"; settings._.build_type = "Release";becomessettings."compiler.cppstd" = "17"; settings.build_type = "Release";.The top-level
settings.compileroption (thesettings_user.ymlproducer) is a different, unrelated option and is not affected.
Notes
-
dev/flake.lockis now committed. The development flake declared its inputs by branch (nixpkgs-unstable,devenv-nixpkgs/rolling, and the unpinnedflake-parts,git-hooks,devenv,treefmt-nix,nix2containerandmk-shell-bin) with no lockfile, so the Woodpeckerdevstep resolved whatever each of them happened to point at when it ran, and two runs of the same commit could build different closures. Refresh the lock deliberately withnix flake update ./dev. This affects the development environment only: nothing undernix/is involved, and conan-flake consumers are unaffected. -
Generated Conan profile files now emit the
[settings]section as a single alphabetically ordered run of entries instead of two consecutive groups (non-compiler entries first, then thecompiler*ones). Anyone diffing generated profile files will seeos=move past thecompiler*entries; the set of rendered lines is unchanged, and Conan parses[settings]into a dictionary, so intra-section order carries no meaning. -
The
README.mdcommand-output blocks are regenerated against this release, withexamples/standalone-submodule-with/default.nix’sfetchGitrev bumped to it andmdshno longer excluded fromREADME.mdindev/treefmt.nix. They now show the ten profile sections and the[settings]entries in one alphabetically ordered run: the same rendering change described above, observed end to end through a real Conan profile. -
Generated Conan profile files now contain all ten sections, ordered as
[settings],[options],[tool_requires],[buildenv],[runenv],[conf],[replace_requires],[replace_tool_requires],[platform_requires]and[platform_tool_requires]. Anyone diffing generated configuration files will see the new (empty) sections and the changed section order.
0.9.0 (Aug 05, 2026)
Improvements
- Added support for multiple Conan profiles (
profiles.<name>), each one rendered as aconfig/profiles/<name>Conan profile and linked into${configLocal}/profiles/. - Added
profiles.<name>.nameoption to override the profile name.
Breaking Changes
- Moved
profiles.*options underprofiles.<name>.*(profiles.Xbecomesprofiles.default.X). - Moved
final.profiles.*options underfinal.profiles.<name>.*(final.profiles.Xbecomesfinal.profiles.default.X).
Notes
- Until this release lands on
mainand theconan-flakepins used by the examples are bumped (examples/standalone-submodule-with/default.nix’sfetchGitrev, and the unlocked flake inputs of the other examples), do not runtreefmt/mdshagainstREADME.md: the pinned revisions still expose the oldprofiles.*interface, so the migrated examples fail to evaluate andmdshempties theREADME.mdcommand-output blocks. The committedREADME.mdis the correct post-release state.
0.8.1 (Jul 31, 2026)
Bug Fixes
- Fix autowiring of
packagesoutputs.
Improvements
- Added local package infrastructure.
- Added
devenvproject development integration (under./dev/).
0.8.0 (Jul 29, 2026)
Improvements
- Added
nix/packages/conan/package.nixto track Conan releases and tweak Conan CLI. - Redirected the output of all
conan remotecommands tostderr.
Breaking Changes
- Set
nix/packages/conan/package.nixas default Conan package.
0.7.0 (Jul 21, 2026)
Improvements
- Silence noisy
pushd/popdduring shell activation. - Added
profile-show-wrapper. - Flush
profile-show-wrapperoutput to avoid buffering issues. - Added
pnameFromStdenvCcandversionFromStdenvCcutility functions. - Added
global.confsupport. - Default
core.graph:compatibility_modetooptimized.
0.6.1 (Jul 07, 2026)
Improvements
- Added
create-lock-install-wrapper.
0.6.0 (Jul 07, 2026)
Improvements
- Added support to shared Conan home directory.
- Added wrapping infrastructure.
0.5.1 (Jun 30, 2026)
Bug Fixes
- Fix exposing of
libutility functions forflake-partsmodule integration.
0.5.0 (Jun 29, 2026)
Improvements
- Add
generatorsoption toconan-flake. - Refactored and improved environment variable handling:
CONAN_FLAKE_ROOT: Root directory of the configuration.CONAN_FLAKE_HOME: If there’s ahomeDirectoryin the configuration, it will be appended toCONAN_FLAKE_ROOTand used as the home directory.CONAN_FLAKE_CONFIG:$CONAN_FLAKE_HOME/${configLocal}CONAN_HOME:$CONAN_FLAKE_HOME/${conanHome}
Breaking Changes
- Refactored
libinterface.
0.4.0 (Jun 13, 2026)
Bug Fixes
- Fixed
flake-partsdocs: added missingdefaultTextfordefaults.devShell.toolsoption. - Fixed treefmt’s project root configuration of
flake-partstest. - Excluded
./examples/devenv-module/devenv.nixfrom dev treefmt settings. - Fixed handling of root configuration path when setting local recipe index repos.
- Set
info.configRootoption. - Fixed tests to use
grep -F.
Improvements
- Improved docs on devenv integration.
- Added tests on overriding defaults.
- Trimmed embedded snippets in README (using veggiemonk’s embedmd’s PR: https://github.com/veggiemonk/embedmd/tree/feat/issue-47-directive-options).
- Added devenv integration example featuring local-recipe-index remote.
- Added
confoption (to compose profiles [conf] section). - Added
autoWireoption (initially supporting onlydevShellsand mapping only the configuration). - Added
buildEnvoption (to compose profiles [buildenv] section). - Added
runEnvoption (to compose profiles [runenv] section). - Added
final.devShell.toolsoption to map the final state ofdevShell.toolsafterdefaultsresolution. - Added CMake by default to
devShell.tools. - Added a
defaults.profiles.platformToolRequiresoption and set acmakeattribute by default depending whether CMake is a required tool or not. conan.stdenv.ccadded as a default tool.- Added
final.profiles.platformToolRequiresoption. - Added
final.settings.compiler,defaults.settings.compilerandsettings.compileroptions usinginfuseto merge andfilterAttrsto filter out nulled attributes. - Added
profiles.settings,final.profiles.settingsanddefaults.profiles.settingsoptions. - Added defaults for
arch,build_typeandosindefaults.profiles.settings. - Added defaults and finals for
profiles.conf. - Added
profiles.settings.compiler,final.profiles.settings.compileranddefaults.profiles.settings.compileroptions. - Whenever a LLVM toolchain is detected (with libcxx):
- Set
defaults.profiles.conf."tools.build:compiler_executables"appropriately. - Set
defaults.profiles.settings.compiler."compiler.libcxx"to"libc++".
- Set
Breaking Changes
- Removed default
infooutput command. - Removed automatic mapping of
config.conan.outputs.packages. - Removed
platformToolRequiresoption (profiles.platformToolRequiresmust be used instead). - Removed the
buildEnv,runEnvandconfoptions (keep only those in theprofilesnamespace). - Removed
settings.baseoption. - Removed
arch,buildTypeandosoptions; thearch,build_typeandosprofiles.settingsmust be used instead respectively. - Removed
compiler,compilerCppStd,compilerLibCxxandcompilerVersionoptions. The following should be used as a replacement (only if necessary):profiles.settings.compiler."compiler";profiles.settings.compiler."compiler.cppstd";profiles.settings.compiler."compiler.libcxx";profiles.settings.compiler."compiler.version".
0.3.1 (May 29, 2026)
Improvements
- Added
release.ymlworkflow. - Improved documentation.
0.3.0 (May 28, 2026)
Improvements
- Added
defaultsoption to track defaults (initially, this contains onlydefaults.devShell.tools). - Improved tests.
Breaking Changes
- Renamed the
devShell.packageoption todevShell.toolsand changed its type to package set.
0.2.0 (May 25, 2026)
Breaking Changes
- Removed the
devShell.apple.sdkoption.