uboot: (firmwareOdroidC2/C4) don't invoke patch tool, use patches = [] instead

https://github.com/NixOS/nixpkgs/blob/master/pkgs/stdenv/generic/setup.sh#L948
this can do it nicely.

Signed-off-by: Anton Arapov <anton@deadbeef.mx>
This commit is contained in:
Anton Arapov 2021-04-03 12:58:10 +02:00 committed by Alan Daniels
commit 56de2bcd43
30691 changed files with 3076956 additions and 0 deletions

View file

@ -0,0 +1,18 @@
(defpackage org.lispbuilds.nix/api
(:documentation "Public interface of org.lispbuilds.nix")
(:use :cl)
(:export
:import-lisp-packages
:database->nix-expression))
(in-package org.lispbuilds.nix/api)
(defgeneric import-lisp-packages (repository database)
(:documentation
"Import Lisp packages (ASDF systems) from repository (Quicklisp,
Ultralisp etc.) into a package database."))
(defgeneric database->nix-expression (database outfile)
(:documentation
"Generate a nix expression from the package database and write it
into outfile."))

View file

@ -0,0 +1,134 @@
(defpackage org.lispbuilds.nix/database/sqlite
(:use :cl)
(:import-from :str)
(:import-from :sqlite)
(:import-from :alexandria :read-file-into-string)
(:import-from :arrow-macros :->>)
(:import-from
:org.lispbuilds.nix/util
:replace-regexes)
(:import-from
:org.lispbuilds.nix/nix
:nix-eval
:system-master
:nixify-symbol
:make-pname
:*nix-attrs-depth*)
(:import-from
:org.lispbuilds.nix/api
:database->nix-expression)
(:export :sqlite-database :init-db)
(:local-nicknames
(:json :com.inuoe.jzon)))
(in-package org.lispbuilds.nix/database/sqlite)
(defclass sqlite-database ()
((url :initarg :url
:reader database-url
:initform (error "url required"))
(init-file :initarg :init-file
:reader init-file
:initform (error "init file required"))))
(defun init-db (db init-file)
(let ((statements (->> (read-file-into-string init-file)
(replace-regexes '(".*--.*") '(""))
(substitute #\Space #\Newline)
(str:collapse-whitespaces)
(str:split #\;)
(mapcar #'str:trim)
(remove-if #'str:emptyp))))
(sqlite:with-transaction db
(dolist (s statements)
(sqlite:execute-non-query db s)))))
;; Writing Nix
(defparameter prelude "
# This file was auto-generated by nix-quicklisp.lisp
{ runCommand, fetchzip, pkgs, ... }:
# Ensures that every non-slashy `system` exists in a unique .asd file.
# (Think cl-async-base being declared in cl-async.asd upstream)
#
# This is required because we're building and loading a system called
# `system`, not `asd`, so otherwise `system` would not be loadable
# without building and loading `asd` first.
#
let createAsd = { url, sha256, asd, system }:
let
src = fetchzip { inherit url sha256; };
in runCommand \"source\" {} ''
mkdir -pv $out
cp -r ${src}/* $out
find $out -name \"${asd}.asd\" | while read f; do mv -fv $f $(dirname $f)/${system}.asd || true; done
'';
getAttr = builtins.getAttr;
in {")
(defmethod database->nix-expression ((database sqlite-database) outfile)
(sqlite:with-open-database (db (database-url database))
(with-open-file (f outfile
:direction :output
:if-exists :supersede)
;; Fix known problematic packages before dumping the nix file.
(sqlite:execute-non-query db
"create temp table fixed_systems as select * from system_view")
(sqlite:execute-non-query db
"alter table fixed_systems add column systems")
(sqlite:execute-non-query db
"update fixed_systems set systems = json_array(name)")
(sqlite:execute-non-query db
"alter table fixed_systems add column asds")
(sqlite:execute-non-query db
"update fixed_systems set asds = json_array(name)")
(format f prelude)
(dolist (p (sqlite:execute-to-list db "select * from fixed_systems"))
(destructuring-bind (name version asd url sha256 deps systems asds) p
(format f "~% ")
(let ((*nix-attrs-depth* 1))
(format
f
"~a = ~a;"
(nix-eval `(:symbol ,name))
(nix-eval
`(:attrs
("pname" (:string ,(make-pname name)))
("version" (:string ,version))
("asds" (:list
,@(mapcar (lambda (asd)
`(:string ,(system-master asd)))
(coerce (json:parse asds) 'list))))
("src" (:funcall
"createAsd"
(:attrs
("url" (:string ,url))
("sha256" (:string ,sha256))
("system" (:string ,(system-master name)))
("asd" (:string ,asd)))))
("systems" (:list
,@(mapcar (lambda (sys)
`(:string ,sys))
(coerce (json:parse systems) 'list))))
("lispLibs" (:list
,@(mapcar (lambda (dep)
`(:funcall
"getAttr"
(:string ,(nixify-symbol dep))
(:symbol "pkgs")))
(remove "asdf"
(str:split-omit-nulls #\, deps)
:test #'string=))))))))))
(format f "~%}~%"))))

View file

@ -0,0 +1,41 @@
CREATE TABLE IF NOT EXISTS sha256 (
id integer PRIMARY KEY AUTOINCREMENT,
url text UNIQUE,
hash text NOT NULL,
created real DEFAULT (julianday('now'))
);
CREATE TABLE IF NOT EXISTS system (
id integer PRIMARY KEY AUTOINCREMENT,
name text NOT NULL,
version text NOT NULL,
asd text NOT NULL,
created real DEFAULT (julianday('now')),
UNIQUE(name, version)
);
CREATE TABLE IF NOT EXISTS dep (
system_id integer NOT NULL REFERENCES system(id),
dep_id integer NOT NULL REFERENCES system(id),
PRIMARY KEY (system_id, dep_id)
);
CREATE TABLE IF NOT EXISTS src (
sha256_id integer REFERENCES sha256(id),
system_id integer UNIQUE REFERENCES system(id)
);
DROP VIEW IF EXISTS system_view;
CREATE VIEW IF NOT EXISTS system_view AS
SELECT
sys.name,
sys.version,
sys.asd,
sha.url,
sha.hash,
group_concat((SELECT name FROM system WHERE id = dep.dep_id)) as deps
FROM system sys
JOIN src ON src.system_id = sys.id
JOIN sha256 sha ON sha.id = src.sha256_id
LEFT JOIN dep ON dep.system_id = sys.id
GROUP BY sys.name;

View file

@ -0,0 +1,40 @@
(defpackage org.lispbuilds.nix/main
(:use :common-lisp
:org.lispbuilds.nix/database/sqlite
:org.lispbuilds.nix/repository/quicklisp
:org.lispbuilds.nix/api))
(in-package org.lispbuilds.nix/main)
(defun resource (name type)
(make-pathname
:defaults (asdf:system-source-directory :org.lispbuilds.nix)
:name name
:type type))
(defvar *sqlite*
(make-instance
'sqlite-database
:init-file (resource "init" "sql")
:url "packages.sqlite"))
(defvar *quicklisp*
(make-instance
'quicklisp-repository
:dist-url
"https://beta.quicklisp.org/dist/quicklisp/2021-12-30/"))
(defun run-importers ()
(import-lisp-packages *quicklisp* *sqlite*)
(format t "Imported packages from quicklisp to ~A~%"
(truename "packages.sqlite")))
(defun gen-nix-file ()
(database->nix-expression *sqlite* "imported.nix")
(format t "Dumped nix file to ~a~%"
(truename "imported.nix")))
(defun main ()
(format t "~%")
(run-importers)
(gen-nix-file))

View file

@ -0,0 +1,81 @@
(defpackage org.lispbuilds.nix/nix
(:documentation "Utilities for generating Nix code")
(:use :cl)
(:import-from :str)
(:import-from :ppcre)
(:import-from :arrow-macros :->>)
(:import-from :org.lispbuilds.nix/util :replace-regexes)
(:export
:nix-eval
:system-master
:nixify-symbol
:make-pname
:*nix-attrs-depth*))
(in-package org.lispbuilds.nix/nix)
;; Path names are alphanumeric and can include the symbols +-._?= and
;; must not begin with a period.
(defun make-pname (string)
(replace-regexes '("^[.]" "[^a-zA-Z0-9+-._?=]")
'("_" "_")
string))
(defun system-master (system)
(first (str:split "/" system)))
;;;; Nix generation
(defun nix-eval (exp)
(assert (consp exp))
(ecase (car exp)
(:string (nix-string (cadr exp)))
(:list (apply #'nix-list (rest exp)))
(:funcall (apply #'nix-funcall (rest exp)))
(:attrs (nix-attrs (cdr exp)))
(:merge (apply #'nix-merge (cdr exp)))
(:symbol (nix-symbol (cadr exp)))))
(defun nix-string (object)
(format nil "\"~a\"" object))
(defun nixify-symbol (string)
(flet ((fix-special-chars (str)
(replace-regexes '("[+]$" "[+][/]" "[+]" "[.]" "[/]")
'("_plus" "_plus/" "_plus_" "_dot_" "_slash_")
str)))
(if (ppcre:scan "^[0-9]" string)
(str:concat "_" (fix-special-chars string))
(fix-special-chars string))))
(defun nix-symbol (object)
(nixify-symbol (format nil "~a" object)))
(defun nix-list (&rest things)
(format nil "[ ~{~A~^ ~} ]" (mapcar 'nix-eval things)))
(defvar *nix-attrs-depth* 0)
(defun nix-attrs (keyvals)
(let ((*nix-attrs-depth* (1+ *nix-attrs-depth*)))
(format
nil
(->> "{~%*depth*~{~{~A = ~A;~}~^~%*depth*~}~%*depth-1*}"
(str:replace-all "*depth*" (str:repeat *nix-attrs-depth* " "))
(str:replace-all "*depth-1*" (str:repeat (1- *nix-attrs-depth*) " ")))
(mapcar (lambda (keyval)
(let ((key (car keyval))
(val (cadr keyval)))
(list (nix-symbol key)
(nix-eval val))))
keyvals))))
(defun nix-funcall (fun &rest args)
(format nil "(~a ~{~a~^ ~})"
(nixify-symbol fun)
(mapcar 'nix-eval args)))
(defun nix-merge (a b)
(format nil "(~a // ~b)"
(nix-eval a)
(nix-eval b)))

View file

@ -0,0 +1,24 @@
(defsystem org.lispbuilds.nix
:class :package-inferred-system
:description "Utilities for importing ASDF systems into Nix"
:depends-on (
:alexandria
:str
:cl-ppcre
:sqlite
:dexador
:arrow-macros
:com.inuoe.jzon
:org.lispbuilds.nix/api
:org.lispbuilds.nix/repository/quicklisp
:org.lispbuilds.nix/database/sqlite
))
(register-system-packages
"cl-ppcre"
'(:ppcre))
(register-system-packages
"dexador"
'(:dex))

View file

@ -0,0 +1,199 @@
(defpackage org.lispbuilds.nix/repository/quicklisp
(:use :cl)
(:import-from :dex)
(:import-from :alexandria :read-file-into-string :ensure-list)
(:import-from :arrow-macros :->>)
(:import-from :str)
(:import-from
:org.lispbuilds.nix/database/sqlite
:sqlite-database
:init-db
:database-url
:init-file)
(:import-from
:org.lispbuilds.nix/api
:import-lisp-packages)
(:import-from
:org.lispbuilds.nix/util
:replace-regexes)
(:export :quicklisp-repository)
(:local-nicknames
(:json :com.inuoe.jzon)))
(in-package org.lispbuilds.nix/repository/quicklisp)
(defclass quicklisp-repository ()
((dist-url :initarg :dist-url
:reader dist-url
:initform (error "dist url required"))))
(defun clear-line ()
(write-char #\Return *error-output*)
(write-char #\Escape *error-output*)
(write-char #\[ *error-output*)
(write-char #\K *error-output*))
(defun status (&rest format-args)
(clear-line)
(apply #'format (list* *error-output* format-args))
(force-output *error-output*))
;; TODO: This should not know about the imported.nix file.
(defun init-tarball-hashes (database)
(status "no packages.sqlite - will pre-fill tarball hashes from ~A to save time~%"
(truename "imported.nix"))
(let* ((lines (uiop:read-file-lines "imported.nix"))
(lines (remove-if-not
(lambda (line)
(let ((trimmed (str:trim-left line)))
(or (str:starts-with-p "url = " trimmed)
(str:starts-with-p "sha256 = " trimmed))))
lines))
(lines (mapcar
(lambda (line)
(multiple-value-bind (whole groups)
(ppcre:scan-to-strings "\"\(.*\)\"" line)
(declare (ignore whole))
(svref groups 0)))
lines)))
(sqlite:with-open-database (db (database-url database))
(init-db db (init-file database))
(sqlite:with-transaction db
(loop while lines do
(sqlite:execute-non-query db
"insert or ignore into sha256(url,hash) values (?,?)"
(prog1 (first lines) (setf lines (rest lines)))
(prog1 (first lines) (setf lines (rest lines))))))
(status "OK, imported ~A hashes into DB.~%"
(sqlite:execute-single db
"select count(*) from sha256")))))
(defmethod import-lisp-packages ((repository quicklisp-repository)
(database sqlite-database))
;; If packages.sqlite is missing, we should populate the sha256
;; table to speed things up.
(unless (probe-file (database-url database))
(init-tarball-hashes database))
(let* ((db (sqlite:connect (database-url database)))
(systems-url (str:concat (dist-url repository) "systems.txt"))
(releases-url (str:concat (dist-url repository) "releases.txt"))
(systems-lines (rest (butlast (str:split #\Newline (dex:get systems-url)))))
(releases-lines (rest (butlast (str:split #\Newline (dex:get releases-url))))))
(flet ((sql-query (sql &rest params)
(apply #'sqlite:execute-to-list (list* db sql params))))
;; Ensure database schema
(init-db db (init-file database))
;; Prepare temporary tables for efficient access
(sql-query "create temp table if not exists quicklisp_system
(project, asd, name unique, deps)")
(sql-query "create temp table if not exists quicklisp_release
(project unique, url, size, md5, sha1, prefix not null, asds)")
(sqlite:with-transaction db
(dolist (line systems-lines)
(destructuring-bind (project asd name &rest deps)
(str:words line)
(sql-query
"insert or ignore into quicklisp_system values(?,?,?,?)"
project asd name (json:stringify (coerce deps 'vector))))))
(sqlite:with-transaction db
(dolist (line releases-lines)
(destructuring-bind (project url size md5 sha1 prefix &rest asds)
(str:words line)
(sql-query
"insert or ignore into quicklisp_release values(?,?,?,?,?,?,?)"
project url size md5 sha1 prefix (json:stringify (coerce
asds
'vector))))))
(sqlite:with-transaction db
;; Should these be temp tables, that then get queried by
;; system name? This looks like it uses a lot of memory.
(let ((systems
(sql-query
"with pkg as (
select
name, asd, url, deps,
ltrim(replace(prefix, r.project, ''), '-_') as version
from quicklisp_system s, quicklisp_release r
where s.project = r.project
)
select
name, version, asd, url,
(select json_group_array(
json_array(value, (select version from pkg where name=value))
)
from json_each(deps)) as deps
from pkg"
)))
;; First pass: insert system and source tarball informaton.
;; Can't insert dependency information, because this works
;; on system ids in the database and they don't exist
;; yet. Could it be better to just base dependencies on
;; names? But then ACID is lost.
(dolist (system systems)
(destructuring-bind (name version asd url deps) system
(declare (ignore deps))
(status "importing system '~a-~a'" name version)
(let ((hash (nix-prefetch-tarball url db)))
(sql-query
"insert or ignore into system(name,version,asd) values (?,?,?)"
name version asd)
(sql-query
"insert or ignore into sha256(url,hash) values (?,?)"
url hash)
(sql-query
"insert or ignore into src values
((select id from sha256 where url=?),
(select id from system where name=? and version=?))"
url name version))))
;; Second pass: connect the in-database systems with
;; dependency information
(dolist (system systems)
(destructuring-bind (name version asd url deps) system
(declare (ignore asd url))
(dolist (dep (coerce (json:parse deps) 'list))
(destructuring-bind (dep-name dep-version) (coerce dep 'list)
(if (eql dep-version 'NULL)
(warn "Bad data in Quicklisp: ~a has no version" dep-name)
(sql-query
"insert or ignore into dep values
((select id from system where name=? and version=?),
(select id from system where name=? and version=?))"
name version
dep-name dep-version))))))))))
(write-char #\Newline *error-output*))
(defun shell-command-to-string (cmd)
;; Clearing the library path is needed to prevent a bug, where the
;; called subprocess uses a different glibc than the SBCL process
;; is. In that case, the call to execve attempts to load the
;; libraries used by SBCL from LD_LIBRARY_PATH using a different
;; glibc than they expect, which errors out.
(let ((ld-library-path (uiop:getenv "LD_LIBRARY_PATH")))
(setf (uiop:getenv "LD_LIBRARY_PATH") "")
(unwind-protect
(uiop:run-program cmd :output '(:string :stripped t))
(setf (uiop:getenv "LD_LIBRARY_PATH") ld-library-path))))
(defun nix-prefetch-tarball (url db)
(restart-case
(compute-sha256 url db)
(try-again ()
:report "Try downloading again"
(nix-prefetch-tarball url db))))
(defun compute-sha256 (url db)
(or (sqlite:execute-single db "select hash from sha256 where url=?" url)
(let ((sha256 (shell-command-to-string (str:concat "nix-prefetch-url --unpack " url))))
sha256)))

View file

@ -0,0 +1,16 @@
(defpackage org.lispbuilds.nix/util
(:use :cl)
(:import-from :ppcre)
(:export
:replace-regexes))
(in-package org.lispbuilds.nix/util)
(defun replace-regexes (from to str)
(assert (= (length from) (length to)))
(if (null from)
str
(replace-regexes
(rest from)
(rest to)
(ppcre:regex-replace-all (first from) str (first to)))))