Sligthly OT Re: Makefile for embedding OpenBUGS in R package
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