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. ↩