Quick, tidy, feature #defines.

  • Centralizes build-time configuration.
  • Imports a list of #defines from Config.inc and applies a set of rules defining dependent features.

Convenience macros are provided in order to free code from #ifdef clutter, allowing one to write

if (have(SOME_FEATURE))
    use_some_feature();

instead of

#if defined SOME_FEATURE
     use_some_feature();
  #endif

Also allows configuration tests to be combined more naturally with conditional syntax. e.g.

if (have(SOME_FEATURE)
      && have(SOME_OTHER_FEATURE)
      && featureData != NULL)
  {
      use_the_features(featureData);
  }

Config.h

#ifndef CONFIG_H
#define CONFIG_H

/* Current configuration */
#include "Config.inc"

/** 
 * Build-time configuration test.
 * e.g. if (have(SOME_FEATURE)) use_some_feature();
 *
 * Default build-time configuration is defined in Config.inc.
 *
 * @param C Configuration feature to test
 */
#define have(C) HAVE_##C()

/* ======================================================================== */
/*   Configuration rules */
/* ======================================================================== */

/* Release features */
#if defined CONFIG_RELEASE
    #define CONFIG_FEATURE_A
    #undef CONFIG_FEATURE_B
#endif

/* Default features */
#if defined CONFIG_DEFAULT
    #define CONFIG_FEATURE_A
#endif

/* Maximum code coverage */
#if defined CONFIG_ALL
    #define CONFIG_FEATURE_A
    #define CONFIG_FEATURE_B
#endif

/* ======================================================================== */
/*   Configuration convenience macros. */
/* ======================================================================== */

/* Set: Enable feature A
 * Unset: Disable feature A
 * Depends: no dependent features
 */
#if defined CONFIG_FEATURE_A
    #define HAVE_CONFIG_FEATURE_A() (1)
#else
    #define HAVE_CONFIG_FEATURE_A() (0)
#endif

/* Set: Enable feature B
 * Unset: Disable feature B
 * Depends: no dependent features
 */
#if defined CONFIG_FEATURE_B
    #define HAVE_CONFIG_FEATURE_B() (1)
#else
    #define HAVE_CONFIG_FEATURE_B() (0)
#endif

#endif /* CONFIG_H */

Config.inc

/* 
 * Default build-time configuration.
 *  See Config.h
 *
 */
#define CONFIG_DEFAULT

Notes

Variables that a feature depends on are either unused or would still need to be excluded from compilation with #ifdef. Or better, refactor the feature and its variables into their own compilation unit.