diff --git a/collects/dynext/compile-unit.ss b/collects/dynext/compile-unit.ss index 5400704e6e..f41af9a39a 100644 --- a/collects/dynext/compile-unit.ss +++ b/collects/dynext/compile-unit.ss @@ -4,7 +4,8 @@ (lib "include.ss") (lib "process.ss") (lib "sendevent.ss") - "private/dirs.ss") + "private/dirs.ss" + "private/cmdargs.ss") (require "compile-sig.ss") @@ -15,8 +16,7 @@ (import) (define (get-unix-compile) - (or (getenv "MZSCHEME_DYNEXT_COMPILER") - (find-executable-path "gcc" #f) + (or (find-executable-path "gcc" #f) (find-executable-path "cc" #f))) (define (get-windows-compile) @@ -26,10 +26,15 @@ (define current-extension-compiler (make-parameter - (case (system-type) - [(unix macosx) (get-unix-compile)] - [(windows) (get-windows-compile)] - [else #f]) + (or (let ([p (or (getenv "MZSCHEME_DYNEXT_COMPILER") + (getenv "CC"))]) + (if (and p (absolute-path? p)) + (find-executable-path p #f) + p)) + (case (system-type) + [(unix macosx) (get-unix-compile)] + [(windows) (get-windows-compile)] + [else #f])) (lambda (v) (when v (if (path-string? v) @@ -91,16 +96,25 @@ (raise-type-error who "list of paths/strings and thunks" l)) l)) + (define (get-env-compile-flags) + (let ([v (or (getenv "MZSCHEME_DYNEXT_COMPILER_FLAGS") + (getenv "CFLAGS"))]) + (if v + (split-command-line-args v) + null))) + (define current-extension-compiler-flags (make-parameter - (case (system-type) - [(unix macosx) (if unix-cc? - unix-compile-flags - gcc-compile-flags)] - [(windows) (if (or win-gcc? win-borland?) - gcc-compile-flags - msvc-compile-flags)] - [(macos) '()]) + (append + (get-env-compile-flags) + (case (system-type) + [(unix macosx) (if unix-cc? + unix-compile-flags + gcc-compile-flags)] + [(windows) (if (or win-gcc? win-borland?) + gcc-compile-flags + msvc-compile-flags)] + [(macos) '()])) (make-flags-guard 'current-extension-compiler-flags))) (define current-extension-preprocess-flags diff --git a/collects/dynext/doc.txt b/collects/dynext/doc.txt index 63bf37735a..0335c6407e 100644 --- a/collects/dynext/doc.txt +++ b/collects/dynext/doc.txt @@ -18,9 +18,10 @@ and Unix: > current-extension-compiler - compiler executable path/string or #f. The default is set by searching for an executable using the - PATH environment variable. Under windows, the search looks for - cl.exe, then gcc.exe, then bcc32.exe (Borland). Under Unix, it - checks the MZSCHEME_DYNEXT_COMPILER environment variable, then + PATH environment variable, or using the CC or + MZSCHEME_DYNEXT_COMPILER environment variable if either is defined + (and the latter takes precedence). Under windows, the search looks + for cl.exe, then gcc.exe, then bcc32.exe (Borland). Under Unix, it looks for gcc, then cc. #f indicates that no compiler could be found. @@ -30,14 +31,19 @@ and Unix: "/MT" 3m-flag-thunk) for cl.exe and (list "-c" "-O2" "-fPIC" 3m-flag-thunk) for gcc.exe and bcc32.exe, where 3m-flag-thunk returns (list "-DMZ_PRECISE_GC") for the '3m variant and null for - any other variant; under Unix, the default is usually - (list "-c" "-O2" "-fPIC" 3m-flag-thunk). + any other variant; under Unix, the default is usually (list "-c" + "-O2" "-fPIC" 3m-flag-thunk). If the CFLAGS or + MZSCHEME_DYNEXT_COMPILER_FLAGS environment variable is defined + (the latter takes precedence), then its value is parsed as a list + of strings that is appended before the defaults. > current-make-compile-include-strings - procedure that takes an include directory path/string and returns a list of strings for the command line. Windows: "dir" -> (list "/Idir") for cl.exe, (list "-Idir") for gcc.exe and bcc32.exe; Unix: "dir" -> (list - "-Idir"). + "-Idir"). If the CFLAGS environment variable is defined, then its + value is parsed as a list of flags that is appended before the + defaults. > current-make-compile-input-strings - procedure that takes an input file path/string and returns a list of strings for the @@ -100,17 +106,21 @@ Linking parameters: > current-extension-linker - linker executable path/string or #f. The default is set by searching for an executable using the PATH - environment variable. Under Windows, it looks for cl.exe, then - ld.exe (gcc), then ilink32.exe (Borland). Under Unix it checks - the MZSCHEME_DYNEXT_LINKER environment variable, then, except - AIX, it looks for ld. Under AIX, it looks for cc. #f indicates - that no linker could be found. + environment variable, or by using the LD or + MZSCHEME_DYNEXT_LINKER environment variable if it is defined (and + the latter takes precedence). Under Windows, it looks for cl.exe, + then ld.exe (gcc), then ilink32.exe (Borland). Under AIX, Mac OS + X, or Darwin, it looks for cc. Under other Unix variants, it + looks for ld. #f indicates that no linker could be found. > current-extension-linker-flags - list of paths/strings and thunks (see `expand-for-link-variant' below). Under Windows, default is - (list "/LD") for cl.exe, (list "--dll") for ld.exe, (list "/Tpd" - "/c") for ilink32.exe. Under Unix, the default varies greatly - among platforms. + (list "/LD") for cl.exe, (list "--dll") for ld.exe, and (list + "/Tpd" "/c") for ilink32.exe. Under Unix, the default varies + greatly among platforms. If the LDFLAGS or + MZSCHEME_DYNEXT_LINKER_FLAGS (the latter takes precedence) + environment variable is defined, then its value is parsed as a + list of strings that is appended before the defaults. > current-make-link-input-strings - procedure that takes an input file path/string and returns a list of strings for the diff --git a/collects/dynext/link-unit.ss b/collects/dynext/link-unit.ss index ea0fcb27e5..763649e8fb 100644 --- a/collects/dynext/link-unit.ss +++ b/collects/dynext/link-unit.ss @@ -5,6 +5,7 @@ (lib "process.ss") (lib "sendevent.ss") "private/dirs.ss" + "private/cmdargs.ss" "filename-version.ss") (require "link-sig.ss") @@ -26,26 +27,32 @@ (find-executable-path "ilink32.exe" #f))) (define (get-unix-linker) - (or (getenv "MZSCHEME_DYNEXT_LINKER") - (let ([s (case (string->symbol (path->string (system-library-subpath #f))) - [(rs6k-aix ppc-macosx i386-macosx ppc-darwin i386-darwin) "cc"] - [else "ld"])]) - (find-executable-path s s)))) + (let ([s (case (string->symbol (path->string (system-library-subpath #f))) + [(rs6k-aix ppc-macosx i386-macosx ppc-darwin i386-darwin) "cc"] + [else "ld"])]) + (find-executable-path s s))) + (define (check-valid-linker-path v) + (unless (and (file-exists? v) + (memq 'execute (file-or-directory-permissions v))) + (error 'current-extension-linker + "linker not found or not executable: ~s" v))) + ;; See doc.txt: (define current-extension-linker (make-parameter - (case (system-type) - [(unix macosx) (get-unix-linker)] - [(windows) (get-windows-linker)] - [else #f]) + (or (let ([p (getenv "MZSCHEME_DYNEXT_LINKER")]) + (if (and p (absolute-path? p)) + (find-executable-path p #f) + p)) + (case (system-type) + [(unix macosx) (get-unix-linker)] + [(windows) (get-windows-linker)] + [else #f])) (lambda (v) (when v (if (path-string? v) - (unless (and (file-exists? v) - (memq 'execute (file-or-directory-permissions v))) - (error 'current-extension-linker - "linker not found or not executable: ~s" v)) + (check-valid-linker-path v) (raise-type-error 'current-extension-linker "path, valid-path string, or #f" v))) v))) @@ -121,17 +128,25 @@ (list "-bundle" "-flat_namespace" "-undefined" "suppress")] [(i386-cygwin) win-gcc-linker-flags] [else (list "-shared")])) + + (define (get-env-link-flags) + (let ([v (or (getenv "MZSCHEME_DYNEXT_LINKER_FLAGS") + (getenv "LDFLAGS"))]) + (if v + (split-command-line-args v) + null))) ;; See doc.txt: (define current-extension-linker-flags (make-parameter - (case (system-type) - [(unix macosx) (get-unix-link-flags)] - [(windows) (cond - [win-gcc? win-gcc-linker-flags] - [win-borland? borland-linker-flags] - [else msvc-linker-flags])] - [(macos) null]) + (append (get-env-link-flags) + (case (system-type) + [(unix macosx) (get-unix-link-flags)] + [(windows) (cond + [win-gcc? win-gcc-linker-flags] + [win-borland? borland-linker-flags] + [else msvc-linker-flags])] + [(macos) null])) (lambda (l) (unless (and (list? l) (andmap string? l)) (raise-type-error 'current-extension-linker-flags "list of strings" l)) diff --git a/collects/dynext/private/cmdargs.ss b/collects/dynext/private/cmdargs.ss new file mode 100644 index 0000000000..c162b7bb4a --- /dev/null +++ b/collects/dynext/private/cmdargs.ss @@ -0,0 +1,33 @@ + +(module cmdargs mzscheme + + (provide split-command-line-args) + + (define (split-command-line-args v) + (let loop ([v (strip-leading-spaces (strip-trailing-spaces v))]) + (if (string=? v "") + null + (let-values ([(s v) (let loop ([v v]) + (cond + [(string=? v "") (values "" "")] + [(regexp-match #rx"^[ \t\r\n]" v) (values "" v)] + [(regexp-match-positions #rx"^\"[^\"]*\"" v) + => (combine v loop 1)] + [(regexp-match-positions #rx"^'[^']*'" v) + => (combine v loop 1)] + [(regexp-match-positions #rx"^[^ \t\r\n]+" v) + => (combine v loop 0)]))]) + (cons s (loop (strip-leading-spaces v))))))) + + (define (combine v loop inset) + (lambda (m) + (let-values ([(rest leftover) (loop (substring v (cdar m)))]) + (values (string-append + (substring v (+ (caar m) inset) (- (cdar m) inset))) + leftover)))) + + (define (strip-leading-spaces v) + (regexp-replace #rx"^[\t \r\n]+" v "")) + + (define (strip-trailing-spaces v) + (regexp-replace #rx"[\t \r\n]+$" v "")))