tonyg / racket-unix-signals

Sending and handling Unix signals from Racket
Other
7 stars 4 forks source link

`raco exe` doesn't work: avoid `collection-path` #4

Open tonyg opened 1 year ago

tonyg commented 1 year ago

A correspondent writes

I’m trying to use your unix-signals Racket package and it works fine when I run my program through the racket CLI. When I build a standalone exe of my program with raco exe, however, I run into the following error at runtime:

collection-path: collection not found
  collection: "unix-signals"
  in collection directories:
   /usr/local/my-project/lib/plt/my-program/collects/
  context...:
   .../private/collect.rkt:11:53: fail
   .../unix-signals/main.rkt:34:0: local-lib-dirs
   .../ffi/unsafe.rkt:131:0: get-ffi-lib
   body of '#%embedded:unix-signals/main:

and the issue is most likely this snippet from main.rkt:

(define (local-lib-dirs)
  ;; FIXME: There's probably a better way to do this with
  ;; define-runtime-path and cross-system-library-subpath,
  ;; but this is what the bcrypt package is doing.
  (list (build-path (collection-path "unix-signals")
                    "private"
                    "compiled"
                    "native"
                    (system-library-subpath #f))))

So to fix it, likely change that to use define-runtime-path and (perhaps?) also cross-system-library-subpath (?).

LiberalArtist commented 1 year ago

I wrote that FIXME comment, and I've written it in enough places that I think it'd be worth starting a discussion on https://racket.discourse.group to figure out what The Right Thing is and record it for posterity.

I'm fairly certain define-runtime-path or one of its relatives will be part of the answer because, per the docs:

Unlike using collection-path, define-runtime-path exposes each run-time path to tools like the executable and distribution creators, so that files and directories needed at run time are carried along in a distribution.

I think what I was imagining with cross-system-library-subpath is that, if you are constructing a relative path programmatically at compile time, you'd want to end up with a path for the target system. But it might be better to use one of the special cases in define-runtime-path like https://github.com/racket/racket/blob/65631ed7d1548179914068110dca54d1fea552de/racket/collects/openssl/libssl.rkt#L14-L23 does. That might require—or it might be better to do this anyway—installing the library to something in get-lib-search-dirs, either be defining copy-foreign-libs and letting raco setup do it for you, or doing it manually. I remember there being some related issues about cooperating with layered installations and the ordering of collection {pre-,post-,}install hooks, but I haven't paged all that back in yet.

LiberalArtist commented 1 year ago

P.S. I'm not sure if ./compiled/native/* should be relegated to Racket BC C extensions or not: it does manage to preserve the benefits of collections as namespaces, rather than dumping everything in a flat get-lib-search-dirs.