Why does a 2-stage command-line build with clang n

2020-02-10 13:10发布

问题:

I have a simple project I want to debug want to produce dSYM folder with debugging symbols.

Running:

clang++ -std=c++14 -stdlib=libc++ -g -o Lazy Lazy.cpp

Creates Lazy.dSYM as I expect.

However:

clang++ -std=c++14 -stdlib=libc++ -g -c Lazy.cpp
clang++ -stdlib=libc++ -g -o Lazy Lazy.o

Does not create Lazy.dSYM (It seems that the symbols are embedded in the binary).

Sadly the 2-step build is what my modified makefile does. How can I generate Lazy.dSYM from a 2-stage compile-and-link build?

I don't need a dSYM directory, just debugging symbols, but would like to understand when and why it is created.

回答1:

The creation of the .dSYM bundle is done by a tool called dsymutil. When Apple added support for DWARF debugging information, they decided to separate "executable linking" from "debug information linking". As such, the debug information linking is not done by the normal linker, it's done by dsymutil.

As a convenience, when you build a program all in one step, the compiler invokes dsymutil on your behalf. That's because it knows it has all of the inputs. If you add the -v (a.k.a. --verbose) option to the compile command, you will see the invocation of dsymutil as the last step it does.

In other cases, though, it doesn't do that. It leaves the debug information linking step for the user to do manually. You can do it by simply issuing the command:

dsymutil <your_program>

Here's an article by an Apple engineer who helped design and implement Apple's support for DWARF explaining their thinking. He also answered a question here on Stack Overflow about this stuff.