194 lines
5.8 KiB
Prolog
194 lines
5.8 KiB
Prolog
/*************************************************************************
|
|
* *
|
|
* YAP Prolog *
|
|
* *
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
* *
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 *
|
|
* *
|
|
**************************************************************************
|
|
* *
|
|
* File: load_foreign.yap *
|
|
* Last rev: 8/2/88 *
|
|
* mods: *
|
|
* comments: Utility predicates for load_foreign *
|
|
* *
|
|
*************************************************************************/
|
|
|
|
|
|
:- system_module( '$_load_foreign', [load_foreign_files/3,
|
|
open_shared_object/2,
|
|
open_shared_object/3], ['$import_foreign'/3]).
|
|
|
|
:- use_system_module( '$_errors', ['$do_error'/2]).
|
|
|
|
:- use_system_module( '$_modules', ['$do_import'/3]).
|
|
|
|
|
|
|
|
/**
|
|
|
|
@defgroup LoadForeign Access to Foreign Language Programs
|
|
@ingroup fli_c_cx
|
|
|
|
@{
|
|
|
|
*/
|
|
|
|
maplist_(_, [], []).
|
|
maplist_(Pred, [A1|L1], [A2|L2]) :-
|
|
call(Pred, A1, A2),
|
|
maplist_(Pred, L1, L2).
|
|
|
|
/** @pred load_foreign_files( _Files_, _Libs_, _InitRoutine_)
|
|
|
|
should be used, from inside YAP, to load object files produced by the C
|
|
compiler. The argument _ObjectFiles_ should be a list of atoms
|
|
specifying the object files to load, _Libs_ is a list (possibly
|
|
empty) of libraries to be passed to the unix loader (`ld`) and
|
|
InitRoutine is the name of the C routine (to be called after the files
|
|
are loaded) to perform the necessary declarations to YAP of the
|
|
predicates defined in the files.
|
|
|
|
YAP will search for _ObjectFiles_ in the current directory first. If
|
|
it cannot find them it will search for the files using the environment
|
|
variable:
|
|
|
|
+ YAPLIBDIR
|
|
|
|
if defined, or in the default library.
|
|
|
|
YAP supports the SWI-Prolog interface to loading foreign code, the shlib package.
|
|
|
|
*/
|
|
|
|
|
|
load_foreign_files(Objs,Libs,Entry) :-
|
|
source_module(M),
|
|
%G = load_foreign_files(Objs,Libs,Entry),
|
|
'$absfs'( Objs, [file_type(executable),
|
|
access(read),
|
|
expand(true),
|
|
file_errors(fail)], NewObjs),
|
|
maplist_( '$load_lib', Libs, NewLibs),
|
|
'$load_foreign_files'(NewObjs,NewLibs,Entry),
|
|
!,
|
|
prolog_load_context(file, F),
|
|
ignore( recordzifnot( '$load_foreign_done', [F, M], _) ).
|
|
|
|
'$absfs'([],_P,[]).
|
|
'$absfs'([F|Fs],P,[NF|NFs]) :-
|
|
'$name_object'(F, P, NF),
|
|
!,
|
|
'$absfs'(Fs,P,NFs).
|
|
'$absfs'([F|Fs],P,[F|NFs]) :-
|
|
'$absfs'(Fs,P,NFs).
|
|
|
|
'$name_object'(I, P, O) :-
|
|
atom(I),
|
|
!,
|
|
absolute_file_name(foreign(I), O, P).
|
|
'$name_object'(I, P, O) :-
|
|
absolute_file_name(I, O, P).
|
|
|
|
'$load_lib'(_,L,L).
|
|
|
|
/** @pred load_absolute_foreign_files( Files, Libs, InitRoutine)
|
|
|
|
Loads object files produced by the C compiler. It is useful when no search should be performed and instead one has the full paths to the _Files_ and _Libs_.
|
|
|
|
*/
|
|
load_absolute_foreign_files(_Objs,_Libs,_Entry).
|
|
'$checklib_prefix'(F,F) :- is_absolute_file_name(F), !.
|
|
'$checklib_prefix'(F, F) :-
|
|
sub_atom(F, 0, _, _, lib), !.
|
|
'$checklib_prefix'(F, Lib) :-
|
|
atom_concat(lib, F, Lib).
|
|
|
|
'$import_foreign'(F, M0, M) :-
|
|
M \= M0,
|
|
predicate_property(M0:P,built_in),
|
|
predicate_property(M0:P,file(F)),
|
|
functor(P, N, K),
|
|
'$do_import'(N/K-N/K, M0, M),
|
|
fail.
|
|
'$import_foreign'(_F, _M0, _M).
|
|
|
|
/** @pred open_shared_object(+ _File_, - _Handle_)
|
|
|
|
File is the name of a shared object file (called dynamic load
|
|
library in MS-Windows). This file is attached to the current process
|
|
and _Handle_ is unified with a handle to the library. Equivalent to
|
|
`open_shared_object(File, [], Handle)`. See also
|
|
load_foreign_library/1 and `load_foreign_library/2`.
|
|
|
|
On errors, an exception `shared_object`( _Action_,
|
|
_Message_) is raised. _Message_ is the return value from
|
|
dlerror().
|
|
|
|
|
|
*/
|
|
open_shared_object(File, Handle) :-
|
|
open_shared_object(File, [], Handle).
|
|
|
|
/** @pred open_shared_object(+ _File_, - _Handle_, + _Options_)
|
|
|
|
As `open_shared_object/2`, but allows for additional flags to
|
|
be passed. _Options_ is a list of atoms. `now` implies the
|
|
symbols are
|
|
resolved immediately rather than lazily (default). `global` implies
|
|
symbols of the loaded object are visible while loading other shared
|
|
objects (by default they are local). Note that these flags may not
|
|
be supported by your operating system. Check the documentation of
|
|
`dlopen()` or equivalent on your operating system. Unsupported
|
|
flags are silently ignored.
|
|
|
|
|
|
*/
|
|
open_shared_object(File, Opts, Handle) :-
|
|
'$open_shared_opts'(Opts, open_shared_object(File, Opts, Handle), OptsI),
|
|
'$open_shared_object'(File, OptsI, Handle),
|
|
prolog_load_context(module, M),
|
|
ignore( recordzifnot( '$foreign', M:'$swi_foreign'(File,Opts, Handle), _) ).
|
|
|
|
'$open_shared_opts'(Opts, G, _OptsI) :-
|
|
var(Opts), !,
|
|
'$do_error'(instantiation_error,G).
|
|
'$open_shared_opts'([], _, 0) :- !.
|
|
'$open_shared_opts'([Opt|Opts], G, V) :-
|
|
'$open_shared_opts'(Opts, G, V0),
|
|
'$open_shared_opt'(Opt, G, OptV),
|
|
V0 is V \/ OptV.
|
|
|
|
'$open_shared_opt'(Opt, G, _) :-
|
|
var(Opt), !,
|
|
'$do_error'(instantiation_error,G).
|
|
'$open_shared_opt'(now, __, 1) :- !.
|
|
'$open_shared_opt'(global, __, 2) :- !.
|
|
'$open_shared_opt'(Opt, Goal, _) :-
|
|
'$do_error'(domain_error(open_shared_object_option,Opt),Goal).
|
|
|
|
/** @pred call_shared_object_function(+ _Handle_, + _Function_)
|
|
|
|
Call the named function in the loaded shared library. The function is
|
|
called without arguments and the return-value is ignored. YAP supports
|
|
installing foreign language predicates using calls to 'UserCCall()`,
|
|
`PL_register_foreign()`, and friends.
|
|
|
|
*/
|
|
|
|
call_shared_object_function( Handle, Function) :-
|
|
'$call_shared_object_function'( Handle, Function),
|
|
prolog_load_context(module, M),
|
|
ignore( recordzifnot( '$foreign', M:'$swi_foreign'( Handle, Function ), _) ).
|
|
%% @}
|
|
|
|
/** @pred $slave is det
|
|
|
|
Called at boot-time when Prolog is run from another language (eg, Java, Python, Android)
|
|
*/
|
|
|
|
'$slave' :-
|
|
getenv( '__PYVENV_LAUNCHER__', _ ),
|
|
use_module( library(python) ).
|