1
votes

This is my first question and I'll try to do my best to write a good one. Please let me know if you need any other information.

I'm going to start with a brief background so you can understand what I'm trying to accomplish and why. Then I'll ask my specific question.

I'm currently developing a package using Rcpp/RcppGSL. I'm using C/C++ because some of the computations I'll be doing will be over very large data sets and they need to be fast. (I'm also a research assistant; I don't always get to choose how we do things.) I'm definitely a novice with respect to C/C++. And to my understanding, C is (almost) a subset of C++. So, I've taken this to mean that I can, essentially, import and run all of my C code as C++ code (sans a few changes). Therefore, I should be able to integrate my C code into an R package using Rcpp/RcppGSL.

After I had all of my C code working, I started actually assembling the R package. I realize now this was a mistake. I should have started the development in RStudio.

I believe I have an issue with R not being able to find GSL, making me think the path variable is incorrect. I think this because I am able to get the given test functions for Rcpp to work, along with a few of my own test functions. However, whenever I try getting RcppGSL to work, specifically, whenever I use CTRL+SHIFT+L on my package, I get the following error:

Error in dyn.load(dllfile) : unable to load shared object '/home/max/research/qeadan/rcnetwork/src/rcnetwork.so': /home/max/research/qeadan/rcnetwork/src/rcnetwork.so: undefined symbol: gsl_vector_alloc

So, after seeing this, I looked at the following sources: Advanced R by Wickham, R Packages by Wickham, Seamless R and C++ Integration with Rcpp by Eddelbuettel, and Writing R Extensions by R Core Team (author check?) and the following SO posts (though there have been more): downloading the gsl headers into the R package is suggested; the package was borked; and the linking wasn't taking place. Nothing I've found directly addresses my issue.

Hence, I suppose my question has two parts: a) am I actually correct as to what I think the error is? and b) would someone please give me a reference that will tell me, or simply tell me, how to fix this? I'm sure the solution is simple; I just don't know how to do it, nor do I know where to look.

I've included my code, NAMESPACE, and Makevars.in folder.

Here is a version of the function I'm trying to export. I've commented out lines that require other functions I've written in C but still produce the same error I'm getting without new ones.

#include <RcppGSL.h>
#include "rootedCorrelationHeaders.h"

using namespace Rcpp;
using namespace RcppGSL;

// [[Rcpp::export]]
Rcpp::List ccm(SEXP datas, SEXP correls, double alpha){

RcppGSL::matrix<double> data = datas;
Rcpp::CharacterVector correl = correls;

//Create C/C++ types
gsl_matrix *cm1, *cm2;


//Get matrix dimensions from GSL matrix
int ROW = (int) data.nrow();
int COL = (int) data.ncol();

//Create structure to hold sorted matrices
//sm *split; //requires outside struct

//Allocate memory to data structure
//split = smAlloc(ROW, COL); //requires outside function

return Rcpp::List::create(Rcpp::Named("Comparison")= ROW,
                          Rcpp::Named("Correl1") = alpha,
                          Rcpp::Named("Correl2") = correl);

} 

Here is my NAMESPACE file. But, honestly, I don't really understand it.

useDynLib(rcnetwork, .registration=TRUE)
exportPattern("^[[:alpha:]]+") 
import(RcppGSL)
importFrom(Rcpp, evalCpp, sourceCpp)

Here is my Makevars.in file. Again, I don't really understand it.

# Set by configure
GSL_CFLAGS = @GSL_CFLAGS@
GSL_LIBS = @GSL_LIB@
RCPP_LDFLAGS = @RCPP_LDFLAGS@

# Combine with standard arguments for R
PKG_CPPGLAGS = $ (GSL_CFLAGS)
PKG_LIBS = $ (GSL_LIBS) $(RCPP_LDFLAGS)

Lastly, here are the relevant parts of the DESCRIPTION file (added as edit per duckmayr's comment).

License: GPL (>= 2)
LazyData: TRUE
Depends: R (>= 3.6.2)
Imports: 
    Rcpp,
    RcppGSL,
    plot.matrix
LinkingTo:
    Rcpp,
    RcppGSL,
    plot.matrix
SystemRequirements: GNU GSL

As a final note, running the command

R.version

yields the following output:

platform       x86_64-pc-linux-gnu         
arch           x86_64                      
os             linux-gnu                   
system         x86_64, linux-gnu           
status                                     
major          4                           
minor          0.0                         
year           2020                        
month          04                          
day            24                          
svn rev        78286                       
language       R                           
version.string R version 4.0.0 (2020-04-24)
nickname       Arbor Day                

Lastly, a fix I've seen a few times on multiple posts is to use the function

compileAttributes()

In particular, people generally have to use it twice. I've done this and it doesn't change anything. It actually doesn't give any output in the console (just in case that's a red flag).

In advance, thank you so much for your help and your time.

