(define image-dir "../../image")
(define prefix (string-append image-dir "/" "usr"))
(define my-lib-dir (string-append prefix "/" "lib"))
(define my-bin-dir (string-append prefix "/" "bin"))
(define my-share-dir (string-append prefix "/" "share"))
(define my-doc-dir (string-append my-share-dir "/" "doc"))
(define my-install-doc-dir (string-append my-doc-dir "/" "show-sqrt-1.0"))

(define clean-files
  (list "wildio.o" "mymath.o"
	"libwildio.so.1.0" "libmymath.so.1.0" 
	"libwildio.so.1" "libmymath.so.1" 
	"libwildio.so" "libmymath.so" 
	"show-sqrt" 
	"manual.dvi" "manual.pdf" "manual.log" "manual.aux"))

(define rule-set
  (makefile
   ;; 
   ;; build libmymath.*
   ;;
   (md5 "mymath.o" 
	("config.h" "mymath.c")
	(lambda () 
	  (run (gcc -fPIC -c ,"mymath.c"))))
   (rule "libmymath.so.1.0" 
	 ("mymath.o") 
	 (lambda () 
	   (run (gcc -shared ,"-Wl,-soname,libmymath.so.1" 
		     -o ,"libmymath.so.1.0" ,"mymath.o"))))
   ;; 
   ;; build wildio.*
   ;;
   (rule "wildio.o" 
	 ("wildio.c")
	 (lambda () 
	   (run (gcc -fPIC -c ,"wildio.c"))))
   (rule "libwildio.so.1.0" 
	 ("wildio.o") 
	 (lambda () 
	   (run (gcc -shared "-Wl,-soname,libwildio.so.1"
		     -o ,"libwildio.so.1.0" ,"wildio.o"))))
   ;; 
   ;; build the program
   ;;
   (rule "show-sqrt" 
	 ("libmymath.so.1" "libwildio.so.1" "main.c" "wildio.h" "mymath.h")
	 (lambda () 
	   (run (gcc -L ,"." -L ,my-lib-dir -rdynamic 
		     -o ,(expand-file-name "show-sqrt" (cwd))
		     ,(expand-file-name "main.c" (cwd))
		     ,(expand-file-name "libwildio.so.1" (cwd))
		     ,(expand-file-name "libmymath.so.1" (cwd)) -ldl))))
   ;; 
   ;; install libs
   ;;
   (rule "libmymath.so.1" 
	 ("libmymath.so.1.0") 
	 (lambda () 
	   (create-symlink "libmymath.so.1.0" "libmymath.so.1")))
   (rule "libmymath.so" 
	 ("libmymath.so.1") 
	 (lambda () 
	   (create-symlink "libmymath.so.1" "libmymath.so")))
   (rule "libwildio.so.1" 
	 ("libwildio.so.1.0") 
	 (lambda () 
	   (create-symlink "libwildio.so.1.0" "libwildio.so.1")))
   (rule "libwildio.so" 
	 ("libwildio.so.1") 
	 (lambda () 
	   (create-symlink "libwildio.so.1" "libwildio.so")))
   (rule (string-append my-lib-dir "/" "libmymath.so.1")
	 ((string-append my-lib-dir "/" "libmymath.so.1.0"))
	 (lambda () 
	   (with-cwd my-lib-dir
		     (create-symlink "libmymath.so.1.0" "libmymath.so.1"))))
   (rule (string-append my-lib-dir "/" "libmymath.so")
	 ((string-append my-lib-dir "/" "libmymath.so.1"))
	 (lambda () 
	   (with-cwd my-lib-dir
		     (create-symlink "libmymath.so.1" "libmymath.so"))))
   (rule (string-append my-lib-dir "/" "libwildio.so.1")
	 ((string-append my-lib-dir "/" "libwildio.so.1.0"))
	 (lambda () 
	   (with-cwd my-lib-dir
		     (create-symlink "libwildio.so.1.0" "libwildio.so.1"))))
   (rule (string-append my-lib-dir "/" "libwildio.so")
	 ((string-append my-lib-dir "/" "libwildio.so.1"))
	 (lambda () 
	   (with-cwd my-lib-dir
		     (create-symlink "libwildio.so.1" "libwildio.so"))))
   (rule (string-append my-lib-dir "/" "libwildio.so.1.0")
	 (my-lib-dir "libwildio.so.1.0")
	 (lambda ()
	   (run (cp ,"libwildio.so.1.0" 
		    ,(string-append my-lib-dir "/" "libwildio.so.1.0")))))
   (rule (string-append my-lib-dir "/" "libmymath.so.1.0")
	 (my-lib-dir "libmymath.so.1.0")
	 (lambda ()
	   (run (cp ,"libmymath.so.1.0"
		    ,(string-append my-lib-dir "/" "libmymath.so.1.0")))))
   ;; 
   ;; install the program
   ;;
   (rule (string-append my-bin-dir "/" "show-sqrt")
	 (my-bin-dir "show-sqrt")
	 (lambda ()
	   (run (cp ,"show-sqrt" 
		    ,(string-append my-bin-dir "/" "show-sqrt")))))
   ;; 
   ;; build the manual
   ;;
   (md5 "manual.dvi"
	("manual.tex")
	(lambda ()
	  (run (latex ,"manual.tex"))))
   (rule "manual.pdf"
	 ("manual.dvi")
	 (lambda ()
	   (run (dvipdfm -o ,"manual.pdf" ,"manual.dvi"))))
   ;; 
   ;; install the manual
   ;;
   (rule (string-append my-install-doc-dir "/" "manual.pdf")
	 (my-install-doc-dir "manual.pdf")
	 (lambda ()
	   (run (cp "manual.pdf" 
		    ,(string-append my-install-doc-dir "/" "manual.pdf")))))
   ;; 
   ;; install all
   ;;
   (rule "install"
	 ((string-append my-lib-dir "/" "libmymath.so.1.0")
	  (string-append my-lib-dir "/" "libwildio.so.1.0")
	  (string-append my-lib-dir "/" "libmymath.so.1")
	  (string-append my-lib-dir "/" "libwildio.so.1")
	  (string-append my-lib-dir "/" "libmymath.so")
	  (string-append my-lib-dir "/" "libwildio.so")
	  (string-append my-bin-dir "/" "show-sqrt")
	  (string-append my-install-doc-dir "/" "manual.pdf"))
	 (lambda ()
	   (display "install done.\n")))
   ;; 
   ;; create checksums.md5
   ;;
   (once "checksums.md5"
	 ("manual.tex" "main.c" "mymath.c" 
	  "mymath.h" "wildio.c" "wildio.h" "config.h")
	 (lambda ()
	   (let ((outport (open-output-file (expand-file-name "checksums.md5"
							      (cwd)))))
	     (with-current-output-port outport (display ""))
	     (close-output-port outport))))
   (rule "config.h"
	 ()
	 (lambda ()
	   (let ((outport (open-output-file 
			   (expand-file-name "config.h" (cwd)))))
	     (with-current-output-port 
	      outport
	      (display "#ifndef MY_DELTA_MAX\n")
	      (display "#define MY_DELTA_MAX 0.000000001\n")
	      (display "#endif\n")
	      (close-output-port outport)))))
   ;; 
   ;; clean rules
   ;;
   (always "clean"
	   ()
	   (lambda ()
	     (for-each (lambda (f) 
			 (delete-filesys-object (expand-file-name f (cwd))))
		       clean-files)))
   ;; 
   ;; clean rules
   ;;
   (always "mrproper"
	   ("clean")
	   (lambda ()
	     (for-each (lambda (f) 
			 (delete-filesys-object (expand-file-name f (cwd))))
		       (list "checksums.md5"))))
   ;; 
   ;; uninstall all
   ;;
   (always "uninstall"
	 ()
	 (lambda ()
	   (display "uninstall: \n")
	   (for-each (lambda (f) 
		       (delete-filesys-object f))
		     (list (string-append my-lib-dir "/" "libmymath.so.1.0")
			   (string-append my-lib-dir "/" "libwildio.so.1.0")
			   (string-append my-lib-dir "/" "libmymath.so.1")
			   (string-append my-lib-dir "/" "libwildio.so.1")
			   (string-append my-lib-dir "/" "libmymath.so")
			   (string-append my-lib-dir "/" "libwildio.so")
			   (string-append my-bin-dir "/" "show-sqrt")
			   (string-append my-install-doc-dir "/" "manual.pdf")
			   my-install-doc-dir
			   my-doc-dir
			   my-share-dir
			   my-lib-dir
			   my-bin-dir
			   prefix
			   image-dir))
	   (display "uninstall done.\n")))
   ;; 
   ;; install dirs
   ;;
   (once image-dir
	 ()
	 (lambda ()
	   (create-directory image-dir)))
   (once prefix
	 (image-dir)
	 (lambda ()
	   (create-directory prefix)))
   (once my-lib-dir
	 (prefix)
	 (lambda ()
	   (create-directory my-lib-dir)))
   (once my-bin-dir
	 (prefix)
	 (lambda ()
	   (create-directory my-bin-dir)))
   (once my-share-dir
	 (prefix)
	 (lambda ()
	   (create-directory my-share-dir)))
   (once my-doc-dir
	 (my-share-dir)
	 (lambda ()
	   (create-directory my-doc-dir)))
   (once my-install-doc-dir
	 (my-doc-dir)
	 (lambda ()
	   (create-directory my-install-doc-dir)))
   ;; 
   ;; a small test
   ;;
   (always "test"
	   ("install")
	   (lambda ()
	     (let ((proggy (expand-file-name "show-sqrt" my-bin-dir)))
	       (display "testing ") (display proggy) (newline)
	       (setenv "LD_LIBRARY_PATH" my-lib-dir)
	       (display "# sqrt 2.0:\n")
	       (run (,proggy ,"2.0"))
	       (display "# sqrt 5.0:\n")
	       (run (,proggy ,"5.0"))
	       (display "ok.\n"))))))