[Rd] Sligthly OT Re: Makefile for embedding OpenBUGS in R package
Tobias Verbeke
tobias.verbeke at businessdecision.com
Tue Aug 14 08:15:17 CEST 2007
Hin-Tak Leung wrote:
> Tobias Verbeke wrote:
> <snipped>
>> Actually, I think Hin-Tak is right about the absolute path. Even when
>> the R code will call the executable that resides in that directory, R
>> will call it from any directory and that (current) directory will be
>> resolved (at least that is what I observe experimentally).
>>
>> When such an absolute path is coded in, everything runs fine -- we now
>> can run a BUGS script from within R under GNU/Linux !
>>
>> It would however be nice to solve the remaining problem of the
>> absolute path in the dlopen() call, i.e. being able to fill in
>> `dynamically' the library path to which the package is actually
>> installed.
>>
>> Is there a way to have the library path to which a package is
>> installed available during package installation and then to do some
>> text-processing to fill in this path dynamically into the C file i.e.
>> as argument of dlopen() before compiling it?
> <snipped>
>
> I don't know if there is a neater way of doing this, but one somewhat
> clunky way is to process the result of .libPath() , append each of its
> elements by <package>/inst/OpenBUGS/bugs.so and test if the file exists,
> (.libPath() should be quite a small character vector so it should be too
> slow to test every one), then pass the result as an explicit
> argument to the main bugs binary before everything else it takes.
>
> I think there is a more clever way of telling where the current package
> is installed/located but it escapes me at the moment. Perhaps the source
> code of data() (just typying 'data' without the () at the comment prompt
> will display the source), can shed some lights on this, since data()
> does something quite similiar.
Thank you, Hin-Tak, for pointing me in the right direction.
Please find below the final C code I use to get OpenBUGS
running.
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>
int main (int argc, char *argv[])
{
void * handle;
void (*cli)(void);
char * error;
char * sopath;
sopath = argv[1]; /* path of brugs.so */
handle = dlopen(sopath, RTLD_LAZY);
if (!handle) {
fprintf (stderr, "%s\n", dlerror());
exit(1);
}
* (void **) (&cli) = dlsym(handle, "CLI");
if ((error = dlerror()) != NULL) {
fprintf (stderr, "%s\n", error);
exit(1);
}
(*cli)();
dlclose(handle);
return 0;
}
At the R level, the use of system.file seemed to me to be
the most generally applicable. The relevant lines from the
calling R code are:
## construct system command
exe <- if (iswin) "bugs.exe" else "linbugs"
sofile <- "brugs.so"
OpenBUGSpath <- system.file("OpenBUGS", package = "CGHmix")
pathexe <- file.path(OpenBUGSpath, exe)
pathso <- file.path(OpenBUGSpath, sofile)
cmd <- if (iswin){
paste(pathexe, "<", scriptfile, ">", resultsfile, sep = " ")
} else {
paste(pathexe, pathso, "<", scriptfile, ">", resultsfile,
sep = " ")
}
system(cmd)
The resulting package now allows for using an embedded OpenBUGS
on GNU/Linux without relying on WINE. Thanks to all for their helpful
comments.
Kind regards,
Tobias
--
Tobias Verbeke - Consultant
Business & Decision Benelux
Rue de la révolution 8
1000 Brussels - BELGIUM
+32 499 36 33 15
tobias.verbeke at businessdecision.com
More information about the R-devel
mailing list