Q: Is there a nicer/more elegant way to do a gcc -D command conditionally in a Makefile? So I'm writing some C files that utilize the classic pattern of doing this sort of business:
    #ifdef DEBUG
    SHOW("debugging");
    #endif    


And also I'm utilizing the -D command of gcc, that lets you define a constant, so that I can turn these on and off via command line args.
Here is a makefile I've written, that makes it so if I want to debug, I can simply do "make d=true", and it will conditionally define DEBUG for me:
#DEBUG: make d=true
VPATH = src

ifeq ($(d),true)
debug = -DDEBUG
endif

flags = -Wall -Werror -g $(debug) 

mealplan: items.o mealplan.h
    gcc $(flags) -o mealplan mealplan.c items.o
items.o: items.c items.h
    gcc $(flags) -c src/items.c
clean:
    rm mealplan items.o

Don't get me wrong, it works 100% as I intended it to. But it looks a bit barbaric to me, is there a cleaner/shorter/more idiomatic way to achieve this conditional setting of the DEBUG define via make?
So I tried this because I read in the make documentation a few facts:

*

*You can pass in custom variables by doing "var=value"

*An undefined variable just has the value of empty string

*You can do conditionals with "ifeq"

So I kind of just slapped this together and it works but I feel like a better solution exists.

A: The simplest solution is to use target-specific variables:
VPATH = src

flags = -Wall -Werror -g $(debug) 

mealplan: items.o mealplan.h
        gcc $(flags) -o mealplan mealplan.c items.o
items.o: items.c items.h
        gcc $(flags) -c src/items.c
clean:
        rm mealplan items.o

.PHONY: debug
debug: mealplan
debug: debug = -DDEBUG

Now if you run make it will build without the debug options and if you run make debug it will build with the debug options.
Or, to rewrite your makefile to be more idiomatic:
VPATH = src

CC = gcc
CFLAGS = -Wall -Werror -g $(debug)

mealplan: mealplan.o items.o

mealplan.o: mealplan.c mealplan.h
items.o: items.c items.h

clean:
        rm mealplan items.o

.PHONY: debug
debug: mealplan
debug: debug = -DDEBUG

Just to note this is really not a great way to handle things.  It's far too easy to forget to do a clean between the build of debug and non-debug and now you have a mix of some objects compiled with debugging and some without.  A more reliable way to do it is write your makefile to put the debug output files in one directory and the non-debug output files in a different directory.
