linux-module.scm 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. ;;; GNU Guix --- Functional package management for GNU
  2. ;;; Copyright © 2019 Danny Milosavljevic <dannym@scratchpost.org>
  3. ;;; Copyright © 2020 Mathieu Othacehe <m.othacehe@gmail.com>
  4. ;;;
  5. ;;; This file is part of GNU Guix.
  6. ;;;
  7. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  8. ;;; under the terms of the GNU General Public License as published by
  9. ;;; the Free Software Foundation; either version 3 of the License, or (at
  10. ;;; your option) any later version.
  11. ;;;
  12. ;;; GNU Guix is distributed in the hope that it will be useful, but
  13. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  14. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. ;;; GNU General Public License for more details.
  16. ;;;
  17. ;;; You should have received a copy of the GNU General Public License
  18. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  19. (define-module (guix build-system linux-module)
  20. #:use-module (guix store)
  21. #:use-module (guix utils)
  22. #:use-module (guix derivations)
  23. #:use-module (guix search-paths)
  24. #:use-module (guix build-system)
  25. #:use-module (guix build-system gnu)
  26. #:use-module (guix packages)
  27. #:use-module (ice-9 match)
  28. #:export (%linux-module-build-system-modules
  29. linux-module-build
  30. linux-module-build-system))
  31. ;; Commentary:
  32. ;;
  33. ;; Code:
  34. (define %linux-module-build-system-modules
  35. ;; Build-side modules imported by default.
  36. `((guix build linux-module-build-system)
  37. ,@%gnu-build-system-modules))
  38. (define (default-linux)
  39. "Return the default Linux package."
  40. ;; Do not use `@' to avoid introducing circular dependencies.
  41. (let ((module (resolve-interface '(gnu packages linux))))
  42. (module-ref module 'linux-libre)))
  43. (define (system->arch system)
  44. (let ((module (resolve-interface '(gnu packages linux))))
  45. ((module-ref module 'system->linux-architecture) system)))
  46. (define (make-linux-module-builder linux)
  47. (package
  48. (inherit linux)
  49. (name (string-append (package-name linux) "-module-builder"))
  50. (inputs
  51. `(("linux" ,linux)))
  52. (arguments
  53. (substitute-keyword-arguments (package-arguments linux)
  54. ((#:phases phases)
  55. `(modify-phases ,phases
  56. (replace 'build
  57. (lambda _
  58. (invoke "make" "modules_prepare")))
  59. (delete 'strip) ; faster.
  60. (replace 'install
  61. (lambda* (#:key inputs outputs #:allow-other-keys)
  62. (let* ((out (assoc-ref outputs "out"))
  63. (out-lib-build (string-append out "/lib/modules/build")))
  64. ;; Delete some huge items that we probably don't need.
  65. ;; TODO: Only preserve the minimum, i.e. [Kbuild], Kconfig,
  66. ;; scripts, include, ".config".
  67. (copy-recursively "." out-lib-build)
  68. (for-each (lambda (name)
  69. (when (file-exists? name)
  70. (delete-file-recursively name)))
  71. (map (lambda (name)
  72. (string-append out-lib-build "/" name))
  73. '("arch" ; 137 MB
  74. ;"tools" ; 44 MB ; Note: is built by our 'build phase.
  75. "tools/testing" ; 14 MB
  76. "tools/perf" ; 17 MB
  77. "drivers" ; 600 MB
  78. "Documentation" ; 52 MB
  79. "fs" ; 43 MB
  80. "net" ; 33 MB
  81. "samples" ; 2 MB
  82. "sound"))) ; 40 MB
  83. ;; Reinstate arch/**/dts since "scripts/dtc" depends on it.
  84. ;; Reinstate arch/**/include directories.
  85. ;; Reinstate arch/**/Makefile.
  86. ;; Reinstate arch/**/module.lds.
  87. (for-each
  88. (lambda (name)
  89. (mkdir-p (dirname (string-append out-lib-build "/" name)))
  90. (copy-recursively name
  91. (string-append out-lib-build "/" name)))
  92. (append (find-files "arch" "^(dts|include)$" #:directories? #t)
  93. (find-files "arch" "^(Makefile|module.lds)$")))
  94. (let* ((linux (assoc-ref inputs "linux")))
  95. (install-file (string-append linux "/System.map")
  96. out-lib-build)
  97. (let ((source (string-append linux "/Module.symvers")))
  98. (when (file-exists? source)
  99. (install-file source out-lib-build))))
  100. #t)))))))))
  101. (define* (lower name
  102. #:key source inputs native-inputs outputs
  103. system target
  104. (linux (default-linux))
  105. #:allow-other-keys
  106. #:rest arguments)
  107. "Return a bag for NAME."
  108. (define private-keywords
  109. `(#:source #:target #:gcc #:kmod #:linux #:inputs #:native-inputs
  110. ,@(if target '() '(#:target))))
  111. (bag
  112. (name name)
  113. (system system) (target target)
  114. (build-inputs `(,@(if source
  115. `(("source" ,source))
  116. '())
  117. ,@native-inputs
  118. ;; TODO: Remove "gmp", "mpfr", "mpc" since they are
  119. ;; only needed to compile the gcc plugins. Maybe
  120. ;; remove "flex", "bison", "elfutils", "perl",
  121. ;; "openssl". That leaves very little ("bc", "gcc",
  122. ;; "kmod").
  123. ,@(package-native-inputs linux)
  124. ,@(if target
  125. ;; Use the standard cross inputs of
  126. ;; 'gnu-build-system'.
  127. (standard-cross-packages target 'host)
  128. '())
  129. ;; Keep the standard inputs of 'gnu-build-system'.
  130. ,@(standard-packages)))
  131. (host-inputs `(,@inputs
  132. ("linux" ,linux)
  133. ("linux-module-builder"
  134. ,(make-linux-module-builder linux))))
  135. (target-inputs (if target
  136. (standard-cross-packages target 'target)
  137. '()))
  138. (outputs outputs)
  139. (build (if target linux-module-build-cross linux-module-build))
  140. (arguments (strip-keyword-arguments private-keywords arguments))))
  141. (define* (linux-module-build store name inputs
  142. #:key
  143. target
  144. (search-paths '())
  145. (tests? #t)
  146. (phases '(@ (guix build linux-module-build-system)
  147. %standard-phases))
  148. (outputs '("out"))
  149. (make-flags ''())
  150. (system (%current-system))
  151. (guile #f)
  152. (substitutable? #t)
  153. (imported-modules
  154. %linux-module-build-system-modules)
  155. (modules '((guix build linux-module-build-system)
  156. (guix build utils))))
  157. "Build SOURCE using LINUX, and with INPUTS."
  158. (define builder
  159. `(begin
  160. (use-modules ,@modules)
  161. (linux-module-build #:name ,name
  162. #:source ,(match (assoc-ref inputs "source")
  163. (((? derivation? source))
  164. (derivation->output-path source))
  165. ((source)
  166. source)
  167. (source
  168. source))
  169. #:search-paths ',(map search-path-specification->sexp
  170. search-paths)
  171. #:phases ,phases
  172. #:system ,system
  173. #:target ,target
  174. #:arch ,(system->arch (or target system))
  175. #:tests? ,tests?
  176. #:outputs %outputs
  177. #:make-flags ,make-flags
  178. #:inputs %build-inputs)))
  179. (define guile-for-build
  180. (match guile
  181. ((? package?)
  182. (package-derivation store guile system #:graft? #f))
  183. (#f ; the default
  184. (let* ((distro (resolve-interface '(gnu packages commencement)))
  185. (guile (module-ref distro 'guile-final)))
  186. (package-derivation store guile system #:graft? #f)))))
  187. (build-expression->derivation store name builder
  188. #:system system
  189. #:inputs inputs
  190. #:modules imported-modules
  191. #:outputs outputs
  192. #:guile-for-build guile-for-build
  193. #:substitutable? substitutable?))
  194. (define* (linux-module-build-cross
  195. store name
  196. #:key
  197. target native-drvs target-drvs
  198. (guile #f)
  199. (outputs '("out"))
  200. (make-flags ''())
  201. (search-paths '())
  202. (native-search-paths '())
  203. (tests? #f)
  204. (phases '(@ (guix build linux-module-build-system)
  205. %standard-phases))
  206. (system (%current-system))
  207. (substitutable? #t)
  208. (imported-modules
  209. %linux-module-build-system-modules)
  210. (modules '((guix build linux-module-build-system)
  211. (guix build utils))))
  212. (define builder
  213. `(begin
  214. (use-modules ,@modules)
  215. (let ()
  216. (define %build-host-inputs
  217. ',(map (match-lambda
  218. ((name (? derivation? drv) sub ...)
  219. `(,name . ,(apply derivation->output-path drv sub)))
  220. ((name path)
  221. `(,name . ,path)))
  222. native-drvs))
  223. (define %build-target-inputs
  224. ',(map (match-lambda
  225. ((name (? derivation? drv) sub ...)
  226. `(,name . ,(apply derivation->output-path drv sub)))
  227. ((name (? package? pkg) sub ...)
  228. (let ((drv (package-cross-derivation store pkg
  229. target system)))
  230. `(,name . ,(apply derivation->output-path drv sub))))
  231. ((name path)
  232. `(,name . ,path)))
  233. target-drvs))
  234. (linux-module-build #:name ,name
  235. #:source ,(match (assoc-ref native-drvs "source")
  236. (((? derivation? source))
  237. (derivation->output-path source))
  238. ((source)
  239. source)
  240. (source
  241. source))
  242. #:system ,system
  243. #:target ,target
  244. #:arch ,(system->arch (or target system))
  245. #:outputs %outputs
  246. #:make-flags ,make-flags
  247. #:inputs %build-target-inputs
  248. #:native-inputs %build-host-inputs
  249. #:search-paths
  250. ',(map search-path-specification->sexp
  251. search-paths)
  252. #:native-search-paths
  253. ',(map
  254. search-path-specification->sexp
  255. native-search-paths)
  256. #:phases ,phases
  257. #:tests? ,tests?))))
  258. (define guile-for-build
  259. (match guile
  260. ((? package?)
  261. (package-derivation store guile system #:graft? #f))
  262. (#f ; the default
  263. (let* ((distro (resolve-interface '(gnu packages commencement)))
  264. (guile (module-ref distro 'guile-final)))
  265. (package-derivation store guile system #:graft? #f)))))
  266. (build-expression->derivation store name builder
  267. #:system system
  268. #:inputs (append native-drvs target-drvs)
  269. #:outputs outputs
  270. #:modules imported-modules
  271. #:guile-for-build guile-for-build
  272. #:substitutable? substitutable?))
  273. (define linux-module-build-system
  274. (build-system
  275. (name 'linux-module)
  276. (description "The Linux module build system")
  277. (lower lower)))
  278. ;;; linux-module.scm ends here