在搭配具有 Apple M1 芯片的 MacBook 上为 R 安装 gfortran

16

我使用的是搭载苹果M1芯片和macOS 11.6 Big Sur操作系统的MacBook Air。我的R版本是4.1.1。我已经安装了Xtools以及针对Apple M1的gfortran

markwhite@marks-air ~ % which xcode-select
/usr/bin/xcode-select
markwhite@marks-air ~ % which gfortran
/usr/local/bin/gfortran

我成功安装并运行了R,但是安装某些软件包时出现了问题:

> install.packages("mvtnorm")

  There is a binary version available but the source version is later:
        binary source needs_compilation
mvtnorm  1.1-2  1.1-3              TRUE

Do you want to install from sources the package which needs compilation? (Yes/no/cancel) Yes
installing the source package ‘mvtnorm’

trying URL 'https://cran.rstudio.com/src/contrib/mvtnorm_1.1-3.tar.gz'
Content type 'application/x-gzip' length 166421 bytes (162 KB)
==================================================
downloaded 162 KB

* installing *source* package ‘mvtnorm’ ...
** package ‘mvtnorm’ successfully unpacked and MD5 sums checked
** using staged installation
** libs
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c C_FORTRAN_interface.c -o C_FORTRAN_interface.o
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c miwa.c -o miwa.o
/opt/R/arm64/bin/gfortran -mtune=native -fno-optimize-sibling-calls  -fPIC  -Wall -g -O2  -c mvt.f -o mvt.o
make: /opt/R/arm64/bin/gfortran: No such file or directory
make: *** [mvt.o] Error 1
ERROR: compilation failed for package ‘mvtnorm’
* removing ‘/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/mvtnorm’
Warning in install.packages :
  installation of package ‘mvtnorm’ had non-zero exit status

The downloaded source packages are in
    ‘/private/var/folders/fx/f46lfqf56_df59fvzgqhcbyr0000gn/T/RtmpfGZUAF/downloaded_packages’
> 

我相信关键的一行是:make: /opt/R/arm64/bin/gfortran: No such file or directory,它在错误的位置寻找gfortran。
确认它不存在:
markwhite@marks-air ~ % cd /opt/R/arm64/
markwhite@marks-air arm64 % ls -la
total 0
drwxrwxr-x   8 root  wheel  256 Oct 18 11:04 .
drwxrwxr-x   3 root  wheel   96 May 13 20:40 ..
drwxrwxr-x  14 root  wheel  448 Oct 19 21:34 bin
drwxrwxr-x  29 root  wheel  928 May 13 20:47 include
drwxrwxr-x  20 root  wheel  640 May 14 18:50 lib
drwxrwxr-x   5 root  wheel  160 May 13 20:40 man
drwxr-xr-x   3 root  wheel   96 May 14 18:28 pkg
drwxrwxr-x   5 root  wheel  160 Oct 18 11:04 share
markwhite@marks-air arm64 % 

所以,我只需要将gfortran从它原来的位置移动到R想要的位置:
markwhite@marks-air gfortran % sudo mv /usr/local/bin/gfortran /opt/R/arm64/bin
Password:
markwhite@marks-air gfortran % 

然后,我重新启动了 R 并尝试再次操作:

> install.packages("mvtnorm")

  There is a binary version available but the source version is later:
        binary source needs_compilation
mvtnorm  1.1-2  1.1-3              TRUE

Do you want to install from sources the package which needs compilation? (Yes/no/cancel) Yes
installing the source package ‘mvtnorm’

trying URL 'https://cran.rstudio.com/src/contrib/mvtnorm_1.1-3.tar.gz'
Content type 'application/x-gzip' length 166421 bytes (162 KB)
==================================================
downloaded 162 KB

