~ chicken-core (chicken-5) a050591790cd312ace9504c1ccf9899326d72e3a
commit a050591790cd312ace9504c1ccf9899326d72e3a Author: felix <felix@y.(none)> AuthorDate: Mon Feb 22 21:00:39 2010 +0100 Commit: felix <felix@y.(none)> CommitDate: Mon Feb 22 21:00:39 2010 +0100 added -deployed to csc; documented deployment (not finished); everything seems to work fine on Linux diff --git a/csc.scm b/csc.scm index cba1d4bf..42e537ee 100644 --- a/csc.scm +++ b/csc.scm @@ -186,7 +186,7 @@ (define dry-run #f) (define gui #f) (define deploy #f) -(define shared-deploy #f) +(define deployed #f) (define extra-libraries (if host-mode @@ -264,7 +264,7 @@ (list (conc "-L\"" library-dir "\"") (conc " -Wl,-R\"" - (if (or deploy shared-deploy) + (if deployed "\\$ORIGIN" (prefix "" "lib" (if host-mode @@ -473,6 +473,8 @@ Usage: #{csc} FILENAME | OPTION ... -host compile for host when configured for cross-compiling -private-repository load extensions from executable path + -deployed compile support file to be used from a deployed + executable Options can be collapsed if unambiguous, so @@ -549,11 +551,8 @@ EOF (pathname-replace-extension (first scheme-files) shared-library-extension) (pathname-replace-extension (first scheme-files) executable-extension) ) ) ) (run-translation) ] ) - (when deploy - (cond (shared - (set! deploy #f) - (set! shared-deploy #t)) - (else (use-private-repository)))) + (when (and deploy (not shared)) + (use-private-repository)) (unless translate-only (run-compilation) (unless compile-only @@ -654,7 +653,10 @@ EOF (set! link-options (cons* "kernel32.lib" "user32.lib" "gdi32.lib" link-options)))))] ((-deploy) - (set! deploy #t)) + (set! deploy #t) + (set! deployed #t)) + ((-deployed) + (set! deployed #t)) [(-framework) (check s rest) (when osx @@ -891,7 +893,7 @@ EOF "install_name_tool -change lib" (if unsafe-libraries "u" "") "chicken.dylib " (quotewrap (let ((lib (if unsafe-libraries "libuchicken.dylib" "libchicken.dylib")) ) - (if (or shared-deploy deploy) + (if deployed (make-pathname "@executable_path" lib) (make-pathname (lib-path) diff --git a/manual/Deployment b/manual/Deployment index 811e0de2..239e8acd 100644 --- a/manual/Deployment +++ b/manual/Deployment @@ -25,28 +25,125 @@ programs to run, unless you link your application statically: libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7be7000) libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7a84000) /lib/ld-linux.so.2 (0xb805d000) + % ls -l myprogram + -rwxr-xr-x 1 felix felix 34839 2010-02-22 20:19 x -... +Linking your application statically will include the runtime library in the executable, +but this will increase its size substantially: -=== Libraries + % ls myprogram + -rwxr-xr-x 1 felix felix 3566656 2010-02-22 20:30 myprogram -... +Programs distributed this way can only use [[Extensions]] if these extensions +get linked in statically, which is basically supported but not available for all +extensions. === Self contained applications -... +The solution to many of these problems is creating an application directory that contains +the executable, the runtime libraries, extensions and additional support files needed by the +program. The executable has to be linked specially to make sure the correct included +runtime library is used. You do this by using the {{-deploy}} options provided by +the compiler driver, {{csc}}: + + % csc -deploy myprogram.scm + % ls -l myprogram + -rwxr-xr-x 1 felix felix 7972753 2010-02-22 20:19 libchicken.so.5 + -rwxr-xr-x 1 felix felix 34839 2010-02-22 20:19 myprogram + % ldd myprogram + linux-gate.so.1 => (0xb806a000) + libchicken.so.5 => /home/felix/tmp/myprogram/libchicken.so.5 (0xb7c30000) + libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7bfa000) + libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7bf5000) + libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7a92000) + /lib/ld-linux.so.2 (0xb806b000) + +As can be seen here, {{myprogram}} is prepared to load the contained {{libchicken}}, +not any installed in the system that happens to have the same name. + +You can even install extensions inside the application directory: + + % chicken-install -deploy -p $PWD/myprogram defstruct + ... + % ls -l myprogram + -rwxr-xr-x 1 felix felix 82842 2010-02-22 20:24 defstruct.import.so + -rw-r--r-- 1 felix felix 182 2010-02-22 20:24 defstruct.setup-info + -rwxr-xr-x 1 felix felix 11394 2010-02-22 20:24 defstruct.so + -rwxr-xr-x 1 felix felix 7972753 2010-02-22 20:19 libchicken.so.5 + -rwxr-xr-x 1 felix felix 34839 2010-02-22 20:19 myprogram + +(Note that the prefix must be an absolute path) + +We can check with ldd that those compiled extension libraries are linked with +the correct library: + + % ldd myprogram/*.so + /home/felix/tmp/myprogram/defstruct.import.so: + linux-gate.so.1 => (0xb7f4f000) + libchicken.so.5 => /home/felix/tmp/myprogram/libchicken.so.5 (0xb7b08000) + libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7ad2000) + libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7acd000) + libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb796a000) + /lib/ld-linux.so.2 (0xb7f50000) + /home/felix/tmp/myprogram/defstruct.so: + linux-gate.so.1 => (0xb80c9000) + libchicken.so.5 => /home/felix/tmp/myprogram/libchicken.so.5 (0xb7c8c000) + libm.so.6 => /lib/tls/i686/cmov/libm.so.6 (0xb7c56000) + libdl.so.2 => /lib/tls/i686/cmov/libdl.so.2 (0xb7c51000) + libc.so.6 => /lib/tls/i686/cmov/libc.so.6 (0xb7aee000) + /lib/ld-linux.so.2 (0xb80ca000) + +The {{-deploy}} option passed to {{csc}} when compiling {{myprogram.scm}} has +taken care of setting up the application directory as the "repository" for +extensions that the program will use at runtime: + + % myprogram/myprogram -:d + [debug] application startup... + [debug] heap resized to 500000 bytes + [debug] stack bottom is 0xbfdbdf60. + [debug] entering toplevel toplevel... + [debug] stack resized to 131072 bytes + [debug] entering toplevel library_toplevel... + [debug] entering toplevel eval_toplevel... + [debug] entering toplevel expand_toplevel... + [debug] loading compiled module `/home/felix/tmp/myprogram/defstruct.so' (handle is 0x886ce98) + ... + +There is one restriction that you should be aware of, though: any extension that +you install inside an application directory must first be installed system-wide +(unless you use a custom repository with the {{CHICKEN_REPOSITORY}} environment variable), +so that {{csc}}/{{chicken}} will find an import library for the extension. Just make +sure you have all the extensions installed that you use in an application (something +you will normally have anyway). + +You can execute the program from its location, or you can install a symbolic +link pointing to it - it will find the correct directory where the actual +executable is located. + +The application directory is fully "portable" in the sense that it will run directly +from an USB-stick or any other removable media. At runtime the program can find +out its location by invoking the {{repository-path}} procedure, which will return +the full pathname in which the application is located. + +Should the program depend on more libraries which are not available by +default on the intended target systems, and which you would like to +include in your application, you will have to hunt them down yourself +and place them in the application directory. If these again have +dependencies, things will get complicated and will involve things like +patching binaries or writing "trampoline" shell scripts to run your +application. ==== Platform-specific notes -... - ===== Linux -... +Deployment is fully suppored on Linux ===== Windows -... +Deployment is fully supported on Windows. Since Windows looks up dynamic link +libraries in the programs original location by default, adding third-party +libraries to the application directory is no problem. ===== MacOS X diff --git a/manual/Extensions b/manual/Extensions index 5b28f650..d0cb50d9 100644 --- a/manual/Extensions +++ b/manual/Extensions @@ -461,7 +461,7 @@ Available options: ; {{-s -sudo}} : use {{sudo(1)}} for installing or removing files ; {{-r -retrieve}} : only retrieve egg into current directory, don't install ; {{-n -no-install}} : do not install, just build (implies {{-keep}}) -; {{-p -prefix PREFIX}} : change installation prefix to {{PREFIX}} +; {{-p -prefix PREFIX}} : change installation prefix to {{PREFIX}}; note: this must be an absolute path ; {{-host}} : when cross-compiling, compile extension for host ; {{-test}} : run included test-cases, if available ; {{-username USER}} : set username for transports that require this @@ -469,6 +469,7 @@ Available options: ; {{-i -init DIRECTORY}} : initialize empty alternative repository ; {{-u -update-db}} : update export database ; {{-repository}} : print path to extension repository +; {{-deploy}} : install extension in the application directory for a deployed application (see [[Deployment]] for more information) === chicken-uninstall reference diff --git a/runtime.c b/runtime.c index 15e82650..2c11d82a 100644 --- a/runtime.c +++ b/runtime.c @@ -1079,7 +1079,7 @@ void C_do_resize_stack(C_word stack) if(diff != 0 && !stack_size_changed) { if(debug_mode) - C_dbg(C_text("debug"), C_text("[debug] stack resized to %d bytes\n"), (int)stack); + C_dbg(C_text("debug"), C_text("stack resized to %d bytes\n"), (int)stack); stack_size = stack; diff --git a/setup-api.scm b/setup-api.scm index 59b5de79..f222f4b5 100644 --- a/setup-api.scm +++ b/setup-api.scm @@ -220,7 +220,7 @@ "" "-setup-mode") (if (keep-intermediates) "-k" "") (if (host-extension) "-host" "") - (if (deployment-mode) "-deploy" "") + (if (deployment-mode) "-deployed" "") *csc-options*) " ") ) ((assoc prg *installed-executables*) =>Trap