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 `stdenv`:
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, my_package }:
rec {
my_package.override {
    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]]