【问题标题】:Can't assign a list of file names to a variable in GNU-make无法将文件名列表分配给 GNU-make 中的变量
【发布时间】:2020-01-24 05:45:36
【问题描述】:

第一次在这里发帖,不是以英语为母语的人,很高兴发帖并帮助他人!

我在使用 make 为我编译 avr-gcc 项目时遇到问题。更具体地说,将不同目录(在我的情况下为子目录)的 *.c 源文件列表分配给 make 中的变量,它将用于生成依赖项。

使用我找到的This 方法,Renaud Pacalet 使用以下语法:

SRC = $(shell find src/ -name "*.cpp")

在我的例子中使用 find 命令如下所示:

SOURCE_FILES = $(shell find -name '*.c')

结果是(在cmd上):

C:\AVR_projetos\Balizar_reserva>find -name '*.c'
./main.c
./modules/i2c/i2c.c
./modules/rom/rom.c

但是,当 make 调用 shell 执行脚本时,该变量只保存序列中的第一个文件名。

到目前为止我尝试过:

  • 使用 $(wildcard *.c) 函数,同样的问题
  • 使用 $(shell echo *.c),同样的问题
  • 使用附加参数 -print0 到 -find 强制进行内联输出,仍然没有任何效果
  • 使用 $(shell find (path) -name '*.c') 使用主目录的绝对路径、相对 ../ 以及所有与附加参数的组合

另外,我参考了这两个手册页:

他们都用简单的方式解释了这是可能的,我做同样的事情却一无所获。

  • 这是我的文件目录:Image

  • 还有我的 make 文件(到处都是,因为我试图实现它):Paste bin

为了记录,我在遇到这个问题之前遇到了一个问题:

avr-gcc -MM main.c > depend.d
  0 [main] sh 14484 sync_with_child: child 15780(0x1DC) died before initialization with status code 0xC0000142
158 [main] sh 14484 sync_with_child: *** child state waiting for longjmp
/usr/bin/sh: fork: Resource temporarily unavailable make: *** [depend] Error 128

为此我发现This fix 看起来有效。

  • 操作系统:Windows 10 专业版 1903 版本。 18362.535

  • GNU-make:3.81

【问题讨论】:

  • 一个区别是'his'包含一个目录名(src/)而你的没有。也许$(shell find . -name '*.c')?这可能不是问题,但是……
  • 吹毛求疵,但为 find 命令指定路径不是一个好主意吗?
  • 不确定它是否对 make 文件(尤其是 Windows)有影响,但 unix shell(如 bash)对于单引号 (')、双引号 (" ) 并且没有引号。他的示例使用了双引号 "*.cpp",所以我会复制它。(参见例如 stackoverflow.com/questions/6697753/…
  • 您能否在您的%o:depend: 规则中添加@echo "rule: $@ on $^" 作为第一个命令(并编辑您的帖子以查看结果)
  • 不要犹豫,发布minimal reproducible example

标签: c makefile dependency-management avr


【解决方案1】:

欢迎来到 SO, 正如你提到的,你指的是通配符功能,但描述说:

通配符函数的一个用途是获取目录中所有 C 源文件的列表,如下所示:$(wildcard *.c)

那我想当你执行Make的时候,main.c编译好了?

您需要改进通配符来搜索子目录或手动添加它们。 看看这个answer 和问题。

【讨论】:

  • 我查看了它,但不幸的是它也没有工作,但我使用 - $(shell find -name "*.c") 让它工作
【解决方案2】:

感谢大家的建议,我真的很感激。使用以下命令让该死的东西工作:

$(shell find -name "*.c")

这样我们可以将它分配给一个变量并使用它。有了这个,我们就可以使用下面的makefile来对应建议的项目结构了。

  • Makefile(葡萄牙语中的 cmets)

这个项目是为 avr-gcc 编程设置的,然而,这个概念适用于普通的 c 和 cpp 编程。 文件结构(示例,其中 i2c 可以是通用模块,而 avr_config.h 是编译 avr-gcc 相关项目时的特殊头文件):

.
├── modules
│   └── i2c
│       ├── i2c.c
│       └── i2c.h
├── main.c
├── Makefile
└── avr_config.h

可以有任意多的模块,因为变量

SOURCE_FILES = $(shell find -name "*.c")

捕获所有这些。我以最简单的方式设置了它,因此,目标文件将与源文件和头文件一起编译,然后在主目录中链接在一起。 还有一个名为

的文件
depend.d

将被创建以完成编译。

makefile 还包含一些有用的命令,这些命令在文件的开头进行了描述。

希望这对某人有所帮助!将发表一篇专门的文章,解释所有上下文以及如何设置通用 avr-gcc 项目以在 Visual Studio 代码中进行微控制器编程。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-11
    • 2015-04-27
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    相关资源
    最近更新 更多