在R包中使用C++ execution头文件,macOS平台CRAN构建是否会失败?
R包使用C++ 头文件的macOS编译问题
问题描述
我正在开发包含C代码的R包,想使用C标准库的<execution>头文件。目前CRAN默认采用C17,理论上应该可行,但Apple Clang还没实现这个头文件,而且macOS上的R包C代码会默认使用Apple工具链编译。我写了一段并行计算集合差的C++代码,请问这段代码会导致macOS平台的CRAN包构建失败吗?
我的C++代码
#include <RcppArmadillo.h> #include <execution> using namespace arma; // [[Rcpp::export]] vec setdiff(const vec& x, const vec& y) { vec xs = sort(x); vec ys = sort(y); std::vector<double> diff; std::set_difference( std::execution::par, xs.begin(), xs.end(), ys.begin(), ys.end(), std::inserter(diff, diff.begin())); return conv_to<vec>::from(diff); } /*** R setdiff(1:10, 3) */
本地编译的临时解决方法
我自己的M1 Mac上,通过在~/.R/Makevars中添加以下内容指定使用g++-13而非Apple Clang,能成功编译:
CXX=/opt/homebrew/bin/g++-13 CXX17=/opt/homebrew/bin/g++-13
回答
这段代码肯定会导致macOS平台的CRAN包构建失败,原因如下:
- CRAN在macOS上的构建环境固定使用Apple官方的Clang工具链,而当前版本的Apple Clang并未实现C++17的
<execution>头文件,编译时会直接抛出"头文件找不到"的错误。 - 你本地修改
Makevars指定g++-13的方式只适用于个人开发环境,CRAN的自动化构建流程不会读取用户自定义的配置,完全按照默认规则使用Apple工具链编译。
可行的解决办法
- 条件编译兼容串行版本
通过编译器特性宏__cpp_lib_execution判断是否支持<execution>,支持就用并行版本,否则回退到普通串行的std::set_difference。修改后的代码如下:#include <RcppArmadillo.h> #ifdef __cpp_lib_execution #include <execution> #endif using namespace arma; // [[Rcpp::export]] vec setdiff(const vec& x, const vec& y) { vec xs = sort(x); vec ys = sort(y); std::vector<double> diff; #ifdef __cpp_lib_execution std::set_difference( std::execution::par, xs.begin(), xs.end(), ys.begin(), ys.end(), std::inserter(diff, diff.begin())); #else std::set_difference( xs.begin(), xs.end(), ys.begin(), ys.end(), std::inserter(diff, diff.begin())); #endif return conv_to<vec>::from(diff); } - 不推荐的方案:指定编译器要求
你可以在包的DESCRIPTION文件中声明需要支持<execution>的编译器,但这会直接导致包在macOS平台无法通过CRAN的审核,不建议这么做。
内容的提问来源于stack exchange,提问作者Øystein S
相关产品推荐
相关产品推荐

