diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 30 | ||||
-rw-r--r-- | scramble.egg | 8 | ||||
-rw-r--r-- | scramble.scm | 77 |
4 files changed, 88 insertions, 28 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d163863 --- /dev/null +++ b/.gitignore | |||
@@ -0,0 +1 @@ | |||
build/ \ No newline at end of file | |||
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..2ac521f --- /dev/null +++ b/Makefile | |||
@@ -0,0 +1,30 @@ | |||
1 | # Automatically generated by scramble | ||
2 | |||
3 | NAME = scramble | ||
4 | CSC = /usr/bin/csc | ||
5 | CSC_OPTIONS = -setup-mode -host -I $(PWD) -C -I$(PWD) | ||
6 | CSC_LIB_OPTIONS = -D compiling-extension -emit-all-import-libraries -dynamic -regenerate-import-libraries | ||
7 | CSC_OPTIONS_EXTRA = -X utf8 | ||
8 | CSI = /usr/bin/csi | ||
9 | BUILD = $(PWD)/build | ||
10 | TESTS = $(PWD)/tests | ||
11 | TEST_ENV = env BUILD=$(BUILD) TESTS=$(TESTS) | ||
12 | |||
13 | .PHONY: all test clean install uninstall | ||
14 | all: /home/acdw/src/scramble/build/scramble | ||
15 | test: $(BUILD) | ||
16 | cd $(BUILD) && $(TEST_ENV) $(CSI) -setup-mode -s $(TESTS)/run.scm $(NAME) | ||
17 | clean: | ||
18 | -rm -rf $(BUILD) *.build.sh *.install.sh $(NAME) *.import.scm *.import.so *.link *.static.o | ||
19 | install: | ||
20 | chicken-install -s | ||
21 | uninstall: | ||
22 | chicken-uninstall -s | ||
23 | |||
24 | # scramble | ||
25 | |||
26 | $(BUILD): | ||
27 | -mkdir $(BUILD) | ||
28 | /home/acdw/src/scramble/build/scramble: /home/acdw/src/scramble/scramble.scm $(BUILD) | ||
29 | $(CSC) $(CSC_OPTIONS) $(CSC_OPTIONS_EXTRA) $< -o $@ | ||
30 | @if test -f scramble.import.scm;then mv scramble.import.scm $(BUILD)/;echo mv scramble.import.scm $(BUILD)/; fi | ||
diff --git a/scramble.egg b/scramble.egg new file mode 100644 index 0000000..28df21b --- /dev/null +++ b/scramble.egg | |||
@@ -0,0 +1,8 @@ | |||
1 | ((author "Case Duckworth") | ||
2 | (synopsis "Convert an egg to a Makefile") | ||
3 | (dependencies (chicken "5.3.0") utf8 srfi-1) | ||
4 | ;; (test-dependencies test) | ||
5 | (component-options | ||
6 | (csc-options -X utf8)) | ||
7 | (components | ||
8 | (program scramble))) | ||
diff --git a/scramble.scm b/scramble.scm index e79fbe0..591ebad 100644 --- a/scramble.scm +++ b/scramble.scm | |||
@@ -1,7 +1,6 @@ | |||
1 | (declare (module scramble)) | ||
2 | |||
3 | (import scheme (chicken base) | 1 | (import scheme (chicken base) |
4 | (chicken file) | 2 | (chicken file) |
3 | (chicken file posix) | ||
5 | (chicken format) | 4 | (chicken format) |
6 | (chicken pathname) | 5 | (chicken pathname) |
7 | (chicken process) | 6 | (chicken process) |
@@ -9,22 +8,17 @@ | |||
9 | (chicken string) | 8 | (chicken string) |
10 | (srfi 1)) | 9 | (srfi 1)) |
11 | 10 | ||
12 | ;; dependencies should be like | ||
13 | ;; (((output jimmy.util) (source jimmy.util)) | ||
14 | ;; ((output jimmy.read) (source jimmy.read) (source jimmy.util)) | ||
15 | ;; ((output jimmy.emit) (source jimmy.emit) (source jimmy.util))) | ||
16 | |||
17 | (define egg (make-parameter #f)) | 11 | (define egg (make-parameter #f)) |
18 | (define build-dir (make-parameter "build")) | 12 | (define build-dir (make-parameter "build")) |
19 | 13 | ||
20 | (define csc-options '("-setup-mode" | 14 | (define csc-options '("-setup-mode" |
21 | "-host" | 15 | "-host" |
22 | "-D compiling-extension" | ||
23 | "-emit-all-import-libraries" | ||
24 | "-dynamic" | ||
25 | "-regenerate-import-libraries" | ||
26 | "-I $(PWD)" | 16 | "-I $(PWD)" |
27 | "-C -I$(PWD)")) | 17 | "-C -I$(PWD)")) |
18 | (define csc-lib-options '("-D compiling-extension" | ||
19 | "-emit-all-import-libraries" | ||
20 | "-dynamic" | ||
21 | "-regenerate-import-libraries")) | ||
28 | 22 | ||
29 | (define source-extensions | 23 | (define source-extensions |
30 | ;; The possible extensions source files can take. | 24 | ;; The possible extensions source files can take. |
@@ -32,10 +26,18 @@ | |||
32 | 26 | ||
33 | (define (read-egg #!optional egg-file) | 27 | (define (read-egg #!optional egg-file) |
34 | ;; Read EGG-FILE and return the structure inside. | 28 | ;; Read EGG-FILE and return the structure inside. |
35 | (unless egg-file | 29 | (define (last-dir pn) (pathname-file pn)) |
36 | (set! egg-file | 30 | (set! egg-file |
37 | (receive (_ _ dirs) (decompose-directory (current-directory)) | 31 | (cond |
38 | (make-pathname (current-directory) (car (reverse dirs)) "egg")))) | 32 | ((not egg-file) |
33 | (make-pathname (current-directory) (last-dir (current-directory)) "egg")) | ||
34 | ((directory? egg-file) | ||
35 | (assert (directory-exists? egg-file) | ||
36 | "Egg directory doesn't exist" egg-file) | ||
37 | (let ((dir egg-file)) | ||
38 | (make-pathname dir (last-dir dir) "egg"))) | ||
39 | (else egg-file))) | ||
40 | |||
39 | (assert (file-exists? egg-file) "Can't find egg file" egg-file) | 41 | (assert (file-exists? egg-file) "Can't find egg file" egg-file) |
40 | (assert (file-readable? egg-file) "Can't read egg file" egg-file) | 42 | (assert (file-readable? egg-file) "Can't read egg file" egg-file) |
41 | (cons* `(egg-directory ,(pathname-directory egg-file)) | 43 | (cons* `(egg-directory ,(pathname-directory egg-file)) |
@@ -59,11 +61,11 @@ | |||
59 | (if (list? dirs) dirs (list dirs))) | 61 | (if (list? dirs) dirs (list dirs))) |
60 | file ext)))) | 62 | file ext)))) |
61 | (else | 63 | (else |
62 | (let loop ((ext (source-extensions))) | 64 | (let loop ((exts (source-extensions))) |
63 | (if (null? ext) #f | 65 | (if (null? exts) #f |
64 | (let ((cand (make-pathname (egg-directory) c ext))) | 66 | (let ((cand (make-pathname (egg-directory) (->string c) (car exts)))) |
65 | (if (file-exists? cand) cand | 67 | (if (file-exists? cand) cand |
66 | (loop (cdr ext))))))))) | 68 | (loop (cdr exts))))))))) |
67 | 69 | ||
68 | (define (output-of c) | 70 | (define (output-of c) |
69 | ;; Return the output file of C. It's okay if it doesn't exist. | 71 | ;; Return the output file of C. It's okay if it doesn't exist. |
@@ -71,7 +73,7 @@ | |||
71 | (->string c) | 73 | (->string c) |
72 | (case (car (find-component c)) | 74 | (case (car (find-component c)) |
73 | ((extension) "so") | 75 | ((extension) "so") |
74 | ((program))))) | 76 | ((program) "")))) |
75 | 77 | ||
76 | (define (find-component name) | 78 | (define (find-component name) |
77 | (find (lambda (c) (eq? name (cadr c))) | 79 | (find (lambda (c) (eq? name (cadr c))) |
@@ -119,12 +121,18 @@ | |||
119 | 121 | ||
120 | (define (rule c) | 122 | (define (rule c) |
121 | (let ((deps (alist-ref c (dependency-graph)))) | 123 | (let ((deps (alist-ref c (dependency-graph)))) |
122 | (sprintf "~a: ~a $(BUILD)\n\t~a\n\t-mv ~a.import.scm $(BUILD)/" | 124 | (sprintf "~a: ~a $(BUILD)\n\t~a\n\t~a" |
123 | (output-of c) | 125 | (output-of c) |
124 | (string-join (cons (source-of (car deps)) | 126 | (string-join (cons (source-of (car deps)) |
125 | (map output-of (cdr deps)))) | 127 | (map output-of (cdr deps)))) |
126 | "$(CSC) $(CSC_OPTIONS) $(CSC_OPTIONS_EXTRA) $< -o $@" | 128 | (string-append "$(CSC) $(CSC_OPTIONS)" |
127 | c))) | 129 | (if (eq? (car (find-component c)) 'extension) |
130 | " $(CSC_LIB_OPTIONS)" "") | ||
131 | " $(CSC_OPTIONS_EXTRA) $< -o $@") | ||
132 | (string-append "@if test -f " (->string c) ".import.scm;" | ||
133 | "then mv " (->string c) ".import.scm $(BUILD)/;" | ||
134 | "echo mv " (->string c) ".import.scm $(BUILD)/;" | ||
135 | " fi")))) | ||
128 | 136 | ||
129 | (define (emit-makefile egg-file) | 137 | (define (emit-makefile egg-file) |
130 | (parameterize ((egg (read-egg egg-file))) | 138 | (parameterize ((egg (read-egg egg-file))) |
@@ -132,6 +140,7 @@ | |||
132 | (print "NAME = " (egg-name)) | 140 | (print "NAME = " (egg-name)) |
133 | (print "CSC = " (find-executable "csc")) | 141 | (print "CSC = " (find-executable "csc")) |
134 | (print "CSC_OPTIONS = " (string-join csc-options)) | 142 | (print "CSC_OPTIONS = " (string-join csc-options)) |
143 | (print "CSC_LIB_OPTIONS = " (string-join csc-lib-options)) | ||
135 | (print "CSC_OPTIONS_EXTRA = " (string-join (egg-csc-options))) | 144 | (print "CSC_OPTIONS_EXTRA = " (string-join (egg-csc-options))) |
136 | (print "CSI = " (find-executable "csi")) | 145 | (print "CSI = " (find-executable "csi")) |
137 | (print "BUILD = $(PWD)/" (build-dir)) | 146 | (print "BUILD = $(PWD)/" (build-dir)) |
@@ -139,14 +148,26 @@ | |||
139 | (print "TEST_ENV = env BUILD=$(BUILD) TESTS=$(TESTS)") | 148 | (print "TEST_ENV = env BUILD=$(BUILD) TESTS=$(TESTS)") |
140 | (newline) | 149 | (newline) |
141 | (print ".PHONY: all test clean install uninstall") | 150 | (print ".PHONY: all test clean install uninstall") |
142 | (print "all: " (string-join (map (o source-of car) (dependency-graph)))) | 151 | (print "all: " (string-join (map (o output-of car) (dependency-graph)))) |
143 | (print "test: build" | 152 | (print "test: $(BUILD)" |
144 | "\n\t" "cd $(BUILD) && " | 153 | "\n\t" "cd $(BUILD) && " |
145 | "$(TEST_ENV) $(CSI) -setup-mode -s $(TESTS)/run.scm $(NAME)") | 154 | "$(TEST_ENV) $(CSI) -setup-mode -s $(TESTS)/run.scm $(NAME)") |
146 | (print "clean:\n\t-rm -rf $(BUILD)") | 155 | (print "clean:\n\t-rm -rf $(BUILD)" |
156 | " *.build.sh *.install.sh $(NAME)" | ||
157 | " *.import.scm *.import.so *.link *.static.o") | ||
147 | (print "install:\n\tchicken-install -s") | 158 | (print "install:\n\tchicken-install -s") |
148 | (print "uninstall:\n\tchicken-uninstall -s") | 159 | (print "uninstall:\n\tchicken-uninstall -s") |
149 | (newline) (print "# " (egg-name)) (newline) | 160 | (newline) (print "# " (egg-name)) (newline) |
150 | (print "$(BUILD):\n\t-mkdir $(BUILD)") | 161 | (print "$(BUILD):\n\t-mkdir $(BUILD)") |
151 | (for-each (o print rule cadr) (egg-components)) | 162 | (for-each (o print rule cadr) (egg-components)))) |
152 | )) | 163 | |
164 | (define (main args) | ||
165 | (let ((egg-file (if (null? args) (current-directory) (car args)))) | ||
166 | ;; TODO: allow customizing build directory | ||
167 | (emit-makefile egg-file))) | ||
168 | |||
169 | (cond-expand | ||
170 | ((or chicken-script compiling) | ||
171 | (import (chicken process-context)) | ||
172 | (main (command-line-arguments))) | ||
173 | (else)) | ||