;; bild - a simple build tool ;; ;;; Commentary: ;; ;; Design constraints ;; ;; - only input is a namespace, no subcommands, no packages ;; - no need to write specific build rules ;; - one rule for hs, one for rs, one for scm, and so on ;; - no need to distinguish between exe and lib, just have a single output ;; - never concerned with deployment/packaging - leave that to another tool (scp? tar?)) ;; ;; Features ;; ;; - namespace maps to filesystem ;; - no need for `bild -l` for listing available targets. Use `ls` or `tree` ;; - you build namespaces, not files/modules/packages/etc ;; - namespace maps to language modules ;; - build settings can be set in the file comments ;; - pwd is always considered the the source directory, no `src` vs `doc` etc. ;; - build methods automaticatly detected with file extensions ;; - flags modify the way to interact with the build ;; - -s = jump into a shell and/or repl ;; - -p = turn on profiling ;; - -t = limit build by type ;; - -e = exclude some regex in the ns tree ;; - -o = optimize level ;; ;; Example Commands ;; ;; bild [-rpt] ;; ;; The general scheme is to build the things described by the targets. A target ;; is a namespace. You can list as many as you want, but you must list at least ;; one. It could just be `.` for the current directory. Build outputs will go ;; into the _bild directory in the root of the project. ;; ;; bild biz.web ;; ;; Or `bild biz/web`. This shows building a file at ./biz/web.hs, this will ;; translate to something like `ghc --make Biz.Web`. ;; ;; bild -r ;; ;; Starts a repl/shell for target. ;; - if target.hs, load ghci ;; - if target.scm, load scheme repl ;; - if target.clj, load a clojure repl ;; - if target.nix, load nix-shell ;; - and so on. ;; ;; bild -p ;; ;; build target with profiling (if available) ;; ;; bild -t nix target ;; ;; only build target.nix, not target.hs and so on (in the case of multiple ;; targets with the same name but different extension). ;; ;; Here is an example integration with GHC. Given the following command-line ;; invocation to compile the namespace 'com.simatime.bild' which depends on ;; 'com.simatime.lib': ;; ;; ghc com/simatime/bild.hs -i com/simatime/lib.hs -o _bild/bild -v \ ;; -main-is Com.Simatime.Bild.main ;; ;; The general template of which is: ;; ;; ghc -i -o -main-is .main ;; ;; Some definitions: ;; ;; - is some source file ;; - is the stack of dependencies ;; - is the target namespace, indicated by 'bild ' ;; ;; To fill out the build template, we can parse the file for known ;; namespaces. The general recipe is: ;; ;; 1. Create a list of namespaces in my git repo. This can be cached, or I can ;; integrate with git somehow. ;; 2. Read the file corresponding to ;; 3. Look for 'import ', where is a namespace in the ;; aforementioned cache. ;; 4. If found, then save current build as a continuation and compile ;; . Result gets put on the dependency stack ;; 5. When finished, return to building ;; ;; Once the build command template is filled out, we can create the nix expression. ;; ;; TODO ;; ;; Questions ;; ;; - how to import (third-party) dependencies? ;; 1 just don't have them...? yeah right ;; 2 the target.nix could be the build description for target.hs ;; 3 just use a default.nix for the com.whatever ;; 4 have a deps.nix file ;; 5 list them in the file with other settings ;; - how to handle multiple output formats? ;; - e.g. that ghcjs and ghc take the same input files... ;; - say you have a .md file, you want to bild it to pdf, html, and more. What do? ;; - i guess the nix file could return a set of drvs instead of a single drv ;; - the top of the file should ;; ;;; Code: (define-module (com simatime bild) #:use-module ((ice-9 ftw) #:prefix ftw:) #:export (ns? ns->path)) (define ns? symbol?) (define (ns->path ns) ;; in place of a spec (when (ns? ns) (string-fold (lambda (a b) (if (eq? a #\.) (string-concatenate (list b (string #\/))) (string-concatenate (list b (string a))))) "" (symbol->string ns)))) (define ns->module-name (ns) TODO) (define (ns sym) (define-module (ns->module-name))) (define (prn a) (display a) (newline)) ;; todo ;; ;; - find buildable files given a namespace ;; - select a build method based on ext ;; - run the build (define (find-buildable ns) (ftw:ftw ns (lambda (a b c) (map prn (list a b c)) #t)))