将(不带换行符)添加到自动生成的 Makefile 依赖项列表中

发布于 2024-09-12 07:39:51 字数 1050 浏览 10 评论 0原文

不确定标题是否有意义......所以我会详细说明一下。

我正在研究这个使用 gcc 的自动依赖列表生成器的 makefile。

同时,我想保留一个良好的排序目录结构,将源代码、标头和资源分开。

布局漂亮又简单,就像

  • MAIN 一样
    • 源代码
    • 包括
    • 对象
    • 依赖项

现在,makefile 依赖列表生成器 atm 是这样的:

$(DEP_PATH)%.d : $(SRC_PATH)%.c
    @${CC} $(CFLAGS) -MM -c $(INCLUDE) $< > $(DEP_PATH)$*.d
include $@

这里的想法是我们生成依赖规则,然后将其包含到 make 构建中。

比如说 foo1.o 的结果是:

foo1.o: src/foo1.c include/foo1.h include/foo2.h include/foo3.h

如果我将所有对象标记在主目录中,这会很好地工作...但是,因为它们位于 /main/objects 中... make 说它不能找到 /main/objects/foo1.o 的规则

现在,我尝试了以下操作:

@echo "$(OBJ_PATH)" > $(DEP_PATH)$*.d
@${CC} $(CFLAGS) -MM -c $(INCLUDE) $< >> $(DEP_PATH)$*.d

Which the >将对象路径提供给新的/覆盖的文件,然后将 GCC 自动依赖规则生成连接到它......但它在两个集合之间添加换行符。

我也尝试使用所述信息来搜索两个单独的文件......但它们也得到了换行符。

有没有一种好的方法可以在依赖文件前面添加不添加换行符?

另外,如果您有关于 makefile、cat 和 echo 的任何真正好的教程,我将非常感激。

感谢您的所有回复。

Not sure if the title makes sense... so I'll elaborate a bit.

I'm toying with this makefile that uses gcc's auto-dependency list generator.

At the same time, I wanted to keep a nice sorted directory structure that separates source, headers, and resources.

The layout's nice and simple like so

  • MAIN
    • src
    • include
    • objects
    • dependencies

Now, the makefile dependency list generator atm is this:

$(DEP_PATH)%.d : $(SRC_PATH)%.c
    @${CC} $(CFLAGS) -MM -c $(INCLUDE) 
lt; > $(DEP_PATH)$*.d
include $@

The idea here being that we generate the dependency rule, then include it to the make build.

and the result for say, foo1.o is:

foo1.o: src/foo1.c include/foo1.h include/foo2.h include/foo3.h

This would work fine if I labled all my objects to be found in the main directory... however since they in /main/objects instead... the make says it can't find the rule for /main/objects/foo1.o

Now, I tried this:

@echo "$(OBJ_PATH)" > $(DEP_PATH)$*.d
@${CC} $(CFLAGS) -MM -c $(INCLUDE) 
lt; >> $(DEP_PATH)$*.d

Which the > feeds the object path to the new/overwritten file, then concatenates the GCC auto-dependency rule generation to it... but it adds the newline between the two sets.

I tried cat'ing two separate files with said info as well... but they also get the newlines.

Is there a nice way to prepend the dependency file w/out adding the newline?

Also, if you've got any real nice tutorials on makefiles, cat, and echo, I'd really appreciate it.

Thanks for any and all responses.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

自在安然 2024-09-19 07:39:51

您提出的问题的答案是 sed:

@${CC} blah blah blah | sed 's|^|$(OBJ_PATH)|' > $(DEP_PATH)$*.d

但是这部分您将遇到不同的问题:

include $@

include 指令是针对 Make 本身的,它不是一个shell 命令(如 $(CC)...)。 $@ 是一个自动变量,在规则内定义,不可用于规则外的指令。相反,尝试这样的事情:

include $(DEP_PATH)/*.d

看看高级自动依赖生成

The answer to the question you asked is sed:

@${CC} blah blah blah | sed 's|^|$(OBJ_PATH)|' > $(DEP_PATH)$*.d

But you're going to have a different problem with this part:

include $@

The include directive is for Make itself, it is not a shell command (like $(CC)...). And $@ is an automatic variable, defined within the rule, not available to directives outside the rule. Instead, try something like this:

include $(DEP_PATH)/*.d

and take a look at Advanced Auto-Dependency Generation.

沫尐诺 2024-09-19 07:39:51

虽然我想象还有其他选择,可能是更好的选择……我想我找到了解决问题的方法。

我可以将 echo 通过管道传输到 tr 中以删除换行符。
所以生成的代码是:

$(DEP_PATH)%.d : $(SRC_PATH)%.c
    @echo "$(OBJ_PATH)" | tr -d '\n' > $(DEP_PATH)$*.d
    @${CC} $(CFLAGS) -MM -c $(INCLUDE) 
lt; >> $(DEP_PATH)$*.d
cat $@
include $@

现在执行以下操作...

1) 对于每个 .d,确保 .c 存在并且是最新的。

2) 回显对象路径,|(管道)它到tr将删除换行符,然后 > 将使结果覆盖/创建到 .d 文件

3) 让 $(CC) 生成依赖项列表...不幸的是,这排除了目标文件的预期位置(这就是为什么存在 1-2 行的原因)

4)只需将生成的文件连接到终端(不需要,但我喜欢看到它现在可以工作!)

5)让 make 将生成的依赖项列表包含到构建中。

应该值得注意的是,在后续运行中...我将其列在顶部:

all: $(MAIN)
-include $(DEP)

它将检查主可执行文件,然后包含依赖项文件(如果创建了它们)。 (如果文件还没有创建,这里的 - 是为了忽略错误......这没关系,因为我从一开始的代码片段将在之后运行。)

同样,任何建议和建设性批评都是值得赞赏的。

While I imagine there are alternatives, possibly better ones... I think I found a solution to my problem.

I can pipe the echo into tr to remove the newline.
So the resultant code is:

$(DEP_PATH)%.d : $(SRC_PATH)%.c
    @echo "$(OBJ_PATH)" | tr -d '\n' > $(DEP_PATH)$*.d
    @${CC} $(CFLAGS) -MM -c $(INCLUDE) 
lt; >> $(DEP_PATH)$*.d
cat $@
include $@

Which does the following now...

1) For each .d, make sure the .c is there and up-to-date.

2) echo the object path, | (pipe) it to tr which will delete the newline, then > will make the result overwrite/create to the .d file

3) have $(CC) generate the dependency list... which unfortunately excludes the object file's intended location (which is why 1-2 lines exist)

4) simply concatenate the resulting file to the terminal (not needed, but I like seeing that this works now!)

5) have make include the resulting dependency list into the build.

Should be worth noting that in subsequent runs... I have this listed up top:

all: $(MAIN)
-include $(DEP)

which will check for the main executable and then include the dependency files if they're created. (the - is here to ignore errors should the files not be made yet... which is ok since my snippet from the begin will run after.)

Again, any suggestions and constructive criticisms are appreciated.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文