使用每个选项简化编译

时间:2010-10-09 19:49:29

标签: c configuration compilation embedded c-preprocessor

我有一个定义列表:MASTERSLAVE0SLAVE1,... SLAVE9来控制将哪个音频数据阵列编程到微控制器中。 micro可以容纳不超过一个声音文件,所以我在main.c文件的顶部包含了以下定义:

#define MASTER
#define SLAVE0
#define SLAVE1
....
#define SLAVE9 

然后,我在音频数组中写下以下内容:

#if defined(MASTER)
    uint8_t sound[4096] PROGMEM = {127,126, ... }
#elif defined(SLAVE0)
    uint8_t sound[4096] PROGMEM = {126,128, ... }
....
#else 
    #ERROR "One of MASTER-SLAVE9 must be defined!"
#endif

然后,希望编译的人必须通过并注释掉#define行中的一行而且只有一行。这不仅乏味,而且容易出错。所以,我正在寻求简化流程。任何以下任务的指针都会有所帮助:

  1. 如何测试一个且只有一个选项存在的宏列表?一个简单的if defined(MASTER) && !(defined(SLAVE0) || defined(SLAVE1) ...)需要11个这样的测试,每个测试有11个微妙的不同条件。这是一次性费用,但它有点难看。感觉这可能是一个共同的需求,并且应该有更好的方式。
  2. 如何简化编译过程?我一直在使用AVRStudio和WinAVR t0编译。它有一个'export makefile'选项,但我没有使用它的经验。我在Windows上遇到这种情况。一个理想的过程可以在一个命令中构建所有11个配置,然后我可以通过单独编程将每个配置编程到微控制器。当前非常不理想的构建过程涉及每次构建时编辑源,以及重命名/移动输出文件。

4 个答案:

答案 0 :(得分:2)

您可以使用单个测试来确保只定义了一个宏。

#if (defined(MASTER) + defined(SLAVE1) + defined(SLAVE2)) != 1
    #error "Too many macros defined"
#endif

对于定义本身,大多数编译器允许您使用命令行选项定义宏;这可能比具有“可配置选项列表”的文件更清晰。然后,您将能够创建多个构建配置,每个构建配置定义一个不同的宏,并按顺序构建它们(我不熟悉您的构建系统,以便能够解释您需要如何做到这一点)。 / p>

答案 1 :(得分:1)

我只是用所有可能的常量的名称做一个块注释,然后用一个定义来跟随它。谁想编译只是写他想要的东西。他第一次检查评论看清单,然后他就会写。

甚至更好,将此列表保留在注释中(供参考)并使用大多数编译器具有的-D选项(例如,-DMASTER定义master),如果您的工具支持它,请为每个位置进行构建配置你改变了-D值。使用不同的构建配置,我猜你也可以改变输出文件名,这样就可以用石头杀死两只鸟。

答案 2 :(得分:0)

为什么不能这样:

#define ARRAY_NAME        (SLAVE0)

...


#if (ARRAY_NAME == MASTER)
    // blah
#elif (ARRAY_NAME == SLAVE0)
    // blah
// etc.

甚至更好,只是:

#define ARRAY_MASTER { 1, 2, 3, 4 }
#define ARRAY_SLAVE0 { 5, 6, 7, 8 }
// etc.

...

const uint8_t sound[] = ARRAY_MASTER;

答案 3 :(得分:0)

当您定义一个宏而不是一个宏时,您需要一条错误消息吗?好吧,只需写下:

#ifdef MASTER
uint8_t sound = { ... };
#endif
#ifdef SLAVE0
uint8_t sound = { ... };
#endif
#ifdef SLAVE1
uint8_t sound = { ... };
#endif

编译器会抱怨多次定义一个标识符。

为什么不用这个?

#define SLAVE <n>

uint8_t sound_master = { ... };
uint8_t sound_slave_0 = { ... };
uint8_t sound_slave_1 = { ... };
uint8_t sound_slave_2 = { ... };

#define XCAT(a,b) a##b
#define CAT(a,b) XCAT(a,b)
#ifdef SLAVE
#define sound CAT(sound_slave_,SLAVE)
#endif
#ifdef MASTER
#ifdef sound
/* warnin or so. but if you need an error just remove this ifdef **/
#endif
#define sound sound_master
#endif