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