My answer (a neat solution): add
LDLIBS = -lstdc++
to the Makefile. According to the manual:
Libraries (-lfoo
) should be added to the LDLIBS
variable instead.
LDFLAGS
are designed for library directory flags such as -L
. On my Linux (Ubuntu 14.04), LDFLAGS = -lstdc++
produces
cc -lstdc++ main.o -o main
which does not work, while LDLIBS = -lstdc++
produces
cc main.o -lstdc++ -o main
which works. I have no idea why the order matters, but it makes sense according to the roles of the two built-in variables. I do not like to alias CC
to CXX
which seems like hacking, as well as confusing for readers.
LDFLAGS v.s. LDLIBS
I just tried and found that this compiler does not work for LDFLAGS = -lstdc++
:
- GCC 4.8.5 on Ubuntu 14.04
but the following compilers accept LDFLAGS = -lstdc++
:
- Clang 3.4 on Ubuntu 14.04
- GCC 4.7.2 on Debian Wheezy
- Clang 7.3.0 (703.0.31) on OS X
So it works most of the time, but is not guaranteed. If you want your makefile to be more portable, use LDLIBS
which works on all the above environments.
Why not other solutions above?
Hasturkun: having main.o
in the rule
main: main.o implementation.o
does not lead to an error. The main.o
is not necessary, but it will still make.
Simon Richter: the solution remove the need to track the header (which is really great), but OP wants an implicit rule. We can actually get the best of both:
VPATH = src include
CPPFLAGS = -I include -MMD -MP
CXXFLAGS = -g -W -Wall -Werror
LDLIBS = -lstdc++
target = main
lib = implementation.cpp
objects = $(target:=.o) $(lib:.cpp=.o)
$(target): $(objects)
%.o: %.cpp %.d
%.d: ;
-include $(objects:.o=.d)
clean::
$(RM) $(target) $(objects) $(objects:.o=.d)
which does what he did, as well as taking advantage of implicit rules. However, this complete solution should not be here, since it is not what the OP desire: OP just want to know why his Makefile does not work, and why. "Auto-Dependency Generation" is yet another huge topic deserving an entire tutorial (like this one). So I'm sorry, but his answer did not actually answer the question.
Jerome: I used to change LINK.o
from $(CC) $(LDFLAGS) $(TARGET_ARCH)
to $(CXX) $(LDFLAGS) $(TARGET_ARCH)
and it worked, but I prefer editing LDLIBS
since LINK.o
is not documented (and possibly not part of the public API) and not future-proof. I would call that a hack.