make installer: add Mac OS X code-signing support

This commit is contained in:
Matthew Flatt 2013-10-19 07:07:08 -06:00
parent 64b1b1037e
commit 2054fb79de
6 changed files with 59 additions and 10 deletions

View File

@ -164,6 +164,10 @@ BUILD_STAMP =
# the default as the version number: # the default as the version number:
INSTALL_NAME = 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: # A README file to download from the server for the client:
README = README.txt 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)"\ PKG_SOURCE_MODE="$(PKG_SOURCE_MODE)" INSTALL_NAME="$(INSTALL_NAME)"\
DIST_NAME="$(DIST_NAME)" DIST_BASE=$(DIST_BASE) \ DIST_NAME="$(DIST_NAME)" DIST_BASE=$(DIST_BASE) \
DIST_DIR=$(DIST_DIR) DIST_SUFFIX=$(DIST_SUFFIX) \ 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)" JOB_OPTIONS="$(JOB_OPTIONS)"
client: client:
@ -419,7 +423,9 @@ bundle-config:
$(RACKET) -l distro-build/set-config $(SET_BUNDLE_CONFIG_q) $(RACKET) -l distro-build/set-config $(SET_BUNDLE_CONFIG_q)
UPLOAD_q = --readme http://$(SVR_PRT)/$(README) --upload http://$(SVR_PRT)/ --desc "$(DIST_DESC)" 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 # Create an installer from the build (with installed packages) that's
# in "bundle/racket": # in "bundle/racket":

View File

