Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understanding Makefile with .c=.o and $<

Tags:

c

makefile

This is my first Makefile, and I can't figure out some of the syntax used. The questions are marked below:

C := gcc

CFLAGS := -Wall -Werror -std=

PROG := program_1\
    program_2\
    program_3

SRCS := program_1.c \
    program_2.c \
    program_3.c

OBJS := ${SRCS:.c=.o} 

all: ${OBJS}
  ${CC} ${OBJS} -o ${PROG}

clean:
    rm -f ${PROG} ${OBJS}


.c.o:
    ${CC} ${CFLAGS} -c $<
  1. What does .c=.o mean? in OBJS := ${SRCS:.c=.o}

  2. Not sure what $< means here, and .c.o?

    .c.o: ${CC} ${CFLAGS} -c $<

like image 876
user3630406 Avatar asked Oct 01 '14 02:10

user3630406


People also ask

What does %O %c mean in makefile?

The simple answer is that %.o is a target that matches any file ending in .o. "%.o: %. c" means that any file ending in .o depends on the same filename ending in . c to be present.

What is CC in a makefile?

Here's a quick and dirty intro : Files. All you need is a file called "makefile" or "Makefile". Comments Pound signs ("#") are comments to end of line. Variables CC = gcc. means that the variable CC contains "gcc".

What is $$ in makefile?

Double dollar sign If you want a string to have a dollar sign, you can use $$ . This is how to use a shell variable in bash or sh . Note the differences between Makefile variables and Shell variables in this next example.

Does order of targets matter in makefile?

The order of rules is not significant, except for determining the default goal: the target for make to consider, if you do not otherwise specify one. The default goal is the target of the first rule in the first makefile. If the first rule has multiple targets, only the first target is taken as the default.


2 Answers

First of all, your Makefile has a bug, it does not make the intended targets. Did you try it?

Second, it is not well written; not following best current practices.

So I will first show you the better version of your Makefile, both correct, as well as written with the best practices:

CFLAGS := -Wall -Werror -std=

SRCS := program_1.c \
    program_2.c \
    program_3.c

OBJS := ${SRCS:c=o} 
PROGS := ${SRCS:.c=}

.PHONY: all
all: ${PROGS}

${PROGS} : % : %.o Makefile
    ${CC} $< -o $@

clean:
    rm -f ${PROGS} ${OBJS}

%.o: %.c Makefile
    ${CC} ${CFLAGS} -c $<

Now, the answers to your questions are:

${SRCS:.c=.o} means, take the variable value ${SRCS}, which is a string composed of words separated by spaces, and for each word, replace the suffix .c with .o . I dropped . in my code because it is not needed and it is common to replace only suffixes after the dot.

This syntax is similar to bash string suffix replacement (for one word) if you are familiar with that.

$< when used in the "recipe", means "the first prerequisite" - the first thing after the : in the line above.

and the last question is no longer relevant: .o.c syntax is obsolete and not recommended currently.

Please take a look at my "10 Commandments" - my answer at this post:

makefile enforce library dependency ordering

, they will give you an idea about the best practices. Then you can also read up in the GNU Make manual, about the terms above in quotes, that I did not explain here.

like image 81
Mark Galeck Avatar answered Nov 15 '22 22:11

Mark Galeck


You didn't specify exactly which variant of make you're using -- there are many. I'm going to assume you are using GNU make, the most widely used variant.

In GNU make, $(SRCS:.c=.o) is a substitution reference, and it means "the value of the SRCS variable, where .c is replaced by .o when it appears at the end of a word." In your example, SRCS has the value program_1.c program_2.c program_3.c, so $(SRCS:.c=.o) means program_1.o program_2.o program_3.o.

The .c.o is an example of what's known an old-fashioned suffix rule. It tells GNU make "here's how to build a .o file from a .c file with the same name." The modern equivalent is a pattern rule which would look the same except to use %.o: %.c in place of .c.o.

Finally, $< is an automatic variable which means "the name of the first prerequisite".

like image 34
Eric Melski Avatar answered Nov 15 '22 21:11

Eric Melski