问题
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:
$(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).$(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:
- Use make conditionals to create two different contexts of invocation with two different rules for your
$(MAIN_PROCESS)target. - 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. - 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