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