* installing *source* package ‘mvtnorm’ ...
** package ‘mvtnorm’ successfully unpacked and MD5 sums checked
** using staged installation
** libs
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c C_FORTRAN_interface.c -o C_FORTRAN_interface.o
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c miwa.c -o miwa.o
/opt/R/arm64/bin/gfortran -mtune=native -fno-optimize-sibling-calls  -fPIC  -Wall -g -O2  -c mvt.f -o mvt.o
mvt.f:861:11:

  861 |       hs = sign( one, dh - r*dk )
      |           1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:862:11:

  862 |       ks = sign( one, dk - r*dh )
      |           1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:1155:16:

 1155 |             K = MOD( C(NP, MIN(NDIM-1,KLIM-1))*DBLE(K), DBLE(P(NP)) )
      |                1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:1215:17:

 1215 |             JP = 1 + J*R(J)
      |                 1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:94:39:

   94 |       DOUBLE PRECISION COV(NL*(NL+1)/2), A(NL), B(NL), DL(NL), Y(NL)
      |                                       1
Warning: Array ‘cov’ at (1) is larger than limit set by ‘-fmax-stack-var-size=’, moved from stack to static storage. This makes the procedure unsafe when called recursively, or concurrently from multiple threads. Consider using ‘-frecursive’, or increase the ‘-fmax-stack-var-size=’ limit, or change the code to use an ALLOCATABLE array. [-Wsurprising]
mvt.f:86:33:

   86 |       SUBROUTINE MVSUBR( N, W, NF, F )
      |                                 1
Warning: Unused dummy argument ‘nf’ at (1) [-Wunused-dummy-argument]
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c mvtnorm-init.c -o mvtnorm-init.o
/opt/R/arm64/bin/gfortran -mtune=native -fno-optimize-sibling-calls  -fPIC  -Wall -g -O2  -c tvpack.f -o tvpack.o
tvpack.f:395:14:

  395 |          HS = SIGN( ONE, DH - R*DK )
      |              1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
tvpack.f:396:14:

  396 |          KS = SIGN( ONE, DK - R*DH )
      |              1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
tvpack.f:60:52:

   60 |       DOUBLE PRECISION ONE, ZRO, EPS, ZROS(3), HS(3), TVT, TVTL
      |                                                    1
Warning: Unused variable ‘hs’ declared at (1) [-Wunused-variable]
tvpack.f:60:45:

   60 |       DOUBLE PRECISION ONE, ZRO, EPS, ZROS(3), HS(3), TVT, TVTL
      |                                             1
Warning: Unused variable ‘zros’ declared at (1) [-Wunused-variable]
tvpack.f:220:72:

  220 |       END
      |                                                                        ^
Warning: ‘fin’ may be used uninitialized in this function [-Wmaybe-uninitialized]
tvpack.f:196:58:

  196 |       DOUBLE PRECISION EI(NL), AI(NL), BI(NL), FI(NL), FIN, ERR, KRNRDT
      |                                                          ^
note: ‘fin’ was declared here
clang -arch arm64 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/opt/R/arm64/lib -o mvtnorm.so C_FORTRAN_interface.o miwa.o mvt.o mvtnorm-init.o tvpack.o -L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0 -L/opt/R/arm64/gfortran/lib -lgfortran -lemutls_w -lm -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
ld: warning: directory not found for option '-L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0'
ld: warning: directory not found for option '-L/opt/R/arm64/gfortran/lib'
ld: library not found for -lgfortran
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [mvtnorm.so] Error 1
ERROR: compilation failed for package ‘mvtnorm’
* removing ‘/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/mvtnorm’
Warning in install.packages :
  installation of package ‘mvtnorm’ had non-zero exit status

The downloaded source packages are in
    ‘/private/var/folders/fx/f46lfqf56_df59fvzgqhcbyr0000gn/T/RtmpmlhiE8/downloaded_packages’
> 

看起来它仍然对目录路径感到困惑,或者mv没有实际移动需要移动的内容。

我该如何将R指向正确的目录或在正确的目录中安装gfortran?

我知道这个问题现在很混乱,我已经查看了其他线程,但似乎无法让任何人建议的内容正常工作。


1
对于其他人来说,我已经撰写了适用于Big Sur和Monterey的说明在这里。Monterey的细节并没有根本上的不同,但是有一些复杂性。 - Mikael Jagan
1
我认为你使用Homebrew安装了gfortran,但没有承认你的错误。 - IRTFM
7个回答

