made it possible to try several versions, use it in readline and openssl

svn: r6138
This commit is contained in:
Eli Barzilay 2007-05-04 06:08:48 +00:00
parent 943967a4ce
commit 26ab4af5f7
3 changed files with 79 additions and 70 deletions

View File

@ -2,8 +2,7 @@
(module foreign mzscheme (module foreign mzscheme
(require #%foreign (require #%foreign (lib "dirs.ss" "setup"))
(lib "dirs.ss" "setup"))
(require-for-syntax (lib "stx.ss" "syntax")) (require-for-syntax (lib "stx.ss" "syntax"))
;; This module is full of unsafe bindings that are not provided to requiring ;; This module is full of unsafe bindings that are not provided to requiring
@ -141,44 +140,53 @@
(define get-ffi-lib (define get-ffi-lib
(case-lambda (case-lambda
[(name) (get-ffi-lib name "")] [(name) (get-ffi-lib name "")]
[(name version) [(name version/s)
(cond (cond
[(not name) (ffi-lib name)] ; #f => NULL => open this executable [(not name) (ffi-lib name)] ; #f => NULL => open this executable
[(not (or (string? name) (path? name))) [(not (or (string? name) (path? name)))
(raise-type-error 'ffi-lib "library-name" name)] (raise-type-error 'ffi-lib "library-name" name)]
[else [else
;; A possible way that this might be misleading: say that there is a ;; A possible way that this might be misleading: say that there is a
;; "foo.so" file in the current directory, which refers to some undefined ;; "foo.so" file in the current directory, which refers to some
;; symbol, trying to use this function with "foo.so" will try a dlopen ;; undefined symbol, trying to use this function with "foo.so" will try
;; with "foo.so" which isn't found, then it tries a dlopen with ;; a dlopen with "foo.so" which isn't found, then it tries a dlopen with
;; "/<curpath>/foo.so" which fails because of the undefined symbol, and ;; "/<curpath>/foo.so" which fails because of the undefined symbol, and
;; since all fails, it will use (ffi-lib "foo.so") to raise the original ;; since all fails, it will use (ffi-lib "foo.so") to raise the original
;; file-not-found error. This is because the dlopen doesn't provide a ;; file-not-found error. This is because the dlopen doesn't provide a
;; way to distinguish different errors (only dlerror, but that's ;; way to distinguish different errors (only dlerror, but that's
;; unreliable). ;; unreliable).
(let* ([version (if (zero? (string-length version)) (let* ([versions (if (list? version/s) version/s (list version/s))]
"" (string-append "." version))] [versions (map (lambda (v)
(if (or (not v) (zero? (string-length v)))
"" (string-append "." v)))
versions)]
[fullpath (lambda (p) (path->complete-path (expand-path p)))] [fullpath (lambda (p) (path->complete-path (expand-path p)))]
[absolute? (absolute-path? name)] [absolute? (absolute-path? name)]
[name0 (path->string (expand-path name))] ; orig name [name0 (path->string (expand-path name))] ; orig name
[name (if (regexp-match lib-suffix-re name0) ; name + suffix [names (map (if (regexp-match lib-suffix-re name0) ; name+suffix
(string-append name0 version) (lambda (v) (string-append name0 v))
(string-append name0 "." lib-suffix version))]) (lambda (v) (string-append name0 "." lib-suffix v)))
(or (and (not absolute?) versions)]
[ffi-lib* (lambda (name) (ffi-lib name #t))])
(or ;; try to look in our library paths first
(and (not absolute?)
(ormap (lambda (dir) (ormap (lambda (dir)
;; try good name first, then original ;; try good names first, then original
(or (ffi-lib (build-path dir name) #t) (or (ormap (lambda (name)
(ffi-lib (build-path dir name0) #t))) (ffi-lib* (build-path dir name)))
names)
(ffi-lib* (build-path dir name0))))
(get-lib-search-dirs))) (get-lib-search-dirs)))
;; Try without DLL path: ;; try a system search
(ffi-lib name #t) ; try good name first (ormap ffi-lib* names) ; try good names first
(ffi-lib name0 #t) ; try original (ffi-lib* name0) ; try original
(and (file-exists? name) ; try a relative path (ormap (lambda (name) ; try relative paths
(ffi-lib (fullpath name) #t)) (and (file-exists? name) (ffi-lib* (fullpath name))))
names)
(and (file-exists? name0) ; relative with original (and (file-exists? name0) ; relative with original
(ffi-lib (fullpath name0) #t)) (ffi-lib* (fullpath name0)))
;; give up: call ffi-lib so it will raise an error ;; give up: call ffi-lib so it will raise an error
(ffi-lib name)))])])) (ffi-lib (car names))))])]))
(define (get-ffi-lib-internal x) (define (get-ffi-lib-internal x)
(if (ffi-lib? x) x (get-ffi-lib x))) (if (ffi-lib? x) x (get-ffi-lib x)))

View File

@ -68,14 +68,15 @@
(with-handlers ([exn:fail? (lambda (x) (with-handlers ([exn:fail? (lambda (x)
(set! ssl-load-fail-reason (exn-message x)) (set! ssl-load-fail-reason (exn-message x))
#f)]) #f)])
(ffi-lib libcrypto-so))) (ffi-lib libcrypto-so '("" "0.9.8b" "0.9.8" "0.9.7"))))
(define libssl (define libssl
(and libcrypto (and libcrypto
(with-handlers ([exn:fail? (lambda (x) (with-handlers ([exn:fail?
(lambda (x)
(set! ssl-load-fail-reason (exn-message x)) (set! ssl-load-fail-reason (exn-message x))
#f)]) #f)])
(ffi-lib libssl-so)))) (ffi-lib libssl-so '("" "0.9.8b" "0.9.8" "0.9.7")))))
(define libmz (ffi-lib #f)) (define libmz (ffi-lib #f))

View File

@ -7,7 +7,7 @@
;; libtermcap needed on some platforms ;; libtermcap needed on some platforms
(define libtermcap (with-handlers ([exn:fail? void]) (ffi-lib "libtermcap"))) (define libtermcap (with-handlers ([exn:fail? void]) (ffi-lib "libtermcap")))
(define libreadline (ffi-lib "libreadline")) (define libreadline (ffi-lib "libreadline" '("" "5" "4")))
(define make-byte-string ; helper for the two types below (define make-byte-string ; helper for the two types below
(get-ffi-obj "scheme_make_byte_string" #f (_fun _pointer -> _scheme))) (get-ffi-obj "scheme_make_byte_string" #f (_fun _pointer -> _scheme)))