1
Do you have RcppGSL in the Linking To field of your DESCRIPTION file? If not add it there (see here for more details). For standalone scripts, you use the // [[Rcpp::depends(RcppGSL)]] you've used to set -I flags, while for packages, you use the Linking To field. - duckmayr
I do! I'll add it to the question, that way everyone can see it. Thank you. I'll try removing the // [[Rcpp::depends(RcppGSL)]] from my script. - Max Black
(It's a very long post and you clearly have done a lot of work but you need to be careful. Some information can be stale, some information can be wrong. I.e. people generally have to use it twice is a) no longer correct (there once was a bug, it is fex) and b) if you already work inside RStudio then you run it zero times because it is generally running for you.) - Dirk Eddelbuettel
In general, I recommend to start with the simplest possible example concerning your issue. Which, for a package using GSL via RcppGSL is to use the embedded example paackage (see examples/RcppGSLExample in your RcppGSL installation) and see if that works for you. - Dirk Eddelbuettel
I just shipped it "as is" to the RHub Buider testing it on macOS (as I don't have macOS here) and it worked just fine: builder.r-hub.io/status/… - Dirk Eddelbuettel

1 Answers

1
votes

Let's look at a simple working example. I start by copying what is included in the package:

edd@rob:~$ cp -ax /usr/local/lib/R/site-library/RcppGSL/examples/RcppGSLExample/ /tmp/
edd@rob:~$ cd /tmp/RcppGSLExample/                                                                       
edd@rob:/tmp/RcppGSLExample$ R CMD build .                                                               
* checking for file ‘./DESCRIPTION’ ... OK
* preparing ‘RcppGSLExample’:
* checking DESCRIPTION meta-information ... OK
* cleaning src                       
* checking for LF line-endings in source and make files and shell scripts
* checking for empty or unneeded directories
* building ‘RcppGSLExample_0.0.3.tar.gz’
                                                    
edd@rob:/tmp/RcppGSLExample$ R CMD check RcppGSLExample_0.0.3.tar.gz 
* using log directory ‘/tmp/RcppGSLExample/RcppGSLExample.Rcheck’
* using R version 4.0.1 (2020-06-06)
* using platform: x86_64-pc-linux-gnu (64-bit)
* using session charset: UTF-8                                                                           
* checking for file ‘RcppGSLExample/DESCRIPTION’ ... OK
* this is package ‘RcppGSLExample’ version ‘0.0.3’                                                       
* checking package namespace information ... OK
* checking package dependencies ... OK         
* checking if this is a source package ... OK    
* checking if there is a namespace ... OK                                                                
* checking for executable files ... OK          
* checking for hidden files and directories ... OK
* checking for portable file names ... OK
* checking for sufficient/correct file permissions ... OK
* checking whether package ‘RcppGSLExample’ can be installed ... OK
* checking installed package size ... OK
* checking package directory ... OK
* checking DESCRIPTION meta-information ... OK
* checking top-level files ... OK
* checking for left-over files ... OK                                                                    
* checking index information ... OK
* checking package subdirectories ... OK
* checking R files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking R files for non-ASCII characters ... OK
* checking R files for syntax errors ... OK
* checking whether the package can be loaded ... OK
* checking whether the package can be loaded with stated dependencies ... OK
* checking whether the package can be unloaded cleanly ... OK
* checking whether the namespace can be loaded with stated dependencies ... OK
* checking whether the namespace can be unloaded cleanly ... OK
* checking loading without being on the library search path ... OK
* checking dependencies in R code ... OK
* checking S3 generic/method consistency ... OK
* checking replacement functions ... OK
* checking foreign function calls ... OK
* checking R code for possible problems ... OK
* checking Rd files ... OK
* checking Rd metadata ... OK
* checking Rd cross-references ... OK
* checking for missing documentation entries ... OK
* checking for code/documentation mismatches ... WARNING
Codoc mismatches from documentation object &apos;colNorm&apos;:
colNorm
  Code: function(G)
  Docs: function(M)
  Argument names in code not in docs:
    G
  Argument names in docs not in code:
    M
  Mismatches in argument names:
    Position: 1 Code: G Docs: M

* checking Rd \usage sections ... OK
* checking Rd contents ... OK
* checking for unstated dependencies in examples ... OK
* checking line endings in shell scripts ... OK
* checking line endings in C/C++/Fortran sources/headers ... OK
* checking line endings in Makefiles ... OK
* checking compilation flags in Makevars ... OK
* checking for GNU extensions in Makefiles ... OK
* checking for portable use of $(BLAS_LIBS) and $(LAPACK_LIBS) ... OK
* checking use of PKG_*FLAGS in Makefiles ... OK
* checking compilation flags used ... OK
* checking compiled code ... OK
* checking examples ... OK
* checking PDF version of manual ... OK
* DONE

Status: 1 WARNING
See
  ‘/tmp/RcppGSLExample/RcppGSLExample.Rcheck/00check.log’
for details.

edd@rob:/tmp/RcppGSLExample$ 

(The one WARNING is something I'll fix in the sources.) This should give you a working example.

If your package does not build then compare its files with the ones of the working example. This in DESCRIPTION, NAMESPACE, src/Makevars and more.

Because the example package is small, this should be quick. But it is hard for to remotely guess which (possibly small but important) step you may have missed.

Last but not least, you also of course need the GSL itself installed as both the run-time and development package. For me on Ubuntu 20.04 that is

edd@rob:/tmp/RcppGSLExample$ dpkg -l| grep libgsl | cut -c-80
ii  libgsl-dev                                 2.5+dfsg-6build1                 
ii  libgsl23:amd64                             2.5+dfsg-6build1                 
ii  libgslcblas0:amd64                         2.5+dfsg-6build1                 
edd@rob:/tmp/RcppGSLExample$