Using Clang instead of GCC: Difference between revisions

From NixOS Wiki
imported>Mickours
Add the trick to override package and build with Clang
 
imported>Mickours
Adding more details + different scenario
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>
 
Depending on the case you may want to set this value in different location, and using different mechanism.
 
 
== 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>
 
== 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">
rec {
    foo = callPackage ./foo { stdenv = pkgs.clangStdenv; };
    bar = callPackage ./bar { };
}
</syntaxhighlight>
 
But if you want both toolchains you can use:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ pkgs, my_package }:
rec {
my_package.override {
    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 75:
</syntaxhighlight>
</syntaxhighlight>


<syntaxhighlight lang="bash">
nix-build ./hello_with_clan.nix
</syntaxhighlight>


[[Category:Nixpkgs]]
[[Category:Nixpkgs]]

Revision as of 12:55, 31 August 2018

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;

Depending on the case you may want to set this value in different location, and using different mechanism.


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 { };
}

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