Reputation: 108
On macOS 12.7.5 (Monterey) using gcc to compile *.c: gcc version 13.2.0, with gnu make 3.81, (I prefer command line tools over XCode), when I pass CFLAGS = -g in a makefile I get full debugging symbols inside the executable but no .dSYM directory. In other words, the symbols are not stripped. However, when I type a typical gcc command:
gcc -g filename1.c filename2.c -o filename
directly from the command line, the .dSYM directory is generated. I can debug either image with lldb as lldb knows how to read a .dSYM. The unstripped executable has the symbols but the .dSYM is valuable in its own right. I can obviously build for release without -g, but this means two separate make tasks. How can I configure the makefile to cause the .dSYM to be generated? That's the whole point of make, to avoid having to type a complex multi-file build command. What am I missing re .dSYM?
Here is an example makefile. All of mine follow this pattern.
# make description file to build a family of hashing programs
LANG = -std=c11
GCOBJS = distanceGC.o hashtblGC.o ../GreatCircle/greatcircle.o
FOBJS = ftlhash.o
HOBJS = hashtbl.o argv.o
GCHDRS = hashGC.h ../GreatCircle/greatcircle.h
FHDRS = ftlhash.h
HHDRS = hashtbl.h ftlhash.h
CC = gcc
CFLAGS = -g -Wall
distanceGC : ${GCOBJS}
${CC} ${LANG} ${CFLAGS} -o $@ ${GCOBJS}
${GCOBJS} : ${GCHDRS}
../GreatCircle/greatcircle.o : ../GreatCircle/greatcircle.h
cd /Users/wills/src/c/GreatCircle; make all
ftlhash : ${FOBJS}
${CC} ${LANG} ${CFLAGS} -o $@ ${FOBJS}
${FOBJS} : ${FHDRS}
hashtbl : ${HOBJS}
${CC} ${LANG} ${CFLAGS} -o $@ ${HOBJS}
${HOBJS} : ${HHDRS}
all : ftlhash hashtbl distanceGC
clean :
/bin/rm -f core *.o
cd /Users/wills/src/c/GreatCircle; /bin/rm -f core *.o
/bin/rm /Users/wills/src/c/HASHTABLE/greatcircle.h
/bin/ln -s /Users/wills/src/c/GreatCircle/ greatcircle.h /Users/wills/src/c/HASHTABLE/greatcircle.h
Here are sample build commands to recompile one of those targets:
touch ftlhash.c
make ftlhash
This yields:
gcc -g -c -o ftlhash.o ftlhash.c
gcc -std=c11 -g -o ftlhash ftlhash.o
I'm guessing there is some Apple utility that an XCode build, or a command line invocation uses by defaut, to strip out the symbols and create the .dSYM, which my makefile is not doing. My command line direct invocation of gcc produced:
drwxr-xr-x 3 wills staff 96 Jul 15 15:03 ftlhash.dSYM
UPDATE: Looks like Apple's dsymutil in macOS is that tool. Now to teach make how to use it.
Thank you Jonathan Leffler for back and forth discussion of issue. /usr/bin/dsymutil $@ added to make build targets solves the problem.
For conditional execution you can do:
ifneq (,$(findstring -g, $(CFLAGS)))
/usr/bin/dsymutil $@
endif
But be aware. Only the actual command is preceded with a tab. The ifneq and endif make statements are not commands, so must not have a leading tab.
Upvotes: 1
Views: 175
Reputation: 754790
I've seen this behaviour.
There's an option to Clang (aka gcc
on a Mac):
-dsym-dir <dir>
— Directory to output dSYM's (if any) toYou might be able to use that in your linking command line, but see below.
I've not previously investigated when the .dSYM
directory is not created. Using -g
on the linking command line is one key factor. Without that, the .dSYM
directory is not created. But there is more to it than that. If I link object files (and libraries) only, the .dSYM
directory is not created, even with the -g
flag. If I specify at least one source file on the linking command line (and -g
), then I seem to get the .dSYM
file.
Many makefiles compile the various source files to object files and then link those object files. So, those programs probably do not get a .dSYM
directory created.
Here's a simple shell script to demo the behaviour:
#!/bin/sh
source=cmplx67
clean()
{
rm -fr $source $source.o $source.dSYM
}
set -x
clean
ls -l
clang -o $source $source.c
ls -l
clean
clang -g -o $source $source.c
ls -l
clean
clang -g -c $source.c
clang -g -o $source $source.o
ls -l
clean
clang -g -c $source.c
clang -g -o $source $source.o -dsym-dir $source.dSYM
ls -l
clean
The file cmplx67.c
is a trivial program.
When run, I get output such as:
2024-07-15 16:49:22
+ clean
+ rm -fr cmplx67 cmplx67.o cmplx67.dSYM
+ ls -l
total 24
-rw-r--r-- 1 jonathanleffler staff 478 Jul 15 16:20 cmplx67.c
-rw-r--r-- 1 jonathanleffler staff 333 Jul 15 16:47 demo.sh
-rw-r--r-- 1 jonathanleffler staff 194 Jul 15 16:23 makefile
+ clang -o cmplx67 cmplx67.c
+ ls -l
total 96
-rwxr-xr-x 1 jonathanleffler staff 33496 Jul 15 16:49 cmplx67
-rw-r--r-- 1 jonathanleffler staff 478 Jul 15 16:20 cmplx67.c
-rw-r--r-- 1 jonathanleffler staff 333 Jul 15 16:47 demo.sh
-rw-r--r-- 1 jonathanleffler staff 194 Jul 15 16:23 makefile
+ clean
+ rm -fr cmplx67 cmplx67.o cmplx67.dSYM
+ clang -g -o cmplx67 cmplx67.c
+ ls -l
total 96
-rwxr-xr-x 1 jonathanleffler staff 33832 Jul 15 16:49 cmplx67
-rw-r--r-- 1 jonathanleffler staff 478 Jul 15 16:20 cmplx67.c
drwxr-xr-x 3 jonathanleffler staff 96 Jul 15 16:49 cmplx67.dSYM
-rw-r--r-- 1 jonathanleffler staff 333 Jul 15 16:47 demo.sh
-rw-r--r-- 1 jonathanleffler staff 194 Jul 15 16:23 makefile
+ clean
+ rm -fr cmplx67 cmplx67.o cmplx67.dSYM
+ clang -g -c cmplx67.c
+ clang -g -o cmplx67 cmplx67.o
+ ls -l
total 104
-rwxr-xr-x 1 jonathanleffler staff 33800 Jul 15 16:49 cmplx67
-rw-r--r-- 1 jonathanleffler staff 478 Jul 15 16:20 cmplx67.c
-rw-r--r-- 1 jonathanleffler staff 2968 Jul 15 16:49 cmplx67.o
-rw-r--r-- 1 jonathanleffler staff 333 Jul 15 16:47 demo.sh
-rw-r--r-- 1 jonathanleffler staff 194 Jul 15 16:23 makefile
+ clean
+ rm -fr cmplx67 cmplx67.o cmplx67.dSYM
+ clang -g -c cmplx67.c
+ clang -g -o cmplx67 cmplx67.o -dsym-dir cmplx67.dSYM
clang: warning: argument unused during compilation: '-dsym-dir cmplx67.dSYM' [-Wunused-command-line-argument]
+ ls -l
total 104
-rwxr-xr-x 1 jonathanleffler staff 33800 Jul 15 16:49 cmplx67
-rw-r--r-- 1 jonathanleffler staff 478 Jul 15 16:20 cmplx67.c
-rw-r--r-- 1 jonathanleffler staff 2968 Jul 15 16:49 cmplx67.o
-rw-r--r-- 1 jonathanleffler staff 333 Jul 15 16:47 demo.sh
-rw-r--r-- 1 jonathanleffler staff 194 Jul 15 16:23 makefile
+ clean
+ rm -fr cmplx67 cmplx67.o cmplx67.dSYM
As you can see, the -dsym-dir
option was ignored when the object file was linked. When I compiled and linked the source file with the option, it was used. (I experimented with -dsym-dir=cmplx67.dSYM
and got a directory =cmplx67.dSYM
!)
You can adapt this to make more experiments. What .dSYM
directory is created if there a multiple source files on the command line, for example.
Testing on an M2 MacBook Pro running macOS Sonoma 14.5 and using:
Apple clang version 15.0.0 (clang-1500.3.9.4)
Target: arm64-apple-darwin23.5.0
I've seen this behaviour on many prior versions of macOS, including those predating macOS Monterey 12.7.5. I've used MacOS X and macOS fairly solidly since at least Mac OS X Jaguar 10.2, and I think I used Mac OS X 10.0 Cheetah, but I'd be hard-pressed to prove that now.
Using the name gcc
instead of clang
doesn't change the behaviour.
Upvotes: 1