【问题标题】:Define target for recursive makefiles invocation定义递归 makefile 调用的目标
【发布时间】:2018-12-20 23:38:29
【问题描述】:

我需要什么:使 LAUNCHMAKES 目标依赖于某些东西,以便在没有更改源文件时不调用子 makefile。

SUB MakeFile 包含 dir 中所有 .cpp 文件的集合,并将它们存储到 obj/。然后没有更改 src 文件,它仍然调用并产生“进入目录 - 离开目录”。我需要在不需要时摆脱它。 我读过--no-print-directory,但事实并非如此。

项目结构:

Project
|----project
|    |----dir1
|    |    |----src1.cpp
|    |    `----Makefile
|    |----dir2
|    |    |----src2.cpp
|    |    `----Makefile
     `----main.cpp
|----obj
|    |----src1.o
|    |----src2.o
|    `----main.o
|----MakeFile

代码:

release: LAUNCHMAKES obj/main.o
    $(CXX) $(CXXFLAGS) main.o src1.o src2.o -o result

LAUNCHMAKES: (?)
    for i in $(SUBDIRS); do \
    $(MAKE) -C $$i CXXFLAGS=$(CXXFLAGS);  \
    done

obj/main.o: project/main.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

【问题讨论】:

  • 您要求的有点矛盾:如果您将子目录的构建委托给子make,那么您告诉make在子Makefile中观看哪些文件,而不是在主Makefile中.但是,如果您希望主 Makefile 足以让 make 决定子目录是否是最新的,那么您必须将您在子 Makefile 中声明的所有依赖项放入主 Makefile。换句话说,您可能应该在平面组织或分层组织之间一劳永逸地做出决定。注意:您的 for 循环在 CXXFLAGS 上迭代(可能不是您想要的)。
  • 谢谢,我已经编辑过了。如果 makefile 检查依赖项是否是最新的,为什么我不能(对不起,如果它天真)将源文件放入 LAUNCHMAKES 的依赖项。例如LAUNCHMAKES: src1.cpp src2.cpp。如果它们被更改,则启动迭代的接收。
  • 问题是文件本身不是最新的或过时的。它是通过引用另一个文件。并且您的LAUNCHMAKES 目标不是一个文件,最后修改时间可以通过 make 与源文件的比较来确定它是最新的还是过时的。因此,在您的主 Makefile 中,您必须复制您在子 Makefile 中声明的完整依赖项。而且复制代码通常是一个非常糟糕的主意......
  • 子 Makefile 的包含可用于避免代码复制,但由于路径可能与不同的目录相关,这将引发新问题。真诚地,我所知道的大多数使用 make 构建系统的项目都不能满足您的要求。他们要么根本不使用递归make,要么系统地运行子make,即使无事可做。他们不会尝试节省(通常可以忽略不计)无用运行子制作所需的时间。

标签: makefile gnu-make


【解决方案1】:

不是您的问题的解决方案,而是一个非递归 Makefile 的示例,只是为了向您展示它对于您的简单示例项目有多么简单:

SUBDIRS := dir1 dir2
OBJDIR  := obj
SRCS    := $(shell find . -type f -name '*.cpp')
OBJS    := $(patsubst %.cpp,$(OBJDIR)/%.o,$(notdir $(SRCS)))
VPATH   := $(SUBDIRS)

.PHONY: release clean

release: result

result: $(OBJS)
    $(CXX) $(LDFLAGS) $^ -o $@

$(OBJDIR)/%.o: %.cpp
    $(CXX) $(CXXFLAGS) -c $< -o $@

clean:
    rm -f $(OBJDIR)/*.o result

演示:

$ make
g++  -c dir2/src2.cpp -o obj/src2.o
g++  -c dir1/src1.cpp -o obj/src1.o
g++  -c main.cpp -o obj/main.o
g++  obj/src2.o obj/src1.o obj/main.o -o result

【讨论】:

  • 谢谢你,雷诺!问题是我必须保留子生成文件,因为我简化了示例,实际上子生成文件做得更多。他们在 obj/.此外,应该可以为不同的源目录使用不同的 makefile。我相信可以将所有内容放入一个 Makefile 中,但现在对我来说太复杂了。谢谢你的回答。
猜你喜欢
  • 1970-01-01
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 2019-09-23
  • 1970-01-01
  • 2013-05-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多