You have a reader for your language that is triggered by "#lang", right?
Is that reader in a `reader` submodule, or is it in a separate ".../lang/reader.rkt" module file? At Fri, 13 Sep 2013 17:01:36 +0400, Dmitry Pavlov wrote: > Matthew, > > Many thanks! Your code works perfectly for my program. > > Now I would like to describe my tries to make a standalone > executable out of my program. > > Most obvious way fails: > > $ raco exe slon-main.rkt > $ ./slon-main > standard-module-name-resolver: collection not found > collection: "slon" > in collection directories: > context...: > standard-module-name-resolver > > Not surprising, as the "slon" collection is not mentioned > in the slon-main.rkt itself, but is required dynamically. > > So my second thought was that maybe ++lib would help. > It did not. (Did I use the flag incorrectly?) > > $ raco exe ++lib slon/slon-language slon-main.rkt > $ ./slon-main > <same error message> > > > Seeking for the solution, I upgraded from raco to the Racket level: > > #lang racket > (require compiler/embed) > > (create-embedding-executable "slon-main" > #:modules '((#f slon/slon-main) (#f slon/slon-language)) > #:literal-expression > (parameterize ([current-namespace (make-base-namespace)]) > (compile `(namespace-require 'slon/slon-main))) > #:configure-via-first-module? #t > #:verbose? #t) > > That worked great. "slon-main" was able to run independently > of its own location in the file system, and indenendeltly > of the presence of the original files in the slon/ collection > on disk. > > But there was another thing. In my implementation, I have > some binary data files that are loaded via > > (define-runtime-path eop.era "../eop/eop.era") > > The resulting program depended on those files. When I renamed > one of them, I got an error message: > > $ ./slon-main > with-input-from-file: cannot open input file > path: /home/dpavlov/era/slon/../eop/eop.era > > > "OK", I thought, "raco distribute is supposed to fix that". > > > $ raco distribute slon-distr slon-main > $ ls ./slon-distr/lib/plt/slon-main/exts/ert/home/dpavlov/era/eop/ > eop.era > $ ./slon-distr/bin/slon-main > standard-module-name-resolver: collection not found > collection: "slon" > in collection directories: > /home/dpavlov/.racket/5.3.4/collects > /home/dpavlov/era/slon/slon-distr/lib/plt/slon-main/collects > > The executable "slon-main" produced by raco distrubute is > different from the original one (although the size is the same). > I guess, raco distribute have eliminated the dependency of the > binary files with absolute paths, but it reintroduced the > dependency on the "slon" collection, which I previously got > rid of with the help of (create-embedding-executable)! > > And here I am stuck, asking for help. > > > Regards, > > Dmitry > > > > > On 09/13/2013 05:33 AM, Matthew Flatt wrote: > > I'm not sure I understand what you want, but here are some ideas about > > evaluating a text that would a module if only a "#lang" line were > > added. > > > > To start, here's a function to `require` an input port that contains a > > module's source. It uses the current namespace, and it gensyms a name > > for the module if you don't provide one. The part that I think is least > > obvious is using `current-module-declare-name` to set the name of the > > module to that it can be found by `dynamic-require`: > > > > (require syntax/modread) > > > > (define (require-input-port p [name (gensym)]) > > (define module-name (make-resolved-module-path name)) > > (parameterize ([current-module-declare-name module-name]) > > (eval-syntax (check-module-form ; ensures that `module` is bound > > (with-module-reading-parameterization > > (lambda () > > (read-syntax (object-name p) p))) > > 'ignored > > #f))) > > (dynamic-require module-name #f)) > > > > The `require-input-port` function assumes that the source starts with > > "#lang". You could use `input-port-append`, as others have suggested, > > to add a "#lang" line: > > > > (define p (input-port-append #t > > (open-input-string "#lang racket/base\n") > > (open-input-file "body.rktd"))) > > (port-count-lines! p) > > (require-input-port p) > > > > A problem with `input-port-append` is that line numbers are off by one > > for error reporting, and positions are off by the length of the first > > line. That's an annoyingly difficult problem to fix, but > > `prefix-input-port` below is my attempt (and maybe `input-port-append` > > should just work better along similar lines). > > > > (define p (prefix-input-port #"#lang racket/base\n" > > (open-input-file "body.rktd"))) > > (port-count-lines! p) > > (require-input-port p) > > > > ---------------------------------------- > > > > ;; prefix-input-port : bytes input-port -> input-port > > ;; Directs position requests to the given port after the > > ;; prefix is read. > > ;; Closes the given input port when the result port is closed. > > (define (prefix-input-port prefix base-p) > > (define-values (prefix-i prefix-o) (make-pipe)) > > (write-bytes prefix prefix-o) > > (close-output-port prefix-o) > > (define (prefix-done?) > > (zero? (pipe-content-length prefix-i))) > > > > (make-input-port > > (object-name base-p) > > ;; read > > (lambda (bstr) > > (define n (read-bytes-avail!* bstr > > (if (prefix-done?) > > base-p > > prefix-i))) > > (if (equal? n 0) > > (wrap-evt base-p (lambda (v) 0)) > > n)) > > ;; peek > > (lambda (bstr offset evt) > > (define pre-n (pipe-content-length prefix-i)) > > (define n (if (offset . >= . pre-n) > > (peek-bytes-avail!* bstr > > (- offset pre-n) > > #f > > base-p) > > (peek-bytes-avail!* bstr > > offset > > #f > > prefix-i))) > > (if (equal? n 0) > > (wrap-evt base-p (lambda (v) 0)) > > n)) > > ;; close > > (lambda () > > (close-input-port base-p)) > > ;; get-progress-evt > > ;; Difficult (impossible?) to support at the > > ;; prefix--base boundary. > > #f > > ;; commit > > #f > > ;; get-location > > (lambda () > > (if (prefix-done?) > > (port-next-location base-p) > > (port-next-location prefix-i))) > > ;; count-lines! > > (lambda () > > (port-count-lines! prefix-i) > > (port-count-lines! base-p)))) > > > > > > ____________________ Racket Users list: http://lists.racket-lang.org/users