简洁的 Makefile

发布于 2024-10-22 14:04:02 字数 750 浏览 5 评论 0原文

我正在做一些 Makefile 重构,并试图找出实现执行以下操作的 Makefile 的最简洁方法:

  1. 有一个变量列出了所有源文件(可以是 C 和 C++ 文件)
  2. 所有目标文件都在 OBJ_DIR 中生成
  3. 如果对象目录不存在,则会创建

它 这是到目前为止我所拥有的:

...

OBJ_DIR = obj/
BIN_DIR = bin/
PROGRAM = program

SRCS = test1.cpp test2.c

OBJS  = $(addprefix $(OBJ_DIR), \
        $(patsubst %.cpp, %.o,  \
        $(patsubst %.c, %.o, $(SRCS))))

$(BIN_DIR)$(PROGRAM) : $(OBJS)
    $(CREATE_OUT_DIR)
    $(LINK)

$(OBJ_DIR)%.o : %.c
    $(CREATE_OBJ_DIR)
    $(CCOMPILE)

$(OBJ_DIR)%.o : %.cpp
    $(CREATE_OBJ_DIR)
    $(CPPCOMPILE)

...

我想消除每次 .o 编译时对 $(CREATE_OBJ_DIR) 的调用。有人知道该怎么做吗?我尝试添加它,但它不会构建目标文件:

$(OBJS): | $(OBJ_DIR)

$(OBJ_DIR):
    $(CREATE_OBJ_DIR)

I am doing some Makefile refactoring and trying to figure out the most concise way to implement a Makefile that does the following:

  1. Has one variable that has all the source files listed (can be both C and C++ files)
  2. All object files are generated in OBJ_DIR
  3. The object directory is created if it does not exist

Here is what I have so far:

...

OBJ_DIR = obj/
BIN_DIR = bin/
PROGRAM = program

SRCS = test1.cpp test2.c

OBJS  = $(addprefix $(OBJ_DIR), \
        $(patsubst %.cpp, %.o,  \
        $(patsubst %.c, %.o, $(SRCS))))

$(BIN_DIR)$(PROGRAM) : $(OBJS)
    $(CREATE_OUT_DIR)
    $(LINK)

$(OBJ_DIR)%.o : %.c
    $(CREATE_OBJ_DIR)
    $(CCOMPILE)

$(OBJ_DIR)%.o : %.cpp
    $(CREATE_OBJ_DIR)
    $(CPPCOMPILE)

...

I'd like to eliminate the call to $(CREATE_OBJ_DIR) for every .o compile. Anyone know how to do this? I tried adding this, but then it would not build the object files:

$(OBJS): | $(OBJ_DIR)

$(OBJ_DIR):
    $(CREATE_OBJ_DIR)

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

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

发布评论

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

评论(3

硬不硬你别怂 2024-10-29 14:04:02

您似乎已经解决了您的第一点:将它们全部放在一个变量中(我不认为您实际上需要像您一样将它们分成 TEMP1 和 TEMP2,只是有不同的构建规则)

对于第二点,您可以告诉编译器在哪里输出目标文件(对于 g++ 来说是这样的:

g++ -c MySourceFile.cpp -o obj/MySourceFile.o

这个的 make 规则看起来像:

obj/%.o: %.cpp
    g++ -c $*.cpp -o obj/$*.o

你的第三点也很容易解决,因为你可以为它制定一个构建规则(只需将目录名称放入在列出所有对象之前,目标的依赖项列表),并且构建规则将如下所示

obj:
    mkdir obj

编辑:或遵循您的代码示例:

$(BIN_DIR)$(PROGRAM) : $(BIN_DIR) $(OBJS) 
$(LINK)

$(BIN_DIR):
    $(CREATE_OUT_DIR) 

You already seem to have solved your first point: Have them all in one variable (I shouldn't think you actually need to to separate them into TEMP1 and TEMP2 like you have, just have different build rules)

For the second point, you can tell the compiler where to output the object files (for g++ its like this:

g++ -c MySourceFile.cpp -o obj/MySourceFile.o

The make rule for this would look like:

obj/%.o: %.cpp
    g++ -c $*.cpp -o obj/$*.o

And your third point is also easily solved, as you can have a build rule for it (Just put the directory name in the dependency list for the target, before all of the objects are listed), and the build rule would look like this

obj:
    mkdir obj

Edit: or following your code examples:

$(BIN_DIR)$(PROGRAM) : $(BIN_DIR) $(OBJS) 
$(LINK)

$(BIN_DIR):
    $(CREATE_OUT_DIR) 
债姬 2024-10-29 14:04:02

至于你的第三点:这个问题已被问到这里之前。不幸的是,对此没有真正好的答案,您需要从答案中找到最不丑陋的黑客。就我个人而言,我投票支持标记文件解决方案。

As for your 3rd point: This question has been asked here before. Unfortunately there is no really good answer for this, and you need to find the least ugly hack from the answer. Personally, I vote for the marker file solution.

匿名。 2024-10-29 14:04:02

这就是我所做的:

$(OBJ_LOC)/%.o: $(SRC_LOC)/%.c
    @[ -d $(OBJ_LOC) ] || mkdir -p $(OBJ_LOC)
    g++ ...

但是,我正在以极大的兴趣查看这些其他答案。

This is what I do:

$(OBJ_LOC)/%.o: $(SRC_LOC)/%.c
    @[ -d $(OBJ_LOC) ] || mkdir -p $(OBJ_LOC)
    g++ ...

But, I am looking at these other answers with great interest.

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