@ -135,6 +135,7 @@
[(#:configure) (and (list? val) (andmap string? val))] [(#:configure) (and (list? val) (andmap string? val))]
[(#:bits) (or (equal? val 32) (equal? val 64))] [(#:bits) (or (equal? val 32) (equal? val 64))]
[(#:vc) (or (equal? val "x86") (equal? val "x64"))] [(#:vc) (or (equal? val "x86") (equal? val "x64"))]
[(#:sign-identity) (string? val)]
[(#:timeout) (real? val)] [(#:timeout) (real? val)]
[(#:j) (exact-positive-integer? val)] [(#:j) (exact-positive-integer? val)]
[(#:repo) (string? val)] [(#:repo) (string? val)]

View File

@ -212,6 +212,11 @@ Site-configuration keywords (where <string*> means no spaces, etc.):
#:vc <string*> --- "x86" or "x64" to select the Visual C build mode; #:vc <string*> --- "x86" or "x64" to select the Visual C build mode;
default depends on `#:bits' default depends on `#:bits'
#:sign-identity <string> --- 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 <integer> --- parallelism for `make' on Unix and Mac OS X and #:j <integer> --- parallelism for `make' on Unix and Mac OS X and
for `raco setup' on all platforms; defaults to 1 for `raco setup' on all platforms; defaults to 1

View File

@ -271,6 +271,7 @@
default-dist-dir)) default-dist-dir))
(define dist-suffix (get-opt c '#:dist-suffix "")) (define dist-suffix (get-opt c '#:dist-suffix ""))
(define dist-catalogs (choose-catalogs c '(""))) (define dist-catalogs (choose-catalogs c '("")))
(define sign-identity (get-opt c '#:sign-identity ""))
(define release? (get-opt c '#:release? default-release?)) (define release? (get-opt c '#:release? default-release?))
(define source? (get-opt c '#:source? #f)) (define source? (get-opt c '#:source? #f))
(define source-pkgs? (get-opt c '#:source-pkgs? source?)) (define source-pkgs? (get-opt c '#:source-pkgs? source?))
@ -291,6 +292,7 @@
" DIST_DIR=" dist-dir " DIST_DIR=" dist-dir
" DIST_SUFFIX=" (q dist-suffix) " DIST_SUFFIX=" (q dist-suffix)
" DIST_CATALOGS_q=" (qq dist-catalogs kind) " DIST_CATALOGS_q=" (qq dist-catalogs kind)
" SIGN_IDENTITY=" (q sign-identity)
" INSTALL_NAME=" (q install-name) " INSTALL_NAME=" (q install-name)
" BUILD_STAMP=" (q build-stamp) " BUILD_STAMP=" (q build-stamp)
" RELEASE_MODE=" (if release? "--release" (q "")) " RELEASE_MODE=" (if release? "--release" (q ""))

View File

@ -10,15 +10,17 @@
make-dmg) make-dmg)
(define hdiutil "/usr/bin/hdiutil") (define hdiutil "/usr/bin/hdiutil")
(define codesign "/usr/bin/codesign")
(define-runtime-path bg-image "macosx-installer/racket-rising.png") (define-runtime-path bg-image "macosx-installer/racket-rising.png")
(define (system*/show . l) (define (system*/show . l)
(displayln (apply ~a #:separator " " l)) (displayln (apply ~a #:separator " " l))
(flush-output)
(unless (apply system* l) (unless (apply system* l)
(error "failed"))) (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 tmp-dmg (make-temporary-file "~a.dmg"))
(define work-dir (define work-dir
(let-values ([(base name dir?) (split-path src-dir)]) (let-values ([(base name dir?) (split-path src-dir)])
@ -27,7 +29,8 @@
(delete-directory/files work-dir #:must-exist? #f) (delete-directory/files work-dir #:must-exist? #f)
(make-directory* work-dir) (make-directory* work-dir)
(printf "Copying ~a\n" src-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) #:keep-modify-seconds? #t)
(when readme (when readme
(call-with-output-file* (call-with-output-file*
@ -37,6 +40,8 @@
(display readme o)))) (display readme o))))
(when bg (when bg
(copy-file bg (build-path work-dir ".bg.png"))) (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 ;; 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 ;; 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 ;; small with >8GB images). It seems that it works to first generate an
@ -58,6 +63,35 @@
tmp-dmg "-o" dmg) tmp-dmg "-o" dmg)
(delete-file tmp-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 (dmg-layout dmg volname bg)
(define-values (mnt del?) (define-values (mnt del?)
(let ([preferred (build-path "/Volumes/" volname)]) (let ([preferred (build-path "/Volumes/" volname)])
@ -99,10 +133,10 @@
(when del? (when del?
(delete-directory mnt))) (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" (define dmg-name (format "bundle/~a-~a~a.dmg"
base-name base-name
(system-library-subpath #f) (system-library-subpath #f)
dist-suffix)) 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) dmg-name)

View File

@ -16,7 +16,7 @@
(define upload-desc "") (define upload-desc "")
(define download-readme #f) (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 (command-line
#:once-each #:once-each
[("--release") "Create a release installer" [("--release") "Create a release installer"
@ -30,7 +30,7 @@
[("--readme") readme "URL for README.txt to include" [("--readme") readme "URL for README.txt to include"
(set! download-readme readme)] (set! download-readme readme)]
#:args #:args
(human-name base-name dir-name dist-suffix) (human-name base-name dir-name dist-suffix sign-identity)
(values human-name (values human-name
(format "~a v~a" human-name (version)) (format "~a v~a" human-name (version))
(format "~a-~a" base-name (version)) (format "~a-~a" base-name (version))
@ -39,7 +39,8 @@
(format "~a-~a" dir-name (version))) (format "~a-~a" dir-name (version)))
(if (string=? dist-suffix "") (if (string=? dist-suffix "")
"" ""
(string-append "-" dist-suffix))))) (string-append "-" dist-suffix))
sign-identity)))
(display-time) (display-time)
@ -57,7 +58,7 @@
(installer-tgz base-name dir-name dist-suffix readme) (installer-tgz base-name dir-name dist-suffix readme)
(case (system-type) (case (system-type)
[(unix) (installer-sh human-name base-name dir-name release? dist-suffix readme)] [(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)]))) [(windows) (installer-exe short-human-name base-name release? dist-suffix readme)])))
(call-with-output-file* (call-with-output-file*