* hackery (was: dynamic linking)
@ 2010-02-15 17:43 Tomas By
2010-02-16 15:20 ` Linas Vepstas
0 siblings, 1 reply; 3+ messages in thread
From: Tomas By @ 2010-02-15 17:43 UTC (permalink / raw)
To: guile-user
Hello again everybody,
After some experimentation, it now seems clear that this has nothing
to do with garbage collection or Mercury. It is probably just a silly
programming error on my part.
Here follows full source code for a simple example that illustrates
the problem I am having. The important bit is the call to the Mercury
defined procedure `testproc_c.' With that call commented out, the
module loads fine.
The intention is that the `mytype' data is manipulated only in
Mercury, and passed around in the Scheme interface as a C pointer.
Would be glad if somebody could explain what I am missing.
(Guile 1.8.7)
/Tomas
---------- mytest.scm ------------------------------------------------
(define-module (mytest))
(export mytest)
(load-extension "libguile-mytest" "init_mytest")
---------- mylib.m (Mercury) -----------------------------------------
:- module mylib.
:- interface.
:- use_module io.
:- import_module list,bool.
:- type mytype ---> stuff(int,float,bool).
:- pred testproc(list(string),mytype,io.state,io.state).
:- mode testproc(in,out,di,uo) is det.
:- implementation.
:- pragma foreign_export("C",testproc(in,out,di,uo),"testproc_c").
testproc(_,X,!IO) :- X = stuff(0,0.0,no).
:- end_module mylib.
---------- mytest.h --------------------------------------------------
#ifndef MYDEF_H
#define MYDEF_H
#include <libguile.h>
SCM testproc_wrapper(SCM,SCM);
void init_mytest(void);
#endif /* MYDEF_H */
---------- mytest.c --------------------------------------------------
#include "mylibrary.h"
#include "mylib.mh"
#include "mytest.h"
#include <mercury.h>
#include <libguile.h>
SCM testproc_wrapper(SCM s,SCM x)
{
MR_Word temp = MR_list_empty();
MR_Word* p;
testproc_c(temp,p); /* CALL TO MERCURY PROCEDURE */
SCM_SET_SMOB_DATA(x,(scm_t_bits)p);
return SCM_BOOL_T;
}
void init_mytest()
{
void *dummy;
char* args[1] = {(char*)""};
mercury_init(1,args,&dummy);
(void)scm_make_smob_type("mytype",0);
scm_c_define_gsubr("mytest",2,0,0,testproc_wrapper);
}
---------- mylib.mh --------------------------------------------------
/*
** Automatically generated from `mylib.m'
** by the Mercury compiler,
** version rotd-2009-12-28, configured for i686-pc-linux-gnu.
** Do not edit.
*/
#ifndef MYLIB_MH
#define MYLIB_MH
#ifdef __cplusplus
extern "C" {
#endif
#ifdef MR_HIGHLEVEL_CODE
#include "mercury.h"
#else
#ifndef MERCURY_HDR_EXCLUDE_IMP_H
#include "mercury_imp.h"
#endif
#endif
#ifdef MR_DEEP_PROFILING
#include "mercury_deep_profiling.h"
#endif
#ifndef MYLIB_DECL_GUARD
#define MYLIB_DECL_GUARD
#endif
void testproc_c(MR_Word, MR_Word *);
#ifdef __cplusplus
}
#endif
#endif /* MYLIB_MH */
---------- Makefile --------------------------------------------------
nothing: lib
CC = gcc
LD = gcc
MMC = mmc
MMAKE = mmake
GUILE_CFLAGS=$(shell guile-config compile)
GUILE_LIBS=$(shell guile-config link)
MERCURY_CFLAGS=$(shell $(MMC) --output-cflags)
MERCURY_LIBS=-L/usr/lib -L/usr/local/mercury-rotd-2009-12-28/lib/mercury/lib \
-L/usr/local/mercury-rotd-2009-12-28/lib/mercury/lib/asm_fast.gc \
-Wl,-rpath,/usr/local/mercury-rotd-2009-12-28/lib/mercury/lib \
-Wl,-rpath,/usr/local/mercury-rotd-2009-12-28/lib/mercury/lib/asm_fast.gc \
-lmer_std -lmer_rt -lm -lgc
LIBS = $(MERCURY_LIBS) $(GUILE_LIBS)
mylibrary.o : mylib.m
$(MMC) --generate-standalone-interface mylibrary mylib.m
mytest.o : mytest.c
$(CC) -c $(GUILE_CFLAGS) $(MERCURY_CFLAGS) mytest.c
mylib.mh : mylib.m
$(MMC) mylib.m
lib : mytest.o mylibrary.o
$(LD) -shared -fPIC mylibrary.o mytest.o -o libguile-mytest.so $(LIBS)
install : mytest.scm libguile-mytest.so
sudo cp mytest.scm /usr/share/guile/1.8/
sudo cp libguile-mytest.so /usr/lib/
---------- without the call to testproc_c ----------------------------
$ guile
guile> (use-modules (mytest))
guile>
---------- with call to testproc_c -----------------------------------
$ guile
guile> (use-modules (mytest))
Backtrace:
In unknown file:
...
?: 13 (begin (if # #) (make-modules-in # full-name))
?: 14* (if (or # #) (try-load-module name))
?: 15 [try-load-module (mytest)]
?: 16 (or (begin (try-module-linked name)) (try-module-autoload name) ...)
?: 17* [try-module-autoload (mytest)]
?: 18 (let* (# # # #) (resolve-module dir-hint-module-name #f) (and # #))
...
?: 19 (letrec ((load-file #)) (dynamic-wind (lambda () #) (lambda () #)
...) ...)
?: 20* [dynamic-wind #<procedure #f ()> #<procedure #f ()> #<procedure #f ()>]
?: 21* [#<procedure #f ()>]
?: 22* (let* ((file #)) (cond (# => #) (# => #)))
?: 23 [#<procedure #f (full)> "/usr/share/guile/1.8/mytest.scm"]
?: 24 [with-fluid* #<fluid 7> #f #<procedure #f ()>]
?: 25* [#<procedure #f ()>]
?: 26* [load-file #<primitive-procedure primitive-load> ...]
?: 27* [save-module-excursion #<procedure #f ()>]
?: 28 (let (# #) (dynamic-wind # thunk #))
?: 29 [dynamic-wind #<procedure #f ()> #<procedure #f ()> #<procedure #f ()>]
?: 30* [#<procedure #f ()>]
?: 31* [primitive-load "/usr/share/guile/1.8/mytest.scm"]
In /usr/share/guile/1.8/mytest.scm:
3: 32* [load-extension "libguile-mytest" "init_mytest"]
/usr/share/guile/1.8/mytest.scm:3:1: In procedure dynamic-link in expression
(load-extension "libguile-mytest" "init_mytest"):
/usr/share/guile/1.8/mytest.scm:3:1: file: "libguile-mytest", message: "file
not found"
ABORT: (misc-error)
guile>
----------------------------------------------------------------------
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: hackery (was: dynamic linking)
2010-02-15 17:43 hackery (was: dynamic linking) Tomas By
@ 2010-02-16 15:20 ` Linas Vepstas
2010-02-16 22:06 ` Tomas By
0 siblings, 1 reply; 3+ messages in thread
From: Linas Vepstas @ 2010-02-16 15:20 UTC (permalink / raw)
To: Tomas By; +Cc: guile-user
On 15 February 2010 11:43, Tomas By <tomas.by@fcsh.unl.pt> wrote:
> Hello again everybody,
Just a wild guess -- i'm focusing on the "file not found" aspect of the
error message:
what does ldd libguile-mytest.so show? Are all dependencies resolved?
If you compile the following, will it run?
#include "mylibrary.h"
#include "mylib.mh"
#include "mytest.h"
#include <mercury.h>
main()
{
MR_Word temp = MR_list_empty();
MR_Word* p;
testproc_c(temp,p);
return 0;
}
i.e. is this enough to compile it:
cc main.c -lguile-mytest.so -L .
or do you need something more?
--linas
disclaimer: I am a guile novice
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: hackery (was: dynamic linking)
2010-02-16 15:20 ` Linas Vepstas
@ 2010-02-16 22:06 ` Tomas By
0 siblings, 0 replies; 3+ messages in thread
From: Tomas By @ 2010-02-16 22:06 UTC (permalink / raw)
To: linasvepstas; +Cc: guile-user
On Tue, February 16, 2010 16:20, Linas Vepstas wrote:
> what does ldd libguile-mytest.so show? Are all dependencies resolved?
I think so.
> If you compile the following, will it run? [...]
> i.e. is this enough to compile it: [...]
Mercury needs to be initialized, and the C compiler needs to know about
the locations of the Mercury .h/.o files, but I compiled it and got a
Mercury error, manifesting itself as a segmentation fault.
So it looks like it is a C/Mercury interface problem, not Guile.
(thanks anyway)
/Tomas
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2010-02-16 22:06 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-02-15 17:43 hackery (was: dynamic linking) Tomas By
2010-02-16 15:20 ` Linas Vepstas
2010-02-16 22:06 ` Tomas By
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).