I am working my way through a make tutorial. Very simple test projects I am trying to build has only 3 files: ./src/main.cpp ./src/implementation.cpp and
My answer (a neat solution): add
LDLIBS = -lstdc++
to the Makefile. According to the manual:
Libraries (
-lfoo
) should be added to theLDLIBS
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.
I just tried and found that this compiler does not work for LDFLAGS = -lstdc++
:
but the following compilers accept LDFLAGS = -lstdc++
:
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.
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.