R语言问题集锦

「Not Found」安装 R 包时 'xxx.h

2019-04-16  本文已影响23人  hyacz

Not Found 是极其常见且容易解决的一种错误类型,计算机是很讲道理的,Not Found 就是 Not Found,而所谓 Not Found 解释一下就是——有东西没在它应该在的地方。那么这就衍生出两个问题,一是什么程序在寻找什么东西,二是这个东西应该在什么地方。所有有关于 Not Found 的问题都可以采用这个思路来排查,接下来就以近日遇到的一个安装 R 包时头文件 Not Found 的例子来讲讲这类问题的排查步骤。

1. 报错信息

更新完系统到 10.14.4 后安装 R 包时报错:

In file included from /usr/local/clang6/include/c++/v1/string:477:
In file included from /usr/local/clang6/include/c++/v1/string_view:176:
In file included from /usr/local/clang6/include/c++/v1/__string:56:
In file included from /usr/local/clang6/include/c++/v1/algorithm:641:
In file included from /usr/local/clang6/include/c++/v1/cstring:61:
/usr/local/clang6/include/c++/v1/string.h:61:15: fatal error: 'string.h' file not found
#include_next <string.h>
              ^~~~~~~~~~

2. 排查思路

2.1. 是什么东西 Not Found?

报错中显而易见有一句这样的语句#include_next <string.h>然后string.h Not Found。那么问题到这里结束了吗?没有,我们还有了更多的问题:string.h 是一个头文件,它属于哪一个 Library?是什么版本的?

好在这些问题也很简单,简单上网搜索一下你就能发现,这个文件在 macOS 中是属于 Command Line Tools 的,Command Line Tools 是随着系统版本来的,那么 Command Line Tools 装好了吗?装到什么地方去了?

2.2. Not Found 的这个东西本该在什么地方?

R 包编译时寻找的头文件的位置是由环境变量控制的,就是看 ${R_HOME}/etc/Makeconf, ~/.R/Makevars, <PKG>/src/Makevars 这三个文件中的配置,第一个是全局的配置,第二个是用户的配置,第三个是包本身的配置,影响范围从大到小,优先级从低到高。那么通常来说 CRAN 上下载的包本身的 Makevars 是没有问题,我也没有配置用户的 Makevars,所以就是系统的 Makeconf 出了问题,这个文件在 macOS 中的路径为 /Library/Frameworks/R.framework/Resources/etc/Makeconf(参见 R-admin#macOS - CRAN)。

其实这个文件里面并没有配置 include path,R 要安装包含 C++ 的包必须另外安装 RTools,macOS 的 RTools 其实就是 clang 和 gfortran,可以在 macOS Tools - CRAN 下载到。所以 include path 就是另外安装的这个 clang 的默认值 /usr/include。

稍稍拓展一下,macOS 的 Command Line Tools 里面是有一个 clang 的,而且 Command Line Tools 的 gcc 就只是 clang 的别名。CLT 中的 clang 与 CRAN 提供的 clang 的最大的区别在于只有后者才支持 OpenMP,如果你的机器报不认识 -fopenmp 这个选项,那说明 clang 的版本有问题。

3. 分析与解决方案

3.1. Why Not Found?

那么为什么string.h没在它该在的地方呢?Xcode 10 release notes 中写的十分清楚:

The command line tools will search the SDK for system headers by default. However, some software may fail to build correctly against the SDK and require macOS headers to be installed in the base system under /usr/include. If you are the maintainer of such software, we encourage you to update your project to work with the SDK or file a bug report for issues that are preventing you from doing so. As a workaround, an extra package is provided which will install the headers to the base system. In a future release, this package will no longer be provided. You can find this package at
/Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

所以这是由于 macOS 10.14 配套的 Xcode 10 的 CommandLineTools 不再默认的创建 /usr/include 导致的头文件缺失。

3.2. 解决方案

打开终端,输入以下命令,按照提示继续安装就可以了,确保你装过了 CommandLineTools。

$ open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

PS:这句 open 指令如果报 Not Found 了请按照本文思路自行拓展寻找解决方案。

上一篇 下一篇

猜你喜欢

热点阅读