我经常从源代码安装 R 包,并且需要一个正确配置的~/.R/Makevars
来执行此操作。我希望能够使用 OpenMP,所以我复制了我在网上找到的Makevars
。我Makevars
最终是这样的:
OPT_LOC = $(HOME)/homebrew/opt
LLVM_LOC = $(OPT_LOC)/llvm
CC=$(LLVM_LOC)/bin/clang
CXX=$(LLVM_LOC)/bin/clang++
# CFLAGS and CXXFLAGS *with* -fopenmp
CFLAGS=-fopenmp -g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe
CXXFLAGS=-fopenmp -g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe
# CFLAGS and CXXFLAGS *without* -fopenmp
# (sometimes the package install process fails if -fopenmp is present)
# CFLAGS=-g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe
# CXXFLAGS=-g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe
LDFLAGS=-L$(OPT_LOC)/gettext/lib -L$(LLVM_LOC)/lib -Wl,-rpath,$(LLVM_LOC)/lib
CPPFLAGS=-I$(OPT_LOC)/gettext/include -I$(LLVM_LOC)/include
我再也找不到我的版本的原始来源,但它与此版本相似。
我的Makevars
工作得很好,除了一些软件包,比如stringi。这些软件包抱怨"C 编译器无法创建可执行文件"。我发现如果我从CFLAGS
中删除-fopenmp
并CXXFLAGS
,此错误通常会消失。如您所见,我已经设置了Makevars
,因此我可以轻松地在有-fopenmp
和没有它的配置之间来回切换。
我的解决方法工作正常,上面链接的堆栈溢出帖子中的"完全删除Makevars
"的解决方法也是如此。但是没有更好的方法吗?令人讨厌的是,由于这些讨厌-fopenmp
标志的依赖项,我不能期望软件包安装成功,而删除该标志意味着我可能会错过某些软件包安装的 OpenMP。
如果您使用GCC而不是Clang,您应该能够在启用OpenMP的情况下安装stringi。我已经测试了许多不同的解决方案,并最终提出了以下步骤,以使用-fopenmp
标志(英特尔macOS v11(Big Sur))从源代码成功安装stringi:
重新安装 Xcode 命令行工具(如果软件更新说"最新",请不要相信 - 它撒谎 -
brew doctor
说我的版本实际上是旧的)sudo rm -rf /Library/Developer/CommandLineTools sudo xcode-select --install
通过Homebrew安装GCC和LLVM(安装Homebrew的说明),或者,如果您已经安装了GCC/LLVM,请跳到下一步。
# WARNING: This can take several hours brew install gcc brew install llvm
如果您已经通过自制软件安装了GCC和LLVM:
brew cleanup brew update brew upgrade brew reinstall gcc brew reinstall llvm
将一些标头链接到/usr/local/include
sudo ln -s /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/* /usr/local/include/ # I believe you can safely ignore warnings like this: #ln: /usr/local/include//tcl.h: File exists #ln: /usr/local/include//tclDecls.h: File exists #ln: /usr/local/include//tclPlatDecls.h: File exists #ln: /usr/local/include//tclTomMath.h: File exists #ln: /usr/local/include//tclTomMathDecls.h: File exists #ln: /usr/local/include//tk.h: File exists #ln: /usr/local/include//tkDecls.h: File exists #ln: /usr/local/include//tkPlatDecls.h: File exists
编辑
~/.R/Makevars
文件(如果~/.R/
目录中没有名为Makevars
的文件,请创建该文件)并仅包含以下行:LOC = /usr/local/gfortran CC=$(LOC)/bin/gcc -fopenmp CXX=$(LOC)/bin/g++ -fopenmp CXX11 = $(LOC)/bin/g++ -fopenmp CFLAGS=-g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe CXXFLAGS=-g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe LDFLAGS=-L$(LOC)/lib -Wl,-rpath,$(LOC)/lib CPPFLAGS=-I$(LOC)/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include FLIBS=-L/usr/local/gfortran/lib/gcc/x86_64-apple-darwin19/10.2.0 -L/usr/local/gfortran/lib -lgfortran -lquadmath -lm CXX1X=/usr/local/gfortran/bin/g++ CXX98=/usr/local/gfortran/bin/g++ CXX11=/usr/local/gfortran/bin/g++ CXX14=/usr/local/gfortran/bin/g++ CXX17=/usr/local/gfortran/bin/g++
在 R/RStudio 中从源代码编译包
# Test if OpenMP is actually enabled install.packages("data.table", type = "source") # (loading data.table will tell you if it was successful) # Compile the stringi package from source install.packages("stringi", type = "source")
注意:一些用户评论说,他们必须安装一个"全新"的GFortran(例如,用于Big Sur(macOS 11),用于英特尔处理器的GFortran 10.2)才能成功编译软件包,而另一些用户则评论说他们不需要LLVM,但这些步骤似乎在大多数情况下都有效。
更新 (2022/04/05)
我最近在使用此~/更新"RcppAlgos"时遇到了错误。R/Makevars(找不到gmp.h或libgmp)。我检查了gmp是否已安装(brew install gmp
),然后将/usr/local/include添加到CPPFLAGS和/usr/local/lib添加到~/中的LDFLAGS。R/Makevars 文件来解决问题,并希望将来能防止出现类似的问题,即编辑您的 Makevar 以仅包含以下行:
LOC=/usr/local/gfortran
CC=$(LOC)/bin/gcc -fopenmp
CXX=$(LOC)/bin/g++ -fopenmp
CXX11 = $(LOC)/bin/g++ -fopenmp
CFLAGS=-g -O3 -Wall -pedantic -std=gnu99 -mtune=native -pipe
CXXFLAGS=-g -O3 -Wall -pedantic -std=c++11 -mtune=native -pipe
LDFLAGS=-L$(LOC)/lib -Wl,-rpath,$(LOC)/lib,-L/usr/local/lib
CPPFLAGS=-I$(LOC)/include -I/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include -I/usr/local/include
FLIBS=-L/usr/local/gfortran/lib/gcc/x86_64-apple-darwin19/10.2.0 -L/usr/local/gfortran/lib -lgfortran -lquadmath -lm
CXX1X=/usr/local/gfortran/bin/g++
CXX98=/usr/local/gfortran/bin/g++
CXX11=/usr/local/gfortran/bin/g++
CXX14=/usr/local/gfortran/bin/g++
CXX17=/usr/local/gfortran/bin/g++