diff --git a/Makefile b/Makefile index 746a96e636..e597455c15 100644 --- a/Makefile +++ b/Makefile @@ -164,6 +164,10 @@ BUILD_STAMP = # the default as the version number: INSTALL_NAME = +# A signing identity (spaces allowed) for Mac OS X binaries in an +# installer: +SIGN_IDENTITY = + # A README file to download from the server for the client: README = README.txt @@ -377,7 +381,7 @@ COPY_ARGS = SERVER=$(SERVER) SERVER_PORT=$(SERVER_PORT) SERVER_HOSTS="$(SERVER_H PKG_SOURCE_MODE="$(PKG_SOURCE_MODE)" INSTALL_NAME="$(INSTALL_NAME)"\ DIST_NAME="$(DIST_NAME)" DIST_BASE=$(DIST_BASE) \ DIST_DIR=$(DIST_DIR) DIST_SUFFIX=$(DIST_SUFFIX) \ - DIST_DESC="$(DIST_DESC)" README="$(README)" \ + DIST_DESC="$(DIST_DESC)" README="$(README)" SIGN_IDENTITY="$(SIGN_IDENTITY)"\ JOB_OPTIONS="$(JOB_OPTIONS)" client: @@ -419,7 +423,9 @@ bundle-config: $(RACKET) -l distro-build/set-config $(SET_BUNDLE_CONFIG_q) UPLOAD_q = --readme http://$(SVR_PRT)/$(README) --upload http://$(SVR_PRT)/ --desc "$(DIST_DESC)" -DIST_ARGS_q = $(UPLOAD_q) $(RELEASE_MODE) $(SOURCE_MODE) "$(DIST_NAME)" $(DIST_BASE) $(DIST_DIR) "$(DIST_SUFFIX)" +DIST_ARGS_q = $(UPLOAD_q) $(RELEASE_MODE) $(SOURCE_MODE) \ + "$(DIST_NAME)" $(DIST_BASE) $(DIST_DIR) "$(DIST_SUFFIX)" \ + "$(SIGN_IDENTITY)" # Create an installer from the build (with installed packages) that's # in "bundle/racket": diff --git a/pkgs/distro-build/config.rkt b/pkgs/distro-build/config.rkt index 63dd6c827d..0c2d3bb615 100644 --- a/pkgs/distro-build/config.rkt +++ b/pkgs/distro-build/config.rkt @@ -135,6 +135,7 @@ [(#:configure) (and (list? val) (andmap string? val))] [(#:bits) (or (equal? val 32) (equal? val 64))] [(#:vc) (or (equal? val "x86") (equal? val "x64"))] + [(#:sign-identity) (string? val)] [(#:timeout) (real? val)] [(#:j) (exact-positive-integer? val)] [(#:repo) (string? val)] diff --git a/pkgs/distro-build/doc.txt b/pkgs/distro-build/doc.txt index e556326ae5..9997d2d517 100644 --- a/pkgs/distro-build/doc.txt +++ b/pkgs/distro-build/doc.txt @@ -212,6 +212,11 @@ Site-configuration keywords (where means no spaces, etc.): #:vc --- "x86" or "x64" to select the Visual C build mode; default depends on `#:bits' + #:sign-identity --- provides an identity to be passed to + `codesign` for code signing on Mac OS X (for all executables in a + distribution), where an empty string disables signing; the default + is "" + #:j --- parallelism for `make' on Unix and Mac OS X and for `raco setup' on all platforms; defaults to 1 diff --git a/pkgs/distro-build/drive-clients.rkt b/pkgs/distro-build/drive-clients.rkt index c3f6a83f78..a25c66c5d6 100644 --- a/pkgs/distro-build/drive-clients.rkt +++ b/pkgs/distro-build/drive-clients.rkt @@ -271,6 +271,7 @@ default-dist-dir)) (define dist-suffix (get-opt c '#:dist-suffix "")) (define dist-catalogs (choose-catalogs c '(""))) + (define sign-identity (get-opt c '#:sign-identity "")) (define release? (get-opt c '#:release? default-release?)) (define source? (get-opt c '#:source? #f)) (define source-pkgs? (get-opt c '#:source-pkgs? source?)) @@ -291,6 +292,7 @@ " DIST_DIR=" dist-dir " DIST_SUFFIX=" (q dist-suffix) " DIST_CATALOGS_q=" (qq dist-catalogs kind) + " SIGN_IDENTITY=" (q sign-identity) " INSTALL_NAME=" (q install-name) " BUILD_STAMP=" (q build-stamp) " RELEASE_MODE=" (if release? "--release" (q "")) diff --git a/pkgs/distro-build/installer-dmg.rkt b/pkgs/distro-build/installer-dmg.rkt index c36fbfcb5d..f18c5413a3 100644 --- a/pkgs/distro-build/installer-dmg.rkt +++ b/pkgs/distro-build/installer-dmg.rkt @@ -10,15 +10,17 @@ make-dmg) (define hdiutil "/usr/bin/hdiutil") +(define codesign "/usr/bin/codesign") (define-runtime-path bg-image "macosx-installer/racket-rising.png") (define (system*/show . l) (displayln (apply ~a #:separator " " l)) + (flush-output) (unless (apply system* l) (error "failed"))) -(define (make-dmg volname src-dir dmg bg readme) +(define (make-dmg volname src-dir dmg bg readme sign-identity) (define tmp-dmg (make-temporary-file "~a.dmg")) (define work-dir (let-values ([(base name dir?) (split-path src-dir)]) @@ -27,7 +29,8 @@ (delete-directory/files work-dir #:must-exist? #f) (make-directory* work-dir) (printf "Copying ~a\n" src-dir) - (copy-directory/files src-dir (build-path work-dir volname) + (define dest-dir (build-path work-dir volname)) + (copy-directory/files src-dir dest-dir #:keep-modify-seconds? #t) (when readme (call-with-output-file* @@ -37,6 +40,8 @@ (display readme o)))) (when bg (copy-file bg (build-path work-dir ".bg.png"))) + (unless (string=? sign-identity "") + (sign-executables dest-dir sign-identity)) ;; The following command should work fine, but it looks like hdiutil in 10.4 ;; is miscalculating the needed size, making it too big in our case (and too ;; small with >8GB images). It seems that it works to first generate an @@ -58,6 +63,35 @@ tmp-dmg "-o" dmg) (delete-file tmp-dmg)) +(define (sign-executables dest-dir sign-identity) + ;; Sign any executable in "bin", top-level ".app", or either of those in "lib" + (define (check-bins dir) + (for ([f (in-list (directory-list dir #:build? #t))]) + (when (and (file-exists? f) + (member 'execute (file-or-directory-permissions f)) + (member (call-with-input-file + f + (lambda (i) + (define bstr (read-bytes 4 i)) + (and (bytes? bstr) + (= 4 (bytes-length bstr)) + (integer-bytes->integer bstr #f)))) + '(#xFeedFace #xFeedFacf))) + (system*/show codesign "-s" sign-identity f)))) + (define (check-apps dir) + (for ([f (in-list (directory-list dir #:build? #t))]) + (when (and (directory-exists? f) + (regexp-match #rx#".app$" f)) + (define name (let-values ([(base name dir?) (split-path f)]) + (path-replace-suffix name #""))) + (define exe (build-path f "Contents" "MacOS" name)) + (when (file-exists? exe) + (system*/show codesign "-s" sign-identity exe))))) + (check-bins (build-path dest-dir "bin")) + (check-bins (build-path dest-dir "lib")) + (check-apps dest-dir) + (check-apps (build-path dest-dir "lib"))) + (define (dmg-layout dmg volname bg) (define-values (mnt del?) (let ([preferred (build-path "/Volumes/" volname)]) @@ -99,10 +133,10 @@ (when del? (delete-directory mnt))) -(define (installer-dmg human-name base-name dist-suffix readme) +(define (installer-dmg human-name base-name dist-suffix readme sign-identity) (define dmg-name (format "bundle/~a-~a~a.dmg" base-name (system-library-subpath #f) dist-suffix)) - (make-dmg human-name "bundle/racket" dmg-name bg-image readme) + (make-dmg human-name "bundle/racket" dmg-name bg-image readme sign-identity) dmg-name) diff --git a/pkgs/distro-build/installer.rkt b/pkgs/distro-build/installer.rkt index bbd351d9ff..ce13618520 100644 --- a/pkgs/distro-build/installer.rkt +++ b/pkgs/distro-build/installer.rkt @@ -16,7 +16,7 @@ (define upload-desc "") (define download-readme #f) -(define-values (short-human-name human-name base-name dir-name dist-suffix) +(define-values (short-human-name human-name base-name dir-name dist-suffix sign-identity) (command-line #:once-each [("--release") "Create a release installer" @@ -30,7 +30,7 @@ [("--readme") readme "URL for README.txt to include" (set! download-readme readme)] #:args - (human-name base-name dir-name dist-suffix) + (human-name base-name dir-name dist-suffix sign-identity) (values human-name (format "~a v~a" human-name (version)) (format "~a-~a" base-name (version)) @@ -39,7 +39,8 @@ (format "~a-~a" dir-name (version))) (if (string=? dist-suffix "") "" - (string-append "-" dist-suffix))))) + (string-append "-" dist-suffix)) + sign-identity))) (display-time) @@ -57,7 +58,7 @@ (installer-tgz base-name dir-name dist-suffix readme) (case (system-type) [(unix) (installer-sh human-name base-name dir-name release? dist-suffix readme)] - [(macosx) (installer-dmg human-name base-name dist-suffix readme)] + [(macosx) (installer-dmg human-name base-name dist-suffix readme sign-identity)] [(windows) (installer-exe short-human-name base-name release? dist-suffix readme)]))) (call-with-output-file*