0

我在编写这个宏时遇到了麻烦。我正在使用ceedling。

我有一个文件“globals.h”,其中包含以下代码:

#ifndef globals
    #ifndef UNITY
        #define STATIC static
    #else
        #define STATIC
    #endif
    #define globals 1
#endif

所以,这里应该发生的是,如果代码没有被统一测试,任何使用 STATIC 的方法都将是静态的,否则它将不是静态的。

我的测试文件包含“unity.h”,然后包含“globals.h”,然后包含“protocol.h”。

正在测试的文件“protocol.c”包括“globals.h”和“protocol.h”。

测试文件“test_protocol.c”包括“unity.h”,然后是“globals.h”,然后是“protocol.h”。

根据我的理解,应该首先定义 UNITY,然后它会去globals.h,并将 STATIC 定义为空,因为 UNITY 已经在 UNITY.h 中定义了

但是,我看到的行为是,无论我做什么,我都无法globals.h输入该#else指令,因此似乎不可能STATIC被定义为static.

但是,我知道我想要完成的事情是可能的,因为很多人推荐并实施了这个策略。那么,我在做什么导致globals.h认为 UNITY 未定义,何时定义?

4

2 回答 2

0

test_protocol.c不需要包含globals.h文件。从观点来看test_protocol.c,里面的一切protocol.c都有外部联系,但它本身并不需要。

因为protocol.ctest_protocol.c位于不同的翻译单元中,所以UNITY 定义在中UNITY.h是看不到的,protocol.c因为它不包括UNITY.h.

当然,被测代码必须保持完整。所以我们必须在测试期间以某种方式告诉protocol.c标志UNITY,而不是在正常编译中。这就是:defines:yaml 文件中的部分亮点所在。

project.yml文件已经定义了一个TEST宏:

:defines:
  # in order to add common defines:
  #  1) remove the trailing [] from the :common: section
  #  2) add entries to the :common: section (e.g. :test: has TEST defined)
  :common: &common_defines []
  :test:
    - *common_defines
    - TEST                      # <--- here
  :test_preprocess:
    - *common_defines
    - TEST                      # <--- and here

您也需要UNITY在此处定义或仅TESTglobals.h. 无论如何,TEST宏都是为此目的而存在的。

TEST如果它被编译用于测试,这可以确保标志被传递给每个翻译单元ceedling,但如果你像往常一样使用普通编译器,则不会在那里。

于 2020-10-14T10:16:31.740 回答
0

好吧,我知道它不是您问题的直接答案,但是您可以在编译代码时#ifndef UNITY传递预处理器标志,而不是检查。

例如

g++ protocol.c -DBUILD_TYPE="not_test"

g++ test_protocol.c -DBUILD_TYPE="test"

然后签入global.h代码为

#define TEST test
#define NOT_TEST not_test

    #ifndef globals
        #if BUILD_TYPE == NOT_TEST
            #define STATIC static
        #else
            #define STATIC
        #endif
        #define globals 1
    #endif
于 2020-07-13T22:59:44.377 回答