简体   繁体   English

Makefile依赖项修改检测

[英]Makefile dependency modification detection

I'm writing a makefile for handling the dependency of build units ONE and TWO -> build unit LIB. 我正在编写一个用于处理构建单元ONE和TWO->构建单元LIB的依赖关系的makefile。

By "build unit" I mean a directory containing directories src, lib, include and bin, as well as a makefile for compiling the source code in src. “构建单元”是指包含目录src,lib,include和bin的目录,以及用于在src中编译源代码的makefile。 Libraries are placed in "lib" and library header-files in "include". 库位于“ lib”中,而库头文件位于“ include”中。 The compiled binary is placed in "bin". 编译后的二进制文件放在“ bin”中。 A build unit accepts "make", "make all", "make lint" and "make clean". 构建单元接受“ make”,“ make all”,“ make lint”和“ make clean”。

When a change is made to a header-file in LIB, this makefile is meant to detect it and recompile + install (copy .a+.h-files to ONE and TWO) the new version of LIB before compiling. 当对LIB中的头文件进行更改时,此makefile可以检测到该文件并在编译前重新编译+安装(将.a + .h文件复制到ONE和2)新版本的LIB。

.PHONY: ONE TWO CLEAN LINT

ALL: ONE TWO

%.a %.h:
    @echo ---------- Compiling LIB ----------
    @cd LIB && gmake.exe LIB

