سؤال

I am doing a c++ project with multiple source files and trying to get used to using makefiles. I want to be able to debug this program with gdb. If I use the following command in Terminal to compile, it works fine:

g++ -o main -g *.cpp

But if I just call make it doesn't generate a debug file (the .dSYM file) even though it compiles the program fine. I assume this has something to do with creating the individual object files first. Here is my makefile:

all: main.o sort.o bubble.o quickSort.o rbs.o
    g++ -g -o main *.o -Wall -O2
main.o: main.cpp
    g++ -c main.cpp
sort.o: sort.cpp sort.h
    g++ -c sort.cpp
bubble.o: bubble.cpp bubble.h
    g++ -c bubble.cpp
quickSort.o: quickSort.cpp quickSort.h
    g++ -c quickSort.cpp
rbs.o: rbs.cpp rbs.h
    g++ -c rbs.cpp
clean:
    rm *.o

How do I create the main.dSYM debug file when using a makefile like this?

هل كانت مفيدة؟

المحلول

If you want the debug files, you must compile all of the components with -g.

The crude way to do this would be to add -g to every object rule:

all: main.o sort.o bubble.o quickSort.o rbs.o
    g++ -g -o main *.o -Wall -O2
main.o: main.cpp
    g++ -c -g main.cpp
sort.o: sort.cpp sort.h
    g++ -c -g sort.cpp
bubble.o: bubble.cpp bubble.h
    g++ -c -g bubble.cpp
quickSort.o: quickSort.cpp quickSort.h
    g++ -c -g quickSort.cpp
rbs.o: rbs.cpp rbs.h
    g++ -c -g rbs.cpp

But that doesn't leave you the option of building without debug information. And there's a lot of redundancy in this makefile. Let's take this in stages. First, we put in automatic variables to simplify the rules:

all: main.o sort.o bubble.o quickSort.o rbs.o
    g++ -g -o main $^ -Wall -O2
main.o: main.cpp
    g++ -c -g $<
sort.o: sort.cpp sort.h
    g++ -c -g $<
bubble.o: bubble.cpp bubble.h
    g++ -c -g $<
quickSort.o: quickSort.cpp quickSort.h
    g++ -c -g $<
rbs.o: rbs.cpp rbs.h
    g++ -c -g $<

Now we see that all of the *.o rules have the same command, which reminds us that Make already knows how to build foo.o from foo.cpp, with a command that looks like:

$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c

So all we have to do is add -g to CXXFLAGS, and we can omit the commands entirely:

CXXFLAGS += -g
all: main.o sort.o bubble.o quickSort.o rbs.o
    g++ -g -o main $^ -Wall -O2
sort.o: sort.h
bubble.o: bubble.h
quickSort.o: quickSort.h
rbs.o: rbs.h

Now that that's in order, we can set up two top-level targets, main and debug, and change CXXFLAGS only for the latter:

debug: CXXFLAGS += -g
main debug: main.o sort.o bubble.o quickSort.o rbs.o
    g++ -g -o $@ $^ -Wall -O2
sort.o: sort.h
bubble.o: bubble.h
quickSort.o: quickSort.h
rbs.o: rbs.h

You can improve this even more, but that should get you started.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top