main.ss
#lang scheme/base

(require dynext/compile
         dynext/link
         dynext/file
         
         scheme/file)

(define (older-than a b)
  (< (file-or-directory-modify-seconds a) (file-or-directory-modify-seconds b)))

(define (depending-on what deps make)
  (when (not (and (file-exists? what)
                  (andmap
                   (λ (dep)
                     (when (not (file-exists? dep))
                       (error "Dependancy not found" dep))
                     (dep . older-than . what))
                   deps)))
    (make what deps))
  what)

(define (maybe-build-path a b)
  (if (absolute-path? b) b
      (build-path a b)))

; use this library, then you can (require "name.ss") and it'll magically work
(define (get-libname location name)
  (define libdir (build-path (if (eq? location 'relative) "." location) "compiled" "native" (system-library-subpath)))
  (when (not (directory-exists? libdir))
    (make-directory* libdir))
  (build-path libdir (append-extension-suffix (string-append name "_ss"))))

(define (library location name . sources)
  (let ((objects (map
                  (λ (source)
                    (let ((source (maybe-build-path location source)))
                      (depending-on
                       (append-object-suffix source)
                       (list source)
                       (λ (object deps)
                         (compile-extension #f (car deps) object null)))))
                  (filter (λ (i) (regexp-match #rx"\\.c(?:c(?:pp)?)?$" (path->string (build-path i))))
                          sources))))
    (depending-on
     (get-libname location name)
     objects
     (λ (lib objects)
       (link-extension #f objects lib))))
  (void))

(provide depending-on library)