Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TEST_SOURCE_FILE: Ceedling 1.0.0 tries to compile and link to source file, even when directive is commented out #978

Open
mikewzr opened this issue Jan 8, 2025 · 12 comments

Comments

@mikewzr
Copy link

mikewzr commented Jan 8, 2025

I have a template test file in my project with following snippet in there:

...

#include "unity.h"

// TEST_SOURCE_FILE("FILE_UNDER_TEST.c")

...

Behavior:
Ceedling 1.0.0 tries to compile and link to files added with TEST_SOURCE_FILE even when they are commented out.
In this case, Ceedling tries to link to the file FILE_UNDER_TEST.c, which does not exist.

Ceedling output (cropped):

👟 Preprocessing Test Files
---------------------------
Preprocessing test_DEVICE_STATE_default.c...
Loading #include statement listing file for test_DEVICE_STATE_default.c...
🧨 EXCEPTION: File 'FILE_UNDER_TEST.c' specified with TEST_SOURCE_FILE() in test_DEVICE_STATE_default cannot be found in the source file collection
🌱 Ceedling could not complete operations because of errors

Expectation:
As I am writing C code, I expect code commented out to not be used in any compilation, tests, etc.

Versions:
Fedora 41
Ruby 3.3.6
Ceedling 1.0.0

@mkarlesky
Copy link
Member

mkarlesky commented Jan 9, 2025

Hi, @mikewzr. Thank you so much for this report and so sorry for the trouble here.

I totally agree that commenting out that macro should cause it to be ignored!

I just reviewed Ceedling’s test suite for handling this and tried to recreate the problem. So far, I am unable to find an unhandled case nor replicate the problem. I see you're using the test preprocessing option. If I include TEST_SOURCE_FILE("boom.c") (boom.c does not exist) it causes an exception when not commented out and does not cause an exception when commented out. The same is true no matter if I enable or disable test preprocessing.

  1. What compiler are you using?
  2. Could you crank up verbosity (--verbosity=debug or -v 5) and provide the logging statements from preprocessing a test file (test_DEVICE_STATE_default.c would be just fine)?

Something is clearly broken. My hunch is that something about how Ceedling calls your toolchain preprocessor is producing different results on your system than Ceedling is expecting.

If you happen to be able to and are willing to do so, I'd be interested to know if the Dockerized version of Ceedling succeeds with the same project configuration and C files. If it does, this would be a strong indication that something about your toolchain preprocessor is behaving differently than we expect.

@parmi93
Copy link

parmi93 commented Jan 10, 2025

I have similar problem with Ceedling v1.0.0, I noticed that it try to run tests that are defined out like this:

#if REMOVED
void test_my_removed_test()
{
    // Ceedling try to run this test
}
#endif

@mvandervoord
Copy link
Member

out of curiosity, @parmi93 -- why do things like this? I have no disagreement that ceedling should handle these situations, but I rarely understand the reason. It would be far better (in my opinion) to use TEST_IGNORE_MESSAGE("Disabled because this version doesn't support this test"); or something like that in the tests that don't require testing... this way it shows up in your summary and you're always aware which tests are running.

@parmi93
Copy link

parmi93 commented Jan 10, 2025

I hadn't thought of using TEST_IGNORE_MESSAGE, I had removed some tests because Ceedling/Cmock doesn't support mocking of variadic functions, I will use this macro.

@mkarlesky
Copy link
Member

@parmi93 Mark's recommendation is a good one. That said, just so you know, Ceedling can handle the case you described and should be doing so… If test preprocessing is enabled. Without this option configured, test cases will be discovered in your test file and then run no matter if they are surrounded by an #ifdef block. Please see the docs on this. The documentation outlines how the preprocessing feature works and exactly in which cases you should and should not use it. The one you're describing is definitely a case where it is appropriate. If you choose to use it, let us know if it's not working for the example you provided. That would be a bug.

