Skip to content

Detecting compilation under R

6 messages · Brian Ripley, Barry Rowlingson, Paul Roebuck

#
The docs tell me:

"The header files define USING_R, which should be used to test if the 
code is indeed being used with R."

but surely you only get that if you #include <R.h>, which you can only 
do if you are using R. If you have code that you might want to compile 
in R and for other purposes, how can you detect this?

  As an example, suppose I have some C that uses GSL to get a random 
number if its a standalone program, or uses R's internals if its being 
compiled to run in R. I want to do something like:

#ifdef USING_R
#include <R.h>
#else
#include <gsl_random.h>
#endif

  and then:

#ifdef USING_R
  x = rand_unif(0.0,1.0);
#else
  x = gsl_runif(0.0,1.0);
#endif

  (cant remember the exact names but hopefully you get the idea). This 
fails because USING_R is only set when R.h is included.

  Are there any preprocessor definitions set by R CMD SHLIB and R CMD 
BUILD that I can test against?

  Of course I can stick PKG_CFLAGS=-DYES_THIS_IS_USING_R in Makevars, 
but I just wondered if there was a default solution I'd missed. Or if it 
was a good idea anyway.

Barry
#
On Thu, 14 Dec 2006, Barry Rowlingson wrote:

            
Nope, also if you include <S.h>, which you can do under either R or 
S(-PLUS).

You got this from the API section in 'Writing R Extensions', and are 
quoting out of context.
So the problem is that you needed rather

#include <R.h>
#ifdef USING_R
x = rand_unif(0.0,1.0);
#else
#include <gsl_random.h>
x = gsl_runif(0.0,1.0);
#endif

since if R.h is not around, the include will not include it.

  
    
#
If R.h is not around, the preprocessor will throw a tantrum:

  cc    -c -o simple.o simple.c
  simple.c:2:15: error: R.h: No such file or directory

  - all of which would be solved if SHLIB and BUILD set a preprocessor 
flag to indicate compilation by R.

  I dont see what use USING_R is. If you #include <R.h> you get it, but 
then you know you're USING_R because you included R.h, hence USING_R is 
going to always be defined in that code (unless the inclusion of R.h is 
conditional on something else...).

  Oh but of course I've missed something... Just tell me what...

Barry
#
On Thu, 14 Dec 2006, Barry Rowlingson wrote:
[Silently discarding the answer to his question, and breaching 'fair use' 
copyright provisions.]
If *no* R.h is around: easy to solve.
What is BUILD?
You've clipped it from my previous mail, with no indication.  As the 
posting guide points out, this is reprehensible.
#
Prof Brian Ripley wrote:

            
Have a dummy R.h somewhere?
Oh, pardon me for forgetting the arbitrary capitalisation of R CMD 
thingies. Can someone come up with a mnemonic for remembering that 
BATCH, COMPILE, SHLIB, INSTALL, LINK and REMOVE are all caps, that 
build, check, and config are lower case, and everything else has initial 
caps? Except for Sd2Rd. (Yes, R --help tells you).
This bit?

#include <R.h>
#ifdef USING_R
x = rand_unif(0.0,1.0);
#else
#include <gsl_random.h>
x = gsl_runif(0.0,1.0);
#endif

  USING_R is only useful here if you can make #include <R.h> not include 
the official R.h file and not give a 'file not found' error message. I 
cant see how to do this without requiring either a dummy R.h file 
somewhere or options on the C command line. This would then be better 
done with cc -DR_CODE and then use #ifdef R_CODE to include R.h. Then 
USING_R is meaningful.

  Here's what I'd like to do. Give someone a file 'simple.c' and say:

  "Compile it with 'cc -o simple simple.c -lgsl' and then run from the 
command line, or do 'R CMD SHLIB simple.c', then do a dyn.load and a 
.C() call'."

  if "R CMD SHLIB" and "R CMD build" set a preprocessor flag then this 
could be done. You could even have -DRSHLIB and -DRbuild on the command 
line to give it a bit more intelligence.

  My behaviour may be reprehensible but sometimes your responses seem 
cryptic to the point of incomprehensible.

Barry
5 days later
#
On Thu, 14 Dec 2006, Prof Brian Ripley wrote:

            
Never saw the reply to Barry's question. His quoting
methodology notwithstanding, I don't see the answer
plainly either.

When Prof. Ripley says above - "easy to solve", is the
implication that R installation become prerequisite or
creating a fake "R.h"?


Would have thought it easiest to solve by adding
-DUSING_R to Makevar's PKG_CPPFLAGS with the code
restructured as below.

#ifdef USING_R
    #include <R.h>
    x = rand_unif(0.0,1.0);
#else
    #include <gsl_random.h>
    x = gsl_runif(0.0,1.0);
#endif

Barry's suggestion to eliminate this step by having any
R-based compile process identify itself (although a single
preprocessor define is sufficient) would be a nice addition,
simplifying life when a source file can be used with
R or standalone.

----------------------------------------------------------
SIGSIG -- signature too long (core dumped)