From tobias.verbeke at businessdecision.com  Tue Aug 14 08:15:17 2007
From: tobias.verbeke at businessdecision.com (Tobias Verbeke)
Date: Tue, 14 Aug 2007 08:15:17 +0200
Subject: [Rd] Sligthly OT Re: Makefile for embedding OpenBUGS in R
	package
In-Reply-To: <46BA2E65.7080301@cimr.cam.ac.uk>
References: <W906017980119021186410641@nocme1bl6.telenet-ops.be>	<Pine.LNX.4.64.0708062029410.27542@gannet.stats.ox.ac.uk>	<46B7B87C.1070808@cimr.cam.ac.uk>	<Pine.LNX.4.64.0708070340290.31210@gannet.stats.ox.ac.uk>	<46B8D6AD.9040707@cimr.cam.ac.uk>
	<46B96EE6.2090606@statistik.uni-dortmund.de>
	<46BA1863.6030609@telenet.be> <46BA2E65.7080301@cimr.cam.ac.uk>
Message-ID: <46C14875.5020008@businessdecision.com>

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



[Rd] Sligthly OT Re: Makefile for embedding OpenBUGS in R package
Tobias Verbeke