C: Difference between revisions
imported>Detailyang m Fixes the nix-shell command usage |
imported from old wiki |
||
(9 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
This | This is a collection of recipes for working on C/C++ projects with Nix. | ||
They do not just apply to C but also C++. | |||
== Differences between nixpkgs and the rest == | == Differences between nixpkgs and the rest == | ||
The way nixpkgs and its stdenv handles compiling and linking is very different from other | The way nixpkgs and its stdenv handles compiling and linking is very different from other Linux distributions. | ||
In more conventional Linux distributions it's usual that header files are put into well known paths i.e. <code>/usr/include</code>, where the compiler will look for them. Same is true when linking against libraries, which are put in a few places, where the build-time linker will find them. Dynamically linked libraries will have a run-time linker (also known as <code>ld.so</code>) set as an interpreter. | |||
look for them. Same is true when linking against libraries, which are put in a few places, where the build-time | |||
linker will find them. Dynamically linked libraries will have a run-time linker (also known as <code>ld.so</code>) set as an interpreter. | |||
This linker reads <code>/etc/ld.so.conf</code> to figure out where to find libraries. | This linker reads <code>/etc/ld.so.conf</code> to figure out where to find libraries. | ||
In nixpkgs in contrast this information is provided by environment variables. | In nixpkgs in contrast this information is provided by environment variables. | ||
Line 105: | Line 103: | ||
== Hardening flags == | == Hardening flags == | ||
To improve the security of applications the wrapper also injects additional hardening compile flags into the application. | To improve the security of applications the wrapper also injects additional hardening compile flags into the application. These nix flags enable different compiler flags, as seen in the [https://nixos.org/nixpkgs/manual/#sec-hardening-in-nixpkgs manual]. | ||
Under some circumstances this can make programs fail to build or function. | Under some circumstances this can make programs fail to build or function. For example, the `fortify` flag enables the `-O2` optimization level -- if you want to change this, you need to disable the `fortify` flag and re-add the compiler flags manually (`env.NIX_CFLAGS_COMPILE = [ "-O" "....."]`). | ||
To disable all hardening options one can export the environment variable <code>hardeningDisable="all"</code>. | To disable all hardening options one can export the environment variable <code>hardeningDisable="all"</code>. | ||
This also works for derivations like that: | This also works for derivations like that: | ||
Line 117: | Line 115: | ||
</syntaxHighlight> | </syntaxHighlight> | ||
It is also possible to only disable certain parts, for example <code>-Werror=format-security</code>: | |||
<syntaxHighlight lang=nix> | <syntaxHighlight lang=nix> | ||
Line 203: | Line 201: | ||
[nix-shell:~] $ echo 'int main {}' > hello.c | [nix-shell:~] $ echo 'int main {}' > hello.c | ||
[nix-shell:~] $ cmake . | [nix-shell:~] $ cmake . | ||
</syntaxHighlight> | |||
== gcc multilib == | |||
<code>pkgs.gcc_multi</code> exports a <code>gcc</code> in a multilib variant, which can produce 32-bit and 64-bit x86 code at the same time. However, <code>gcc_multi</code> falls back to the gcc version coming from <code>pkgs.gcc</code>. To use a specific version of gcc, you might use something like that: | |||
<syntaxHighlight lang=nix> | |||
{ | |||
gcc11_multi = pkgs.wrapCCMulti pkgs.gcc11; | |||
// or | |||
gcc13_multi = pkgs.wrapCCMulti pkgs.gcc13; | |||
} | |||
</syntaxHighlight> | </syntaxHighlight> | ||
Line 272: | Line 282: | ||
gcc (GCC) 8.3.0 | gcc (GCC) 8.3.0 | ||
</syntaxHighlight> | </syntaxHighlight> | ||
* Available gcc based stdenv variants: gcc{49,6-12}Stdenv, gccMultiStdenv (32bit/64bit mixed support) | |||
* Available clang based stdenv variants: llvmPackages_[5-13].{stdenv,libcxxStdenv}, clangMultiStdenv (32bit/64bit mixed support) | |||
Those stdenv instances can be also constructed using the <code>overrideCC</code> function: | |||
Here we are creating a shell environment that will always have the latest available gcc: | |||
<syntaxHighlight lang=nix> | |||
(overrideCC stdenv gcc_latest).mkDerivation { | |||
name = "env"; | |||
} | |||
</syntaxHighlight> | |||
Note that this will only affect compiler and not the used linker. To overwrite the linker and maybe also the used libc | |||
Check out the <code>wrapCCWith</code> example in the next section. | |||
See also: [[Using Clang instead of GCC]] | |||
== Get a compiler without default libc == | == Get a compiler without default libc == | ||
Line 386: | Line 413: | ||
[[Category:Languages]] | [[Category:Languages]] | ||
[[Category:Cookbook]] |