gpt4 book ai didi

c - 目标文件位于单独目录中的简单非递归 Makefile

转载 作者:行者123 更新时间:2023-12-05 04:16:43 24 4
gpt4 key购买 nike

我已经搜索并尝试了一些示例来使用非递归 makefile 完成一个简单的项目。过去,我使用的是简单的单一目录代码库,但现在我正在为多个工程师构建一个环境:-)

+--app
| +-- obj/
| +-- Makefile
| +-- first.c
| +-- second.c
|
+--lib1
| +-- obj/
| +-- Makefile
| +-- foo.c
| +-- bar.c
|
+--lib2
| +-- obj/
| +-- Makefile
| +-- sample.c

没什么特别的——只有两个目录(以后可能是第三个),其中包含库代码和多个应用程序,都在“app”目录中。为了清洁,我想将 .o 和 .d 文件保存在单独的 obj/目录中。

  1. 我希望能够在每个子目录(如 lib1 和 lib2)中执行“make”以验证库。他们将分别生成 libabc.a 和 libxyz.a。
  2. 我写了一些简单的 Makefile,但我的规则不起作用,我试图理解 GNU make 手册,但我迷路了。

lib1/生成文件:

lib_src = foo.c bar.c
lib_obj = $(patsubst %.c,obj/%.o,$(lib_src))
libabc.a: $(lib_obj)
@echo [Archive... $(@F)]
@$(AR) -cr libabc.a $^
obj/%.c : %.c
$(CC) $(CFLAGS) -c -o $@ $<

应用程序/生成文件:

ALL_APP = first second
% : %.c libabc.a libxyz.a
$(CC) $(CLFAGS) $^ -o $@
include ../lib1/Makefile
include ../lib2/Makefile

现在,我很难在每个 Makefile 中定义相同的目标(很明显)。就像我无法在 lib1/Makefile 和 app/Makefile 中定义一个 clean 因为 lib1 包含在那里。虽然我希望我可以单独在 lib1 中执行 make clean,但这是有道理的。

现在当我在“应用程序”中制作时,没有制作 obj/foo.o 的规则。我猜是因为路径都是假的。 “obj/”指的是 lib1/obj/,但随着 Makefile 被包含在内,这一切都丢失了。

我做错了什么,我能否像上面那样使用非常简单的 Makefile 来构建我的项目。大多数在线示例都相当复杂,因为它们试图实现更多(我相信)。

提前致谢(对于已经讨论过多次的话题,我们深表歉意)。如果可以避免的话,我宁愿现在不学习 automake 和 cmake。我希望我的项目足够简单,不需要使用这些强大的工具。

最好的问候,

最佳答案

让我们从 lib1/Makefile 开始:

lib_src = foo.c bar.c
lib_obj = $(patsubst %.c,obj/%.o,$(lib_src))

libabc.a: $(lib_obj)
@echo [Archive... $(@F)]
@$(AR) -cr libabc.a $^

obj/%.c : %.c
$(CC) $(CFLAGS) -c -o $@ $<

我们引入变量HERE,并做一些小改动:

HERE := ../lib1

lib_src := foo.c bar.c
lib_obj := $(patsubst %.c,$(HERE)/obj/%.o,$(lib_src))

$(HERE)/libabc.a: $(lib_obj)
@echo [Archive... $(@F)]
@$(AR) -cr $@ $^

$(HERE)/obj/%.c : $(HERE)/%.c
$(CC) $(CFLAGS) -c -o $@ $<

当从 lib1/ 中调用时,此 makefile 仍将像以前一样工作。但是一旦我们对lib2/Makefile做了相应的修改,我们就可以修改app/Makefile:

ALL_APP = first second
% : %.c ../lib1/libabc.a ../lib2/libxyz.a
$(CC) $(CLFAGS) $^ -o $@

include ../lib1/Makefile
include ../lib2/Makefile

现在是 clean 规则。 我们重命名 lib1/Makefile => lib1/lib1.maklib2/Makefile => lib2/lib2.mak,写一个新的lib1/Makefile:

include lib1.mak

clean:
@rm -f lib*.a obj/*

lib2/中做同样的事情,修改app/Makefile:

...

include ../lib1/lib1.mak
include ../lib1/lib1.mak

clean:
@rm -f $(ALL_APP)
@$(MAKE) -C ../lib1 clean
@$(MAKE) -C ../lib2 clean

(我们可以不用递归,但会更复杂,而且这样使用递归 Make 确实没有错。)

一些进一步的改进是可能的。例如,以这种方式将路径硬编码到 lib1/lib1.maklib2/lib2.mak 中是不好的,但可以修复。但这足够一天了。

关于c - 目标文件位于单独目录中的简单非递归 Makefile,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26497453/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com