我正在Mac OSX上开发一个R包,其中包含一些低级C/C++
代码和openMP
支持。 C++
代码是使用Rcpp
包编写的。我的全球' Makevars''文件放在~/.R/
文件夹下。该文件如下所示。
CC=clang-omp
CXX=clang-omp++
PKG_CFLAGS=Wall -pedantic
PKG_CFLAGS= -fopenmp
PKG_CXXFLAGS= -fopenmp
PKG_LIBS= -fopenmp -lgomp
在这种配置下,一切都很棒!
但是,现在我想为自己的编译构建特定于包的Makevars
文件,以使包可移植。我尝试的只是将全局Makevars
文件移动到我的R pakcage src
文件夹中。但是,编译器抱怨它无法找到openMP头文件omp.h
:
** 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.2/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/bigmemory/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/BH/include" -fopenmp -fPIC -Wall -mtune=core2 -g -O2 -c RcppExports.cpp -o RcppExports.o
RcppExports.cpp:12:10: fatal error: 'omp.h' file not found
#include <omp.h>
^
1 error generated.
make: *** [RcppExports.o] Error 1
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.2/Resources/library/Rcpp/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/bigmemory/include" -I"/Library/Frameworks/R.framework/Versions/3.2/Resources/library/BH/include" -fopenmp -fPIC -Wall -mtune=core2 -g -O2 -c RcppExports.cpp -o RcppExports.o
RcppExports.cpp:12:10: fatal error: 'omp.h' file not found
#include <omp.h>
^
1 error generated.
make: *** [RcppExports.o] Error 1
正如您所看到的,编译器变为clang
和clang++
,而不是Makevars
文件中指定的内容:CC=clang-omp
和CXX=clang-omp++
。
问题1:那么如何解决此问题并在R包中构建Makevars
文件?
另一件事是,我从Writing R extensions注意到,
For example, a package with C code written for OpenMP should have in src/Makevars the lines
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CFLAGS)
问题2:例如,宏$(SHLIB_OPENMP_CFLAGS)
和标记-fopenmp
之间有什么区别?我应该在哪种环境下使用?我试图用宏替换标志,但仍无法解决问题。
答案 0 :(得分:4)
关于问题,我最喜欢的方法是从工作包复制。这是例如(推荐/核心)包mgcv:
的部分PKG_LIBS = $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS) $(SHLIB_OPENMP_CFLAGS)
PKG_CFLAGS = $(SHLIB_OPENMP_CFLAGS)
我自己和Andreas在较小的winsorize包(在GitHub上)使用相同的代码段。
关于问题2:第一种形式更通用,并允许其他OpenMP实现。它使用R在配置时发现可用的东西。
答案 1 :(得分:0)
听起来你需要像Dirk描述的Makevars包;对于您的本地环境,让〜/ .R / Makevars使用CC和CXX将C和C ++编译器设置为支持OpenMP的版本。
你的软件包(如果用于CRAN,实际上任何没有与安装OpenMP版本的clang作斗争的Mac R用户)都需要在没有OpenMP的情况下工作,所以你的代码和编译器标志可能不应该没有。假设它存在。