r2784: *** empty log message ***
[uffi.git] / src-mcl / libraries.cl
1 ;;;; -*- Mode: LISP; Syntax: ANSI-Common-Lisp; Base: 10; Package: UFFI -*-
2 ;;;; *************************************************************************
3 ;;;; FILE IDENTIFICATION
4 ;;;;
5 ;;;; Name:          libraries.cl
6 ;;;; Purpose:       UFFI source to load foreign libraries
7 ;;;; Programmers:   Kevin M. Rosenberg and John DeSoi
8 ;;;; Date Started:  Feb 2002
9 ;;;;
10 ;;;; $Id: libraries.cl,v 1.2 2002/09/20 04:51:14 kevin Exp $
11 ;;;;
12 ;;;; This file, part of UFFI, is Copyright (c) 2002 by Kevin M. Rosenberg
13 ;;;; and John DeSoi
14 ;;;;
15 ;;;; UFFI users are granted the rights to distribute and use this software
16 ;;;; as governed by the terms of the Lisp Lesser GNU Public License
17 ;;;; (http://opensource.franz.com/preamble.html), also known as the LLGPL.
18 ;;;; *************************************************************************
19
20 (declaim (optimize (debug 3) (speed 3) (safety 1) (compilation-speed 0)))
21 (in-package :uffi)
22
23 (defvar *loaded-libraries* nil
24   "List of foreign libraries loaded. Used to prevent reloading a library")
25
26 ;in MCL calling this more than once for the same library does not do anything
27 #-openmcl
28 (defmacro load-foreign-library (filename &key module supporting-libraries force-load)
29   (declare (ignore module supporting-libraries force-load))
30   `(eval-when (:compile-toplevel :load-toplevel :execute)
31      (when (ccl:add-to-shared-library-search-path ,filename t) 
32        (pushnew ,filename *loaded-libraries*))))
33
34
35 ; Note we are not dealing with OpenMCL's ability to close the library
36 ; As of v0.13 .dylibs can't be closed but bundles can. See the docs for the latest.
37 #+openmcl
38 (defmacro load-foreign-library (filename &key module supporting-libraries force-load)
39   (declare (ignore module supporting-libraries force-load))
40   `(let ((path (if (pathnamep ,filename) (namestring ,filename) ,filename)))
41      (when (stringp path)
42        (if (position path *loaded-libraries* :test #'string-equal)
43          t
44          (when (ccl:open-shared-library path)
45            (pushnew path *loaded-libraries*)
46            t)))))
47
48
49 (defun find-foreign-library (names directories &key types drive-letters)  
50   "Looks for a foreign library. directories can be a single
51 string or a list of strings of candidate directories. Use default
52 library type if type is not specified."
53   (unless types
54     (setq types (default-foreign-library-type)))
55   (unless (listp types)
56     (setq types (list types)))
57   (unless (listp names)
58     (setq names (list names)))
59   (unless (listp directories)
60     (setq directories (list directories)))
61   #+(or win32 mswindows)
62   (unless (listp drive-letters)
63     (setq drive-letters (list drive-letters)))
64   #-(or win32 mswindows)
65   (setq drive-letters '(nil))
66   (dolist (drive-letter drive-letters)
67     (dolist (name names)
68       (dolist (dir directories)
69         (dolist (type types)
70           (let ((path (make-pathname 
71                        #+lispworks :host
72                        #+lispworks (when drive-letter drive-letter)
73                        #-lispworks :device
74                        #-lispworks (when drive-letter drive-letter)
75                        :name name 
76                        :type type
77                        :directory 
78                        (etypecase dir
79                          (pathname
80                           (pathname-directory dir))
81                          (list
82                           dir)
83                          (string
84                           (pathname-directory 
85                            (parse-namestring dir)))))))
86             (when (probe-file path)
87               (return-from find-foreign-library path)))))))
88    nil)
89
90
91
92 (defun default-foreign-library-type ()
93   "Returns string naming default library type for platform"
94   #+(or win32 mswindows) "dll"
95   #-(or win32 mswindows mcl) "so"
96   #+openmcl '("dylib" "so" nil)
97   #-openmcl '(nil))
98   
99   
100   
101   
102