I have an Rcpp function where I would like to call boost::posix_time::time_from_string()
.
I've taken the example code from the boost documentation and translated it to a c++ function using Rcpp
library(Rcpp)
cppFunction(
includes = '
#include <boost/date_time/posix_time/posix_time.hpp>
',
code = '
void time_test() {
std::string t = "2002-01-20 23:59:59.000";
boost::posix_time::ptime pt(boost::posix_time::time_from_string(t));
Rcpp::Rcout << "time from string: " << pt << std::endl;
}
',
depends = "BH"
)
However, this doesn't compile.
I've seen a few comments saying you need to link to -lboost_date_time
, such as this line in Dirk's RcppBDT
library
// The next function uses the non-stream-based parsing in Boost Date_Time
// and requires _linking_ with -lboost_date_time which makes the (otherwise
// header-only) build more complicate
// // [ [ Rcpp::export ] ]
// Rcpp::DatetimeVector charToPOSIXctNS(Rcpp::CharacterVector sv) {
// ... code omitted ...
// }
How do you provide the appropriate links to lboost_date_time
, other than including the posix_time.hpp
header, so that one can use time_from_string()
?
It's possible to use other functions from the boost/date_time
library, as demonstrated by this function, so what makes time_from_string()
different?
cppFunction(
includes = '
#include <boost/date_time/posix_time/posix_time.hpp>
',
code = '
void time_test() {
Rcpp::Datetime dt("2002-01-20 23:59:59.000");
boost::posix_time::hours h( dt.getHours() );
boost::posix_time::minutes m( dt.getMinutes() );
boost::posix_time::seconds s( dt.getSeconds() );
Rcpp::Rcout << h << std::endl;
Rcpp::Rcout << m << std::endl;
Rcpp::Rcout << s << std::endl;
}
',
depends = "BH"
)
time_test()
# 12:00:00
# 00:59:00
# 00:00:59
As you already found out, you need to link with boost at the system level. The BH package is not sufficient. So first you have to install the required boost library. On Debian (dervied) Linux systems this can be done via
sudo apt-get install libboost-date-time-dev
Then you need to tell R to add -I/path/to/boost/headers
and -L/path/to/boost/libraries -lboost_date_time
to the compiler flags. You can do this by setting appropriate environment variables:
library(Rcpp)
Sys.setenv(PKG_LIBS="-L/usr/lib -lboost_date_time", PKG_CPPFLAGS="-I/usr/include")
cppFunction(
includes = '
#include <boost/date_time/posix_time/posix_time.hpp>
',
code = '
void time_test() {
std::string t = "2002-01-20 23:59:59.000";
boost::posix_time::ptime pt(boost::posix_time::time_from_string(t));
Rcpp::Rcout << "time from string: " << pt << std::endl;
}
'
)
Notes:
-I...
and -L...
are unnecessary, since the library is installed in a standard location. One does need these flags in other cases, though.