Build flags: Difference between revisions

From NixOS Wiki
imported>Lassulus
No edit summary
Klinger (talk | contribs)
 
(6 intermediate revisions by 5 users not shown)
Line 7: Line 7:
You need to be a trusted user to override the local system feature.
You need to be a trusted user to override the local system feature.


<code>optimised_openssl.nix</code>
{{file|optimised_openssl.nix|nix|<nowiki>
<syntaxhighlight lang="nix">
let
let
   pkgs = import <nixpkgs> {
   pkgs = </nowiki>import <nixpkgs> {<nowiki>
     localSystem = {
     localSystem = {
       gcc.arch = "skylake";
       gcc.arch = "skylake";
       gcc.tune = "skylake";
       gcc.tune = "skylake";
       system = "x86_64-linux";
       system = "x86_64-linux";
     };
     </nowiki>};
   };
   };
in
in
pkgs.openssl
  pkgs.openssl
</syntaxhighlight>
}}


Then build the file:
Then build the file:
Line 25: Line 24:
nix-build optimised_openssl.nix --option system-features gccarch-skylake
nix-build optimised_openssl.nix --option system-features gccarch-skylake
</code>
</code>
==== Adapting a derivation to specific plaforms ====
The technique above should pass the correct flags to gcc so that it uses the processor to its fullest. However, some build systems or configure scripts want to know whether to enable some processor-specific instructions, for example sse. One way to do so is to inspect the <code>stdenv.hostPlatform.*Support</code> predicates: here is an example from g2o:
<code>
cmakeFlags = [  "-DDISABLE_SSE3=${  if stdenv.hostPlatform.sse3Support  then "OFF" else "ON"}" ]
</code>
Available [https://unix.stackexchange.com/questions/43539/what-do-the-flags-in-proc-cpuinfo-mean flags] are defined in [https://github.com/NixOS/nixpkgs/blob/master/lib/systems/architectures.nix lib/systems/architectures.nix].


==== Building the whole system on NixOS ====
==== Building the whole system on NixOS ====
In <code>/etc/nixos/configuration/nix</code>:
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
<syntaxhighlight lang="nix">
{ config, pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
{
{
     nixpkgs.localSystem = {
     nixpkgs.hostPlatform = {
       gcc.arch = "skylake";
       gcc.arch = "skylake";
       gcc.tune = "skylake";
       gcc.tune = "skylake";
Line 37: Line 45:
     };
     };
}
}
</syntaxhighlight>
</nowiki>}}




Line 56: Line 64:
   pkgs.openssl
   pkgs.openssl
</syntaxhighlight>
</syntaxhighlight>
[[Category:Development]]
[[Category:nix]]

Latest revision as of 20:25, 24 April 2024

Building a package for a specific CPU

By default, packages built for, say, x86_64 do not take advantage of the feature of more recent cpus so that the executables you compile also work on older cpus of the same architecture. This is essential because of the binary cache feature of nix: if a package is compiled on hydra by a recent CPU, older systems using hydra may download software that they can't run.

However, you can build some package or even all your system to take advantage of the specific model of your cpu. Note that you will not be able to take advantage of the binary cache and thus build everything locally from scratch. The first step is to determine the -march and -mtune arguments that you want to pass to gcc. In the following we want to target a skylake cpu so -march=skylake -mtune=skylake.

Building a single package

You need to be a trusted user to override the local system feature.

optimised_openssl.nix
let
  pkgs = import <nixpkgs> {
    localSystem = {
      gcc.arch = "skylake";
      gcc.tune = "skylake";
      system = "x86_64-linux";
    };
  };
in
  pkgs.openssl

Then build the file: nix-build optimised_openssl.nix --option system-features gccarch-skylake


Adapting a derivation to specific plaforms

The technique above should pass the correct flags to gcc so that it uses the processor to its fullest. However, some build systems or configure scripts want to know whether to enable some processor-specific instructions, for example sse. One way to do so is to inspect the stdenv.hostPlatform.*Support predicates: here is an example from g2o: cmakeFlags = [ "-DDISABLE_SSE3=${ if stdenv.hostPlatform.sse3Support then "OFF" else "ON"}" ]

Available flags are defined in lib/systems/architectures.nix.

Building the whole system on NixOS

/etc/nixos/configuration.nix
{ config, pkgs, lib, ... }:
{
    nixpkgs.hostPlatform = {
      gcc.arch = "skylake";
      gcc.tune = "skylake";
      system = "x86_64-linux";
    };
}


Building an impure package with -march=native

To build an openssl specially tailored to the local CPU, build

let
  pkgs = import <nixpkgs> {
    overlays = [
      (self: super: {
        stdenv = super.impureUseNativeOptimizations super.stdenv;
      })
    ];
  };
in
  pkgs.openssl