在 R 中安装 stringi 时"C compiler cannot create executables"



我经常从源代码安装 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中删除-fopenmpCXXFLAGS,此错误通常会消失。如您所见,我已经设置了Makevars,因此我可以轻松地在有-fopenmp和没有它的配置之间来回切换。

我的解决方法工作正常,上面链接的堆栈溢出帖子中的"完全删除Makevars"的解决方法也是如此。但是没有更好的方法吗?令人讨厌的是,由于这些讨厌-fopenmp标志的依赖项,我不能期望软件包安装成功,而删除该标志意味着我可能会错过某些软件包安装的 OpenMP。

如果您使用GCC而不是Clang,您应该能够在启用OpenMP的情况下安装stringi。我已经测试了许多不同的解决方案,并最终提出了以下步骤,以使用-fopenmp标志(英特尔macOS v11(Big Sur))从源代码成功安装stringi:

  1. 重新安装 Xcode 命令行工具(如果软件更新说"最新",请不要相信 - 它撒谎 -brew doctor说我的版本实际上是旧的)

    sudo rm -rf /Library/Developer/CommandLineTools
    sudo xcode-select --install
    
  2. 通过Homebrew安装
  3. GCC和LLVM(安装Homebrew的说明),或者,如果您已经安装了GCC/LLVM,请跳到下一步。

    # WARNING: This can take several hours
    brew install gcc
    brew install llvm
    
  4. 如果您已经通过自制软件安装了GCC和LLVM:

    brew cleanup
    brew update
    brew upgrade
    brew reinstall gcc
    brew reinstall llvm
    
  5. 将一些标头链接到/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
    
  6. 编辑~/.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++
    
  7. 在 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++