Search code examples
rboostrcppr-package

Error in including boost tokenizer.hpp file when building R package on MacOS/CRAN


I'm running into issues publishing my R package to CRAN, because of a specific error when including boost libraries. The top of my one .cpp file in the package is

#include <Rcpp.h>
#include <boost/tokenizer.hpp>
#include <boost/algorithm/string.hpp>
#include <algorithm>
#include <string>
#include <unordered_map>
#include <omp.h>
#include <vector>

// [[Rcpp::depends(BH)]]
// [[Rcpp::plugins(openmp)]]

When running through the check on MacOS (via rhub::check(platform = "macos-highsierra-release-cran"), I get the following error:

In file included from wgt_jaccard.cpp:6: /Users/user2suimGYX/R/BH/include/boost/tokenizer.hpp:63:9: error: field of type 'std::_1::wrap_iter<const char *>' has private constructor : first(c.begin()), last(c.end()), f(f) { } ^

wgt_jaccard.cpp:117:19: note: in instantiation of function template specialization 'boost::tokenizer<boost::char_separator<char, std::__1::char_traits >, std::__1::__wrap_iter<const char *>, std::__1::basic_string ::tokenizer<Rcpp::internal::string_proxy<16, PreserveStorage> >' requested here tokenizer tokens(y(i), sep); ^

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/iterator:1420:31: note: declared private here _LIBCPP_INLINE_VISIBILITY __wrap_iter(iterator_type __x) _NOEXCEPT_DEBUG : __i(__x) {} ^

My Makevars file's contents are

PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS) -DBOOST_NO_AUTO_PTR
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS)
CXX_STD = CXX11

I've tried searching around, but can't find much on this error. The full package is located here. Any help is much appreciated.


Solution

  • Relative to the repo you kindly supplied, we found a need for two changes:

    First, to no (unconditionally) have an #include <omp.h> as OpenMP can be optional, esp. on macOS. A simpled #ifdef OPENMP does the job.

    Second, the (arguably near-incomprehensible) compiler message had to do with the fact that the Boost type / class for tokenizer was puzzled by the Rcpp object you gave it by directly indexing from an Rcpp::CharacterVector. Been there, done that -- a more conservative approach is to first assign to std::string and to then pass that on.

    With those two changes, it's all roses and it compiles on macOS under clang++ as well.

    The (by now merged, thanks) PR #2 has the gory details, but is short.