Makefile在另一个目录中编译库,如果它不';t不存在或目录已被修改
嗨,我有一个makefile,它编译我的库,然后编译程序。我想做的是,makefile重新编译总是修改我的库文件,因为我在本文中考虑到了这一点Makefile在另一个目录中编译库,如果它不';t不存在或目录已被修改,makefile,directory,shared-libraries,Makefile,Directory,Shared Libraries,嗨,我有一个makefile,它编译我的库,然后编译程序。我想做的是,makefile重新编译总是修改我的库文件,因为我在本文中考虑到了这一点 ifneq ("$(wildcard $(PATH_LIB.A)","") FILE_EXIST = 1 else FILE_EXIST = 0 endif $(MAIN_PROCESS): $(PATH_LIB.A) check_lib ...thing to do... $(PATH_LIB.a): FILE_EXIST = 0 check_l
ifneq ("$(wildcard $(PATH_LIB.A)","")
FILE_EXIST = 1
else
FILE_EXIST = 0
endif
$(MAIN_PROCESS): $(PATH_LIB.A) check_lib
...thing to do...
$(PATH_LIB.a):
FILE_EXIST = 0
check_lib:
ifeq("$(FILE_EXIST)","0")
$(MAKE) -C $(PATH_MAKEFILE_LIB.A)
endif
我的问题是,当我编译它时,它会一直重新链接“…thins to do…”,因为正在将所有时间的check_lib检查为可更新,您建议我做什么?Make不是bash或python之类的脚本语言。它需要的是对目标和先决条件之间的相互依赖关系的描述,以及构建它们的方法。在您的情况下(但我不确定我是否了解所有细节),您可以尝试:
$(MAIN_PROCESS): $(PATH_LIB.A)
...thing to do...
$(PATH_LIB.A):
$(MAKE) -C $(PATH_MAKEFILE_LIB.A)
仅此而已(但继续阅读,还有更多需要理解)。这告诉我们:
$(主进程)
取决于$(路径库A)
,如果它不存在或比$(路径库A)
旧,还需要做些什么来构建$(主进程)
$(PATH_LIB.A)
不依赖于任何东西,以及如果它不存在该怎么办$(PATH_LIB.A)
已经存在,但已经过期(相对于它自己的源文件),它将不会被重建。一种解决方法是将其声明为虚假:
这样make将始终尝试重建它,即使它已经存在。如果需要,sub make会这样做,否则它只会告诉您它是最新的。但这并不是全部的故事:因为make总是试图重建<代码> $(PATHOLIB。A),它会考虑<代码> $(MIN进程)< /C>也必须重建,即使子make没有做任何事情,因为<代码> $(PATHOLIB .A)< /C> >是最新的。
如果这是一个问题,可以使用更棘手的解决方案,如使用一个或多个子品牌。其思路如下:
$(主进程)
目标创建两个不同的调用上下文,并使用两个不同的规则$(主进程)
依赖于虚假的$(路径库A)
,但是它的配方,而不是…要做的事情…
是另一个上下文中对make的第二次调用$(主进程)
依赖于非虚假的$(路径库A)
,并将有其正常的配方SECONDPASS
,在下面的代码中),这两个上下文得以区分
例如:
host> cat lib/Makefile
foo.a: foo.c
touch $@
host> cat Makefile
ifeq ($(SECONDPASS),)
$(MAIN_PROCESS): $(PATH_LIB.A)
$(MAKE) SECONDPASS=1
.PHONY: $(PATH_LIB.A)
$(PATH_LIB.A):
$(MAKE) -C $(dir $@)
else
$(MAIN_PROCESS): $(PATH_LIB.A)
touch $@
endif
host> make --no-print-directory
make -C lib/
touch foo.a
make SECONDPASS=1
touch bar
host> make --no-print-directory
make[1]: 'foo.a' is up to date.
make SECONDPASS=1
make[1]: 'bar' is up to date.
host> touch lib/foo.c
host> make --no-print-directory
make -C lib/
touch foo.a
make SECONDPASS=1
touch bar
host> touch lib/foo.a
host> make --no-print-directory
make -C lib/
make[1]: 'foo.a' is up to date.
make SECONDPASS=1
touch bar
嗯,我明白你的意思,但例如,如果我的
lib.a
有一个名为foo.c
的文件,并且我修改foo.c
(在lib.a目录中),当我要做的时候,它将检查$(主进程)
和$(路径库a)
,并且它们将匹配,尽管lib.a
应该更新。也许我应该检查库目录中的所有文件?但是,在这种情况下,我是否必须为我的库使用的每个函数创建另一个宏?@JaumeGarciaSanchez:不,因为它是假的,make将始终尝试重建$(PATH_lib.A)
。要做到这一点,它将启动子make,负责$(PATH_LIB.A)
的源文件。请注意,我忘了提到这种方法的一个缺点:$(主进程)
也将始终重建,即使sub make最终决定$(PATH\u LIB.a)
是最新的。这是一个问题吗?哦,看起来像是.PHONY
的东西还不够,但直到现在我一直在Makefile的最顶端使用.PHONY
之类的东西,但没有正常工作,当我看到你的例子时,我试着在规则之前编写。PHONY:$(PATH_LIB.a)
,这很有效。现在我意识到,在声明之前,我说过要将Makefile转换成假的$(PATH_LIB.A),这可能是因为它不起作用。非常感谢你。我用了这个棘手的部分来解决问题。如果你把它贴出来,我会打勾表示正确。非常感谢。
host> cat lib/Makefile
foo.a: foo.c
touch $@
host> cat Makefile
ifeq ($(SECONDPASS),)
$(MAIN_PROCESS): $(PATH_LIB.A)
$(MAKE) SECONDPASS=1
.PHONY: $(PATH_LIB.A)
$(PATH_LIB.A):
$(MAKE) -C $(dir $@)
else
$(MAIN_PROCESS): $(PATH_LIB.A)
touch $@
endif
host> make --no-print-directory
make -C lib/
touch foo.a
make SECONDPASS=1
touch bar
host> make --no-print-directory
make[1]: 'foo.a' is up to date.
make SECONDPASS=1
make[1]: 'bar' is up to date.
host> touch lib/foo.c
host> make --no-print-directory
make -C lib/
touch foo.a
make SECONDPASS=1
touch bar
host> touch lib/foo.a
host> make --no-print-directory
make -C lib/
make[1]: 'foo.a' is up to date.
make SECONDPASS=1
touch bar