Using Clang instead of GCC: Difference between revisions
imported>Mickours Add the trick to override package and build with Clang |
imported>Artturin Undoing a edit because it's not exactly true and is because of a bug, linked the issue |
||
(8 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
You can use Clang instead of GCC as a compiler for any package by overriding | You can use Clang instead of GCC as a compiler for any package by overriding <code>stdenv</code>, which contains the compilation toolchain, with: | ||
<syntaxhighlight lang="nix"> | |||
stdenv = pkgs.clangStdenv; | |||
</syntaxhighlight> | |||
or to get a specific version of clang: | |||
<syntaxhighlight lang="nix"> | |||
stdenv = pkgs.llvmPackages_9.stdenv; | |||
</syntaxhighlight> | |||
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 == | |||
If you have a set of packages in a repository tree, you can set the | |||
<code>stdenv</code> value in the scope where the <code>callPackage</code> are | |||
called. Be carefull '''all the packages present in the scope will be built with Clang''' | |||
because the <code>callPackage</code> that resolves the package function | |||
inputs will use the <code>pkgs.clangStdenv</code> for all packages. | |||
<syntaxhighlight lang="nix"> | |||
rec { | |||
stdenv = pkgs.clangStdenv; | |||
foo = callPackage ./foo { }; | |||
bar = callPackage ./bar { }; | |||
} | |||
</syntaxhighlight> | |||
or import nixpkgs with replaceStdenv. | |||
<syntaxhighlight lang="nix"> | |||
import <nixpkgs> { config = { replaceStdenv = ({ pkgs }: pkgs.clangStdenv); }; } | |||
</syntaxhighlight> | |||
== 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 <code>callPackage</code> or | |||
creating a package override. | |||
Here only foo will be built with Clang, and only with Clang. | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ pkgs, | rec { | ||
foo = callPackage ./foo { stdenv = pkgs.clangStdenv; }; | |||
bar = callPackage ./bar { }; | |||
} | |||
</syntaxhighlight> | |||
But if you want both toolchains you can use: | |||
<syntaxhighlight lang="nix"> | |||
rec { | |||
foo_gcc = callPackage ./foo { }; | |||
foo_clang = callPackage ./foo { stdenv = pkgs.clangStdenv; }; | |||
bar = callPackage ./bar { }; | |||
} | |||
</syntaxhighlight> | |||
== Using Nix CLI on existing packages == | |||
Directly inline with CLI just do: | |||
<syntaxhighlight lang="bash"> | |||
nix-build -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }" | |||
</syntaxhighlight> | |||
or, if you want a shell for development: | |||
<syntaxhighlight lang="bash"> | |||
nix-shell -E "with import <nixpkgs> {}; pkgs.hello.override{ stdenv = pkgs.clangStdenv; }" | |||
</syntaxhighlight> | |||
== Using an external override definition == | |||
<syntaxhighlight lang="nix"> | |||
# in file ./hello_with_clan.nix | |||
with import <nixpkgs> {}; | |||
hello.override { | |||
# use Clang instead of GCC | # use Clang instead of GCC | ||
stdenv = pkgs.clangStdenv; | stdenv = pkgs.clangStdenv; | ||
Line 9: | Line 87: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<syntaxhighlight lang="bash"> | |||
nix-build ./hello_with_clan.nix | |||
</syntaxhighlight> | |||
== With nix-shell == | |||
To use clang in nix-shell instead of gcc: | |||
<syntaxhighlight lang="nix"> | |||
# in file ./shell.nix | |||
with import <nixpkgs> {}; | |||
clangStdenv.mkDerivation { | |||
name = "clang-nix-shell"; | |||
buildInputs = [ /* add libraries here */ ]; | |||
} | |||
</syntaxhighlight> | |||
== See also == | |||
* [[C#Use_a_different_compiler_version|C # Use a different compiler version]] | |||
[[Category:Nixpkgs]] | [[Category:Nixpkgs]] |
Latest revision as of 03:08, 15 October 2023
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
# in file ./hello_with_clan.nix
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:
# in file ./shell.nix
with import <nixpkgs> {};
clangStdenv.mkDerivation {
name = "clang-nix-shell";
buildInputs = [ /* add libraries here */ ];
}