From cd38a16fbc9f78a8eda90c215a6d69a54f9e6c28 Mon Sep 17 00:00:00 2001 From: nixo Date: Mon, 29 Jul 2019 18:45:26 +0200 Subject: [PATCH 1/2] build: Add julia-build-system. * guix/build/julia-build-system.scm: New file. * guix/build-system/julia.scm: New file. * Makefile.am: Added new files. --- Makefile.am | 2 + guix/build-system/julia.scm | 106 +++++++++++++++++++++ guix/build/julia-build-system.scm | 147 ++++++++++++++++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 guix/build-system/julia.scm create mode 100644 guix/build/julia-build-system.scm diff --git a/Makefile.am b/Makefile.am index 0bd85e8fcf..d14487045a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -125,6 +125,7 @@ MODULES = \ guix/build-system/gnu.scm \ guix/build-system/guile.scm \ guix/build-system/haskell.scm \ + guix/build-system/julia.scm \ guix/build-system/linux-module.scm \ guix/build-system/node.scm \ guix/build-system/perl.scm \ @@ -183,6 +184,7 @@ MODULES = \ guix/build/texlive-build-system.scm \ guix/build/waf-build-system.scm \ guix/build/haskell-build-system.scm \ + guix/build/julia-build-system.scm \ guix/build/linux-module-build-system.scm \ guix/build/store-copy.scm \ guix/build/json.scm \ diff --git a/guix/build-system/julia.scm b/guix/build-system/julia.scm new file mode 100644 index 0000000000..a54b0f37f1 --- /dev/null +++ b/guix/build-system/julia.scm @@ -0,0 +1,106 @@ +(define-module (guix build-system julia) + #:use-module ((guix build julia-build-system)) + #:use-module (gnu packages julia) + #:use-module (guix store) + #:use-module (guix utils) + #:use-module (guix packages) + #:use-module (guix derivations) + #:use-module (guix search-paths) + #:use-module (guix build-system) + #:use-module (guix build-system gnu) + #:use-module (ice-9 match) + #:use-module (srfi srfi-26) + #:export (%julia-build-system-modules + julia-build + julia-build-system)) + +(define %julia-build-system-modules + ;; Build-side modules imported by default. + `((guix build julia-build-system) + ,@%gnu-build-system-modules)) + +(define* (lower name + #:key source inputs native-inputs outputs system target + (julia julia) + #:allow-other-keys + #:rest arguments) + "Return a bag for NAME." + (define private-keywords + '(#:target #:julia #:inputs #:native-inputs)) + + (and (not target) ;XXX: no cross-compilation + (bag + (name name) + (system system) + (host-inputs `(,@(if source + `(("source" ,source)) + '()) + ,@inputs + ;; Keep the standard inputs of 'gnu-build-system'. + ,@(standard-packages))) + (build-inputs `(("julia" ,julia) + ,@native-inputs)) + (outputs outputs) + (build julia-build) + (arguments (strip-keyword-arguments private-keywords arguments))))) + +(define* (julia-build store name inputs + #:key source + (tests? #f) + (parallel-tests? #t) + (test-command ''("make" "check")) + (phases '(@ (guix build julia-build-system) + %standard-phases)) + (outputs '("out")) + ;; (include (quote %default-include)) + ;; (exclude (quote %default-exclude)) + (search-paths '()) + (system (%current-system)) + (guile #f) + (imported-modules %julia-build-system-modules) + (modules '((guix build julia-build-system) + (guix build utils)))) + "Build SOURCE using Julia, and with INPUTS." + (define builder + `(begin + (use-modules ,@modules) + (julia-build #:name ,name + #:source ,(match (assoc-ref inputs "source") + (((? derivation? source)) + (derivation->output-path source)) + ((source) + source) + (source + source)) + #:system ,system + #:test-command ,test-command + #:tests? ,tests? + #:phases ,phases + #:outputs %outputs + ;; #:include ,include + ;; #:exclude ,exclude + #:search-paths ',(map search-path-specification->sexp + search-paths) + #:inputs %build-inputs))) + + (define guile-for-build + (match guile + ((? package?) + (package-derivation store guile system #:graft? #f)) + (#f ; the default + (let* ((distro (resolve-interface '(gnu packages commencement))) + (guile (module-ref distro 'guile-final))) + (package-derivation store guile system #:graft? #f))))) + + (build-expression->derivation store name builder + #:inputs inputs + #:system system + #:modules imported-modules + #:outputs outputs + #:guile-for-build guile-for-build)) + +(define julia-build-system + (build-system + (name 'julia) + (description "The build system for Julia packages") + (lower lower))) diff --git a/guix/build/julia-build-system.scm b/guix/build/julia-build-system.scm new file mode 100644 index 0000000000..5f222f0850 --- /dev/null +++ b/guix/build/julia-build-system.scm @@ -0,0 +1,147 @@ +(define-module (guix build julia-build-system) + #:use-module ((guix build gnu-build-system) #:prefix gnu:) + #:use-module (guix build utils) + ;; #:use-module (srfi srfi-1) + ;; #:use-module (srfi srfi-11) + ;; #:use-module (srfi srfi-26) + ;; #:use-module (ice-9 rdelim) + ;; #:use-module (ice-9 regex) + #:use-module (ice-9 match) + #:export (%standard-phases + julia-create-package-toml + julia-build)) + +;; (define* (set-emacs-load-path #:key source inputs #:allow-other-keys) +;; (define (inputs->directories inputs) +;; "Extract the directory part from INPUTS." +;; (match inputs +;; (((names . directories) ...) directories))) + +;; (define (input-directory->el-directory input-directory) +;; "Return the correct Emacs Lisp directory in INPUT-DIRECTORY or #f, if there +;; is no Emacs Lisp directory." +;; (let ((legacy-elisp-directory (string-append input-directory %legacy-install-suffix)) +;; (guix-elisp-directory +;; (string-append +;; input-directory %install-suffix "/" +;; (store-directory->elpa-name-version input-directory)))) +;; (cond +;; ((file-exists? guix-elisp-directory) guix-elisp-directory) +;; ((file-exists? legacy-elisp-directory) legacy-elisp-directory) +;; (else #f)))) + +;; (define (input-directories->el-directories input-directories) +;; "Return the list of Emacs Lisp directories in INPUT-DIRECTORIES." +;; (filter-map input-directory->el-directory input-directories)) + +;; "Set the EMACSLOADPATH environment variable so that dependencies are found." +;; (let* ((source-directory (getcwd)) +;; (input-elisp-directories (input-directories->el-directories +;; (inputs->directories inputs))) +;; (emacs-load-path-value +;; (string-join +;; (append input-elisp-directories (list source-directory)) +;; ":" 'suffix))) +;; (setenv "EMACSLOADPATH" emacs-load-path-value) +;; (format #t "environment variable `EMACSLOADPATH' set to ~a\n" +;; emacs-load-path-value))) + + +(define* (install #:key outputs source #:allow-other-keys) + (let* ((out (assoc-ref outputs "out")) + (package-dir (string-append out "/share/julia/packages/" + (string-append + (strip-store-file-name source))))) + (mkdir-p package-dir) + (copy-recursively source package-dir)) + #t) + +;; FIXME: Precompilation is working, but I don't know how to tell +;; julia to use use it. If setting HOME to +;; /gnu/store/xib48jxkhiy0gylnm3q430zfwk6am47h-profile/share/julia/compiled/, +;; julia tries to write files there +(define* (precompile #:key outputs source inputs #:allow-other-keys) + (define (inputs->directories inputs) + "Extract the directory part from INPUTS." + (match inputs + (((names . directories) ...) directories))) + (let* ((out (assoc-ref outputs "out")) + (builddir (string-append out "/share/julia/")) + (pacakge (strip-store-file-name source))) + (mkdir-p builddir) + (setenv "JULIA_DEPOT_PATH" builddir) + (setenv "JULIA_LOAD_PATH" + (string-append + "@stdlib:" + (string-append out "/share/julia/packages/:") + (string-join (inputs->directories inputs) "/share/julia/packages/:"))) + ;; (invoke "julia" "-e" (string-append "println(LOAD_PATH)")) + (invoke "julia" "-e" (string-append "using " pacakge)) + ) + #t) + +;; (define* (check #:key outputs source inputs #:allow-other-keys) +;; (define (inputs->directories inputs) +;; "Extract the directory part from INPUTS." +;; (match inputs +;; (((names . directories) ...) directories))) +;; (let* ((out (assoc-ref outputs "out")) +;; (builddir (string-append out "/share/julia/")) +;; (pacakge (strip-store-file-name source))) +;; (mkdir-p builddir) +;; (setenv "JULIA_DEPOT_PATH" builddir) +;; (setenv "JULIA_LOAD_PATH" +;; (string-append +;; "@:@v#.#:@stdlib:" +;; (string-append out "/share/julia/packages/:") +;; (string-join (inputs->directories inputs) "/share/julia/packages/:"))) +;; ;; (invoke "julia" "-e" (string-append "println(LOAD_PATH)")) +;; (invoke "julia" "-e" (string-append "using Pkg; Pkg.test(\"" pacakge "\")")) +;; ) +;; #t) + +;;* +(define (julia-create-package-toml outputs source + name uuid version + deps) + (let ((f (open-file + (string-append + (assoc-ref outputs "out") + "/share/julia/packages/" + (string-append + name "/Project.toml")) + "w"))) + (display (string-append + " +name = \"" name "\" +uuid = \"" uuid "\" +version = \"" version "\" +") f) + (when (not (null? deps)) + (display "[deps]\n" f) + (for-each (lambda dep + (display (string-append (car (car dep)) " = \"" (cdr (car dep)) "\"\n") + f)) + deps)) + (close-port f)) + #t) + +(define %standard-phases + (modify-phases gnu:%standard-phases + (replace 'install install) + (add-after 'install 'precompile precompile) + ;; (replace 'check check) + ;; (add-after 'unpack 'set-julia-load-path set-julia-load-path) + (delete 'configure) + (delete 'bootstrap) + (delete 'patch-usr-bin-file) + (delete 'build) + (delete 'reset-gzip-timestamps) + (delete 'check))) + +(define* (julia-build #:key inputs (phases %standard-phases) + #:allow-other-keys #:rest args) + "Build the given Julia package, applying all of PHASES in order." + (apply gnu:gnu-build + #:inputs inputs #:phases phases + args)) -- 2.22.0