Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Makefile seems to ignore flags. Why?

It seems like make is ignoring my cflag options, as the compiler complains that I need to have -std=c++11 as a flag, but that option is included in my makefile.

CC=g++
# Flags for the C compiler
CXX_FLAGS= \
    -Wall \
    -std=c++11 \
    -O2
# Linker Flags
LD_FLAGS= 

# Sources to compile
SOURCES=main.cpp
OBJECTS=$(SOURCES:.cpp=.o)
EXE=HolidayLights.out

all: $(SOURCES) $(EXE)

# Primary build target
$(EXE): $(OBJECTS)
    $(CC) $(LD_FLAGS) $(OBJECTS) -o $@

.o:
    $(CC) -c $(CXX_FLAGS) -o $@ $<

The output of the build commands of this makefile are:

g++     -c -o main.o main.cpp

I don't understand why it's not listing my flags in the output. Also, I know for a fact that it is ignoring -std=c++11 flag as it complains about non-static constant member, and it shouldn't with that flag enabled.

Edit0: Notation change

like image 677
HSchmale Avatar asked Feb 02 '15 04:02

HSchmale


People also ask

How do I enable flags in makefile?

The only way of doing that is to edit the makefile to change the options. There is no convenient way to override the options without modifying the makefile . This is where make flags come into play. Flags in make are just variables containing options that should be passed to the tools used in the compilation process.

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 CFLAGS in makefile?

CFLAGS and CXXFLAGS are either the name of environment variables or of Makefile variables that can be set to specify additional switches to be passed to a compiler in the process of building computer software.


1 Answers

Your .o: rule is not being selected, change it to .cpp.o: instead.

By default (from the GNU make doco):

n.o is made automatically from n.cc, n.cpp, or n.C with a recipe of the form '$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c'

The reason why your rule is not working in the first case is that a single-suffix implicit rule is supposed to be the source type rather than the target type. Hence the rule would be .cpp: (again, from the make doco):

A double-suffix rule is defined by a pair of suffixes: the target suffix and the source suffix. It matches any file whose name ends with the target suffix. The corresponding implicit prerequisite is made by replacing the target suffix with the source suffix in the file name. A two-suffix rule whose target and source suffixes are '.o' and '.c' is equivalent to the pattern rule '%.o : %.c'.

A single-suffix rule is defined by a single suffix, which is the source suffix. It matches any file name, and the corresponding implicit prerequisite name is made by appending the source suffix. A single-suffix rule whose source suffix is '.c' is equivalent to the pattern rule '% : %.c'.

However, read that last sentence carefully. The .cpp: rule is only effective if you want to turn XYZZY.cpp into XYZZY. Since your target is of the form XYZZY.o, it won't be used.

Of course, the other alternative is to not touch the default rules at all, and instead just modify the variables they use:

CXX      = g++
CPPFLAGS = -Wall -std=c++11 -O2
LD_FLAGS =

SOURCES  = main.cpp
OBJECTS  = $(SOURCES:.cpp=.o)
EXE      = HolidayLights.out

all: $(SOURCES) $(EXE)

$(EXE): $(OBJECTS)
    $(CXX) $(LD_FLAGS) $(OBJECTS) -o $@

And, if you want to use implicit rules, you should really use the preferred form, which is the newer pattern rules. They're a lot more powerful than the suffix ones.

like image 123
paxdiablo Avatar answered Oct 22 '22 22:10

paxdiablo