The simple way to do this is to escape the quotes around the string, something like:
VERSION=$(shell git describe)
CFLAGS += -DVERSION=\"$(VERSION)\"
Alternately, you can pass the raw output and stringify it via preprocessor macros as needed. This is useful when you need both a string and raw version of something. In the Makefile, that's just a matter of not putting the value in quotes. For example:
VERSION=$(shell git describe)
CFLAGS+=-DVERSION=$(VERSION)
Now in our C or C++ code, we need a macro that stringifies this, however it needs to stringify the value rather than literal name of the VERSION:
#define _STR(s) # s
#define STR(s) _STR(s)
/* then, somewhere... */
const char *version_string = STR(VERSION);
printf("version: %s\n", version_string);
The _STR macro stringifies via the '#' operator while the STR macro ensures that _STR acts on the result of a macro rather than the literal macro name. A huge thanks to my friend Andrey Smirnov for teaching me this macro.