这涉及到我刚才的问题:Why does .PHONY not work in this situation?。我想让我的makefile更独立!
我有我写的很容易让开发商谁不熟悉的牌子,做他们的任务生成文件系统。简而言之,所有项目都有一个通用部分,以及一组特定于特定项目的makefile。具体项目包括通用项目。由于某种原因,它在3.80上运行效果很好,但是当我在3.81上试用它时遇到了一些问题。这迫使我进行上述文章中提到的更改。现在我有一些新问题,所以我决定再发一个帖子。就像在那篇文章中,我做了一个更小更简单的makefile来显示问题。不幸的是,这个“简单”案件由6个文件组成。对于那个很抱歉。首先,我将与 “项目专用” 的人(这些是为了简单)开始:
生成文件:
TARGETS:=\
Lib1.mk \
Lib2.mk \
my_prog.mk \
include generic/top.mk
Lib1.mk:
BINARY:=Lib1
TYPE:=LIB
LOCATION:=a/location
include generic/rules.mk
Lib2.mk:
BINARY:=Lib2
TYPE:=LIB
LOCATION:=another/location
LIBS:=Lib1
include generic/rules.mk
my_prog.mk:
BINARY:=my_prog
TYPE:=EXE
LOCATION:=some/location
LIBS:=Lib1 Lib2
include generic/rules.mk
的简短描述:Makefile中仅列出所有目标的名称。目标是可执行文件或库。 BINARY是库或可执行文件的名称(扩展名由通用部分添加)。 TYPE是EXE或LIB。 LOCATION是二进制文件应该去的地方。 LIBS是这个二进制文件依赖的任何库。真正的可以为用户创建所有的-L,rpath等等东西(以及它们与visual studio的等价物)。现在的通用一(这些做实际工作):
通用/ top.mk:
ALL_BINS:=
.PHONY: all
all:
include $(TARGETS)
all: $(ALL_BINS)
%.so %.exe:
mkdir -p $(dir [email protected])
touch [email protected]
clean:
rm -rf out
终于..
通用/ rules.mk:
ifeq (EXE,$(TYPE))
$(BINARY).FULL_FILE_NAME:=out/$(LOCATION)/$(BINARY).exe
else
$(BINARY).FULL_FILE_NAME:=out/$(LOCATION)/lib$(BINARY).so
endif
$(BINARY).DEP_LIBS:=$(foreach a,$(LIBS),$($(a).FULL_FILE_NAME))
ALL_BINS+=$(BINARY)
$(BINARY): $($(BINARY).FULL_FILE_NAME)
$($(BINARY).FULL_FILE_NAME): $($(BINARY).DEP_LIBS)
BINARY:=
LOCATION:=
LIBS:=
好了,在这种状态下,东西做工精细。正确处理所有的依赖关系,如果我触及任何文件,它将正确地“构建”它所需的那些文件,除此之外别无其他。
TARGETS:=\
my_prog.mk \
Lib1.mk \
Lib2.mk \
这个问题似乎是,虽然它正在经历rules.mk:当你从makefile文件采取m_prog.mk行并将其移动到列表的顶端,像这样的问题发生为my_prog.mk它还不知道什么LIB1和LIB2完整库路径(它们是空字符串)。所以最后,它认为my_prog是不依赖于任何东西的,它会尝试按顺序构建它。在这个例子中,你只看到它的“触摸” my_prog第一,然后其他。当然,当我有真正的编译器和连接器命令在那里,它抛出一个错误。
当我简单地让.PHONY目标互相依赖(所以my_prog依赖于Lib1和Lib2)时,生活变得简单和谐。现在我不能那样做,生活变得更加困难。
你可以说,“heck把它放在正确的顺序!”。到目前为止,这已经通过最终用户自动处理。事实上,大多数客户一直在按字母顺序排列东西。他们不知道或不在乎彼此依赖的顺序。如果现在要告诉他们重新排列所有这些,那就太臭了。对不起,这篇文章的长度。我会很感激任何答案!
这里的问题是,我重用变量BINARY,类型,位置,和在每个目标的makefile LIBS(我再重置他们在rules.mk年底清空包括前下一个客户.mk文件)。因此,如果我要将其改为=而不是:=,那么我认为它会使用该变量的最后一个值集合?如果是这样,那不是理想的结果。事实上,我在上面的例子中试过了,我得到了循环依赖。 – user545226 2011-01-27 15:06:16
我不习惯这种使用make的方法,其中每个makefile基本上都是一个每次包含它时都会扩展的宏,并且包含多次,但它看起来像:makefile设置目标并包含top.mk,其中包括所有提到的在目标中,每个目标设置BINARY/LOCATION/LIBS并包含定义了很多内容的rules.mk。然后在最后定义“全部”目标。无论如何。你确实需要BINARY,TYPE,LOCATION,LIBS立即评估,所以:=对他们有好处。但请注意,ALL_BINS是使用+ =构建的,已使用延迟评估。 – metamatt 2011-01-28 02:03:09