CONFIRMED SOLUTION ON GCC & MSVC
Despite claims out there about how this is impossible - it can be done! And it's not all that painful when you see the solution...
This is what I'm doing from top to bottom for a use case where I want to allow a collection of interdependent libraries to be built from one master project and then ported around (as headers + binaries) to other projects with variable directory layouts / include paths.
First, a client project sets a define to a "top level" config file path. CONDITIONALLY, defines may be provide for (include path relative) directories containing headers. This can be done from CMake, QMake, make, etc.
The config file contains some friendly macros setup to find the headers for specific libraries.
An implementation then includes the dynamic config file path and calls the macros to find other library paths.
CMake Driven Defines Example
target_compile_definitions(${TARGET_NAME} PUBLIC MY_CONFIG_PATH=\"my_core/include/myconfig.h\") target_compile_definitions(${TARGET_NAME} PUBLIC MY_INC_PATHS_OVERRIDE) target_compile_definitions(${TARGET_NAME} PUBLIC MY_CORE_INC_PATH=custom/path/my_core/include)
(Alternative) Make Defines Example
-DMY_CONFIG_PATH=\"my_core/include/myconfig.h\" -DMY_INC_PATHS_OVERRIDE -DMY_CORE_INC_PATH=custom/path/my_core/include
myconfig.h Example
#define MY_STR( X ) __MY_STR( X ) #define __MY_STR( X ) #X #define MY_PATH_CAT( X, Y ) X/Y #ifndef MY_INC_PATHS_OVERRIDE # define MY_CORE_INC_PATH my_core/include #endif #ifdef MY_CORE_INC_PATH # define MY_CORE_INCLUDE( FILE ) \ MY_STR( MY_PATH_CAT( MY_CORE_INC_PATH, FILE ) ) #else # define MY_CORE_INCLUDE( FILE ) MY_STR( FILE ) #endif
Implementation
#include MY_CONFIG_PATH #include MY_CORE_INCLUDE( something.h )
EXTRA NOTE:
I found that when using this within a Qt framework, the macros to resolve the include paths will cause trouble in the context of generating .moc files, or doing some other kinds of Qt / Qt Creator magic requiring source parsing. But, the internals of the libs and the non Qt related lib headers still played nice with such macros in place.