使用源代码编译R包的过程
R包的安装方式可以归纳为 源代码安装
和 二进制文件安装
两类: 源代码安装
是指从包的源代码进行编译安装。包括:① 通过CRAN安装源代码版本的包(如果没有二进制版本,或者指定了安装源代码)。② 从GitHub、Bioconductor等平台获取源码并安装。③ 本地源码包的安装。 二进制文件安装
是指直接安装编译好的包,无需编译。这种方式通常更快,特别是在Windows和macOS上。包括:① 通过CRAN直接下载并安装预编译的二进制包。② 安装本地的二进制包文件。
安装过程中任意一个环节出错都会安装失败,具体失败原因查看报错内容!!!因此掌握R包安装过程并学会查看报错内容是自己解决环境问题的不二法门。
R 包编译流程
R 编译包的过程涉及多个步骤,包括配置、编译源代码、链接库以及安装包。R 包可以包含纯 R 代码、C/C++、Fortran 等多种语言的代码,编译过程视具体情况而定。以下是 R 编译包的具体流程和各个步骤的详细解释:
1. 准备工作
- 包源代码通常打包成
.tar.gz
格式,包含DESCRIPTION
文件、R 脚本文件(通常位于R/
目录)、文档(man/
)、示例代码(tests/
、examples/
)、源代码(src/
目录)以及其他辅助文件。 - R 包的源代码可以通过
R CMD build
生成。
2. R 包安装流程
安装一个 R 包的常见命令是:
R CMD INSTALL <package_name>.tar.gz
R 在安装包时会按照以下步骤进行
3. 解压包并检查 DESCRIPTION 文件
- 解压缩: R 首先解压
.tar.gz
文件,检查DESCRIPTION
文件中的元数据,例如包名、版本、依赖关系等。 - 依赖检查: 如果包有依赖项,R 会检查是否满足依赖条件,未满足时会尝试安装所需依赖包。
4. 配置(Configure Phase)
- R 包可能包含一个
configure
脚本(类似于 GNU 编译工具链),它会在编译前执行,用于检查目标系统上是否有合适的工具链和库(例如gcc
,g++
,make
,以及其他外部依赖),比如使用pkg-config
工具去查找库路径、PKG_CFLAG
或PKG_LIBS
等。 - 如果
configure
脚本找到需要的库或编译工具,它会生成Makevars
文件,包含库路径、编译选项和标志。 - 这个阶段允许用户自定义编译选项,例如通过设置
PKG_LIBS
、PKG_CPPFLAGS
等环境变量来指定头文件和库的路径。 - 以下为安装
rjava
包时计算机未安装java
导致的配置报错
ERROR: configuration failed for package ‘rJava’
removing ‘/root/anaconda3/envs/myview/lib/R/library/rJava’
5. 编译(Compilation Phase)
- 纯 R 代码: 如果包中只有 R 代码,R 不需要编译,只需检查并解析代码即可。
- C/C++/Fortran 代码:
- R 会根据
src/
目录下的文件,调用系统的编译器(如gcc
,g++
,gfortran
)来编译源代码。R 使用Makevars
文件或包中的Makefile
来控制编译过程。 - 头文件路径和编译标志通过
PKG_CPPFLAGS
或PKG_CFLAGS
来指定,例如:PKG_CPPFLAGS = -I/usr/local/include
- 链接阶段使用
PKG_LIBS
指定库路径和库名,例如:PKG_LIBS = -L/usr/local/lib -lmylib
- 编译器将
.c
或.cpp
文件编译为目标文件(.o
文件)。
- R 会根据
6. 链接(Linking Phase)
- 在编译完成后,R 会调用链接器将生成的目标文件(
.o
文件)与外部库进行链接,生成共享对象文件(.so
)。 - 这些
.so
文件是可以被 R 动态加载的,允许 R 通过.Call()
或.C()
等函数与本地代码进行交互。
7. 安装(Installation Phase)
- 一旦编译和链接完成,R 会将编译生成的二进制文件、R 脚本文件、文档等按照目录结构安装到用户的 R 库路径中。安装路径通常在
.libPaths()
所列的目录中。 - 如果包有动态链接的共享库(如
.so
文件),R 会在加载包时通过系统的动态链接器找到并加载这些库。
8. 后续步骤
- 字节码编译(可选): R 会将 R 脚本字节码编译为
.rds
文件以加快加载速度。 - 文档生成: R 还会自动处理包中的文档文件(
man/
),使用roxygen2
或Rd
格式生成帮助文档。 - Vignettes 编译: 如果包包含 vignettes,R 会调用 Sweave 或 knitr 编译 vignettes 为可读的 PDF 或 HTML 文件。
9. 清理(Optional Clean Up)
- R 安装包后,临时文件(如中间生成的
.o
文件和未使用的临时文件)会被删除,除非在安装时使用--no-clean-on-error
选项保留这些文件以便调试。
10. 加载包
- 完成安装后,用户可以通过
library()
或require()
加载包,R 会通过动态链接器加载所需的动态库,并运行包中的初始化代码(如果有)。
举例:一个包含 C 代码的 R 包编译过程
假设一个包包含 src/
目录下的 C 代码文件 mylib.c
:
- 解压
.tar.gz
并读取DESCRIPTION
文件。 - 执行
configure
,根据需要生成Makevars
文件,指定编译和链接选项。 - 调用
gcc
编译mylib.c
为mylib.o
:gcc -I/path/to/R/include -I/usr/local/include -c mylib.c -o mylib.o
- 链接
mylib.o
生成共享对象文件:gcc -shared -o mylib.so mylib.o -L/usr/local/lib -lmylib
- 将生成的 mylib.so 以及其他文件安装到 R 包库路径中
完成编译和链接后,R 会将 mylib.so 文件和其他必要的文件(如 R 脚本、文档等)安装到 R 包的库路径中,这个路径通常是 .libPaths() 所列的目录。 - 用户通过 library(mypackage) 加载包完成安装后,用户可以通过以下命令加载包:
library(mypackage)
总结
- R 包编译过程 包含配置、编译源代码、链接库、安装等多个步骤。每个步骤都依赖于包的内容(是否有 C/C++ 代码、外部库依赖等)。
- 编译时的控制:通过
PKG_CPPFLAGS
指定头文件路径,通过PKG_LIBS
指定库文件路径和库名。动态链接器不会在编译时使用LD_LIBRARY_PATH
,它仅用于运行时查找共享库。
原文地址:https://blog.csdn.net/weixin_55102248/article/details/142343437
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!