Hello Chicken users!
I have a program suite written in Chicken, which uses a number of
eggs, and I want to be able to distribute it without relying on user
to install all eggs by hand. Or to install them at all, since user's
Chicken environment is mainly aimed for development and should not be
affected by third party software that only uses Chicken, without
providing any Chicken functionality itself.
I understand that my options in this case is either link the binary
statically, or provide -private-repository flag and put all the eggs'
dynamic libs beside my binaries. The first solution I just don't like
very much.
The -private-repository flag, which enables compiled binaries to load
extensions from the directory where the binary is located, which is
not ideal, since in case of manual installation I'd like to have my
binaries in /bin and libs in /var/lib or /usr/lib or something like
that.
One possible solution occurred to me: what if we could have a way to
set -private-repository not only to the location of the compiled
binary, but to an arbitrary location? I tried to implement this in
form of new flag -private-repository-path, and it seems to work for my
case.
I also think that a general solution for creating Chicken environments
(analogous to e.g. Python's venv) can be based on this.
All that said, I still have some questions:
1. Isn't there some more obvious already existing way to do what I
want, which I overlooked?
2. Doesn't the solution I devised break anything? At the first glance
it doesn't but I still can be missing something obvious
The patch with -private-repository-path for Chicken 5.4.0:
diff --git a/chicken.h b/chicken.h
index d0d6be20..3ad33235 100644
--- a/chicken.h
+++ b/chicken.h
@@ -1566,10 +1566,14 @@ typedef void (C_ccall *C_proc)(C_word, C_word
*) C_noret;
#define C_ub_i_pointer_f32_set(p, n) (*((float *)(p)) = (n))
#define C_ub_i_pointer_f64_set(p, n) (*((double *)(p)) = (n))
-#ifdef C_PRIVATE_REPOSITORY
-# define C_private_repository()
C_use_private_repository(C_executable_dirname())
+#ifdef C_PRIVATE_REPOSITORY_PATH
+# define C_private_repository()
C_use_private_repository(C_text(C_PRIVATE_REPOSITORY_PATH))
#else
-# define C_private_repository()
+# ifdef C_PRIVATE_REPOSITORY
+# define C_private_repository()
C_use_private_repository(C_executable_dirname())
+# else
+# define C_private_repository()
+# endif
#endif
#ifdef C_GUI
diff --git a/csc.scm b/csc.scm
index 1fe896b7..ee3bdfeb 100644
--- a/csc.scm
+++ b/csc.scm
@@ -507,7 +507,8 @@ Usage: #{csc} [OPTION ...] [FILENAME ...]
-host compile for host when configured for
cross-compiling
-private-repository load extensions from executable path
- -deployed link support file to be used from a deployed
+ -private-repository-path PATH load extensions from PATH
+ -deployed link support file to be used from a deployed
executable (sets `rpath'
accordingly, if supported
on this platform)
-no-elevation embed manifest on Windows to
supress elevation
@@ -553,6 +554,9 @@ EOF
(define (use-private-repository)
(set! compile-options (cons "-DC_PRIVATE_REPOSITORY" compile-options)))
+ (define (use-private-repository-path path)
+ (set! compile-options (cons (sprintf
"-DC_PRIVATE_REPOSITORY_PATH=\"~A\"" path) compile-options)))
+
(define (generate-target-filename source-filename)
(pathname-replace-extension
source-filename
@@ -687,6 +691,10 @@ EOF
(set! rest (cdr rest)) ]
((-private-repository)
(use-private-repository))
+ ((-private-repository-path)
+ (check s rest)
+ (use-private-repository-path (car rest))
+ (set! rest (cdr rest)))
((-ignore-repository)
(set! ignore-repository #t)
(t-options arg))
--