C: Difference between revisions

imported>Mic92
fix markup
imported>Mic92
NIX_DEBUG=1 and hardening flags
Line 1: Line 1:
This article gives practical advices when working C/C++ projects with Nix.
This article gives practical advices when working C/C++ projects with Nix.
It is written to be read from top to bottom.


== Differences between nixpkgs and the rest ==
== Differences between nixpkgs and the rest ==
Line 11: Line 10:
In nixpkgs in contrast this information is provided by environment variables that will
In nixpkgs in contrast this information is provided by environment variables that will
be set based on the build inputs that are given when building a package or
be set based on the build inputs that are given when building a package or
when loading a nix expression into a `<code>nix-shell</code>`.
when loading a nix expression into a <code>nix-shell</code>.
Therefore it is not sufficient to just install libraries with <code>nix-env</code> into the profile
Therefore it is not sufficient to just install libraries with <code>nix-env</code> into the profile
since the compiler will not look in those paths when compiling.
since the compiler will not look in those paths when compiling.
Line 39: Line 38:
and <code>NIX_LDFLAGS</code>
and <code>NIX_LDFLAGS</code>


<syntaxHighlight>
<syntaxHighlight lang=console>
$ cat > shell.nix <<EOF
$ cat > shell.nix <<EOF
with import <nixpkgs> {};
with import <nixpkgs> {};
Line 63: Line 62:
We can print the <code>RPATH</code> of executable using the <code>patchelf</code> command.
We can print the <code>RPATH</code> of executable using the <code>patchelf</code> command.


<syntaxHighlight>
<syntaxHighlight lang=console>
nix-shell -p hello --command 'patchelf --print-rpath $(which hello)'
$ nix-shell -p hello --command 'patchelf --print-rpath $(which hello)'
/nix/store/fivq0nbggp4y8mhy3ixprqd7qyn1hy2j-glibc-2.27/lib
/nix/store/fivq0nbggp4y8mhy3ixprqd7qyn1hy2j-glibc-2.27/lib
</syntaxHighlight>
</syntaxHighlight>
== Debugging the compiler wrapper ==
To inspect what how the shell wrapper processes the variables one can set the <code>NIX_DEBUG</code>
<syntaxHighlight  lang=console>
$ nix-shell -p hello --command 'NIX_DEBUG=1 $CC -v'
HARDENING: disabled flags: pie
HARDENING: Is active (not completely disabled with "all" flag)
HARDENING: enabling fortify
HARDENING: enabling stackprotector
HARDENING: enabling strictoverflow
HARDENING: enabling format
HARDENING: enabling pic
extra flags before to /nix/store/4ga86h16l157r7bas9hcwxgl9d3r32s6-gcc-7.4.0/bin/gcc:
  ''
original flags to /nix/store/4ga86h16l157r7bas9hcwxgl9d3r32s6-gcc-7.4.0/bin/gcc:
  -v
extra flags after to /nix/store/4ga86h16l157r7bas9hcwxgl9d3r32s6-gcc-7.4.0/bin/gcc:
  ''
Using built-in specs.
COLLECT_GCC=/nix/store/4ga86h16l157r7bas9hcwxgl9d3r32s6-gcc-7.4.0/bin/gcc
COLLECT_LTO_WRAPPER=/nix/store/4ga86h16l157r7bas9hcwxgl9d3r32s6-gcc-7.4.0/libexec/gcc/x86_64-unknown-linux-gnu/7.4.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with:
Thread model: posix
gcc version 7.4.0 (GCC)
</syntaxHighlight>
== Hardening flags ==
To improve the security of application the wrapper also inject additional hardening compile flags into the application.
Under some circumstances this can make programs fails to build or function.
To disable all hardening options one can export the environment variable <code>hardeningDisable="all"</code>.
This also works for derivations like that:
<syntaxHighlight lang=nix>
with import <nixpkgs> {};
stdenv.mkDerivation {
  hardeningDisable = [ "all" ];
};
</syntaxHighlight>
It is also possible to only enable certain parts:
<syntaxHighlight lang=nix>
with import <nixpkgs> {};
stdenv.mkDerivation {
  hardeningDisable = [ "format" ];
};
</syntaxHighlight>
Further options are described in the [https://nixos.org/nixpkgs/manual/#sec-hardening-in-nixpkgs manual]