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
Detecting compilation under R
6 messages · Brian Ripley, Barry Rowlingson, Paul Roebuck
On Thu, 14 Dec 2006, Barry Rowlingson wrote:
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
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.
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.
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.
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.
Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
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.]
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:
If *no* R.h is around: easy to solve.
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.
What is BUILD?
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...
You've clipped it from my previous mail, with no indication. As the posting guide points out, this is reprehensible.
Brian D. Ripley, ripley at stats.ox.ac.uk Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ University of Oxford, Tel: +44 1865 272861 (self) 1 South Parks Road, +44 1865 272866 (PA) Oxford OX1 3TG, UK Fax: +44 1865 272595
Prof Brian Ripley wrote:
If *no* R.h is around: easy to solve.
Have a dummy R.h somewhere?
What is BUILD?
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).
You've clipped it from my previous mail, with no indication. As the posting guide points out, this is reprehensible.
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:
On Thu, 14 Dec 2006, Barry Rowlingson wrote: [Silently discarding the answer to his question, and breaching 'fair use' copyright provisions.]
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:
If *no* R.h is around: easy to solve.
cc -c -o simple.o simple.c simple.c:2:15: error: R.h: No such file or directory
[SNIP - PLR]
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)