20
以下是我在Mac OS M1系统上使用的方法,可以安装R 4.2.1和gfortran。此方案修改自这里的方案,可能适用于Intel Macs。
  1. 使用brew install gcc安装包含gfortran的gcc。

  2. 如果尚不存在,请创建文件~/.R/Makevars。例如这里提供了相应的示例。

  3. 将以下行添加到~/.R/Makevars中:

FC = /opt/homebrew/Cellar/gcc/11.3.0_2/bin/gfortran
F77 = /opt/homebrew/Cellar/gcc/11.3.0_2/bin/gfortran
FLIBS = -L/opt/homebrew/Cellar/gcc/11.3.0_2/lib/gcc/11

请注意,你可能需要将gcc版本11.3.0_2更改为你使用的版本。


1
FLIBS = -L/opt/homebrew/Cellar/gcc/VERSION/lib 这行代码为我解决了编译警告。 - optimus_prime
可以确认它起作用了,谢谢! - undefined
我确认这解决了问题。确保路径正确(通过调整版本号)。 - undefined
谢谢!解决了我安装mvtnorm的问题。 - undefined

8

我删除了与gfortran相关的所有内容并重新开始。

我使用浏览器下载了.tar.xz文件这里,然后将文件转储到我的下载文件夹中。我双击它来解压缩。

我将该目录移动到R想要的位置:

markwhite@marks-air ~ % sudo mv Downloads/gfortran /opt/R/arm64/

然后我重新启动R并尝试再次安装,在此过程中它向我发送了一些Fortran编译消息,但我不会在这里假装理解。不过最终它成功地安装好了。

> install.packages("mvtnorm")

  There is a binary version available but the source version is later:
        binary source needs_compilation
mvtnorm  1.1-2  1.1-3              TRUE

Do you want to install from sources the package which needs compilation? (Yes/no/cancel) Yes
installing the source package ‘mvtnorm’

trying URL 'https://cran.rstudio.com/src/contrib/mvtnorm_1.1-3.tar.gz'
Content type 'application/x-gzip' length 166421 bytes (162 KB)
==================================================
downloaded 162 KB

* installing *source* package ‘mvtnorm’ ...
** package ‘mvtnorm’ successfully unpacked and MD5 sums checked
** using staged installation
** libs
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c C_FORTRAN_interface.c -o C_FORTRAN_interface.o
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c miwa.c -o miwa.o
/opt/R/arm64/bin/gfortran -mtune=native -fno-optimize-sibling-calls  -fPIC  -Wall -g -O2  -c mvt.f -o mvt.o
mvt.f:861:11:

  861 |       hs = sign( one, dh - r*dk )
      |           1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:862:11:

  862 |       ks = sign( one, dk - r*dh )
      |           1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:1155:16:

 1155 |             K = MOD( C(NP, MIN(NDIM-1,KLIM-1))*DBLE(K), DBLE(P(NP)) )
      |                1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:1215:17:

 1215 |             JP = 1 + J*R(J)
      |                 1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
mvt.f:94:39:

   94 |       DOUBLE PRECISION COV(NL*(NL+1)/2), A(NL), B(NL), DL(NL), Y(NL)
      |                                       1
Warning: Array ‘cov’ at (1) is larger than limit set by ‘-fmax-stack-var-size=’, moved from stack to static storage. This makes the procedure unsafe when called recursively, or concurrently from multiple threads. Consider using ‘-frecursive’, or increase the ‘-fmax-stack-var-size=’ limit, or change the code to use an ALLOCATABLE array. [-Wsurprising]
mvt.f:86:33:

   86 |       SUBROUTINE MVSUBR( N, W, NF, F )
      |                                 1
Warning: Unused dummy argument ‘nf’ at (1) [-Wunused-dummy-argument]
clang -arch arm64 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c mvtnorm-init.c -o mvtnorm-init.o
/opt/R/arm64/bin/gfortran -mtune=native -fno-optimize-sibling-calls  -fPIC  -Wall -g -O2  -c tvpack.f -o tvpack.o
tvpack.f:395:14:

  395 |          HS = SIGN( ONE, DH - R*DK )
      |              1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
