c++ 在R中快速重复生成包

mwecs4sa  于 2023-02-26  发布在  其他
关注(0)|答案(2)|浏览(105)

我有一个用R编写的包,里面有一大堆复杂的C++代码,编译起来需要一段时间。
当我修改代码时,我想快速地重新构建软件包以便测试它,但是R CMD build似乎每次都是从头开始,而不是使用代码的makefile只做需要做的事情。
有没有一种方法可以快速地在R中重复构建一个包来进行测试?

w8f9ii69

w8f9ii691#

我有点迟了一个简短的博客文章关于这一点,但我提到过几次之前:使用ccache。当文件不改变时(即当你只是改变帮助页面时),或者当很少的文件改变时,它会有很大的帮助。缓存是一个非常聪明的技巧,并且包是健壮的。
在Ubuntu/Debian上: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 buildR CMD INSTALL的选项以跳过小插图和/或手动构建,从而进一步加快重建速度。
说明:这里是重新安装Rcpp本身(新鲜从一个git pull),其中第一次安装需要21.9秒在我的(体面的)机器上工作,第二次然后只需要1.4秒感谢ccache

~/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)$
  • 几年后编辑:* 我做了write that blog post,它包含了另一个重要的内容。我们真的需要一个文件~/.ccache/ccache.conf,因为:a)R新解压缩文件(新的ctime),并将它们放到temp.目录中。所以当使用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
0x6upsns

0x6upsns2#

上面的Dirk's answer为我指出了正确的方向,但是还不够。因为他要求我不要附加我所要求的最后步骤,所以我在这里这样做。没有下面的内容,我的问题就不可能得到回答。
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 .

事实证明,ccache有时会考虑文件的位置。R CMD build.似乎是在临时目录中构建的,因此文件的位置每次都在变化。

相关问题