-
-
Notifications
You must be signed in to change notification settings - Fork 261
Open
Description
Description:
Necessary source file is not being linked (and compiled for that matter) for a test file whose source file use other source file which is nested deeper in the project tree. To illustrate this, I have provided a minimal example.
Project stcture:
├── compile_commands.json
├── include
│ └── parent.h
├── project.yml
├── src
│ └── parent
│ ├── child
│ │ ├── child.c
│ │ ├── child.h
│ │ └── child.test.c
│ ├── parent.c
│ └── parent.test.c
└── tests_build
├── artifacts
│ └── test
├── logs
├── test
│ ├── cache
│ ├── dependencies
│ │ ├── child_runner.d
│ │ ├── child.d
│ │ ├── child.test_runner.d
│ │ ├── child.test.d
│ │ ├── parent_runner.d
│ │ ├── parent.d
│ │ ├── parent.test_runner.d
│ │ ├── parent.test.d
│ │ └── unity.d
│ ├── mocks
│ │ ├── child
│ │ ├── child.test
│ │ ├── parent
│ │ └── parent.test
│ ├── out
│ │ ├── child
│ │ │ ├── child_runner.o
│ │ │ ├── child.o
│ │ │ ├── child.out
│ │ │ └── unity.o
│ │ ├── child.test
│ │ │ ├── child.o
│ │ │ ├── child.test_runner.o
│ │ │ ├── child.test.o
│ │ │ ├── child.test.out
│ │ │ └── unity.o
│ │ ├── parent
│ │ │ ├── parent_runner.o
│ │ │ ├── parent.o
│ │ │ └── unity.o
│ │ └── parent.test
│ │ ├── child.o
│ │ ├── parent.o
│ │ ├── parent.test_runner.o
│ │ ├── parent.test.o
│ │ ├── parent.test.out
│ │ └── unity.o
│ ├── results
│ └── runners
│ ├── child_runner.c
│ ├── child.test_runner.c
│ ├── parent_runner.c
│ └── parent.test_runner.c
└── vendor
├── cmock
│ └── src
│ ├── cmock_internals.h
│ ├── cmock.c
│ ├── cmock.h
│ └── meson.build
└── unity
└── src
├── meson.build
├── unity_internals.h
├── unity.c
└── unity.h
child.c:
int mul(int a, int b) {
return a * b;
}
child.test.c
#include "unity.h"
#include "child.h"
void test_mul(void)
{
TEST_ASSERT_EQUAL_INT(6, mul(3,2));
}
child.h
int mul(int a, int b);
parent.c
T
int sum(int a, int b) {
return a + b;
}
int square(int n) {
return mul(n,2);
}
parent.test.c
#include "unity.h"
#include "parent.h"
TEST_SOURCE_FILE("child/child.c");
void test_sum(void)
{
TEST_ASSERT_EQUAL_INT(5, sum(3,2));
}
include/parent.h
int sum(int a, int b);
int square(int n);
Output from running ceedling test in root:
🚧 Loaded project configuration from working directory.
> Using: <dir>/project.yml
> Working directory: <dir>
Ceedling set up completed in 56 milliseconds
👟 Preparing Build Paths...
👟 Collecting Test Context
--------------------------
Parsing parent.c for build directive macros, #includes, and test case names...
Parsing parent.test.c for build directive macros, #includes, and test case names...
Parsing child.c for build directive macros, #includes, and test case names...
Parsing child.test.c for build directive macros, #includes, and test case names...
👟 Ingesting Test Configurations
--------------------------------
Collecting search paths, flags, and defines parent.c...
Collecting search paths, flags, and defines parent.test.c...
Collecting search paths, flags, and defines child.c...
Collecting search paths, flags, and defines child.test.c...
👟 Determining Files to be Generated...
👟 Mocking
----------
👟 Test Runners
---------------
Generating runner for parent.c...
Generating runner for parent.test.c...
Generating runner for child.c...
Generating runner for child.test.c...
👟 Determining Artifacts to Be Built...
👟 Building Objects
-------------------
Compiling parent.c...
Compiling parent::parent_runner.c...
Compiling parent::unity.c...
Compiling parent.test.c...
Compiling parent.test::child.c...
Compiling parent.test::parent.c...
Compiling parent.test::parent.test_runner.c...
Compiling parent.test::unity.c...
Compiling child.c...
Compiling child::child_runner.c...
Compiling child::unity.c...
Compiling child.test.c...
Compiling child.test::child.c...
Compiling child.test::child.test_runner.c...
Compiling child.test::unity.c...
👟 Building Test Executables
----------------------------
Linking parent.out...
ℹ️ NOTICE: If the linker reports missing symbols, the following may be to blame:
1. This test lacks #include statements corresponding to needed source files (see note below).
2. Project file paths omit source files corresponding to #include statements in this test.
3. Complex macros, #ifdefs, etc. have obscured correct #include statements in this test.
4. Your project is attempting to mix C++ and C file extensions (not supported).
5. This test does not #include needed mocks (that triggers their generation).
NOTE: A test file directs the build of a test executable with #include statemetns:
* By convention, Ceedling assumes header filenames correspond to source filenames.
* Which code files to compile and link are determined by #include statements.
* An #include statement convention directs the generation of mocks from header files.
OPTIONS:
1. Doublecheck this test's #include statements.
2. Simplify complex macros or fully specify symbols for this test in :project ↳ :defines.
3. If no header file corresponds to the needed source file, use the TEST_SOURCE_FILE()
build diective macro in this test to inject a source file into the build.
See the docs on conventions, paths, preprocessing, compilation symbols, and build directive macros.
🧨 EXCEPTION: 'Default Test Linker' (gcc) terminated with exit code [1] and output >>
Undefined symbols for architecture arm64:
"_mul", referenced from:
_square in parent.o
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
🌱 Ceedling could not complete operations because of errors
As you can see, parent.test.c file misses source from child.c
Please notice that I do not expect solutions in form "change your project structure" because I desire flexibility and freedom in my projects.
Theoretically TEST_SOURCE_FILE("child/child.c") should have done the thing but it didnt
project.yml:
:defines:
:common: &common_defines []
:test:
- *common_defines
- TEST
- UNITY_INCLUDE_DOUBLE # Add it here without D prefix
:paths:
:source:
- src/**
:include:
- include
- src
:test:
- src/** # unit tests live next to code
:flags:
:preprocess:
:compile: []
:project:
# how to use ceedling. If you're not sure, leave this as `gem` and `?`
:ceedling_version: 1.0.1
# optional features. If you don't need them, keep them turned off for performance
:use_mocks: TRUE
:use_decorators: :auto # decorate Ceedling's output text. options are :auto, :all, or :none
# tweak the way ceedling handles automatic tasks
:build_root: tests_build
:test_file_prefix: ""
:test_file_suffix: ".test.c"
:default_tasks:
- test:all
:release_build: FALSE
:plugins:
:load_paths: []
:enabled:
- module_generator # handy for quickly creating source, header, and test templates
- report_tests_pretty_stdout
:extension:
:executable: .out
---
# Configuration Options specific to CMock. See CMock docs for details
# ====
# ====
# ====
:cmock:
:mock_path: test/support/mocks
:stub_path: test/support/stubs
:mock_prefix: mock_
:when_no_prototypes: :warn
:enforce_strict_ordering: TRUE
:plugins:
:enabled:
- :ignore
- :callback
- stdout_pretty_tests_report
- module_generator
:treat_as:
uint8: HEX8
uint16: HEX16
uint32: UINT32
int8: INT8
bool: UINT8
################################################################
# PLUGIN CONFIGURATION
################################################################
#clang 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:
:summaries: TRUE # Enable simple coverage summaries to console after tests
:report_task: FALSE # Disabled dedicated report generation task (this enables automatic report generation)
:utilities:
- gcovr # Use gcovr to create the specified reports (default).
#- ReportGenerator # Use ReportGenerator to create the specified reports.
:reports: # Specify one or more reports to generate.
# Make an HTML summary report.
- HtmlBasic
:gcovr:
:html_medium_threshold: 75
:html_high_threshold: 90
Metadata
Metadata
Assignees
Labels
No labels