commit 6b69a149046b0408bf517f3d7f6a1d0e5c4a9947
parent eed71349a84d16db8738017cacbd6639e2a2990d
Author: Matthew Flatt <mflatt@racket-lang.org>
Date: Sat, 19 Oct 2013 07:07:08 -0600
make installer: add Mac OS X code-signing support
original commit: 2054fb79de5b2895260cdcf863d956377b939db3
Diffstat:
5 files changed, 51 insertions(+), 8 deletions(-)
diff --git 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
@@ -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;
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
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
@@ -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
@@ -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
@@ -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*