Reputation: 372
I'm trying to figure out makefiles and already have a little project directory I want to test it on. Sadly I can't seem to satisfy the compiler's needs. g++ warns me I need the -std=c++11
flag which I have and further prints errors to C++11 related features (like threads).
I don't know what I'm doing wrong.
Here are the first lines of error:
make
g++ -c -o Graphics.o Graphics.cpp
In file included from /usr/include/c++/5/thread:35:0,
from Graphics.h:4,
from Graphics.cpp:1:
/usr/include/c++/5/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support \
^
In file included from Graphics.cpp:1:0:
And here the Makefile:
csrc=$(wildcard *.c)
cppsrc=$(wildcard *.cpp)
obj=$(cppsrc:.cpp=.o) $(csrc:.c=.o)
CXXC = g++
#CXXCFLAGS = -std=c++14
EXEC = myprog
LOPENGL = -lGLEW -lGLM
LSFML = -lsfml-graphics -lsfml-window -lsfml-system
LDFLAGS = $(LSFML) $(LOPENGL)
all: $(obj)
$(CXXC) -std=c++11 $^ $(LDFLAGS) -o $(EXEC)
.PHONY: clean
clean:
rm .f $(obj)
I cannot figure it out. Internet is just saying "Well, add the Flag then" when I search the error. I already tried:
switching the flag's position or writing it directly in the line (you can actually see this by the commented CXXCFLAGS
).
using different flags -std=c++11
, -std=gnu++11
, -std=c++14
I also noticed the flag not showing up when the compiler runs (to see in the second line of the errors).
Also if you can point out anything wrong with format, other errors or conventional things please be sure to leave a comment to that I'm eager to improve.
Upvotes: 2
Views: 2238
Reputation: 30831
Konrad's answer explains why your g++
command isn't being executed with your desired argument.
You can use make --print-data-base
to help you understand what rules are built-in to Make. The ones relevant here are
%.o: %.cpp
# recipe to execute (built-in):
$(COMPILE.cpp) $(OUTPUT_OPTION) $<
This is the rule that makes your object files from your *.cpp
source files. Following the definition of COMPILE.cpp
, we find it comes back to
COMPILE.cc = $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c
So we just need to add our option into CXXFLAGS
(not CPPFLAGS
- that's for C preprocessor, and is shared with the C language):
CXXFLAGS += -std=c++14
%: %.cc
# recipe to execute (built-in):
$(LINK.cc) $^ $(LOADLIBES) $(LDLIBS) -o $@
This is the link step that we want to copy as the command to produce the executable from the object files.
A couple of other things to note:
all
target never creates a file called all
, so the link step will happen even if the executable is up to date.-Wall
for the diagnostics you always want.clean
target has misspelt -f
, and doesn't clean object files that no longer have corresponding source files (i.e. when you remove a source).clean
remove editor backup files, too.Here's my improved version of your makefile:
EXEC = myprog
csrc := $(wildcard *.c)
cppsrc := $(wildcard *.cpp)
obj := $(cppsrc:.cpp=.o) $(csrc:.c=.o)
CXX = g++
CXXFLAGS += -std=c++14
CXXFLAGS += -Wall -Wextra
LDLIBS += -lGLEW -lGLM
LDLIBS += -lsfml-graphics -lsfml-window -lsfml-system
all: $(EXEC)
$(EXEC): $(objs)
$(LINK.cc) $(OUTPUT_OPTION) $^ $(LOADLIBES) $(LDLIBS)
clean:
$(RM) *.o *~
.PHONY: all clean
Upvotes: 0
Reputation: 545598
You commented out the relevant line:
#CXXCFLAGS = -std=c++14
Remove the comment to make it work. Furthermore, the variables are misspelled. Their actual names are CXX
and CXXFLAGS
(no trailing/intermittent C
!).
You might also need to specify that you are dealing with C++ files:
%.o: %.cpp
$(CXX) $(CXXFLAGS) -o $@ $<
To explain what’s wrong: the following rule
all: $(obj)
$(CXXC) -std=c++11 $^ $(LDFLAGS) -o $(EXEC)
isn’t compiling the code. Instead, it’s linking the — already compiled — object files (which is what $(obj)
refers to). But to obtain these object files, the source files need to be compiled and make
is using an implicit rule for .o
files for this.
— There are more errors in your Makefile. For instance, the clean
rule should invoke rm -f
instead of rm .f
. You need to be a a lot more meticulous when writing code.
Upvotes: 5