auto-download pre-built Win/Mac binaries during build

This commit is contained in:
Matthew Flatt 2010-06-12 08:37:43 -06:00
parent 930fefc3fc
commit 51396e2baa
5 changed files with 186 additions and 25 deletions

View File

@ -41,11 +41,9 @@ the Unix instructions below, but note the following:
installed into "racket/lib". This framework is used by the `racket'
executable that goes into "racket/bin".
* The GRacket build creates a framework, "GRacket.framework", which is
installed into "racket/lib". This framework is used by the
executable bundle GRacket.app that goes into the "racket" directory.
The installation creates a script, "racket/bin/gracket", that runs
the bundle.
* The GRacket build creates a GUI-executable variant of the Racket
executable. The GRacket build process also downloads (from github)
pre-built libraries for Cairo, Pango, etc.
* The `--enable-shared' flag for `configure' must not be used, because
builds create and use frameworks by default. Furthermore,
@ -55,7 +53,9 @@ the Unix instructions below, but note the following:
* To build an X11-based GRacket, run `configure' with the
`--enable-xonx' flag. Frameworks are not used for such builds, so
--enable-shared is allowed. The `--enable-xonx' flag also affects
the Racket build, so that `system-type' reports 'unix.
the Racket build, so that `system-type' reports 'unix. Pre-built
libraries are not downloaded in this more; you must have Cairo,
Pango, and GTk installed.
* To use `--prefix' without `--enable-xonx', you must also supply
`--enable-macprefix'. BEWARE! The directory structure for a
@ -67,10 +67,9 @@ the Unix instructions below, but note the following:
directory structure on top of an existing Unix-style directory
structure.)
* Under Mac OS X 10.6 and later, `configure' by default selects 32-bit
mode for building Racket and GRacket. To build Racket in 64-bit mode
(GRacket is not support in that mode), use the following arguments to
`configure': `--enable-mac64', `--enable-sgc', and `--disable-gracket'.
* Under Mac OS X 10.6 and later, `configure' by default selects
32-bit mode for building Racket. To build Racket in 64-bit mode,
use `--enable-mac64'.
========================================================================
Compiling for supported Unix variants (including Linux) or Cygwin
@ -102,15 +101,10 @@ Detailed instructions:
remove it (unless you are using an "in-place" build from a
repository as described below).
Also, make sure that you have libraries and header files for Xft and
Cairo (v1.23 and up) if you would like support for font smoothing
(Xft) and graphics smoothing (Cairo). These libraries are not
distributed with Racket. The configure process checks automatically
whether these libraries are available.
OpenGL support for GRacket sometimes requires special configuration
(though generally not under Linux). See the note at the end of this
section if OpenGL fails to work.
Also, make sure that you have libraries and header files for
Cairo, Pango, and GTk. These libraries are not distributed with
Racket. The configure process checks automatically whether these
libraries are available.
Finally, the content of the "foreign" subdirectory may require GNU
`make'. If the build fails with another variant of `make', please

View File