tvpack.f:396:14:

  396 |          KS = SIGN( ONE, DK - R*DH )
      |              1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1) [-Wconversion]
tvpack.f:60:52:

   60 |       DOUBLE PRECISION ONE, ZRO, EPS, ZROS(3), HS(3), TVT, TVTL
      |                                                    1
Warning: Unused variable ‘hs’ declared at (1) [-Wunused-variable]
tvpack.f:60:45:

   60 |       DOUBLE PRECISION ONE, ZRO, EPS, ZROS(3), HS(3), TVT, TVTL
      |                                             1
Warning: Unused variable ‘zros’ declared at (1) [-Wunused-variable]
tvpack.f:220:72:

  220 |       END
      |                                                                        ^
Warning: ‘fin’ may be used uninitialized in this function [-Wmaybe-uninitialized]
tvpack.f:196:58:

  196 |       DOUBLE PRECISION EI(NL), AI(NL), BI(NL), FI(NL), FIN, ERR, KRNRDT
      |                                                          ^
note: ‘fin’ was declared here
clang -arch arm64 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/opt/R/arm64/lib -o mvtnorm.so C_FORTRAN_interface.o miwa.o mvt.o mvtnorm-init.o tvpack.o -L/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0 -L/opt/R/arm64/gfortran/lib -lgfortran -lemutls_w -lm -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
ld: warning: could not create compact unwind for _mvkrsv_: register 75 saved somewhere other than in frame
ld: warning: could not create compact unwind for _mvkbrv_: stack size is too large for frameless function
ld: warning: could not create compact unwind for _mvstdt_: register 75 saved somewhere other than in frame
ld: warning: could not create compact unwind for _mvbvtl_: registers 78 and 79 not saved contiguously in frame
ld: warning: could not create compact unwind for _pntgnd_: registers 72 and 73 not saved contiguously in frame
ld: warning: could not create compact unwind for _mvbvu_: registers 72 and 73 not saved contiguously in frame
ld: warning: could not create compact unwind for _tvtmfn_: register 73 saved somewhere other than in frame
ld: warning: could not create compact unwind for _krnrdt_: registers 74 and 75 not saved contiguously in frame
ld: warning: could not create compact unwind for _mvbvn_: registers 21 and 22 not saved contiguously in frame
ld: warning: could not create compact unwind for _bvnd_: registers 78 and 79 not saved contiguously in frame
ld: warning: could not create compact unwind for _bvtl_: registers 78 and 79 not saved contiguously in frame
ld: warning: could not create compact unwind for _tvtlrcall_: registers 72 and 73 not saved contiguously in frame
ld: warning: could not create compact unwind for _mvbvt_: registers 21 and 22 not saved contiguously in frame
ld: warning: could not create compact unwind for _mvspcl_: register 73 saved somewhere other than in frame
ld: warning: could not create compact unwind for _mvsort_: register 77 saved somewhere other than in frame
ld: warning: could not create compact unwind for _mvvlsb_: registers 27 and 28 not saved contiguously in frame
ld: warning: could not create compact unwind for _mvtdst_: registers 23 and 24 not saved contiguously in frame
ld: warning: could not create compact unwind for _mvbvtc_: register 73 saved somewhere other than in frame
installing to /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/00LOCK-mvtnorm/00new/mvtnorm/libs
** R
** inst
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded from temporary location
** checking absolute paths in shared objects and dynamic libraries
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (mvtnorm)

The downloaded source packages are in
    ‘/private/var/folders/fx/f46lfqf56_df59fvzgqhcbyr0000gn/T/RtmptXzvKK/downloaded_packages’

这对我有用(谢谢!),但是需要进入 Mac 安全设置(两次)才能批准运行 Fortran。 - julianstanley
这对我不起作用。我已经更改了所有权限和安全批准。我认为这是因为轮子正在搜索gfotran可执行文件而不是文件夹。 - ghosh'.
谢谢,这让我尝试简单地重新安装gccbrew reinstall gcc,解决了我的问题。 - gaspanic

