Ceedling icon indicating copy to clipboard operation
Ceedling copied to clipboard

Application with multiple Ceedling projects

Open xXFrank01Xx opened this issue 10 months ago • 2 comments

Hello,

Using Ceedling 1.0.0, my application includes multiple Ceedling projects for my modules and I ran on a problem when I want to run the unit tests of all the project at once.

My project looks like this:

main.c
config.h
modules
  |__ ModuleA
  |__ ModuleB

In this example, both ModuleA and ModuleB are set up as Ceedling projects, which allows me to individually test them like:

> cd modules/ModuleA
> ceedling test

The only way I found to allow me to run all unit tests with one command is to make the whole application a Ceedling project, having a project.yml file in the root of the project in addition to the ones in ModuleA and ModuleB, making it look like this:

main.c
config.h
project.yml
modules
  |__ ModuleA
  |     |__ src
  |     |     |__ ModuleA.h
  |     |     |__ ModuleA.c
  |     |__ test
  |     |     |__ test_ModuleA.c
  |     |__ project.yml
  |__ ModuleB
        |__ (same as ModuleA)

With very simple modules it works, but since my Modules are built to be reuseable in different projects, they require a configuration to adapt them, which is located in my example in the file config.h. This means that my application does not use all the capabilities of the module as some things are turned off, but I want my module to be fully tested. To do that, I use the support folder:

main.c
config.h  <- version used by my application
project.yml
modules
  |__ ModuleA
        |__ src
        |     |__ ModuleA.h
        |     |__ ModuleA.c
        |__ test
        |     |__ support
        |     |     |__ config.h  <- version to test ModuleA
        |     |__ test_ModuleA.c
        |__ project.yml

If I run ceedling from the ModuleA folder, it works well, but if I run it from the root folder, it seems like the test runner sees the file from the support folder, but no matter what I'm doing, the ModuleA source file cannot see it and looks for the other one, which creates compilation errors.

Is there a way to fix this, or I need to find work around to run Ceedling in all the modules without making the whole app a Ceedling project?

Thank you

xXFrank01Xx avatar Feb 13 '25 15:02 xXFrank01Xx

I started to respond to this with enthusiasm, thinking I had the perfect solution for you... and now I'm realizing I have a close-but-not-yet solution:

You want to check out the dependencies plugin.

It's designed to have sub-projects which stand on their own. So each of your subprojects could have their own project.yml file and have their own build and configuration information. Then, the full project would include the dependencies plugin to use those files along with the rest of your source to build/test just the things you care about for your main project.

While it's documentation needs more work, it already has the capability of optionally fetching source code from somewhere else (in your case, it's already there). It also has the capability of optionally posting various artifacts when done. In your case, you can set the artifacts as source and include paths of files you want your main project to pick up. You can even optionally have different configuration settings for these different projects.

This plugin introduces new command-line options of the following:

  • dependencies:clean
  • dependencies:fetch
  • dependencies:make
  • dependencies:deploy

There's rarely even any need to learn these, as it will automatically trigger the ones you need when it goes to build these dependencies!

But here's where the disappointment comes in: In my memory, there was also a dependencies:test option. It's job was to trigger any tests that that dependency might have. It's in my original plan for it, but I can see we didn't get that far when we pushed the last release. So this feature will be "someday" but not now.

All this to say that there IS intention of handling exactly the situation you are describing: a single command which runs all the tests. But at this moment, there isn't a simple way to do it.

mvandervoord avatar Feb 13 '25 15:02 mvandervoord

Thank you for the quick reply. I will be waiting for this feature.

For the moment, I found a workaround that I'll leave here in case it helps others: In my project.yml in the root of the project, I added a define ROOT_TEST that is not present in the project.yml inside the modules

main.c
config.h
project.yml  <- Added ROOT_TEST as preprocessor define
modules
  |__ ModuleA
        |__ src
        |     |__ ModuleA.h
        |     |__ ModuleA.c
        |__ test
        |     |__ support
        |     |     |__ config.h
        |     |__ test_ModuleA.c
        |__ project.yml

And inside ModuleA.h, I force which config.h to select:

ModuleA.h

#if defined(ROOT_TEST)
#    include "../test/support/config.h"
#else
#    include "config.h"
#endif

The results:

  • When compiling the application, it uses the official config.h in the root folder
  • When executing ceedling test from inside the ModuleA it knows to take the one in the support folder
  • When executing ceedling test:all from the root folder, it's forced to take the specific one from that specific support folder

It is not the cleanest solution, but I can live with it for now.

Thanks again

xXFrank01Xx avatar Feb 13 '25 18:02 xXFrank01Xx