p.s. For anyone following this thread, the original issue described by @mikewzr and the one described by @parmi93 are similar in concept but largely unrelated in features. Commenting out TEST_SOURCE_FILE() should work regardless of preprocessing features. A conditional compilation block around a test case requires Ceedling’s preprocessing features.

@mikewzr
Copy link
Author

mikewzr commented Jan 10, 2025

Hello @mkarlesky,

I'm using gcc 14.2.1 provided by DNF on Fedora 41.
Here is the output of the preprocessing with debug output enabled (I put it in a pastebin, because it is an ESP project and it has a whole lot of includes):
https://pastebin.com/MPgcnXQH

I stripped away some paths and includes (replaced by %stripped% and %stripped-includes%, respectively), because it is a project for the company I'm working.

I also tried to run Ceedling in the container, but it did not resolve the issue. It too complains about not finding the file, although it is commented out.

@mkarlesky
Copy link
Member

I'm really quite stumped on this one so far, @mikewzr.

I gather there is some sensitive information in your project. Are you able to provide (anonymized) project configuration, the test file, and any mixins you might be using?

@mikewzr
Copy link
Author

mikewzr commented Jan 13, 2025

Hello,

I discussed with the team today and it would probably be very hard to anonymize the project file good enough. But we came up with the idea of creating a minimal example, which would be easier to debug anyway.

Thus, I set up a little project with the new command of Ceedling itself, to try if I get the same behavior on my system. And the result is yes, it still tries to find files in commented out TEST_SOURCE_FILE directives.

The directory now looks like this:

tree
.
├── project.yml
├── src
└── test
    ├── support
    └── test_example.c

4 directories, 3 files

The project file is essentially the default generated one, with :use_test_preprocessing: set to :all. I put the config file at the end, because it is the longest. Here is the test file, i created:

#include "unity.h"

// TEST_SOURCE_FILE("FILE_UNDER_TEST.c")

void setUp(void)
{
}

void tearDown(void)
{
}


void test_my_thingy(void) {
    TEST_ASSERT_EQUAL(0, 0);
}

And the resulting output of the Ceedling preprocessing step:

👟 Preprocessing Test Files
---------------------------
Preprocessing test_example.c...
Loading #include statement listing file for test_example.c...
Loaded existing #include list from build/test/preprocess/includes/test_example/test_example.c.yml:
 - build/vendor/unity/src/unity.h

Command: {:name=>"default_test_file_full_preprocessor", :executable=>"gcc", :options=>{}, :line=>"gcc -E -I\"build/test/mocks/test_example\" -I\"test/support\" -I\"src\" -I\"build/vendor/unity/src\" -I\"build/vendor/cmock/src\" -D\"TEST\" -D\"UNITY_EXCLUDE_FLOAT\" -DGNU_COMPILER -x c \"test/test_example.c\" -o \"build/test/preprocess/files/test_example/full_expansion/test_example.c\""}

> Shell executed command:
`gcc -E -I"build/test/mocks/test_example" -I"test/support" -I"src" -I"build/vendor/unity/src" -I"build/vendor/cmock/src" -D"TEST" -D"UNITY_EXCLUDE_FLOAT" -DGNU_COMPILER -x c "test/test_example.c" -o "build/test/preprocess/files/test_example/full_expansion/test_example.c"`
> With $stdout: <empty>
> With $stderr: <empty>
> And terminated with status: pid 199070 exit 0

Command: {:name=>"default_test_file_directives_only_preprocessor", :executable=>"gcc", :options=>{}, :line=>"gcc -E -I\"build/test/mocks/test_example\" -I\"test/support\" -I\"src\" -I\"build/vendor/unity/src\" -I\"build/vendor/cmock/src\" -D\"TEST\" -D\"UNITY_EXCLUDE_FLOAT\" -DGNU_COMPILER -x c -fdirectives-only \"test/test_example.c\" -o \"build/test/preprocess/files/test_example/directives_only/test_example.c\""}

