【问题标题】:makefile automatic src file detection and dependency generationmakefile 自动 src 文件检测和依赖生成
【发布时间】:2013-12-12 11:20:16
【问题描述】:

我的 c++ 项目有以下设置:

在 src 文件夹中,有 *.cpp 和对应的 *.h 文件和 在 obj 文件夹中,我想拥有我的 .o 文件。

到目前为止,编译和链接都不是问题。但是现在我有太多的 .cpp 和 .h 文件无法手动将它们放入 Makefile 中。所以我决定在makefile中写这个小指令:

collect_sources:
@echo "collecting source files";
@echo "SRCS = \\" > sources;
@for file in ./src/*.cpp; \
do \
    echo "$$file \\" >> sources; \
done

我也是

-include sources

在makefile的开头

生成的文件sources 看起来不错,尽管最后一行有一个我不喜欢的反斜杠。但是,afaik 它也应该是有害的。

我现在还需要自动建立依赖关系。在我在 Makefile 中直接将 *.cpp 文件定义为 SRCS 的上一个版本中,以下代码很好:

$(SRCDIR)/%.cpp:
  @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);
clear_dependencies:
    echo "" > $(DEP);

depend: clear_dependencies $(SRCS)

但是包含sources-文件,它永远不会到达上面的代码块。

以下是 Makefile 顶部定义的常量:

CXX = g++
CXXFLAGS = -Wall \
       -Wextra \
       -Wuninitialized \
       -Wmissing-declarations \
       -pedantic \
       -O3 \
       -p -g -pg
LDFLAGS =  -p -g -pg
DEPFLAGS = -MM

SRCDIR  = ./src
OBJDIR  = ./obj

TARGET = ./bin/my_funky_function_which_is_not_the_real_name

-include sources

OBJSTMP =   $(SRCS:.cpp=.o)
OBJS        =   $(OBJSTMP:$(SRCDIR)=$(OBJDIR))
DEP = depend.main
EXT_SRC =   .cpp
EXT_OBJ =   .o

我错过了什么?我的方法有效/可行吗?

【问题讨论】:

  • 附注:请不要推荐任何已经可以做到这一点的工具。我真的很想了解这一点并完全控制正在发生的事情。
  • 有一个简单的错误和很多可能的改进。你想走多远?
  • 一步一步达到绝对最优;-)

标签: c++ makefile


【解决方案1】:

好吧,你要的。

1: 你的collect_sources:... include sources 是光荣的鲁布戈德堡黑客。只需这样做:

SRCS = $(wildcard ./src/*.cpp)

如果你想用肉眼确认,你可以这样做:

$(info $(SRCS))

2:

clear_dependencies:
    echo "" > $(DEP);

只是为了美观,让我们解决这个问题。

clear_dependencies:
    $(RM) $(DEP);

3:

$(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
  "$(subst $(SRCDIR),$(OBJDIR),$(subst $(EXT_SRC),$(EXT_OBJ),$$file))" \
  $(addprefix ,$$file) >> $(DEP);

这需要一些工作。首先是眼前的问题:目标是存在的真实文件,规则没有先决条件。因此,该规则将不会运行(我不知道为什么它在以前的版本中对您有用,也许还有其他不同的地方)。作为临时修复,我建议我们切换到静态模式规则和 PHONY 目标:

.PHONY:$(SRCS)
$(SRCS) : $(SRCDIR)/%.cpp:
    @$(CXX) $(DEPFLAGS) -MT \
   ...

看看一切是否奏效,然后我们就可以解决大问题了。

【讨论】:

  • 首先,感谢您的回答。我不明白您所说的“目标是存在的真实文件”是什么意思。你是对的,它最初不是那个代码。而不是 $$file 它是带有@的东西。
  • @stefan,可能是$@。实际上,Make 在考虑是否重建类似./src/foo.cpp 的东西时会使用此规则。这几乎肯定是一个已经存在的文件(除非这个问题比你告诉我们的更多)。所以 Make 会得出结论,该文件是最新的,不需要重建。即使/当 Make 运行规则时,我认为 $$file 的东西不会起作用。
  • 你说得对。并与您的“PHONY”建议和“$@”一起工作正常:)
  • 酷。几个小时后,我将有时间添加更多内容。
  • 事实上那会很棒 :) 出于某种我还不明白的原因,编译器会构建每个对象而无需更改任何文件。我可能在这里搞砸了..
猜你喜欢
  • 2023-04-11
  • 2012-06-20
  • 1970-01-01
  • 2012-08-05
  • 2013-09-22
  • 2012-07-06
  • 1970-01-01
  • 2016-10-13
  • 2017-10-03
相关资源
最近更新 更多