Make:避免在多个 Makefile 中具有相同目标的问题
Make: Avoiding issues from having same targets in multiple Makefiles
我需要知道处理这个问题的最佳方法。您也可以回答这个问题——在阅读下面的示例之后——:查看 package.make
中的 makelib
目标并告诉我是否有办法强制将其视为未更新,如果配方( make -C ../lib/ -f lib.make) 报告什么都不做(不使用有序的先决条件)?
我需要用一个例子来解释这一点。我继承了这一点,我需要最好的方法来做到这一点。
其他目标将依赖的目标:
File lib.make
--------------
.DEFAULT_GOAL = thelib.dll
%.dll: file1.obj file2.obj
makelib file1.obj file2.obj -o thelib.dll
这本身就很扎实。你 运行 它一次 (make -f lib.make
) 并且它创建了库。如果你随后 运行 它没有修改过的文件,那么它会告诉你它无关紧要。
现在我们将在其他地方以特殊方式使用它:
File: package.make
------------------
.DEFAULT_GOAL: all
all: package
makelib:
@make -C ../lib/ -f lib.make
package: makelib file3 file4
@package_files file3 file4 ../lib/out/*.dll -o package
这就是 lib.make
在 package.make
中的引用方式。
问题是,即使在您调用 make -f package.make all
时创建了包,make 也会假设 package
目标每次都需要重建,因为它的依赖项之一 -- makelib
- - 必须重新制作
Make 认为 makelib
已过时,尽管输入 lib.make
后发生了什么。
为了纠正这个问题,我想到了几个选择:
将 makelib
移动到订购的先决条件(在 |
之后)但这不太正确,因为如果是新建库,我的包将不会更新
第二次将 dll (thelib.dll
) 添加为 makelib
目标的依赖项,但这几乎会重复逻辑并破坏封装。
删除 makelib
目标并将行 @make -C ../lib/ -f lib.make
移动到 package
配方中。这有一个问题,那就是我已经删除了包和库之间的依赖关系。如果 lib 需要更新,包不会知道它也不会得到更新。
使用 include lib.make
,然后将 package
规则重写为:package: thelib.dll file3 file4
。这也有问题,其中最少的是要包含一个 make 文件,它必须这样写。否则会引入很多overwriting/conflicting目标和定义。
除了直接将 dll 列为依赖项之外,还有其他建议吗?
主要有两种工作方式:
首先,如果您使用递归 make(请记住始终使用 $(MAKE)
调用子 make,切勿直接 make
),那么您应该使父 makefile 中的目标成为实际目标子make生成的文件:
package: lib/thelib.dll ...
...
lib/thelib.dll: FORCE
$(MAKE) -f lib
FORCE:
其次,您可以使用非递归 make,这意味着您将子 makefile 包含到父 make 中并按照它的预期编写。您可以使用变量等技巧来使其更通用,因此如果需要,可以从父目录或子目录调用它。
我需要知道处理这个问题的最佳方法。您也可以回答这个问题——在阅读下面的示例之后——:查看 package.make
中的 makelib
目标并告诉我是否有办法强制将其视为未更新,如果配方( make -C ../lib/ -f lib.make) 报告什么都不做(不使用有序的先决条件)?
我需要用一个例子来解释这一点。我继承了这一点,我需要最好的方法来做到这一点。
其他目标将依赖的目标:
File lib.make
--------------
.DEFAULT_GOAL = thelib.dll
%.dll: file1.obj file2.obj
makelib file1.obj file2.obj -o thelib.dll
这本身就很扎实。你 运行 它一次 (make -f lib.make
) 并且它创建了库。如果你随后 运行 它没有修改过的文件,那么它会告诉你它无关紧要。
现在我们将在其他地方以特殊方式使用它:
File: package.make
------------------
.DEFAULT_GOAL: all
all: package
makelib:
@make -C ../lib/ -f lib.make
package: makelib file3 file4
@package_files file3 file4 ../lib/out/*.dll -o package
这就是 lib.make
在 package.make
中的引用方式。
问题是,即使在您调用 make -f package.make all
时创建了包,make 也会假设 package
目标每次都需要重建,因为它的依赖项之一 -- makelib
- - 必须重新制作
Make 认为 makelib
已过时,尽管输入 lib.make
后发生了什么。
为了纠正这个问题,我想到了几个选择:
将
makelib
移动到订购的先决条件(在|
之后)但这不太正确,因为如果是新建库,我的包将不会更新第二次将 dll (
thelib.dll
) 添加为makelib
目标的依赖项,但这几乎会重复逻辑并破坏封装。删除
makelib
目标并将行@make -C ../lib/ -f lib.make
移动到package
配方中。这有一个问题,那就是我已经删除了包和库之间的依赖关系。如果 lib 需要更新,包不会知道它也不会得到更新。使用
include lib.make
,然后将package
规则重写为:package: thelib.dll file3 file4
。这也有问题,其中最少的是要包含一个 make 文件,它必须这样写。否则会引入很多overwriting/conflicting目标和定义。
除了直接将 dll 列为依赖项之外,还有其他建议吗?
主要有两种工作方式:
首先,如果您使用递归 make(请记住始终使用 $(MAKE)
调用子 make,切勿直接 make
),那么您应该使父 makefile 中的目标成为实际目标子make生成的文件:
package: lib/thelib.dll ...
...
lib/thelib.dll: FORCE
$(MAKE) -f lib
FORCE:
其次,您可以使用非递归 make,这意味着您将子 makefile 包含到父 make 中并按照它的预期编写。您可以使用变量等技巧来使其更通用,因此如果需要,可以从父目录或子目录调用它。