> Shell executed command:
`gcc -E -I"build/test/mocks/test_example" -I"test/support" -I"src" -I"build/vendor/unity/src" -I"build/vendor/cmock/src" -D"TEST" -D"UNITY_EXCLUDE_FLOAT" -DGNU_COMPILER -x c -fdirectives-only "test/test_example.c" -o "build/test/preprocess/files/test_example/directives_only/test_example.c"`
> With $stdout: <empty>
> With $stderr: <empty>
> And terminated with status: pid 199075 exit 0

#<Thread:0x00007f129fe45008 /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:54 run> terminated with exception (report_on_exception is true):
/home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker_helper.rb:73:in `block in validate_build_directive_source_files': File 'FILE_UNDER_TEST.c' specified with TEST_SOURCE_FILE() in test_example cannot be found in the source file collection (CeedlingException)
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker_helper.rb:54:in `each'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker_helper.rb:54:in `validate_build_directive_source_files'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker.rb:280:in `block (3 levels) in setup_and_invoke'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker.rb:279:in `each'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker.rb:279:in `block (2 levels) in setup_and_invoke'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:61:in `block (5 levels) in exec'
        from <internal:kernel>:187:in `loop'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:59:in `block (4 levels) in exec'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:57:in `handle_interrupt'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:57:in `block (3 levels) in exec'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:55:in `handle_interrupt'
        from /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:55:in `block (2 levels) in exec'
Extra source files found via TEST_SOURCE_FILE() in test/test_example.c:
 - FILE_UNDER_TEST.c

🧨 EXCEPTION: File 'FILE_UNDER_TEST.c' specified with TEST_SOURCE_FILE() in test_example cannot be found in the source file collection

Debug Backtrace ==>
/home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker_helper.rb:73:in `block in validate_build_directive_source_files': (CeedlingException)
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker_helper.rb:54:in `each'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker_helper.rb:54:in `validate_build_directive_source_files'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker.rb:280:in `block (3 levels) in setup_and_invoke'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker.rb:279:in `each'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/test_invoker.rb:279:in `block (2 levels) in setup_and_invoke'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:61:in `block (5 levels) in exec'
        <internal:kernel>:187:in `loop'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:59:in `block (4 levels) in exec'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:57:in `handle_interrupt'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:57:in `block (3 levels) in exec'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:55:in `handle_interrupt'
        /home/michael/.local/share/gem/ruby/gems/ceedling-1.0.0/lib/ceedling/build_batchinator.rb:55:in `block (2 levels) in exec'
🌱 Ceedling could not complete operations because of errors

I hope this helps and feel free to ask any further question, if you need anything else.

Here is the project.yml file for completeness:

# =========================================================================
#   Ceedling - Test-Centered Build System for C
#   ThrowTheSwitch.org
#   Copyright (c) 2010-25 Mike Karlesky, Mark VanderVoord, & Greg Williams
#   SPDX-License-Identifier: MIT
# =========================================================================

---
:project:
  # how to use ceedling. If you're not sure, leave this as `gem` and `?`
  :which_ceedling: gem
  :ceedling_version: 1.0.0

  # optional features. If you don't need them, keep them turned off for performance
  :use_mocks: TRUE
  :use_test_preprocessor: :all  # options are :none, :mocks, :tests, or :all
  :use_deep_preprocessor: :none  # options are :none, :mocks, :tests, or :all
  :use_backtrace: :simple        # options are :none, :simple, or :gdb
  :use_decorators: :auto         # decorate Ceedling's output text. options are :auto, :all, or :none

  # tweak the way ceedling handles automatic tasks
  :build_root: build
  :test_file_prefix: test_
  :default_tasks:
    - test:all

  # performance options. If your tools start giving mysterious errors, consider 
  # dropping this to 1 to force single-tasking
  :test_threads: 8
  :compile_threads: 8

  # enable release build (more details in release_build section below)
  :release_build: FALSE

# Specify where to find mixins and any that should be enabled automatically
:mixins:
  :enabled: []
  :load_paths: []

# further details to configure the way Ceedling handles test code
:test_build:
  :use_assembly: FALSE

# further details to configure the way Ceedling handles release code
:release_build:
  :output: MyApp.out
  :use_assembly: FALSE
  :artifacts: []

# Plugins are optional Ceedling features which can be enabled. Ceedling supports
# a variety of plugins which may effect the way things are compiled, reported, 
# or may provide new command options. Refer to the readme in each plugin for 
# details on how to use it.
:plugins:
  :load_paths: []
  :enabled:
    #- beep                           # beeps when finished, so you don't waste time waiting for ceedling
    - module_generator                # handy for quickly creating source, header, and test templates
    #- gcov                           # test coverage using gcov. Requires gcc, gcov, and a coverage analyzer like gcovr
    #- bullseye                       # test coverage using bullseye. Requires bullseye for your platform
    #- command_hooks                  # write custom actions to be called at different points during the build process
    #- compile_commands_json_db       # generate a compile_commands.json file
    #- dependencies                   # automatically fetch 3rd party libraries, etc.
    #- subprojects                    # managing builds and test for static libraries
    #- fake_function_framework        # use FFF instead of CMock

    # Report options (You'll want to choose one stdout option, but may choose multiple stored options if desired)
    #- report_build_warnings_log
    #- report_tests_gtestlike_stdout
    #- report_tests_ide_stdout
    #- report_tests_log_factory
    - report_tests_pretty_stdout
    #- report_tests_raw_output_log
    #- report_tests_teamcity_stdout

# Specify which reports you'd like from the log factory
:report_tests_log_factory:
  :reports:
    - json 
    - junit 
    - cppunit 
    - html 

# override the default extensions for your system and toolchain
:extension:
  #:header: .h
  #:source: .c
  #:assembly: .s
  #:dependencies: .d
  #:object: .o
  :executable: .out
  #:testpass: .pass
  #:testfail: .fail
  #:subprojects: .a

# This is where Ceedling should look for your source and test files.
# see documentation for the many options for specifying this.
:paths:
  :test:
    - +:test/**
    - -:test/support
  :source:
    - src/**
  :include:
    - src/** # In simple projects, this entry often duplicates :source
  :support:
    - test/support
  :libraries: []

# You can even specify specific files to add or remove from your test
# and release collections. Usually it's better to use paths and let
# Ceedling do the work for you!
:files:
  :test: []
  :source: []

# Compilation symbols to be injected into builds
# See documentation for advanced options:
#  - Test name matchers for different symbols per test executable build
#  - Referencing symbols in multiple lists using advanced YAML
#  - Specifiying symbols used during test preprocessing
:defines:
  :test:
    - TEST # Simple list option to add symbol 'TEST' to compilation of all files in all test executables
  :release: []

  # Enable to inject name of a test as a unique compilation symbol into its respective executable build. 
  :use_test_definition: FALSE 

# Configure additional command line flags provided to tools used in each build step
# :flags:
#   :release:
#     :compile:         # Add '-Wall' and '--02' to compilation of all files in release target
#       - -Wall
#       - --O2
#   :test:
#     :compile:
#       '(_|-)special': # Add '-pedantic' to compilation of all files in all test executables with '_special' or '-special' in their names
#         - -pedantic
#       '*':            # Add '-foo' to compilation of all files in all test executables
#         - -foo

# Configuration Options specific to CMock. See CMock docs for details
:cmock:
  # Core conffiguration
  :plugins:                        # What plugins should be used by CMock?
    - :ignore
    - :callback
  :verbosity:  2                   # the options being 0 errors only, 1 warnings and errors, 2 normal info, 3 verbose
  :when_no_prototypes:  :warn      # the options being :ignore, :warn, or :erro

  # File configuration
  :skeleton_path:  ''              # Subdirectory to store stubs when generated (default: '')
  :mock_prefix:  'mock_'           # Prefix to append to filenames for mocks
  :mock_suffix:  ''                # Suffix to append to filenames for mocks

  # Parser configuration
  :strippables:  ['(?:__attribute__\s*\([ (]*.*?[ )]*\)+)']
  :attributes:
     - __ramfunc
     - __irq
     - __fiq
     - register
     - extern
  :c_calling_conventions:
     - __stdcall
     - __cdecl
     - __fastcall
  :treat_externs:  :exclude        # the options being :include or :exclud
  :treat_inlines:  :exclude        # the options being :include or :exclud

  # Type handling configuration
  #:unity_helper_path: ''          # specify a string of where to find a unity_helper.h file to discover custom type assertions
  :treat_as:                       # optionally add additional types to map custom types
    uint8:    HEX8
    uint16:   HEX16
    uint32:   UINT32
    int8:     INT8
    bool:     UINT8
  #:treat_as_array:  {}            # hint to cmock that these types are pointers to something
  #:treat_as_void:  []             # hint to cmock that these types are actually aliases of void
  :memcmp_if_unknown:  true        # allow cmock to use the memory comparison assertions for unknown types
  :when_ptr:  :compare_data        # hint to cmock how to handle pointers in general, the options being :compare_ptr, :compare_data, or :smart

  # Mock generation configuration
  :weak:  ''                       # Symbol to use to declare weak functions
  :enforce_strict_ordering: true   # Do we want cmock to enforce ordering of all function calls?
  :fail_on_unexpected_calls: true  # Do we want cmock to fail when it encounters a function call that wasn't expected?
  :callback_include_count: true    # Do we want cmock to include the number of calls to this callback, when using callbacks?
  :callback_after_arg_check: false # Do we want cmock to enforce an argument check first when using a callback?
  #:includes: []                   # You can add additional includes here, or specify the location with the options below
  #:includes_h_pre_orig_header: [] 
  #:includes_h_post_orig_header: []
  #:includes_c_pre_header:  []
  #:includes_c_post_header:  []
  #:array_size_type:  []            # Specify a type or types that should be used for array lengths
  #:array_size_name:  'size|len'    # Specify a name or names that CMock might automatically recognize as the length of an array
  :exclude_setjmp_h:  false        # Don't use setjmp when running CMock. Note that this might result in late reporting or out-of-order failures.

# Configuration options specific to Unity. 
:unity:
  :defines:
    - UNITY_EXCLUDE_FLOAT

# You can optionally have ceedling create environment variables for you before
# performing the rest of its tasks.
:environment: []
# :environment:
#   # List enforces order allowing later to reference earlier with inline Ruby substitution
#   - :var1: value
#   - :var2: another value
#   - :path:            # Special PATH handling with platform-specific path separators
#     - #{ENV['PATH']}  # Environment variables can use inline Ruby substitution
#     - /another/path/to/include

# 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: []

################################################################
# PLUGIN CONFIGURATION
################################################################

# 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
    # - HtmlDetailed
    # - Text
    # - Cobertura
    # - SonarQube
    # - JSON
    # - HtmlInline
    # - HtmlInlineAzure
    # - HtmlInlineAzureDark
    # - HtmlChart
    # - MHtml
    # - Badges
    # - CsvSummary
    # - Latex
    # - LatexSummary
    # - PngChart
    # - TeamCitySummary
    # - lcov
    # - Xml
    # - XmlSummary
  :gcovr:
    # :html_artifact_filename: TestCoverageReport.html
    # :html_title: Test Coverage Report
    :html_medium_threshold: 75
    :html_high_threshold: 90
    # :html_absolute_paths: TRUE
    # :html_encoding: UTF-8

# :module_generator:
#   :project_root: ./
#   :source_root: source/
#   :inc_root: includes/
#   :test_root: tests/
#   :naming: :snake #options: :bumpy, :camel, :caps, or :snake
#   :includes:
#     :tst: []
#     :src: []
#   :boilerplates:
#     :src: ""
#     :inc: ""
#     :tst: ""

# :dependencies:
#   :libraries:
#     - :name: WolfSSL
#       :source_path:   third_party/wolfssl/source
#       :build_path:    third_party/wolfssl/build
#       :artifact_path: third_party/wolfssl/install
#       :fetch:
#         :method: :zip
#         :source: \\shared_drive\third_party_libs\wolfssl\wolfssl-4.2.0.zip
#       :environment:
#         - CFLAGS+=-DWOLFSSL_DTLS_ALLOW_FUTURE
#       :build:
#         - "autoreconf -i"
#         - "./configure --enable-tls13 --enable-singlethreaded"
#         - make
#         - make install
#       :artifacts:
#         :static_libraries:
#           - lib/wolfssl.a
#         :dynamic_libraries:
#           - lib/wolfssl.so
#         :includes:
#           - include/**

# :subprojects:  
#   :paths:
#    - :name: libprojectA
#      :source:
#        - ./subprojectA/source
#      :include:
#        - ./subprojectA/include
#      :build_root: ./subprojectA/build
#      :defines: []

# :command_hooks:
#   :pre_mock_preprocess:
#   :post_mock_preprocess:
#   :pre_test_preprocess:
#   :post_test_preprocess:
#   :pre_mock_generate:
#   :post_mock_generate:
#   :pre_runner_generate:
#   :post_runner_generate:
#   :pre_compile_execute:
#   :post_compile_execute:
#   :pre_link_execute:
#   :post_link_execute:
#   :pre_test_fixture_execute:
#   :post_test_fixture_execute:
#   :pre_test:
#   :post_test:
#   :pre_release:
#   :post_release:
#   :pre_build:
#   :post_build:
#   :post_error:

################################################################
# TOOLCHAIN CONFIGURATION
################################################################

#: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
# :tools:
#   :test_compiler: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :test_linker: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :test_assembler: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :test_fixture: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :test_includes_preprocessor: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :test_file_preprocessor: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :test_file_preprocessor_directives: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :test_dependencies_generator: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :release_compiler: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :release_linker: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :release_assembler: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
#   :release_dependencies_generator: 
#     :executable:
#     :arguments: []
#     :name: 
#     :optional: FALSE
...

@mvandervoord
Copy link
Member

Thanks for the extra info. I see what the issue is. I'll have a fix rolling out soon. :)

@mikewzr
Copy link
Author

mikewzr commented Jan 13, 2025

Nice, thank you. Happy that I could help. 👍

@mkarlesky
Copy link
Member

mkarlesky commented Jan 14, 2025

@mikewzr We found the problem. The root cause is a difference in the preprocessors offered by the locally installed toolchains that Ceedling calls. There's a few different steps involved in preprocessing test and mockable header files. In one of those steps Ceedling asks gcc to run the file through the preprocessor but only handle directives (e.g. #ifdef); otherwise, it leaves macros untouched. Ceedling then processes the output and extracts macros to be reconstituted with other information in the file that Ceedling generates.

It turns out that some toolchains interpret this mode differently — specifically, some preserve comments. The code in Ceedling that processes the file on the other side of this directives-only preprocessing step assumes that comments will have been stripped by the toolchain preprocessor. Therein lies the problem!

Unfortunately, it doesn't appear there's a foolproof way to ensure comments get stripped out via the toolchain preprocessor. But, Ceedling handles comment stripping itself in other cases. With a little surgery we can make use of that functionality to ensure toolchain-preprocessed output is always stripped of comments in this case.

The fix is forthcoming.

@mvandervoord
Copy link
Member

Hi @mikewzr -- if you're able, can you give the latest prerelease of 1.0.1 a shot? I believe it should fix the issue you encountered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants