summaryrefslogtreecommitdiff
path: root/pkgs/os-specific/linux/kernel-headers/default.nix
blob: 3bee4e848c76595cb42214a25ea6c64ca4d7aac9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
{
  stdenvNoCC,
  lib,
  buildPackages,
  fetchurl,
  perl,
  elf-header,
  bison,
  flex,
  rsync,
  writeTextFile,
  nix-update-script,
  linux_latest,
}:

let

  # As part of building a hostPlatform=mips kernel, Linux creates and runs a
  # tiny utility `arch/mips/boot/tools/relocs_main.c` for the buildPlatform.
  # This utility references a glibc-specific header `byteswap.h`.  There is a
  # compatibility header in gnulib for most BSDs, but not for Darwin, so we
  # synthesize one here.
  darwin-endian-h = writeTextFile {
    name = "endian-h";
    text = ''
      #include <byteswap.h>
    '';
    destination = "/include/endian.h";
  };
  darwin-byteswap-h = writeTextFile {
    name = "byteswap-h";
    text = ''
      #pragma once
      #include <libkern/OSByteOrder.h>
      #define bswap_16 OSSwapInt16
      #define bswap_32 OSSwapInt32
      #define bswap_64 OSSwapInt64
    '';
    destination = "/include/byteswap.h";
  };

  makeLinuxHeaders =
    {
      src,
      version,
      patches ? [ ],
      passthru ? { },
    }:
    stdenvNoCC.mkDerivation {
      inherit src;

      pname = "linux-headers";
      inherit version;

      env.ARCH = stdenvNoCC.hostPlatform.linuxArch;

      strictDeps = true;
      enableParallelBuilding = true;

      # It may look odd that we use `stdenvNoCC`, and yet explicit depend on a cc.
      # We do this so we have a build->build, not build->host, C compiler.
      depsBuildBuild = [ buildPackages.stdenv.cc ];
      # `elf-header` is null when libc provides `elf.h`.
      nativeBuildInputs = [
        perl
        elf-header
      ]
      ++ lib.optionals stdenvNoCC.hostPlatform.isAndroid [
        bison
        flex
        rsync
      ]
      ++ lib.optionals (stdenvNoCC.buildPlatform.isDarwin && stdenvNoCC.hostPlatform.isMips) [
        darwin-endian-h
        darwin-byteswap-h
      ];

      extraIncludeDirs = lib.optionals (with stdenvNoCC.hostPlatform; isPower && is32bit && isBigEndian) [
        "ppc"
      ];

      inherit patches;

      hardeningDisable = lib.optional stdenvNoCC.buildPlatform.isDarwin "format";

      makeFlags = [
        "SHELL=bash"
        # Avoid use of runtime build->host compilers for checks. These
        # checks only cared to work around bugs in very old compilers, so
        # these changes should be safe.
        "cc-version:=9999"
        "cc-fullversion:=999999"
        # `$(..)` expanded by make alone
        "HOSTCC:=$(CC_FOR_BUILD)"
        "HOSTCXX:=$(CXX_FOR_BUILD)"
        # To properly detect LFS flags 32-bit build environments like
        # pkgsi686Linux.linuxHeaders Kbuild uses this Makefile bit:
        #     HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null)
        #
        # `getconf` is not available in early bootstrap and thus the
        # build fails on filesystems with 64-bit inodes as:
        #     linux-headers> fixdep: error fstat'ing file: scripts/basic/.fixdep.d: Value too large for defined data type
        #
        # Let's hardcode subset of the output of `getconf` for this case.
        "HOST_LFS_CFLAGS=-D_FILE_OFFSET_BITS=64"
      ];

      # Skip clean on darwin, case-sensitivity issues.
      buildPhase =
        lib.optionalString (!stdenvNoCC.buildPlatform.isDarwin) ''
          make mrproper $makeFlags
        ''
        + (
          if stdenvNoCC.hostPlatform.isAndroid then
            ''
              make defconfig
              make headers_install
            ''
          else
            ''
              make headers $makeFlags
            ''
        );

      checkPhase = ''
        make headers_check $makeFlags
      '';

      # The following command requires rsync:
      #   make headers_install INSTALL_HDR_PATH=$out $makeFlags
      # but rsync depends on popt which does not compile on aarch64 without
      # updateAutotoolsGnuConfigScriptsHook which is not enabled in stage2,
      # so we replicate it with cp. This also reduces bootstrap closure size.
      installPhase = ''
        mkdir -p $out
        cp -r usr/include $out
        find $out -type f ! -name '*.h' -delete
      ''
      # Some builds (e.g. KVM) want a kernel.release.
      + ''
        mkdir -p $out/include/config
        echo "${version}-default" > $out/include/config/kernel.release
      '';

      inherit passthru;

      meta = {
        description = "Header files and scripts for Linux kernel";
        license = lib.licenses.gpl2Only;
        platforms = lib.platforms.linux;
        teams = [ lib.teams.linux-kernel ];
      };
    };
in
{
  inherit makeLinuxHeaders;

  linuxHeaders =
    let
      version = "6.18.7";
    in
    makeLinuxHeaders {
      inherit version;
      src = fetchurl {
        url = "mirror://kernel/linux/kernel/v${lib.versions.major version}.x/linux-${version}.tar.xz";
        hash = "sha256-tyak0Vz5rgYhm1bYeCB3bjTYn7wTflX7VKm5wwFbjx4=";
      };
      patches = [
        ./no-relocs.patch # for building x86 kernel headers on non-ELF platforms
      ];
      passthru.updateScript = nix-update-script {
        extraArgs = [
          "--version"
          "${linux_latest.meta.branch}"
        ];
      };
    };
}