Jump to content

C: Difference between revisions

1,652 bytes added ,  23 June
imported from old wiki
imported>Milahu
(add link to: Using Clang instead of GCC)
(imported from old wiki)
 
(8 intermediate revisions by 5 users not shown)
Line 1: Line 1:
This article gives practical advices when working on C/C++ projects with Nix.
This is a collection of recipes for working on C/C++ projects with Nix.
The article does not just apply to C but also C++.
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 linux distributions.
The way nixpkgs and its stdenv handles compiling and linking is very different from other Linux distributions.
Usually header files are put into well known paths i.e. <code>/usr/include</code>, where the compiler will  
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 enable certain parts:


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]]
See also: [[Using Clang instead of GCC]]
Line 388: Line 413:


[[Category:Languages]]
[[Category:Languages]]
[[Category:Cookbook]]