Hi,

I am trying to create racket distribution for my application, except I
am tripping on my first few steps - that of generating the binary.

First, the architecture of the application. There is a driver program
that is configured with a backend at run-time (although one can argue
this should be a compile time configuration - happy to change that).

The configuration that matches the driver to the backend is an
environment relative path - which is then used to dynamic-require the
backend.

The tree looks like:

`|- info.rkt
 |- driver.rkt
 |- build.rkt
 |
 `-archs
   |- intel
   |  `- name.rkt
   `- arm
      `- name.rkt

info.rkt:
#lang info

(define collection 'multi)
;------------------------


driver.rkt:

#lang racket

(unless (getenv "ARCH")
  (raise-user-error 'driver "Please define ARCH with suitable path"))

(define arch-path (getenv "ARCH"))
(define arch-name-path
  (build-path arch-path "name.rkt"))

(module+ main

  (define arch-proc
    (dynamic-require arch-name-path
                     'get-arch))
  (printf "loading arch ~a~n" (arch-proc)))
;------------------------

archs/intel/name.rkt

#lang racket

(provide get-arch)

(define (get-arch)
  (if (fixnum? (expt 2 32))
      'x86_64
      'i386))
;------------------------

archs/arm/name.rkt


#lang racket

(provide get-arch)

;; Support for 32bits arm only
(define (get-arch)
  'arm32)


So far so good.
$ raco pkg install --link --auto
$ ARCH=archs/intel racket driver.rkt
loading arch x86_64
$ ARCH=archs/arm racket driver.rkt
loading arch arm32

Not, I try to create an executable using raco exe:
$ mkdir bin
$ raco exe ++lib archs/intel/name.rkt ++lib archs/arm/name.rkt -o
bin/r-prog driver.rkt
$ ARCH=archs/intel bin/r-prog
loading arch x86_64
$ cd bin
$ ARCH=archs/intel ./r-prog
open-input-file: cannot open module file
  module path: /home/pmatos/tmp/racket-distro/bin/archs/intel/name.rkt

This doesn't work but it's understandable. However, if only I could
replicate this behaviour in a build script using
create-embedding-executable:

build.rkt:

#lang racket

(require compiler/embed)

(create-embedding-executable
 "prog"
 #:verbose? #t
 #:modules (list (list #f '(file "driver.rkt"))
                 (list #f '(file "archs/intel/name.rkt"))
                 (list #f '(file "archs/arm/name.rkt")))
 #:configure-via-first-module? #t
 #:literal-expression
 (parameterize ([current-namespace (make-base-namespace)])
   (compile
    `(begin
       (namespace-require ''driver))))
 #:cmdline (list "-U" "--"))

(make-directory* "bin")
(delete-directory/files "bin/prog" #:must-exist? #f)
(copy-directory/files "prog" "bin/prog")
(delete-directory/files "prog")


$ ARCH=archs/intel bin/prog

This finishes successfully and returns nothing which makes me think that
nothing is being executed. This is slightly different from the error I
initially had but I am quite lost with the inner workings of
create-embedding-executable and am using examples online to guide me
which are few and don't really deal exactly with the kind of program I
am trying to compile.

At this point I have a few questions:
1. It is still not clear what the first element in each sublist in
#:modules exactly represents. I understand that it is related to a
module prefix but I don't understand how any value besides #f is useful.
The example in the docs has #f so I used that. Can someone clarify the
usefulness of having a prefix or #t?
2. All examples I have seen create a new namespace in literal-expression
and then use namespace-require. Why can't I just do (require ...) in the
literal-expression?
3. I will have some problems once I got the basics to work with paths. I
assume the solution is define-runtime-path.

I tried
(define-runtime-path arch-path (getenv "ARCH"))

but this will, I think, evaluate the value at both compile time and
runtime which means I will potentially get two different values for
arch-path depending if I am compiling or executing. This also means I am
moving the backend configuration to compile time which is ok but how can
I get the variable at compile time, and then cache that for use at runtime?

I tried
(define-for-syntax foo (getenv "FOO"))
(define-runtime-path p (build-path foo "name.rkt"))

but this will tell me foo is not available at runtime, so I sort of need
to move the compile-time value to runtime. Maybe I am over-complicating
this though so I am happy to hear some comments on this.

Kind regards,

-- 
Paulo Matos

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to