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 perl
63 elf-header
64 ]
65 ++ lib.optionals stdenvNoCC.hostPlatform.isAndroid [
66 bison
67 flex
68 rsync
69 ]
70 ++ lib.optionals (stdenvNoCC.buildPlatform.isDarwin && stdenvNoCC.hostPlatform.isMips) [
71 darwin-endian-h
72 darwin-byteswap-h
73 ];
74
75 extraIncludeDirs = lib.optionals (with stdenvNoCC.hostPlatform; isPower && is32bit && isBigEndian) [
76 "ppc"
77 ];
78
79 inherit patches;
80
81 hardeningDisable = lib.optional stdenvNoCC.buildPlatform.isDarwin "format";
82
83 makeFlags = [
84 "SHELL=bash"
85 # Avoid use of runtime build->host compilers for checks. These
86 # checks only cared to work around bugs in very old compilers, so
87 # these changes should be safe.
88 "cc-version:=9999"
89 "cc-fullversion:=999999"
90 # `$(..)` expanded by make alone
91 "HOSTCC:=$(CC_FOR_BUILD)"
92 "HOSTCXX:=$(CXX_FOR_BUILD)"
93 # To properly detect LFS flags 32-bit build environments like
94 # pkgsi686Linux.linuxHeaders Kbuild uses this Makefile bit:
95 # HOST_LFS_CFLAGS := $(shell getconf LFS_CFLAGS 2>/dev/null)
96 #
97 # `getconf` is not available in early bootstrap and thus the
98 # build fails on filesystems with 64-bit inodes as:
99 # linux-headers> fixdep: error fstat'ing file: scripts/basic/.fixdep.d: Value too large for defined data type
100 #
101 # Let's hardcode subset of the output of `getconf` for this case.
102 "HOST_LFS_CFLAGS=-D_FILE_OFFSET_BITS=64"
103 ];
104
105 # Skip clean on darwin, case-sensitivity issues.
106 buildPhase =
107 lib.optionalString (!stdenvNoCC.buildPlatform.isDarwin) ''
108 make mrproper $makeFlags
109 ''
110 + (
111 if stdenvNoCC.hostPlatform.isAndroid then
112 ''
113 make defconfig
114 make headers_install
115 ''
116 else
117 ''
118 make headers $makeFlags
119 ''
120 );
121
122 checkPhase = ''
123 make headers_check $makeFlags
124 '';
125
126 # The following command requires rsync:
127 # make headers_install INSTALL_HDR_PATH=$out $makeFlags
128 # but rsync depends on popt which does not compile on aarch64 without
129 # updateAutotoolsGnuConfigScriptsHook which is not enabled in stage2,
130 # so we replicate it with cp. This also reduces bootstrap closure size.
131 installPhase = ''
132 mkdir -p $out
133 cp -r usr/include $out
134 find $out -type f ! -name '*.h' -delete
135 ''
136 # Some builds (e.g. KVM) want a kernel.release.
137 + ''
138 mkdir -p $out/include/config
139 echo "${version}-default" > $out/include/config/kernel.release
140 '';
141
142 meta = {
143 description = "Header files and scripts for Linux kernel";
144 license = lib.licenses.gpl2Only;
145 platforms = lib.platforms.linux;
146 teams = [ lib.teams.linux-kernel ];
147 };
148 };
149in
150{
151 inherit makeLinuxHeaders;
152
153 linuxHeaders =
154 let
155 version = "6.16";
156 in
157 makeLinuxHeaders {
158 inherit version;
159 src = fetchurl {
160 url = "mirror://kernel/linux/kernel/v${lib.versions.major version}.x/linux-${version}.tar.xz";
161 hash = "sha256-Gkvi/mtSRqpKyJh6ikrzTEKo3X0ItGq0hRa8wb77zYM=";
162 };
163 patches = [
164 ./no-relocs.patch # for building x86 kernel headers on non-ELF platforms
165 ];
166 };
167}