1
votes

I've been having some trouble figuring out why my Makefile has not been recompiling some C object files even right after I edit header files which are prerequisites of those object files.

I suspect I do not understand how the case of multiple matching targets is handled. For example, I can think of three rough cases, in increasing order of complexity, where this confusion would arise.

Case 1: Trivial

.PHONY: blah

blah:
    [code to do something]

blah:
    [code to do something else]

Case 2: One target rule is more specific than another

a.out: source.o

source.o: source.c
    [commands to build source.o]

%.o: %.c
    [something else entirely]

# And does the order of these prerequisites matter?

Case 3: An included Makefile has a redundant target name

Now, this is the problem that I am running into currently. My Makefile is including automatically generated Makefiles each holding prerequisites for object files. Specifically, it has the following structure:

DEPS = [list of prerequisite Makefiles to be auto-generated]
OBJS = [all the object files from other source files besides a.c]

a.out: a.o $(DEPS) $(OBJS)
    [compile the .out from the .o files]

$(BUILD_DIR)/%.d: $(SRC_DIR)/%.c
    [build the .d Makefile using gcc -MM]

$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c
    [compile the target]

include $(DEPS)

Here, each of DEPS has a single target of the form $(BUILD_DIR)/%.o. Thus, this target is redundant to the one for object files above, though the target in the .d file may have additional prerequisites besides $(SRC_DIR)/%.c.

What is Make's policy for selecting targets to process? And would this explain why my object files for a.out are not being compiled, even when I have just written to a header file which is a prerequisite of an object file (in one of the included Makefiles), and this object file is a prerequisite of a.out?

1
Does this answer your question? - Renaud Pacalet
The problem is most likely that you don't have multiple matching targets and so your prerequisites are not correct. However, all the info we'd need to determine that is hidden behind variables in your question. Without knowing the structure of the DEPS file and the contents of the OBJS variable there's nothing we can really say to help you solve your problem. For help with auto-generating prerequisites you might also want to check out make.mad-scientist.net/papers/… - MadScientist
Yes, Renaud that answers it. And you were right, MadScientist. - MattS

1 Answers

0
votes

After some debugging, I discovered the issue was slightly silly in that I was not generating the correct dependency files (the targets had no prefix $(BUILD_DIR) on the file path). But, I also figured out the original question.

  1. Per Renaud's link on multiple rules for one target, if one target is specified in multiple rules, then Make takes the union of all prerequisites for all rules specifying that target, and uses that as the prerequisite. Then, the last recipe specified is selected (with a warning message) and executed.
  2. If one target rule is an implicit/pattern rule as in the question, then the regular rule and recipe are given precedence, no matter the order. Explicit gets priority over implicit.
  3. For the include case, the included rules and recipes are treated the same as if they were in the original Makefile. In my case the issue was something else.