为什么在运行Ceedling时我必须在C中重新包含头文件?

lnvxswe2  于 2022-12-11  发布在  其他
关注(0)|答案(1)|浏览(274)

我有一个C项目,我打算用Ceedling,CMock和Unity stack测试。我在运行测试时确实有一个问题...
我的项目结构如下

mytest
    ├── lib
    │   ├── bar.c
    │   └── include
    │       └── bar.h
    ├── project.yml
    ├── src
    │   ├── foo.c
    │   └── include
    │       └── foo.h
    └── test
        ├── support
        └── test_foo.c

还有我的Ceedling项目.yml文件

---

# Notes:
# Sample project C code is not presently written to produce a release artifact.
# As such, release build options are disabled.
# This sample, therefore, only demonstrates running a collection of unit tests.

:project:
  :use_exceptions: FALSE
  :use_test_preprocessor: TRUE
  :use_auxiliary_dependencies: TRUE
  :build_root: build
#  :release_build: TRUE
  :test_file_prefix: test_
  :which_ceedling: gem
  :ceedling_version: 0.31.1
  :default_tasks:
    - test:all

#:test_build:
#  :use_assembly: TRUE

#:release_build:
#  :output: MyApp.out
#  :use_assembly: FALSE

:environment:

:extension:
  :executable: .out

:paths:
  :test:
    - +:test/**
    - -:test/support
  :source:
    - src/**
    - src/include
    - lib/**
    - lib/include
  :support:
    - test/support
  :libraries: []

: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
  :test_preprocess:
    - *common_defines
    - TEST

:cmock:
  :mock_prefix: mock_
  :when_no_prototypes: :warn
  :enforce_strict_ordering: TRUE
  :plugins:
    - :ignore
    - :callback
  :treat_as:
    uint8:    HEX8
    uint16:   HEX16
    uint32:   UINT32
    int8:     INT8
    bool:     UINT8

# Add -gcov to the plugins list to make sure of the gcov plugin
# You will need to have gcov and gcovr both installed to make it work.
# For more information on these options, see docs in plugins/gcov
:gcov:
  :reports:
    - HtmlDetailed
  :gcovr:
    :html_medium_threshold: 75
    :html_high_threshold: 90

#:tools:
# Ceedling defaults to using gcc for compiling, linking, etc.
# As [:tools] is blank, gcc will be used (so long as it's in your system path)
# See documentation to configure a given toolchain for use

# LIBRARIES
# These libraries are automatically injected into the build process. Those specified as
# common will be used in all types of builds. Otherwise, libraries can be injected in just
# tests or releases. These options are MERGED with the options in supplemental yaml files.
:libraries:
  :placement: :end
  :flag: "-l${1}"
  :path_flag: "-L ${1}"
  :system: []    # for example, you might list 'm' to grab the math library
  :test: []
  :release: []

:plugins:
  :load_paths:
    - "#{Ceedling.load_path}"
  :enabled:
    - stdout_pretty_tests_report
    - module_generator
...

巴.h:

int addMe(int a, int b);

巴C:

#include "bar.h"

int addMe(int a, int b) 
{
    return a + b;
}

foo.h:

#ifndef FOO_H
#define FOO_H

    int addMore(int a, int b, int c);

#endif // FOO_H

表C:

#include "bar.h"
#include "foo.h"

int addMore(int a, int b, int c)
{
    return addMe(a, b) + c;
}

我的测试文件test_foo. c如下所示:

#include "unity.h"
#include "foo.h"

void setUp(void)
{
}

void tearDown(void)
{
}

void test_foo_addMore(void)
{
    printf("%d", addMore(1, 2, 3));
}

运行ceedling test:all时,出现如下错误:

/usr/bin/ld: build/test/out/c/foo.o: in function `addMore':
/home/USER/mytest/src/foo.c:6: undefined reference to `addMe'

如果包含bar.h头文件,一切都正常,但为什么我必须这样做呢?我在已经包含bar.h的地方包含了foo.h
我还将src/include bin bin/include文件路径添加到项目.yml中。
那么,这是为什么呢?
尝试按照我描述的方式设置项目,它并没有按照我想象的方式行事。

plicqrtu

plicqrtu1#

如果包含bar.h头文件,一切都正常,但为什么我必须这样做呢?
因为Ceedling就是这样工作的。从documentation
Ceedling通过每个测试文件中包含的#include列表知道要编译哪些文件并将其链接到每个单独的测试可执行文件中。配置的搜索目录中与测试文件中包含的头文件相对应的任何C源文件都将被编译并链接到生成的测试夹具可执行文件中。
因此,您需要显式地将头文件包含到测试源文件中,这样Ceedling才知道要编译哪些源文件如果您包含bar.h,那么它将查找bar.c请注意,如果您.c文件被称为其他名称,如bar_new.c,则构建将失败

相关问题