我正在编写一个 R 包,其中包含大量复杂的 C++ 代码,编译需要一段时间。
当我更改代码时,我想快速重建包以便测试。然而,R CMD build
每次似乎都是从头开始编译,而不是使用我的代码的 makefiles 执行所需的内容。
有没有一种方法可以快速地在 R 中对一个包进行重复构建以进行测试?
sudo apt-get install ccache
,然后在~/.R/Makevars
中添加以下内容:VER=
CCACHE=ccache
#CCACHE=
CC=$(CCACHE) gcc$(VER)
CXX=$(CCACHE) g++$(VER)
CXX11=$(CCACHE) g++$(VER)
CXX14=$(CCACHE) g++$(VER)
这还允许在g++
版本之间切换。将其更改为clang++
留给读者自己练习;-)
此外,查看R CMD build
和R CMD INSTALL
的选项,以跳过vignette和/或手动构建以进一步加快重新构建速度。
示例:这是对Rcpp本身进行重新安装(从git pull
中获取)的过程,在我(像样的)工作机器上,第一次安装需要21.9秒,然后由于ccache
,第二次只需要1.4秒:
~/git/rcpp(master)$ time R CMD INSTALL .
* installing to library ‘/usr/local/lib/R/site-library’
* installing *source* package ‘Rcpp’ ...
** libs
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c Date.cpp -o Date.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c Module.cpp -o Module.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c Rcpp_init.cpp -o Rcpp_init.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c api.cpp -o api.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c attributes.cpp -o attributes.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c barrier.cpp -o barrier.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o Rcpp.so Date.o Module.o Rcpp_init.o api.o attributes.o barrier.o -L/usr/lib/R/lib -lR
installing to /usr/local/lib/R/site-library/Rcpp/libs
** R
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
* DONE (Rcpp)
real 0m21.917s
user 0m21.388s
sys 0m2.304s
~/git/rcpp(master)$ ./cleanup
~/git/rcpp(master)$ time R CMD INSTALL .
* installing to library ‘/usr/local/lib/R/site-library’
* installing *source* package ‘Rcpp’ ...
** libs
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c Date.cpp -o Date.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c Module.cpp -o Module.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c Rcpp_init.cpp -o Rcpp_init.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c api.cpp -o api.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c attributes.cpp -o attributes.o
ccache g++ -I/usr/share/R/include -DNDEBUG -I../inst/include/ -fpic -g -O3 -Wall -pipe -pedantic -Wextra -Wno-empty-body -Wno-unused -c barrier.cpp -o barrier.o
g++ -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o Rcpp.so Date.o Module.o Rcpp_init.o api.o attributes.o barrier.o -L/usr/lib/R/lib -lR
installing to /usr/local/lib/R/site-library/Rcpp/libs
** R
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** installing vignettes
** testing if installed package can be loaded
* DONE (Rcpp)
real 0m1.444s
user 0m1.380s
sys 0m1.452s
~/git/rcpp(master)$
几年后的编辑: 我写了那篇博客文章, 它包含另一个重要的提示。一个人确实需要一个文件~/.ccache/ccache.conf
,因为a)R会新鲜地解压文件(所以“较新的ctime
”),并将它们放入临时目录中。因此,在使用R CMD INSTALL somepkg_1.2.3.tar.gz
(而不仅仅是源代码)时,这很有帮助:
max_size = 5.0G
# important for R CMD INSTALL *.tar.gz as tarballs are expanded freshly -> fresh ctime
sloppiness = include_file_ctime
# also important as the (temp.) directory name will differ
hash_dir = false
Dirk的回答指引我朝正确的方向,但仍然不够。由于他要求我不要附加我所需的最后几个步骤,因此我在这里附上。 如果没有以下内容,我的问题将无法得到解答。
对我而言,Dirk的回答并不能立即解决问题。如果编译仍然感到缓慢,请尝试运行:
ccache -s
cache directory /home/myuser/.ccache
primary config /home/myuser/.ccache/ccache.conf
secondary config (readonly) /etc/ccache.conf
cache hit (direct) 0
cache hit (preprocessed) 0
cache miss 989
cache hit rate 0 %
called for link 12
preprocessor error 12
cleanups performed 16
files in cache 177
cache size 31.1 MB
max cache size 5.0 GB
Note that cache isn't getting hit, which means ccache isn't doing anything.
您可以使用:
export CCACHE_LOGFILE=ccache.log
R CMD build .
我需要进行一些调试,但对我没有帮助。
解决问题的方法是运行:
export CCACHE_NOHASHDIR=true
R CMD build .
R CMD INSTALL pkg_1.2-3.tar.gz
从tarball安装。或者,在开发过程中,从目录中运行R CMD INSTALL .
进行安装。R CMD build
是完全错误的。 - Dirk EddelbuettelR CMD build
生成了相关的 tarball,从而提供了有关编译能力的即时反馈,避免了不必要的安装。 - Richardcd ..; R CMD build mydir/; R CMD check mydir_1.2-3.tar.gz; R CMD INSTALL mydir_1.2-3.tar.gz
是记录在案和推荐的工作流程,对我来说始终使用ccache
。R CMD INSTALL .
也是如此。 - Dirk Eddelbuettel
ccache
已经有十年左右了。 - Dirk Eddelbuettel