【问题标题】:gcc not found by win-builderwin-builder 找不到 gcc
【发布时间】:2016-07-11 19:13:55
【问题描述】:

我已经构建了一个包含 C/C++ 代码的 R 包。我现在正试图在win-builder 上测试这个包。不幸的是,00install.out 中返回了以下错误:

* installing *source* package 'mypackage' ...
** libs
  running 'src/Makefile.win' ...
/usr/bin/make --directory=lib/mylib/
gcc -g -Wall -fPIC -c mycode.c
make[1]: gcc: Command not found
make[1]: *** [mycode.o] Error 127
make: *** [mylib] Error 2
Warning: running command 'make --no-print-directory -f "Makefile.win"' had status 2
ERROR: compilation failed for package 'mypackage'
* removing 'd:/RCompile/CRANguest/R-release/lib/mypackage'

尝试使用gccgcc.execc 产生了类似的结果。

据此,我根据these instructions在Windows虚拟机上搭建了一个测试环境。在此环境中从命令行对代码运行 R CMD INSTALL . 导致代码编译和软件包安装没有问题。 (运行R CMD build . 也没有产生任何错误。)

win-builder 是怎么回事,如何实现编译?

或者,更重要的是,能够在 Windows 上构建软件包就足够了,无论它是否适用于 win-builder?

我的Makefile.win如下:

export CCOMP = gcc
export CPPCOMP = c++
export ADD_CC_FLAGS = -O3
APP_DIR = ./apps/myapp
LIB_DIR = ./lib/mylib

.PHONY: all $(APP_DIR) $(LIB_DIR)

all: $(APP_DIR) $(LIB_DIR)

$(APP_DIR) $(LIB_DIR): mylib
  $(MAKE) --directory=$@

$(APP_DIR): $(LIB_DIR) mylib

mylib:
  $(MAKE) --directory=lib/mylib

echo %PATH% 插入到mylib 目标下的make 文件中产生:

Makefile.win:24: *** missing separator.  Stop.

【问题讨论】:

  • 您可以包含您的 Makefile.win 内容吗?

标签: r windows gcc


【解决方案1】:

您在此处收到一个不明确的错误,因为您包含了一个文件 Makefile.win

但是make的语义,如果找到这样的文件,就会被使用……这不是你想要的。 R 构建它自己的 Makefile.win 并且您应该只提供一个要包含的 sn-p —— 必须将其称为 Makevars.win

这是第一条规则。第二条规则是不要包含您将包含在Makefile 中的所有材料——因为您会破坏 R 已经带来的内容。所有这些都在编写 R 扩展中,但当然可以更清楚。

我的务实建议:取一个你知道和喜欢的包,它在 win-builder 中有一个工作 R 构建,并修改它。如果您可以使用 Rtools 等访问 R 系统,则可以在本地进行测试。


从 OP 编辑​​

我需要编译一个依赖于多个库的可执行文件。库代码在src/libs 中,可执行文件的代码在src/apps 中。我确保在每个子目录中运行make 有效,并将src/apps/Makefile 设置为使用相对路径来提取src/libs 的结果。那时唯一的问题是让整个链条运转起来。为此,我创建了一个文件src/Makevars.win,其结构如下:

.PHONY: all myprogram sublib1 sublib2

all: sublib1 sublib2 myprogram

myprogram: sublib1 sublib2
  @(cd apps/myprogram && $(MAKE) CXX="$(CXX)" CC="$(CC)" CFLAGS="$(CFLAGS) $(CPICFLAGS)" AR="$(AR)" RANLIB="$(RANLIB)")

sublib1:
  @(cd lib/sublib1    && $(MAKE) CXX="$(CXX)" CC="$(CC)" CFLAGS="$(CFLAGS) $(CPICFLAGS)" AR="$(AR)" RANLIB="$(RANLIB)")

sublib2:
  @(cd lib/sublib2    && $(MAKE) CXX="$(CXX)" CC="$(CC)" CFLAGS="$(CFLAGS) $(CPICFLAGS)" AR="$(AR)" RANLIB="$(RANLIB)")

据我了解,Makevars.win 嵌入在 R 生成的动态生成的Makefile 中。所以,$(CC) 实际上是在引用这个隐藏代码。

(可能有更聪明的方法可以做到这一点。)

【讨论】:

  • 谢谢。 Writing R Extensions 确实可以更清楚。我查看了另一个我喜欢的包 (dplyr),它的代码似乎比我的要简单得多。我的makefile 递归调用六个不同的子目录,它们有自己的makefile。这些生成静态库,然后将其组装成可执行文件。我不知道如何用Makevars 捕捉到这一点,尽管这可能是一个单独的问题。
  • 这很难。一些软件包会这样做——而另一些软件包则将其分配给 configureconfigure.win
  • 现在阅读this link
  • 使用Makevars.winMakevars 肯定是解决方案。谢谢!
  • 很高兴知道!如果你有一个从Makevars 构建依赖包/库的好解决方案,那么可能值得写一篇博文或类似的文章......因为这确实不是那么明显或有据可查。
猜你喜欢
  • 2012-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-08
  • 2016-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多