Using Clang instead of GCC: Difference between revisions
imported>Artturin add replaceStdenv |
m style fixes |
||
| (2 intermediate revisions by 2 users not shown) | |||
| Line 10: | Line 10: | ||
Depending on the case you may want to set this value in different location, and using different mechanism. | Depending on the case you may want to set this value in different location, and using different mechanism. | ||
Note you may get errors like <code>fatal error: ... file not found</code> on standard library <code>#include</code> directives, because of this bug https://github.com/NixOS/nixpkgs/issues/150655 | |||
== Globally, in a package repository tree == | == Globally, in a package repository tree == | ||
If you have a set of packages in a repository tree, you can set the | If you have a set of packages in a repository tree, you can set the | ||
| Line 22: | Line 22: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
rec { | rec { | ||
stdenv = pkgs.clangStdenv; | |||
foo = callPackage ./foo { }; | |||
bar = callPackage ./bar { }; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 33: | Line 33: | ||
import <nixpkgs> { config = { replaceStdenv = ({ pkgs }: pkgs.clangStdenv); }; } | import <nixpkgs> { config = { replaceStdenv = ({ pkgs }: pkgs.clangStdenv); }; } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== For a specific package in a repository tree == | == For a specific package in a repository tree == | ||
| Line 45: | Line 44: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
rec { | rec { | ||
foo = callPackage ./foo { stdenv = pkgs.clangStdenv; }; | |||
bar = callPackage ./bar { }; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 54: | Line 53: | ||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
rec { | rec { | ||
foo_gcc = callPackage ./foo { }; | |||
foo_clang = callPackage ./foo { stdenv = pkgs.clangStdenv; }; | |||
bar = callPackage ./bar { }; | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| Line 65: | Line 64: | ||
Directly inline with CLI just do: | Directly inline with CLI just do: | ||
<syntaxhighlight lang= | <syntaxhighlight lang=console> | ||
nix-build -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }" | $ nix-build -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }" | ||
</syntaxhighlight> | </syntaxhighlight> | ||
or, if you want a shell for development: | or, if you want a shell for development: | ||
<syntaxhighlight lang= | <syntaxhighlight lang=console> | ||
nix-shell -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }" | $ nix-shell -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }" | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== Using an external override definition == | == Using an external override definition == | ||
{{file|./hello_with_clan.nix|nix|3= | |||
with import <nixpkgs> {}; | with import <nixpkgs> {}; | ||
hello.override { | hello.override { | ||
# use Clang instead of GCC | |||
stdenv = pkgs.clangStdenv; | |||
} | } | ||
}} | |||
<syntaxhighlight lang= | <syntaxhighlight lang=console> | ||
nix-build ./hello_with_clan.nix | $ nix-build ./hello_with_clan.nix | ||
</syntaxhighlight> | </syntaxhighlight> | ||
== With nix-shell == | == With nix-shell == | ||
To use clang in nix-shell instead of gcc: | To use clang in nix-shell instead of gcc: | ||
{{file|./shell.nix|nix|3= | |||
with import <nixpkgs> {}; | with import <nixpkgs> {}; | ||
clangStdenv.mkDerivation { | clangStdenv.mkDerivation { | ||
| Line 99: | Line 96: | ||
buildInputs = [ /* add libraries here */ ]; | buildInputs = [ /* add libraries here */ ]; | ||
} | } | ||
}} | |||
== See also == | == See also == | ||
Latest revision as of 18:31, 19 July 2026
You can use Clang instead of GCC as a compiler for any package by overriding stdenv, which contains the compilation toolchain, with:
stdenv = pkgs.clangStdenv;
or to get a specific version of clang:
stdenv = pkgs.llvmPackages_9.stdenv;
Depending on the case you may want to set this value in different location, and using different mechanism.
Note you may get errors like fatal error: ... file not found on standard library #include directives, because of this bug https://github.com/NixOS/nixpkgs/issues/150655
Globally, in a package repository tree
If you have a set of packages in a repository tree, you can set the
stdenv value in the scope where the callPackage are
called. Be carefull all the packages present in the scope will be built with Clang
because the callPackage that resolves the package function
inputs will use the pkgs.clangStdenv for all packages.
rec {
stdenv = pkgs.clangStdenv;
foo = callPackage ./foo { };
bar = callPackage ./bar { };
}
or import nixpkgs with replaceStdenv.
import <nixpkgs> { config = { replaceStdenv = ({ pkgs }: pkgs.clangStdenv); }; }
For a specific package in a repository tree
If you a one specific package in your package repository that you want to build
with Clang. You can either override stdenv in the callPackage or
creating a package override.
Here only foo will be built with Clang, and only with Clang.
rec {
foo = callPackage ./foo { stdenv = pkgs.clangStdenv; };
bar = callPackage ./bar { };
}
But if you want both toolchains you can use:
rec {
foo_gcc = callPackage ./foo { };
foo_clang = callPackage ./foo { stdenv = pkgs.clangStdenv; };
bar = callPackage ./bar { };
}
Using Nix CLI on existing packages
Directly inline with CLI just do:
$ nix-build -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }"
or, if you want a shell for development:
$ nix-shell -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }"
Using an external override definition
with import <nixpkgs> {};
hello.override {
# use Clang instead of GCC
stdenv = pkgs.clangStdenv;
}
$ nix-build ./hello_with_clan.nix
With nix-shell
To use clang in nix-shell instead of gcc:
with import <nixpkgs> {};
clangStdenv.mkDerivation {
name = "clang-nix-shell";
buildInputs = [ /* add libraries here */ ];
}