Makefile compile a library in another directory when it doesn't exist or the directory has been modify

烂漫一生 提交于 2019-12-11 17:46:53

问题


Hi i have a makefile that compiles my library and then compiles the program. What i want to do is that the makefile recompile alway i modify my library's files for that i thought in this

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

My problem es that when i compile it relinks all time "...thins to do..." because is checking all time check_lib as updateable what do you suggest for do what i want to do?


回答1:


Make is not a scripting language like bash or python. What it needs is a description of inter-dependencies between targets and prerequisites, plus recipes to build them. In your case (but I am not sure I understood all details) you could try:

$(MAIN_PROCESS): $(PATH_LIB.A)
    ...thing to do...

$(PATH_LIB.A):
    $(MAKE) -C $(PATH_MAKEFILE_LIB.A)

And that's all (but continue reading, there is more to understand). This tells make that:

  1. $(MAIN_PROCESS) depends on $(PATH_LIB.A), plus the things to do to build $(MAIN_PROCESS) if it does not exist or if it is older than $(PATH_LIB.A).
  2. $(PATH_LIB.A) depends on nothing, plus what to do if it does not exist.

It almost works. Almost only because if $(PATH_LIB.A) already exists but is out of date (with respect to its own source files) it will not be rebuilt. A solution is to declare it as phony:

.PHONY: $(PATH_LIB.A)

$(MAIN_PROCESS): $(PATH_LIB.A)
    ...thing to do...

$(PATH_LIB.A):
    $(MAKE) -C $(PATH_MAKEFILE_LIB.A)

This way make will always try to rebuild it, even if it already exists. The sub-make will do it if needed, else it will just tell you that it was up to date. But it is not the whole story: as make always tries to rebuild $(PATH_LIB.A), it will consider that $(MAIN_PROCESS) must also be rebuilt, even if the sub-make didn't do anything because $(PATH_LIB.A) was up-to-date.

If this is a problem, more tricky solutions can be used, like using one more sub-make. The idea is the following:

  1. Use make conditionals to create two different contexts of invocation with two different rules for your $(MAIN_PROCESS) target.
  2. On the first invocation of make, the first context is used where $(MAIN_PROCESS) depends on the phony $(PATH_LIB.A) but its recipe, instead of ...thing to do... is a second invocation of make, in the other context.
  3. For this second invocation $(MAIN_PROCESS) depends on the non-phony $(PATH_LIB.A) and will have its normal recipe.

The two contexts are distinguished thanks to a dedicated make variable (SECONDPASS in the code below).

Example:

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


来源:https://stackoverflow.com/questions/51098828/makefile-compile-a-library-in-another-directory-when-it-doesnt-exist-or-the-dir

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!