Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing target name to a dependency in makefile

If I have the following rule in a makefile:

$(OBJ)/%.o: $(SRC)/%.c
    $(CC) -c -o $@ $< $(CFLAGS)

Every file matching the prefix ./obj/ and sufix .o will have its stem passed to %, so I can provide some dependencies based on its name.

But, suppose I have this kind of rule, which I specify one by one the targets I want:

OBJECTS=abc.o bca.o cba.o
$(OBJECTS): $(SRC)/%.c
    $(CC) -c -o $@ $< $(CFLAGS)

How do I make the % stem actually work for the current target name make is executing? Just using % doesn't work, neither $@.

Note that I'm trying to write the actual target name to its own dependency. For example, when make is executing the rule for abc.o, it would include $(SRC)/abc.c and just it (something like $(patsubst %.o, $(SRC)/%.c, MAGIC_TARGET_NAME_VARIABLE)).

like image 423
Toribio Avatar asked Jan 29 '13 00:01

Toribio


People also ask

What is the target in makefile?

A simple makefile consists of “rules” with the following shape: target … : prerequisites … recipe … … A target is usually the name of a file that is generated by a program; examples of targets are executable or object files.

What is a dependency in a makefile?

A dependency is a file that is used as input to create the target. A target often depends on several files. A command is an action that make carries out. A rule may have more than one command, each on its own line.

What does colon mean in makefile?

In the first line, the list of target names is terminated by a colon. This, in turn, is followed by the dependency list, if there is one. If several targets are listed, this indicates that each such target is to be built independently using the rule supplied.

What is prerequisite in makefile?

The prerequisites or dependents are those files that must exist before the target can be successfully created. And the commands are those shell commands that will create the target from the prerequisites.


2 Answers

You can just replace this rule:

$(OBJECTS): $(SRC)/%.c

with:

$(OBJECTS) : %.o : $(SRC)/%.c

You will need to add the $(OBJ) to the -o part of the recipe if you still want them built there:

$(OBJECTS) : %.o : $(SRC)/%.c
     $(CC) -c -o $(OBJ)/$@ $< $(CFLAGS)
like image 167
Carl Norum Avatar answered Sep 30 '22 04:09

Carl Norum


I’m not completely clear on what you’re asking, but I think this accomplishes what you’re trying to do:

OBJECTS=abc.o bca.o cba.o

.PHONY: all
all: $(OBJECTS:%=obj/%)

$(OBJ)/%.o: $(SRC)/%.c
    echo $(CC) -c -o $@ $< $(CFLAGS)

All .o files are built; each .o file is built using only the .c file corresponding to it; and if you want to refer to the list of all object files or source files in the command for compiling a .o file, then you can reference ${OBJECTS} directly.


If this isn’t what you’re trying to do, you’ll be able to get a better answer by listing the input files you have, the output files you want to make, the input dependencies of each output file, and what compilation command you want to execute for each output file.

like image 44
andrewdotn Avatar answered Sep 30 '22 06:09

andrewdotn