Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile, Pattern-Rules and Directories

Tags:

makefile

I want to write a (gmake) makefile for a compiler that - unlike gcc - puts all output files into a specific directory. Unfortunately this behavior cannot be changed.

My sources are in multiple directories. How do I write a pattern-rule that lets me compile the sources.

Okay, that's a bit unclear. Here is an example. My sources look may like this:

./folder1/foo.c
./folder2/bar.c

and the output files will end up like this:

./obj/foo.obj
./obj/bar.obj

How should my rule to compile my sources look like?

%.obj : %.c 
   $(COMPILER) -c $< 

will not work.

Any ideas? I'd like to avoid an implicit rule for each source file...

like image 395
Nils Pipenbrinck Avatar asked Dec 26 '09 16:12

Nils Pipenbrinck


People also ask

What is pattern rule in makefile?

A pattern rule looks like an ordinary rule, except that its target contains the character ' % ' (exactly one of them). The target is considered a pattern for matching file names; the ' % ' can match any nonempty substring, while other characters match only themselves.

What does $() mean in makefile?

The $@ and $< are called automatic variables. The variable $@ represents the name of the target and $< represents the first prerequisite required to create the output file.

What is Vpath in makefile?

The value of the make variable VPATH specifies a list of directories that make should search. Most often, the directories are expected to contain prerequisite files that are not in the current directory; however, make uses VPATH as a search list for both prerequisites and targets of rules.

What is implicit rules in makefile?

Implicit rules tell make how to use customary techniques so that you do not have to specify them in detail when you want to use them. For example, there is an implicit rule for C compilation. File names determine which implicit rules are run.


1 Answers

Extracted from some Makefile of mine:

OBJS := $(sort $(patsubst %.cpp,$(OBJECT_DIRECTORY)/%.o,$(patsubst %.c,$(OBJECT_DIRECTORY)/%.o,$(notdir $(SRCS)))))

Where OBJECT_DIRECTORY points to the object directory and SRCS is the list of source files (which you can even populate using $(wildcard)).

Then in the Makefile, I have:

define define_compile_rules
$(OBJECT_DIRECTORY)/%.o: $(1)%.c
  @echo " + Compiling '$$<'"
  @mkdir -p $$(@D)
  $(CC) $$(CFLAGS) -o $$@ -c $$<
endef

$(foreach directory,$(sort $(dir $(SRCS))),$(eval $(call define_compile_rules,$(directory))))

See the $(eval) function.

like image 70
Gregory Pakosz Avatar answered Sep 18 '22 18:09

Gregory Pakosz