|
From: | Maxim Yegorushkin |
Subject: | Re: Request for review of failing makefile |
Date: | Thu, 17 Dec 2009 22:33:20 +0000 |
User-agent: | Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.4pre) Gecko/20090922 Fedora/3.0-3.9.b4.fc12 Thunderbird/3.0b4 |
On 17/12/09 16:06, David Aldrich wrote:
Hi I have a problem with my makefile and would appreciate a peer review please. The makefile builds an .exe file from C++ source code and a static library. The static library has its own separate makefile. I find that if I touch a source file component of the static library and then execute the makefile below, the source file is compiled and the library is rebuilt, but the executable is not rebuilt. Running the same makefile a second time rebuilds the executable. Here's the code: ================================================================ TRUNKDIR := .. EXEFILE := myapp include $(TRUNKDIR)/MakeVars.mk # Include the kernel and other static libraries as required STATIC_LIBS := $(TRUNKDIR)/Kernel .PHONY : release release : $(OBJDIR_R)/$(EXEFILE) # Generate the list of archives to be linked from the library paths specified in STATIC_LIBS ARCHIVES_R = $(patsubst %,%/$(OBJDIR_R)/lib.a,$(STATIC_LIBS)) # Perform link (release mode) $(OBJDIR_R)/$(EXEFILE) : $(ARCHIVES_R) $(CXX) -o $(OBJDIR_R)/$(EXEFILE) -ldl -Wl,-whole-archive,-export-dynamic $(ARCHIVES_R) $(EXTRA_LIBS_R) -Wl,--no-whole-archive $(ARCHIVES_R) : $(STATIC_LIBS) .PHONY : $(STATIC_LIBS) $(STATIC_LIBS) : @$(MAKE) --quiet --directory=$@ $(MAKECMDGOALS) ================================================================
The above says that $(ARCHIVES_R) depend on a phony target $(STATIC_LIBS). What it does not say is how to update $(ARCHIVES_R), so that make considers $(ARCHIVES_R) to be always up-to-date, although its phony dependency always gets rebuild.
You can quickly check if my hypothesis is correct by adding an empty command to $(ARCHIVES_R), e.g.
$(ARCHIVES_R) : $(STATIC_LIBS) @echo "updated $@"Although this won't solve the problem since now make considers that $(ARCHIVES_R) is always gets rebuild, triggering relinking $(OBJDIR_R)/$(EXEFILE) all the time.
The real problem is that the dependencies of $(ARCHIVES_R) are unknown, so that make can not know whether $(ARCHIVES_R) needs to be rebuild. This is a well-known problem with recursive makefiles that the dependency graph is incomplete.
A (classical) fix, without abandoning the recursive model, is to execute $(ARCHIVES_R) makefile first and then the makefile which builds $(OBJDIR_R)/$(EXEFILE).
$ make --directory=$(STATIC_LIBS) && make -- Max
[Prev in Thread] | Current Thread | [Next in Thread] |