Makefile 将自动生成的源文件存档/链接在一起

发布于 2024-08-08 19:47:37 字数 406 浏览 4 评论 0原文

基本上,我有一个文件“blah.txt”。该文件由“编译器”解析,并从中生成 N 个输出 .c 文件。我想要一个 makefile,它将从该 .txt 文件生成 c 文件,然后编译所有文件并将它们存档在 libmystuff.a 中,

我认为这样的事情:

all: dogen libmystuff.a

dogen: source.txt
    mycompiler $^

libmystuff.a: $(addsuffix .o, $(shell ls *.c))
    $(AR) rcs $@ $^

.PHONY: dogen

但显然这不起作用,因为依赖项是在开始时评估的此时 *.c 还不会产生任何结果,因为它们不存在。

有谁知道如何实现这一点(无需明确列出所有生成的 *.c)?

Basically, I have a file 'blah.txt'. That files gets parsed by a 'compiler' and from it will generate N output .c files. I want a makefile that will from that .txt file generate the c files then compile all of them and archive them in a libmystuff.a

I tought of something like this :

all: dogen libmystuff.a

dogen: source.txt
    mycompiler $^

libmystuff.a: $(addsuffix .o, $(shell ls *.c))
    $(AR) rcs $@ $^

.PHONY: dogen

But obviously that doesn't work because the dependencies are evaluated at the start and at that point the *.c just doesn't yield anything yet since they don't exist.

Does anyone see how to accomplish that (without listing all the generated *.c explicitely) ?

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

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

发布评论

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

评论(3

樱花细雨 2024-08-15 19:47:38

使用sentry“makefile”强制make重新读取makefile并替换*.c处的正确列表:

include sources-sentry

sources-sentry: source.txt
    mycompiler $^
    touch $@

libmystuff.a: $(addsuffix .o, $(shell ls *.c))
    $(AR) rcs $@ $^

include指令用于包含其他makefile(就像C的#include)。它有一个很好的特点,如果它包含的 makefile 本身就是目标,make 程序首先将其视为目标并尝试更新。如果它不是最新的,make 会调用更新它所需的命令,然后重新读取 makefile,再次替换所有变量

因此,如果自上次处理以来 source.txt 发生了更改(时间被记录为sources-sentry文件的时间戳),则源将被更新并重新调用make,< code>*.c 被替换为 c 文件的更新集。

Use sentry "makefile" to force make to re-read makefile and substitute correct list at *.c:

include sources-sentry

sources-sentry: source.txt
    mycompiler $^
    touch $@

libmystuff.a: $(addsuffix .o, $(shell ls *.c))
    $(AR) rcs $@ $^

include directive is used to include other makefiles (just like C's #include). It has a nice pecularity that if makefile it includes is a target itself, make program first considers it as a target and tries to update. If it is not up-to-date, make invokes the commands needed to update it and then re-reads makefile, substituting all the variables again.

Thus, if source.txt changed since the last time you processed it (the time being recorded as timestamp of sources-sentry file), the sources will be updated and make will be re-invoked, the *.c being substituted to the updates set of c-files.

天生の放荡 2024-08-15 19:47:38

Pavel Shved 是对的(*),您必须重新运行 Make。这是我相当自豪的一个技巧。它将处理对可能尚不存在的对象的依赖关系,并且不会不必要地运行。

SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

all: libmystuff.a

ifeq ($(MAKELEVEL),0) 
libmystuff.a: source.txt
    mycompiler $^ 
    @$(MAKE) -s $@
else
libmystuff.a: $(OBJECTS)
    $(AR) rcs $@ $^ 
endif

(*)我的宿敌,我们又见面了。

编辑:
如果某个 other 拨打 this 电话...我没有想到这一点。但我认为这会解决这个问题:(

SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

all: libmystuff.a

libmystuff.a: source.txt
    mycompiler $^ 
    @$(MAKE) -s phonyLib

.PHONY: phonyLib
phonyLib: $(OBJECTS)
    $(AR) rcs libmystuff.a $^ 

是的,我知道,如果您想要构建一个名为“phonyLib”的文件,您将无法使用此 makefile 来完成此操作,但我们不要反常。)

Pavel Shved is right(*), you must rerun Make. Here is a trick I'm rather proud of. It will handle dependencies on objects that may not yet exist, and won't run unnecessarily.

SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

all: libmystuff.a

ifeq ($(MAKELEVEL),0) 
libmystuff.a: source.txt
    mycompiler $^ 
    @$(MAKE) -s $@
else
libmystuff.a: $(OBJECTS)
    $(AR) rcs $@ $^ 
endif

(*) My old nemesis, we meet again.

EDIT:
If some other make calls this make... I hadn't thought of that. But I think this will solve it:

SOURCES = $(wildcard *.c)
OBJECTS = $(SOURCES:.c=.o)

all: libmystuff.a

libmystuff.a: source.txt
    mycompiler $^ 
    @$(MAKE) -s phonyLib

.PHONY: phonyLib
phonyLib: $(OBJECTS)
    $(AR) rcs libmystuff.a $^ 

(Yes, I know, if you feel an urge to build a file called "phonyLib" you won't be able to do it with this makefile, but let's not be perverse.)

昨迟人 2024-08-15 19:47:38

如果您的 .c 文件仅由 .txt 生成,那么您可以让 libmystuff.a 依赖于 txt,并在规则主体中评估 $(shell ls *.c) 。

If your .c files are only produced by the .txt, then you can let the libmystuff.a depend on the txt, and evaluate the $(shell ls *.c) in the rule body instead.

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