[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