Clang preprocessor concatenates an extra space vs. gcc - standard C99
I think this is beyond the jurisdiction of the C standard.  See https://stackoverflow.com/questions/37796947/spaces-inserted-by-the-c-preprocessor.  All the standard says on the topic is a footnote:


  Note that adjacent string literals are not concatenated into a single string literal (see the translation phases in 5.1.1.2); thus, an expansion that results in two string literals is an invalid directive.


https://port70.net/~nsz/c/c11/n1570.html#note170

But this doesn't really matter since you are not making multiply strings.



Investigating GCC and Clang...

GCC does different things depending on what you ask for:

STRINGIFY(PROJECT DASH SUB_PROJECT DASH VERSION.c)


... gets me "myProject - mySub - 1.01.c" with GCC 9.3 and -E, but ...

#include STRINGIFY(PROJECT DASH SUB_PROJECT DASH VERSION.c)


gets me myProject-mySub-1.01.c: No such file or directory.  So -E has spaces and #include doesn't.

Clang is at least consistent.  With Clang 10, #include has spaces: fatal error: 'myProject - mySub - 1.01.c' file not found And Clang 10 and -E also has spaces myProject - mySub - 1.01.c.

In my opinion, Clang's behavior makes the most sense.  Suppose you wanted a space -- how else could you do that?



#define ID(arg) arg


This is a common trick.  I think it's a good idea although it looks a little ugly when you have to use it in so many spots.



#define STRINGIFY(arg) STRINGIFY_(arg)
#define STRINGIFY_(arg) #arg


This is fine, but I think it'd be clearer to define STRINGIFY below the helper macro it uses.



Can you get away with something like:

#if VERSION == 1
#include "library-version-1.h"
#else
#include "library-version-other.h"
#endif