LIB_HEADERS := $(wildcard LIB/src/*.h)

ONE: ONE/lib/libLIB.a $(subst LIB/src/,ONE/include/,$(LIB_HEADERS))
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

TWO: TWO/lib/libLIB.a $(subst LIB/src/,TWO/include/,$(LIB_HEADERS))
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

CLEAN LINT:
    @cd ONE && gmake.exe $@
    @cd TWO && gmake.exe $@
    @cd LIB && gmake.exe $@

(Assume the makefile for LIB handles copying into ONE and TWO) (假设LIB的makefile处理复制到一个和两个)

  1. How come make does not run the rule "%.a %.h:" when I make a change to one of the header-files in LIB/src? 当我更改LIB / src中的头文件之一时,make为什么不运行规则“%.a%.h:”?
  2. How do I generalize ONE and TWO into a single rule? 如何将一个和两个概括为一个规则? I want to do this (but a target cannot be used in dependencies, at least this way): 我想这样做(但是至少不能以这种方式在依赖项中使用目标):

     ONE TWO: $@/lib/libLIB.a $(subst LIB/src/,$@/include/,$(LIB_HEADERS)) @echo ---------- Compiling $@ ---------- @cd $@ && gmake.exe 

UPDATE: 更新:

I found the solution by taking a step back, drawing Directed Acyclic Graphs, and thinking in terms of single files, instead of all files of a certain type. 我通过退后一步,绘制有向非循环图并考虑单个文件而不是某个类型的所有文件来找到解决方案。

Here is the (not very elegant) solution, for completeness: 为了完整性,这是(不是很优雅的)解决方案:

.PHONY: ONE TWO CLEAN LINT

ALL: ONE TWO

LIB_HEADERS := $(sort $(subst name.h,,$(wildcard LIB/src/*.h)))

# ------------------------------------------------------------
ONE/include/%.h: LIB/src/%.h
    @echo Copying $< to $@
    @mkdir ONE\\include 2> NUL || :)
    @copy $(subst /,\,$<) ONE\\include\\ 1> NUL

TWO/include/%.h: LIB/src/%.h
    @echo Copying $< to $@
    @mkdir TWO\\include 2> NUL || :)
    @copy $(subst /,\,$<) TWO\\include\\ 1> NUL
# ------------------------------------------------------------
ONE/lib/liblib.a: LIB/bin/liblib.a
    @echo Copying $< to $@
    @mkdir ONE\\lib 2> NUL || :)
    @copy $(subst /,\,$<) ONE\\lib\\ 1> NUL

TWO/lib/liblib.a: LIB/bin/liblib.a
    @echo Copying $< to $@
    @mkdir TWO\\lib 2> NUL || :)
# Windows-equivalent of touch (discarding any output to stdout):
    @copy $(subst /,\,$<) TWO\\lib\\ 1> NUL
# ------------------------------------------------------------
LIB/bin/liblib.a: $(LIB_HEADERS) $(wildcard LIB/src/*.cpp)
    @echo ---------- Looking for changes to liblib ----------
    @cd LIB && gmake.exe LIB
    @copy /b $(subst /,\,$@) +,, 1> NUL || :)
# ------------------------------------------------------------
ONE: ONE/lib/liblib.a $(subst LIB/src/,ONE/include/,$(LIB_HEADERS))
    @echo ---------- Compiling ONE ----------
    @cd ONE && gmake.exe

TWO: TWO/lib/liblib.a $(subst LIB/src/,TWO/include/,$(LIB_HEADERS))
    @echo ---------- Compiling TWO ----------
    @cd TWO && gmake.exe
# ------------------------------------------------------------
CLEAN LINT:
    @cd ONE && gmake.exe $@
    @cd TWO && gmake.exe $@
    @cd LIB && gmake.exe $@

I very much welcome tips on how to generalize ONE and TWO further. 我非常欢迎有关如何进一步概括一和二的技巧。

For question 1 : Maybe you need to move the LIB_HEADERS definition up and change the rule to 对于问题1:也许您需要向上移动LIB_HEADERS定义并将规则更改为
%.a %.h: $(LIB_HEADERS) ? %.a%.h:$(LIB_HEADERS)吗?

I'm sorry to have to tell you this, but your build system is a monstrosity. 很抱歉不得不告诉您这一点,但是您的构建系统是一个怪物。 You are attempting to do sophisticated dependency handling by means of extravagant use of recursive Make; 您正试图通过大量使用递归Make来进行复杂的依赖关系处理; recursive Make has its uses, but one of its drawbacks is that it defeats Make's native ability to handle dependencies. 递归Make有其用途,但其缺点之一是它使Make的固有能力无法处理依赖项。 There are other problems that indicate that the author of this system didn't really understand how Make works, or what a good makefile should look like. 还有其他问题表明该系统的作者并没有真正理解Make的工作原理或良好的makefile的外观。

The reason Make doesn't run this %.a %.h: rule when you change a header file in LIB/src/ is that this rule has no dependencies, and nothing in this makefile depends on a header file that doesn't exist. 当您在LIB/src/更改头文件时,Make不运行此%.a %.h:规则的原因是该规则没有依赖性,并且该makefile中的任何内容都不依赖于不存在的头文件。 If that makes no sense to you, then you don't understand how Make rules work. 如果这对您没有意义,则您不了解Make规则的工作原理。

These rules: 这些规则:

ONE: ONE/lib/libLIB.a $(subst LIB/src/,ONE/include/,$(LIB_HEADERS))
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

TWO: TWO/lib/libLIB.a $(subst LIB/src/,TWO/include/,$(LIB_HEADERS))
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

can be combined into one rule: 可以组合为一个规则:

ONE TWO: % : %/lib/libLIB.a $(addprefix %/include/,$(notdir $(LIB_HEADERS)))
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

But don't do this. 但是不要这样做。 Instead, eliminate ONE/include/ and TWO/include/ , since they bring nothing but headaches. 相反,请消除ONE/include/TWO/include/ ,因为它们只会带来麻烦。 Then the rule here can be 那么这里的规则可以是

ONE TWO: % : %/lib/libLIB.a $(LIB_HEADERS)
    @echo ---------- Compiling $@ ----------
    @cd $@ && gmake.exe

and the makefiles in ONE/ and TWO/ can refer to LIB/src/ . ONE/TWO/的makefile可以参考LIB/src/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM