Skip to contentSkip to conversation

Makefile: do not optimize when DEBUG=1

PATCH In review Johannes Schindelin 3 participants 5 messages Jun 15, 2016 Kbuild

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Makefile: do not optimize when DEBUG=1

There is this wonderful debugger named gdb, which sometimes has severe problems when the source is compiled with optimization. So, you have to recompile (at least parts of the source) _without_ -O2 if you want to have a chance to look at otherwise optimized-out variables.

You can do that now by removing just the object files containing the code you want to debug, and saying "make DEBUG=1".

---
 Makefile |    7 ++++++-
 1 files changed, 6 insertions(+), 1 deletions(-)
Makefile +6 -1
index c3d67af..18fdc5e 100644
@@ -110,6 +110,8 @@ all::
 # Define NO_PERL_MAKEMAKER if you cannot use Makefiles generated by perl's
 # MakeMaker (e.g. using ActiveState under Cygwin).
 #
+# Define DEBUG=1 to compile without optimization.
+#
 
 GIT-VERSION-FILE: .FORCE-GIT-VERSION-FILE
 	@$(SHELL_PATH) ./GIT-VERSION-GEN
@@ -123,7 +125,10 @@ uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not')
 
 # CFLAGS and LDFLAGS are for the users to override from the command line.
 
-CFLAGS = -g -O2 -Wall
+CFLAGS = -g -Wall
+ifndef DEBUG
+	CFLAGS += -O2
+endif
 LDFLAGS =
 ALL_CFLAGS = $(CFLAGS)
 ALL_LDFLAGS = $(LDFLAGS)
Signature · 1 line
1.5.0.3.2559.g30d3b
#1 lore raw

Makefile uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') · line 131

Quoted 8 lines · Johannes Schindelin

You can do that now by removing just the object files containing the code you want to debug, and saying "make DEBUG=1".
[...]

Makefile +4 -1
-CFLAGS = -g -O2 -Wall
+CFLAGS = -g -Wall
+ifndef DEBUG
+       CFLAGS += -O2
+endif

I think the shortcut to remove just the interesting object file does not work because Makefile notices (the GIT-CFLAGS rule) that there are "new flags or prefix", and so recompiles everything.

-- Hannes

#2 lore raw

Hi,

Quoted 13 lines · Johannes Sixt

Makefile uname_P := $(shell sh -c 'uname -p 2>/dev/null || echo not') · line 131

Quoted 8 lines · Johannes Schindelin

You can do that now by removing just the object files containing the code you want to debug, and saying "make DEBUG=1".
[...]

Makefile +4 -1
-CFLAGS = -g -O2 -Wall
+CFLAGS = -g -Wall
+ifndef DEBUG
+       CFLAGS += -O2
+endif

I think the shortcut to remove just the interesting object file does not work because Makefile notices (the GIT-CFLAGS rule) that there are "new flags or prefix", and so recompiles everything.

That is unfortunatley true, and was hidden in my test by something completely unrelated.

I do something completely different now:

@@ -846,7 +841,8 @@ TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\

GIT-CFLAGS: .FORCE-GIT-CFLAGS
@FLAGS='$(TRACK_CFLAGS)'; \
- if test x"$$FLAGS" != x"cat GIT-CFLAGS 2>/dev/null" ; then \
+ if test x"$$FLAGS" != x"cat GIT-CFLAGS 2>/dev/null" -a \
+ -z "$(IGNORE_GIT_CFLAGS)"; then \
echo 1>&2 " * new build flags or prefix"; \
echo "$$FLAGS" >GIT-CFLAGS; \
fi

... and in my config.mak, there is

ifdef DEBUG

	ALL_CFLAGS := $(filter-out -O2,$(ALL_CFLAGS))
	IGNORE_GIT_CFLAGS = YesPlease

endif

I'm happy now.

Ciao,
Dscho

#3 lore raw

PATCH 1/1 Avoid rebuilding everything if user changes CFLAGS on the make command line

From: Johannes Sixt <[email protected]>

The following sequence of commands is commonly used to recompile selected files with different flags, for example, to change the debug information:

make
rm builtin-diff.o
make CFLAGS="-g -O0"

However, the Makefile is clever enough to notice that the second 'make' invocation changes the build flags and rebuilds everything.

This change exempts the value of CFLAGS (which is explicitly declared as reserved for the user to change from the command line) from this auto-detection.

---

Review

Quoted 8 lines · Johannes Schindelin

GIT-CFLAGS: .FORCE-GIT-CFLAGS

        @FLAGS='$(TRACK_CFLAGS)'; \
(quoted diff) +2 -1
-           if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" ; then \
+           if test x"$$FLAGS" != x"`cat GIT-CFLAGS 2>/dev/null`" -a \
+                   -z "$(IGNORE_GIT_CFLAGS)"; then \
                echo 1>&2 "    * new build flags or prefix"; \
                echo "$$FLAGS" >GIT-CFLAGS; \
             fi

IMHO, the value of $(CFLAGS) (which the Makefile declares as "for the users to override from the command line") should never take part in this build-flags-change-autodetection.

-- Hannes

 Makefile |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
Makefile +1 -1
index 9a37b15..8410530 100644
@@ -812,7 +812,7 @@ tags:
 	find . -name '*.[hcS]' -print | xargs ctags -a
 
 ### Detect prefix changes
-TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
+TRACK_CFLAGS = $(subst ','\'',$(BASIC_CFLAGS)):\
             

$(bindir_SQ):$(gitexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)

GIT-CFLAGS: .FORCE-GIT-CFLAGS

Signature · 1 line
1.5.0.2.279.g4808
#4 lore raw

Re: [PATCH] Avoid rebuilding everything if user changes CFLAGS on the make command line

Quoted 3 lines · Johannes Sixt

IMHO, the value of $(CFLAGS) (which the Makefile declares as "for the users to override from the command line") should never take part in this build-flags-change-autodetection.

This on the surface looks nicer than the other Johannes's approach, but I have reservations. The user can always say "make CFLAGS=-DNO_SYNLINK_HEAD=NoThanks" from the command line to affect the behaviour, and in such a case this approach breaks.

As long as you declare CFLAGS is there for users to override only the way the programs are compiled (e.g. optimization) and it is forbidden to use CFLAGS to affect the way the programs are to behave (iow, "use of -D<FEATURE> in CFLAGS is forbidden"), it would be Ok, but in effect it is forcing people to modify config.mak even for "try out this configuration just this time, one-shot" compilation, which makes me somewhat unhappy.

IGNORE_GIT_CFLAGS looks much uglier, but is much nicer from design standpoint. At least the user declares "I know what I am doing, and I assume full responsibility". That might be less confusing in the end.

Undecided.