~ chicken-core (chicken-5) c6e57fa85d702b6e3db182128cec81d238b1e0cd


commit c6e57fa85d702b6e3db182128cec81d238b1e0cd
Author:     felix <felix@call-with-current-continuation.org>
AuthorDate: Fri Feb 19 11:36:40 2010 +0100
Commit:     felix <felix@call-with-current-continuation.org>
CommitDate: Fri Feb 19 11:36:40 2010 +0100

    various changes regarding deployment for csc and chicken-install

diff --git a/CHICKEN.icns b/CHICKEN.icns
new file mode 100644
index 00000000..8203c7da
Binary files /dev/null and b/CHICKEN.icns differ
diff --git a/chicken-install.scm b/chicken-install.scm
index 933a44e2..961edc4e 100644
--- a/chicken-install.scm
+++ b/chicken-install.scm
@@ -84,6 +84,7 @@
   (define *proxy-port* #f)
   (define *running-test* #f)
   (define *mappings* '())
+  (define *deploy* #f)
 
   (define-constant +module-db+ "modules.db")
   (define-constant +defaults-file+ "setup.defaults")
@@ -200,6 +201,7 @@
   (define *eggs+dirs+vers* '())
   (define *dependencies* '())
   (define *checked* '())
+
   (define *csi* 
     (shellpath (make-pathname *program-path* (foreign-value "C_CSI_PROGRAM" c-string))))
 
@@ -333,6 +335,7 @@
      (if (and *no-install* (not dep?)) " -e \"(setup-install-mode #f)\"" "")
      (if *host-extension* " -e \"(host-extension #t)\"" "")
      (if *prefix* (sprintf " -e \"(installation-prefix \\\"~a\\\")\"" *prefix*) "")
+     (if *deploy* " -e \"(deployment-mode #t)\"" "")
      #\space
      (shellpath (make-pathname (cadr e+d+v) (car e+d+v) "setup"))) )
 
@@ -468,6 +471,7 @@ usage: chicken-install [OPTION | EXTENSION[:VERSION]] ...
   -i   -init DIRECTORY          initialize empty alternative repository
   -u   -update-db               update export database
        -repository              print path used for egg installation
+       -deploy                  build extensions for deployment
 EOF
 );|
     (exit code))
@@ -564,6 +568,9 @@ EOF
 			    (string=? "-host-extension" arg)) ; DEPRECATED
                         (set! *host-extension* #t)
                         (loop (cdr args) eggs))
+		       ((string=? "-deploy" arg)
+			(set! *deploy* #t)
+			(loop (cdr args) eggs))
                        ((string=? "-username" arg)
                         (unless (pair? (cdr args)) (usage 1))
                         (set! *username* (cadr args))
diff --git a/csc.scm b/csc.scm
index 62c4b8b4..a4399fa6 100644
--- a/csc.scm
+++ b/csc.scm
@@ -62,8 +62,10 @@
 (define mingw (eq? (build-platform) 'mingw32))
 (define msvc (eq? (build-platform) 'msvc))
 (define osx (eq? (software-version) 'macosx))
-(define hpux-hppa (and (eq? (software-version) 'hpux)
-                       (eq? (machine-type) 'hppa)))
+(define win (or mingw msvc))
+
+(define elf
+  (memq (software-version) '(linux freebsd netbsd openbsd dragonfly solaris)))
 
 (define (quit msg . args)
   (fprintf (current-error-port) "~a: ~?~%" CSC_PROGRAM msg args)
@@ -182,6 +184,8 @@
 (define show-libs #f)
 (define dry-run #f)
 (define gui #f)
+(define deploy #f)
+(define shared-deploy #f)
 
 (define extra-libraries
   (if host-mode
@@ -253,18 +257,22 @@
              TARGET_LIB_HOME)) )
 
 (define link-options '())
-(define builtin-link-options
-  (cond ((or osx hpux-hppa mingw)
-	 (list (conc "-L\"" library-dir "\"")))
-	(else 
+
+(define (builtin-link-options)
+  (cond (elf
 	 (list
 	  (conc "-L\"" library-dir "\"")
-	  (conc " -Wl,-R\"" (prefix "" "lib"
-				    (if host-mode
-					INSTALL_LIB_HOME
-					TARGET_RUN_LIB_HOME))
-		"\"")) ) ) )
-
+	  (conc " -Wl,-R\""
+		(if (or deploy shared-deploy)
+		    "\\$ORIGIN"
+		    (prefix "" "lib"
+			    (if host-mode
+				INSTALL_LIB_HOME
+				TARGET_RUN_LIB_HOME)))
+		"\"")) )
+	(else
+	 (list (conc "-L\"" library-dir "\"")))))
+	
 (define target-filename #f)
 (define verbose #f)
 (define keep-files #f)
@@ -408,6 +416,7 @@ Usage: ~a FILENAME | OPTION ...
                                     code
     -dll -library                  compile multiple units into a dynamic
                                     library
+    -deploy                        deploy self-contained application bundle
 
   Options to other passes:
 
@@ -500,11 +509,16 @@ EOF
              (else "-shared")) link-options))
     (set! shared #t) )
 
+  (define (use-private-repository)
+    (set! compile-options (cons "-DC_PRIVATE_REPOSITORY" compile-options))
+    (when osx
+      (set! link-options (cons "-framework CoreFoundation" link-options))))
+
   (let loop ([args args])
     (cond [(null? args)
 	   ;; Builtin search directory options do not override explict options
            (set! compile-options (append compile-options builtin-compile-options))
-           (set! link-options (append link-options builtin-link-options))
+           (set! link-options (append link-options (builtin-link-options)))
 	   ;;
 	   (when inquiry-only
 	     (when show-cflags (print* (compiler-options) #\space))
@@ -534,16 +548,23 @@ 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))))
 	   (unless translate-only 
 	     (run-compilation)
 	     (unless compile-only
 	       (when (member target-filename scheme-files)
 		 (printf "Warning: output file will overwrite source file `~A' - renaming source to `~A.old'~%"
 			 target-filename target-filename)
-		 (command "~A ~A ~A" 
-			  (if windows-shell "move" "mv")
-			  (quotewrap target-filename)
-			  (quotewrap (string-append target-filename ".old"))))
+		 (command 
+		  (sprintf
+		      "~A ~A ~A" 
+		      (if windows-shell "move" "mv")
+		    (quotewrap target-filename)
+		    (quotewrap (string-append target-filename ".old")))))
 	       (run-linking)) ) ]
 	  [else
 	   (let* ([arg (car args)]
@@ -617,9 +638,7 @@ EOF
 		(t-options "-static-extension" (car rest))
 		(set! rest (cdr rest)) ]
 	       ((-private-repository)
-		(set! compile-options (cons "-DC_PRIVATE_REPOSITORY" compile-options))
-		(when osx
-		  (set! link-options (cons "-framework CoreFoundation" link-options))))
+		(use-private-repository))
 	       [(-gui
 		 -windows |-W|)		;DEPRECATED
 		(set! gui #t)
@@ -633,6 +652,8 @@ EOF
 		   (msvc
 		    (set! link-options
 		      (cons* "kernel32.lib" "user32.lib" "gdi32.lib" link-options)))))]
+	       ((-deploy)
+		(set! deploy #t))
 	       [(-framework)
 		(check s rest)
 		(when osx 
@@ -831,17 +852,35 @@ EOF
 ;;; Link object files and libraries:
 
 (define (run-linking)
-  (let ((files (map quotewrap
-		    (append object-files
-			    (nth-value 0 (static-extension-info)) ) ) )
-	(target (quotewrap target-filename)))
+  (let* ((files (map quotewrap
+		     (append object-files
+			     (nth-value 0 (static-extension-info)) ) ) )
+	 (target (quotewrap target-filename))
+	 (targetdir #f))
+    (when deploy
+      (set! targetdir (pathname-strip-extension target-filename))
+      (when osx 
+	(set! targetdir (make-pathname #f targetdir "app"))
+	(command
+	 (sprintf "mkdir -p ~a"
+	   (quotewrap (make-pathname targetdir "{Contents/MacOS,Contents/Resources}")))))
+      (set! target-filename
+	(make-pathname
+	 targetdir
+	 (if osx
+	     (string-append "Contents/MaCOS/" (pathname-file target-filename))
+	     (pathname-file target-filename))))
+      (set! target (quotewrap target-filename))
+      (unless (directory-exists? targetdir)
+	(print "creating " targetdir)
+	(create-directory targetdir)))
     (command
      (string-intersperse 
       (cons* (cond (cpp-mode c++-linker)
 		   (else linker) )
 	     (append
 	      files
-	      (list (string-append link-output-flag target)
+	      (list (string-append link-output-flag (quotewrap target-filename))
 		    (linker-options)
 		    (linker-libraries #f) ) ) ) ) )
     (when (and osx (or (not cross-chicken) host-mode))
@@ -849,17 +888,53 @@ EOF
        (string-append
 	"install_name_tool -change lib" (if unsafe-libraries "u" "") "chicken.dylib "
 	(quotewrap 
-	 (make-pathname
-	  (prefix "" "lib"
-		  (if host-mode
-		      INSTALL_LIB_HOME
-		      TARGET_RUN_LIB_HOME))
-	  (if unsafe-libraries "libuchicken.dylib" "libchicken.dylib")) )
+	 (let ((lib (if unsafe-libraries "libuchicken.dylib" "libchicken.dylib")) )
+	   (if (or shared-deploy deploy)
+	       (make-pathname "@executable_path" lib)
+	       (make-pathname
+		(lib-path)
+		lib))))
 	" " 
 	target) )
-      (when gui (rez target)))
+      (when (and gui (not deploy))
+	(rez target)))
+    (when deploy
+      (copy-libraries targetdir)
+      (when osx
+	(create-mac-bundle
+	 (pathname-file target-filename)
+	 targetdir)))
     (unless keep-files (for-each $delete-file generated-object-files)) ) )
 
+(define (lib-path)
+  (prefix "" 
+	  "lib"
+	  (if win
+	      INSTALL_BIN_HOME
+	      (if host-mode
+		  INSTALL_LIB_HOME
+		  TARGET_RUN_LIB_HOME))))
+
+(define (copy-libraries targetdir)
+  (let ((lib (make-pathname
+	      (lib-path) 
+	      (if unsafe-libraries
+		  "libuchicken"
+		  "libchicken")
+	      (cond (osx "dylib")
+		    (win "dll")
+		    (else "so")))))
+    (copy-files lib targetdir)))
+
+(define (copy-files from to)
+  (command
+   (sprintf "~a ~a ~a"
+     (if windows-shell 
+	 "copy /Y"
+	 "cp")
+     (quotewrap from)
+     (quotewrap to))))
+
 (define (static-extension-info)
   (let ((rpath (repository-path)))
     (if (and rpath (pair? static-extensions))
@@ -936,8 +1011,8 @@ EOF
 	(if (zero? raw-exit-code) 0 1))
       last-exit-code)))
 
-(define (command fstr . args)
-  (unless (zero? (apply $system fstr args))
+(define (command str)
+  (unless (zero? ($system str))
     (exit last-exit-code)))
 
 (define ($delete-file str)
@@ -948,22 +1023,37 @@ EOF
 (define (rez file)
   ;; see also: http://www.cocan.org/getting_started_with_ocaml_on_mac_os_x
   (command 
-   "/Developer/Tools/Rez -t APPL -o ~a ~a"
-   (quotewrap file)
-   (quotewrap (make-pathname home "mac.r"))))
+   (sprintf "/Developer/Tools/Rez -t APPL -o ~a ~a"
+     (quotewrap file)
+     (quotewrap (make-pathname home "mac.r")))))
 
 (define (create-mac-bundle prg dname)
-  (let ((d (make-pathname dname "Contents/MacOS")))
-    (command "mkdir -p ~a" (qs (normalize-pathname d)))
-    (let ((pl (make-pathname d "Info.plist")))
+  (let* ((d0 (make-pathname dname "Contents"))
+	 (d (make-pathname dname "Contents/MacOS"))
+	 (d2 (make-pathname dname "Contents/Resources")))
+    (let ((icons (make-pathname d2 "CHICKEN.icns")))
+      (unless (file-exists? icons)
+	(copy-files 
+	 (make-pathname home "CHICKEN.icns") 
+	 d2)))
+    (let ((pl (make-pathname d0 "Info.plist")))
       (unless (file-exists? pl)
 	(with-output-to-file pl
 	  (cut print #<#EOF
 <?xml version="1.0" encoding="UTF-8"?>
-<plist version="1.0">
+<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
+<plist version="0.9">
 <dict>
-  <key>CFBundleExecutable</key>
-  <string>#{prg}</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleIconFile</key>
+	<string>CHICKEN.icns</string>
+        <key>CFBundleGetInfoString</key>
+	<string>Created by CHICKEN</string>
+	<key>CFBundleSignature</key>
+	<string>????</string>
+	<key>CFBundleExecutable</key>
+	<string>#{prg}</string>
 </dict>
 </plist>
 EOF
diff --git a/distribution/manifest b/distribution/manifest
index 1636235e..712cb5e0 100644
--- a/distribution/manifest
+++ b/distribution/manifest
@@ -262,6 +262,7 @@ setup-api.import.c
 setup-download.import.c
 types.db
 mac.r
+CHICKEN.icns
 manual/Accessing external objects
 manual/Acknowledgements
 manual/Basic mode of operation
diff --git a/rules.make b/rules.make
index 0f0cabe4..0faceadc 100644
--- a/rules.make
+++ b/rules.make
@@ -964,6 +964,9 @@ install-setup-files:
 	$(INSTALL_PROGRAM) $(INSTALL_PROGRAM_FILE_OPTIONS) $(SRCDIR)setup.defaults "$(DESTDIR)$(IDATADIR)"
 	$(INSTALL_PROGRAM) $(INSTALL_PROGRAM_EXECUTABLE_OPTIONS) setup-api.so "$(DESTDIR)$(IEGGDIR)"
 	$(INSTALL_PROGRAM) $(INSTALL_PROGRAM_EXECUTABLE_OPTIONS) setup-download.so "$(DESTDIR)$(IEGGDIR)"
+ifeq ($(PLATFORM),macosx)
+	$(INSTALL_PROGRAM) $(INSTALL_PROGRAM_FILE_OPTIONS) $(SRCDIR)CHICKEN.icns "$(DESTDIR)$(IDATADIR)"
+endif
 
 uninstall:
 	$(REMOVE_COMMAND) $(REMOVE_COMMAND_OPTIONS) "$(DESTDIR)$(IBINDIR)$(SEP)$(CHICKEN_PROGRAM)$(EXE)" \
diff --git a/setup-api.scm b/setup-api.scm
index 9802b2e9..85e8e03e 100644
--- a/setup-api.scm
+++ b/setup-api.scm
@@ -43,7 +43,7 @@
      make make/proc
      host-extension
      install-extension install-program install-script
-     setup-verbose-mode setup-install-mode
+     setup-verbose-mode setup-install-mode deployment-mode
      installation-prefix
      chicken-prefix 			;XXX remove at some stage from exports
      find-library find-header 
@@ -113,6 +113,7 @@
 (define setup-root-directory      (make-parameter *base-directory*))
 (define setup-verbose-mode        (make-parameter #f))
 (define setup-install-mode        (make-parameter #t))
+(define deployment-mode           (make-parameter #f))
 (define program-path              (make-parameter *chicken-bin-path*))
 (define keep-intermediates (make-parameter #f))
 
@@ -219,6 +220,7 @@
 		     "" "-setup-mode")
 		 (if (keep-intermediates) "-k" "")
 		 (if (host-extension) "-host" "")
+		 (if (deployment-mode) "-deploy" "")
 		 *csc-options*) 
 	  " ") )
 	((assoc prg *installed-executables*) =>
Trap