@ -72,9 +72,11 @@ bin:
$(MAKE) @MAIN_VARIANT@
3m:
$(MAKE) libs/ready
cd gc2; $(MAKE) 3m
cgc:
$(MAKE) libs/ready
$(MAKE) $(LINKRESULT)
both:
@ -121,6 +123,9 @@ grmain_ee.@LTO@ : gracket.@LTO@
ee-main:
$(MAKE) grmain_ee.@LTO@
libs/ready:
$(RACKET) -c "$(srcdir)/get-libs.rkt" --ready "$(srcdir)" libs
clean:
rm -f *.@LTO@ *.d core gracket gracket3m
rm -f gc2/*.@LTO@ gc2/xsrc/* gc2/macxsrc/* gc2/*.d gc2/*.dd
@ -155,16 +160,17 @@ install-post-collects:
$(MAKE) install-@WXVARIANT@-post-collects
install-common:
cd ..; rm -f "$(DESTDIR)$(bindir)/gracket@CGC_INSTALLED@"
cd ..; rm -f "$(DESTDIR)$(bindir)/gracket@MMM_INSTALLED@"
cd ..; echo 'MROPTIONS=@MROPTIONS@' >> $(BUILDINFO)
cd ..; echo "MRLIBS=$(GUILIBS_@WXVARIANT@)" >> $(BUILDINFO)
cd ..; echo "MRLDFLAGS=$(GRACKETLDFLAGS)" >> $(BUILDINFO)
$(RACKET) -c "$(srcdir)/get-libs.rkt" --install . "$(DESTDIR)$(libpltdir)"
# X11 ----------------------------------------
install-wx_xt:
$(MAKE) install-common
cd ..; rm -f "$(DESTDIR)$(bindir)/gracket@CGC_INSTALLED@"
cd ..; rm -f "$(DESTDIR)$(bindir)/gracket@MMM_INSTALLED@"
cd ..; echo 'MROPTIONS=@MROPTIONS@' >> $(BUILDINFO)
cd ..; echo "MRLIBS=$(GUILIBS_@WXVARIANT@)" >> $(BUILDINFO)
cd ..; echo "MRLDFLAGS=$(GRACKETLDFLAGS)" >> $(BUILDINFO)
cd ..; mkdir -p "$(DESTDIR)$(bindir)"
install-no-lib-cgc-wx_xt:
@ -203,6 +209,7 @@ install-wx_xt-post-collects:
FRAMEWORK_REL_PREFIX="@executable_path/../../../lib/"
install-wx_mac:
$(MAKE) install-common
cd ..; rm -rf "$(prefix)/GRacket@CGC_CAP_INSTALLED@.app"
cd ..; rm -rf "$(prefix)/GRacket@MMM_CAP_INSTALLED@.app"

148
src/gracket/get-libs.rkt Normal file
View File

@ -0,0 +1,148 @@
#lang racket/base
(require racket/cmdline
racket/tcp)
;; This program avoids racket/port and net/url, because
;; it is loaded without using bytecode.
(define mode (make-parameter 'download))
(define touch-ready? (make-parameter #f))
(define-values (src-dir dest-dir)
(command-line
#:once-any
[("--download") "download mode (the default)" (mode 'download)]
[("--install") "install mode" (mode 'install)]
#:once-each
[("--ready") "touch `ready' on download success" (touch-ready? #t)]
#:args
(src-dir dest-dir)
(values src-dir dest-dir)))
(define url-host "github.com")
(define url-path "/mflatt/gracket-libs/raw/master/")
(define url-base (string-append "http://" url-host url-path))
(define needed-files
(case (system-type)
[(unix)
;; Pre-built binaries are for Windows and Mac only
null]
[(macosx)
'("libcairo.2.dylib"
"libintl.8.dylib"
"libgio-2.0.0.dylib"
"libjpeg.62.dylib"
"libglib-2.0.0.dylib"
"libpango-1.0.0.dylib"
"libgmodule-2.0.0.dylib"
"libpangocairo-1.0.0.dylib"
"libgobject-2.0.0.dylib"
"libpixman-1.0.dylib"
"libgthread-2.0.0.dylib"
"libpng14.14.dylib")]
[(windows)
'("freetype6.dll"
"libgobject-2.0-0.dll"
"libatk-1.0-0.dll"
"libgtk-win32-2.0-0.dll"
"libcairo-2.dll"
"libjpeg-7.dll"
"libexpat-1.dll"
"libpango-1.0-0.dll"
"libfontconfig-1.dll"
"libpangocairo-1.0-0.dll"
"libgdk-win32-2.0-0.dll"
"libpangoft2-1.0-0.dll"
"libgdk_pixbuf-2.0-0.dll"
"libpangowin32-1.0-0.dll"
"libgio-2.0-0.dll"
"libpng14-14.dll"
"libglib-2.0-0.dll"
"libwimp.dll"
"libgmodule-2.0-0.dll"
"zlib1.dll"
"gtkrc")]))
(define explained? #f)
(define (purify-port port)
(let ([m (regexp-match-peek-positions
#rx"^HTTP/.*?(?:\r\n\r\n|\n\n|\r\r)" port)])
(if m (read-string (cdar m) port) "")))
(define (copy-port src dest)
(let ([s (make-bytes 4096)])
(let loop ()
(let ([c (read-bytes-avail! s src)])
(cond
[(number? c)
(let loop ([start 0])
(unless (= start c)
(let ([c2 (write-bytes-avail s dest start c)])
(loop (+ start c2)))))
(loop)]
[else
;; Must be EOF
(void)])))))
(define (download-if-needed dest-dir file)
(let ([dest (build-path dest-dir file)]
[tmp (build-path dest-dir (format "~a.download" file))])
(if (file-exists? dest)
(printf " ~a is ready\n" file)
(let ([src (format "~a~a/~a"
url-path
(system-library-subpath #f)
file)])
(unless explained?
(set! explained? #t)
(printf ">> Downloading files from\n>> ~a~a\n" url-base (system-library-subpath #f))
(printf ">> If you don't want automatic download, downlaod each file\n")
(printf ">> yourself from there to\n")
(printf ">> ~a\n" (path->complete-path dest-dir)))
(printf " ~a downloading..." file)
(flush-output)
(let-values ([(i o) (tcp-connect url-host 80)])
(fprintf o "GET ~a HTTP/1.0\r\n" (string-append src))
(fprintf o "Host: ~a\r\n" url-host)
(fprintf o "\r\n")
(flush-output o)
(tcp-abandon-port o)
(purify-port i)
(call-with-output-file tmp
#:exists 'truncate/replace
(lambda (out)
(copy-port i out)))
(rename-file-or-directory tmp dest #t)
(printf "done\n"))))))
(define (same-content? f1 f2)
;; approximate:
(and (file-exists? f1)
(file-exists? f2)
(= (file-size f1) (file-size f2))))
(define (install-file src dest)
(unless (same-content? src dest)
(printf "Updating ~a\n" dest)
(when (file-exists? dest)
(delete-file dest))
(copy-file src dest)))
(case (mode)
[(download)
(let ([libs dest-dir])
(unless (directory-exists? libs)
(make-directory libs))
(for-each (lambda (file)
(download-if-needed libs file))
needed-files)
(when (touch-ready?)
(let ([ok (build-path libs "ready")])
(unless (file-exists? ok)
(with-output-to-file ok void)))))]
[(install)
(for-each (lambda (file)
(install-file (build-path src-dir "libs" file)
(build-path dest-dir file)))
needed-files)])

View File

@ -103,6 +103,16 @@ In addition, building RacketCGC executes
which copies .exp, .obj, and .lib files into racket\lib\, and also
copies DLLs from the "extradlls" directory to to racket\lib\.
Finally, you must install pre-build DLLs that GRacket needs to run.
The DLLs are available from
http://github.com/mflatt/gracket-libs/tree/master/win32/i386/?raw=true
and they must be installed into
racket\lib
Building Racket3m and GRacket3m
-------------------------------
@ -118,7 +128,7 @@ After RacketCGC and GRacketCGC are built, you can can build 3m binaries:
The resulting Racket.exe and GRacket.exe will appear in the top-level
"racket" directory, along with DLLs libracket3mxxxxxxx.dll and
libgracket3mxxxxxxx.dll in racket/lib. (There is no corresponding
libgracket3mxxxxxxx.dll in racket\lib. (There is no corresponding
libmzgc3mxxxxxxx.dll. Instead, it is merged with
libracket3mxxxxxxx.dll.)

View File

@ -8,6 +8,8 @@ cd gc2
..\..\..\racketcgc -cu make.rkt
cd ..
..\..\..\racketcgc -cu ..\gracket\get-libs.rkt ..\gracket ..\..\lib
cd mzcom
devenv mzcom.sln /Build Release
cd ..\libmysterx