3

I have written my first R package using Rcpp; the package is a simple utility to read in binary data files written by the application TransCAD. When I build the package in Rstudio, everything runs correctly.

I pushed my work to GitHub, and installed it from a different R session. Everything is as it should be.

devtools::install_github("gregmacfarlane/tcadr")

Downloading github repo gregmacfarlane/tcadr@master
Installing tcadr
'/Library/Frameworks/R.framework/Resources/bin/R' --vanilla CMD INSTALL  \
  '/private/var/folders/wr/zlxhfd3d3591b4b9zgq4c5xr0000gn/T/Rtmpa2Xoyi/devtools3ca351cdd2e/gregmacfarlane-tcadr-65fc460'  \
  --library='/Library/Frameworks/R.framework/Versions/3.1/Resources/library'  \
  --install-tests 

* installing *source* package ‘tcadr’ ...
** libs
clang++ -I/Library/Frameworks/R.framework/Resources/include -DNDEBUG  -I/usr/local/include -I/usr/local/include/freetype2 -I/opt/X11/include -I"/Library/Frameworks/R.framework/Versions/3.1/Resources/library/Rcpp/include"   -fPIC  -Wall -mtune=core2 -g -O2  -c RcppExports.cpp -o RcppExports.o
clang++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o tcadr.so RcppExports.o get_df_from_binary.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
installing to /Library/Frameworks/R.framework/Versions/3.1/Resources/library/tcadr/libs
** R
** data
*** moving datasets to lazyload DB
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
* DONE (tcadr)

But when I try to run my package's primary R function, it cannot find the c++ function I wrote.

library(tcadr)
df <- read_tcad_bin(dir, file)
Error in as.data.frame(get_df_from_binary(bin_file, dcb$name, dcb$type,  : 
  could not find function "get_df_from_binary"

I have checked that the [rcpp export] function was compiled properly by the Rstudio build. Are there other things I ought to check also?

mwe the package data/ folder has an example dataset that you can test on if needed.


Update

I think this should not be a new question, but may rather help to indicate what the problem is.

On three different computers (two OS X 10.10.3, one Windows 7) the following happens:

  • If I install the package with devtools::install_github(), the R function is unable to find the C function.

  • If I clone the repository from github and build it inside RStudio, the library works flawlessly.

As per the comment on compilers below, it seems RStudio on Mac uses gcc, but in the console uses clang. Windows uses g++ in both.

gregmacfarlane
  • 2,121
  • 3
  • 24
  • 53

1 Answers1

3

Here is the set of errors I am getting under Ubuntu 14.10:

/tmp$ cat /tmp/tcadr.Rcheck/00install.out
* installing *source* package ‘tcadr’ ...
** libs
ccache g++ -I/usr/share/R/include -DNDEBUG   -I"/usr/local/lib/R/site-library/Rcpp/include"   -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -c RcppExports.cpp -o RcppExports.o
ccache g++ -I/usr/share/R/include -DNDEBUG   -I"/usr/local/lib/R/site-library/Rcpp/include"   -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -c get_df_from_binary.cpp -o get_df_from_binary.o
get_df_from_binary.cpp: In function ‘Rcpp::List get_df_from_binary(Rcpp::String, Rcpp::CharacterVector, Rcpp::CharacterVector, Rcpp::NumericVector, Rcpp::NumericVector, int)’:
get_df_from_binary.cpp:31:53: error: no matching function for call to ‘std::basic_fstream<char>::open(Rcpp::String&, std::_Ios_Openmode)’
   bf.open(bin_file, ios::in | ios::binary | ios::ate);
                                                     ^
get_df_from_binary.cpp:31:53: note: candidate is:
In file included from get_df_from_binary.cpp:4:0:
/usr/include/c++/4.9/fstream:889:7: note: void std::basic_fstream<_CharT, _Traits>::open(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]
       open(const char* __s,
       ^
/usr/include/c++/4.9/fstream:889:7: note:   no known conversion for argument 1 from ‘Rcpp::String’ to ‘const char*’
/usr/lib/R/etc/Makeconf:142: recipe for target 'get_df_from_binary.o' failed
make: *** [get_df_from_binary.o] Error 1
ccache g++ -I/usr/share/R/include -DNDEBUG   -I"/usr/local/lib/R/site-library/Rcpp/include"   -fpic  -g -O3 -Wall -pipe -Wno-unused -pedantic -c get_df_from_binary.cpp -o get_df_from_binary.o
get_df_from_binary.cpp: In function ‘Rcpp::List get_df_from_binary(Rcpp::String, Rcpp::CharacterVector, Rcpp::CharacterVector, Rcpp::NumericVector, Rcpp::NumericVector, int)’:
get_df_from_binary.cpp:31:53: error: no matching function for call to ‘std::basic_fstream<char>::open(Rcpp::String&, std::_Ios_Openmode)’
   bf.open(bin_file, ios::in | ios::binary | ios::ate);
                                                     ^
get_df_from_binary.cpp:31:53: note: candidate is:
In file included from get_df_from_binary.cpp:4:0:
/usr/include/c++/4.9/fstream:889:7: note: void std::basic_fstream<_CharT, _Traits>::open(const char*, std::ios_base::openmode) [with _CharT = char; _Traits = std::char_traits<char>; std::ios_base::openmode = std::_Ios_Openmode]
       open(const char* __s,
       ^
/usr/include/c++/4.9/fstream:889:7: note:   no known conversion for argument 1 from ‘Rcpp::String’ to ‘const char*’
/usr/lib/R/etc/Makeconf:142: recipe for target 'get_df_from_binary.o' failed
make: *** [get_df_from_binary.o] Error 1
ERROR: compilation failed for package ‘tcadr’
* removing ‘/tmp/tcadr.Rcheck/tcadr’
/tmp$ 

I think you need to fix a few things.

Edit: It appears to at least compile if you do this instead:

diff --git a/src/get_df_from_binary.cpp b/src/get_df_from_binary.cpp
index 13d1b4a..15cd340 100644
--- a/src/get_df_from_binary.cpp
+++ b/src/get_df_from_binary.cpp
@@ -28,7 +28,7 @@ List get_df_from_binary(

   // Open the binary data file and make sure it exists
   std::fstream bf;
-  bf.open(bin_file, ios::in | ios::binary | ios::ate);
+  bf.open(bin_file.get_cstring(), ios::in | ios::binary | ios::ate);
   if(!bf.is_open()){
     throw std::range_error("could not open binary file");
   }
Dirk Eddelbuettel
  • 360,940
  • 56
  • 644
  • 725