1{ stdenvNoCC, lib, buildPackages, fetchurl, perl, elf-header
2, bison, flex, rsync
3, writeTextFile
4}:
5
6let
7
8 # As part of building a hostPlatform=mips kernel, Linux creates and runs a
9 # tiny utility `arch/mips/boot/tools/relocs_main.c` for the buildPlatform.
10 # This utility references a glibc-specific header `byteswap.h`. There is a
11 # compatibility header in gnulib for most BSDs, but not for Darwin, so we
12 # synthesize one here.
13 darwin-endian-h = writeTextFile {
14 name = "endian-h";
15 text = ''
16 #include <byteswap.h>
17 '';
18 destination = "/include/endian.h";
19 };
20 darwin-byteswap-h = writeTextFile {
21 name = "byteswap-h";
22 text = ''
23 #pragma once
24 #include <libkern/OSByteOrder.h>
25 #define bswap_16 OSSwapInt16
26 #define bswap_32 OSSwapInt32
27 #define bswap_64 OSSwapInt64
28 '';
29 destination = "/include/byteswap.h";
30 };
31
32 makeLinuxHeaders = { src, version, patches ? [] }: stdenvNoCC.mkDerivation {
33 inherit src;
34
35 pname = "linux-headers";
36 inherit version;
37
38 ARCH = stdenvNoCC.hostPlatform.linuxArch;
39
40 strictDeps = true;
41 enableParallelBuilding = true;
42
43 # It may look odd that we use `stdenvNoCC`, and yet explicit depend on a cc.
44 # We do this so we have a build->build, not build->host, C compiler.
45 depsBuildBuild = [ buildPackages.stdenv.cc ];
46 # `elf-header` is null when libc provides `elf.h`.
47 nativeBuildInputs = [
48 perl elf-header
49 ] ++ lib.optionals stdenvNoCC.hostPlatform.isAndroid [
50 bison flex rsync
51 ] ++ lib.optionals (stdenvNoCC.buildPlatform.isDarwin &&
52 stdenvNoCC.hostPlatform.isMips) [
53 darwin-endian-h
54 darwin-byteswap-h
55 ];
56
57 extraIncludeDirs = lib.optionals (with stdenvNoCC.hostPlatform; isPower && is32bit && isBigEndian) ["ppc"];
58
59 inherit patches;
60
61 hardeningDisable = lib.optional stdenvNoCC.buildPlatform.isDarwin "format";
62
63 makeFlags = [
64 "SHELL=bash"
65 # Avoid use of runtime build->host compilers for checks. These
66 # checks only cared to work around bugs in very old compilers, so
67 # these changes should be safe.
68 "cc-version:=9999"
69 "cc-fullversion:=999999"
70 # `$(..)` expanded by make alone
71 "HOSTCC:=$(CC_FOR_BUILD)"
72 "HOSTCXX:=$(CXX_FOR_BUILD)"
73 ];
74
75 # Skip clean on darwin, case-sensitivity issues.
76 buildPhase = lib.optionalString (!stdenvNoCC.buildPlatform.isDarwin) ''
77 make mrproper $makeFlags
78 '' + (if stdenvNoCC.hostPlatform.isAndroid then ''
79 make defconfig
80 make headers_install
81 '' else ''
82 make headers $makeFlags
83 '');
84
85 checkPhase = ''
86 make headers_check $makeFlags
87 '';
88
89 # The following command requires rsync:
90 # make headers_install INSTALL_HDR_PATH=$out $makeFlags
91 # but rsync depends on popt which does not compile on aarch64 without
92 # updateAutotoolsGnuConfigScriptsHook which is not enabled in stage2,
93 # so we replicate it with cp. This also reduces bootstrap closure size.
94 installPhase = ''
95 mkdir -p $out
96 cp -r usr/include $out
97 find $out -type f ! -name '*.h' -delete
98 ''
99 # Some builds (e.g. KVM) want a kernel.release.
100 + ''
101 mkdir -p $out/include/config
102 echo "${version}-default" > $out/include/config/kernel.release
103 '';
104
105 meta = with lib; {
106 description = "Header files and scripts for Linux kernel";
107 license = licenses.gpl2;
108 platforms = platforms.linux;
109 };
110 };
111in {
112 inherit makeLinuxHeaders;
113
114 linuxHeaders = let version = "6.3"; in
115 makeLinuxHeaders {
116 inherit version;
117 src = fetchurl {
118 url = "mirror://kernel/linux/kernel/v${lib.versions.major version}.x/linux-${version}.tar.xz";
119 hash = "sha256-ujSR9e1r0nCjcMRAQ049aQhfzdUoki+gHnPXZX23Ox4=";
120 };
121 patches = [
122 ./no-relocs.patch # for building x86 kernel headers on non-ELF platforms
123 ];
124 };
125}