5
我在尝试从源代码安装一个包时遇到了类似的问题。我的解决方案是:
  1. 安装Homebrew版本的gcc(包括gfortran)

    brew install gcc

  2. 告诉R应该在哪里查找gfortran 这些信息存储在文件“Makeconf”中,在我的情况下可以在此处找到: /Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/etc/Makeconf

在“Makeconf”中更改以下行:

FLIBS =  -L/Volumes/Builds/opt/R/arm64/gfortran/lib/gcc/aarch64-apple-darwin20.2.0/11.0.0 -L/Volumes/Builds/opt/R/arm64/gfortran/lib/gcc -L/Volumes/Builds/opt/R/arm64/gfortran/lib -lgfortran -lemutls_w -lm

to

FLIBS =  -L/opt/homebrew/Cellar/gcc/11.3.0/lib/gcc/11/gcc/aarch64-apple-darwin21/11 -L/opt/homebrew/Cellar/gcc/11.3.0/lib/gcc/11 -lgfortran -lquadmath -lm

根据您系统中安装的gcc版本,您可能需要适应路径。

  1. 重新启动R

3

你是否尝试回答“否”来回答以下问题:

Do you want to install from sources the package which needs compilation? (Yes/no/cancel)

除非你真的需要下载最新版本的软件包,否则似乎不必像你那样在指定文件夹中安装gfortran,它仍然可以正常运行。


3

当我安装其他软件包时,我遇到了类似的问题,但是我尝试做出以下选择后,它允许我继续进行:

Update all/some/none? [a/s/n]: 
n

1
使用一个Makevars文件来修复(如R中的错误消息所建议的链接)对我来说没有起作用,但是修改这里的其他答案之一(https://dev59.com/4cLra4cB1Zd3GeqPKXpJ#72200132)起作用了。
背景:我使用的是MacBook Pro 2023 M2 Max,macOS Ventura 13.5.2,R 4.3.1,使用homebrew安装了gfortran和安装了Xcode。
  1. 以防万一,备份您的Makeconf文件,例如Makeconf.bak
  2. 使用您选择的编辑器打开Makeconf文件
  3. 您可能会看到很多内容。在下面,CC++部分之后,您应该找到Fortran部分,它可能看起来像这样:
## Fortran
FC = /opt/gfortran/bin/gfortran -arch arm64
FCFLAGS = -Wall -g -O2 $(LTO_FC)
## additional libs needed when linking with $(FC), e.g. on some Oracle compilers
FCLIBS_XTRA = 
FFLAGS = -Wall -g -O2 $(LTO_FC)
FLIBS =  -L/opt/gfortran/lib/gcc/aarch64-apple-darwin20.0/12.2.0 -L/opt/gfortran/lib -lgfortran -lemutls_w -lquadmath
FPICFLAGS = -fPIC
FPIEFLAGS = -fPIE
F_VISIBILITY = 

你需要在这里更改两行代码,分别是FCFLIBS,如下所示:
对于FC:通过运行which gfortran命令,找出gfortran在终端上的可访问位置。
对于FLIBS:运行brew info gfortran命令,找出已安装的gfortran版本以及需要放在版本前面的位置,以完成正确的路径。
Makeconf中,使用这些信息编辑FCFLIBS的行。
作为对比,这是我在Makeconf中的两行代码的样子:
FC = /opt/homebrew/bin/gfortran -arch arm64
FLIBS =  -L/opt/homebrew/Cellar/gcc/13.2.0/lib/gcc/13 -L/opt/homebrew/lib -lgfortran -lemutls_w -lquadmath

希望这能对这个问题有所启发,帮助那些对于无法解决Makevars问题而感到沮丧的人。

0
我按照这个教程的说明操作,成功了: https://www.cynkra.com/blog/2021-03-16-gfortran-macos/

我创建了一个文件 ~/.R/Makevars

并且按照教程输入以下内容(使用我的自己的gfortran目录):

FC      = /usr/local/bin/gfortran
F77     = /usr/local/bin/gfortran
FLIBS   = -L/usr/local/bin/gfortran/lib

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接