ThrowTheSwitch / Ceedling

Ruby-based unit testing and build system for C projects

Home Page:http://throwtheswitch.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ceedling cannot work if the header file and the source file do not share the same name?

roxysosa opened this issue · comments

Hello, I'm experiencing an issue with Ceedling. It seems unable to link the header file properly. In this scenario, I have two files named A.c and B.c, and both are using the same header file named M.h. When I execute the test_A.c file, I encounter an error indicating that the functions in A.c are undefined. Upon further investigation, I realize that the issue arises because the header file and the source file do not share the same name (A.c -> M.h). Therefore, I need to find a solution that allows me to work with this naming configuration. What steps can I take to resolve this?
Thanks in advance. :)

Hi. From your test, you can still include the header file (if you otherwise still want it included). In addition, you can use the following macro to specify that you also want to include an additional source file in your test:

TEST_FILE("A.c");

Also, a quick note: In the soon-to-be-released Ceedling, this feature is getting an updated name to the following:

TEST_SOURCE_FILE("A.c");

What about the header file? I don't want to include an additional source file in my test. The issue is that the header file used for this test has a different name than the source file I am testing, which causes the function I want to test to be undefined.
In this case, the header file is named bus.h, and the source file is buss.c, which includes #include "bus.h". My test file is named test_buss.c, also including #include "bus.h". The path is correct in the project.yml file.

terminal
ceedling test:buss
output:

  Test 'test_buss.c'
  ------------------
  Generating runner for test_buss.c...
  Compiling test_buss_runner.c...
  Compiling test_buss.c...
  Linking test_buss.out...
  /usr/bin/ld: build/test/out/c/test_buss.o: in function `test_bus_readBus32_should_ShowAnErrorrMessageAndEndTheOparetion_when_DoesNotOpendFile':
  /home/quside/Documents/Rsosa/modules/bus/test/test_buss.c:62: undefined reference to `readBus32'
  /usr/bin/ld: /home/Documents/Rsosa/modules/bus/test/test_buss.c:66: undefined reference to `readBus32'
  /usr/bin/ld: /home/Documents/Rsosa/modules/bus/test/test_buss.c:67: undefined reference to `readBus32'
  /usr/bin/ld: /home/Documents/Rsosa/modules/bus/test/test_buss.c:73: undefined reference to `readBus32'
  collect2: error: ld returned 1 exit status
  ERROR: Shell command failed.
  > Shell executed command:
  'gcc "build/test/out/c/test_buss_runner.o" "build/test/out/c/test_buss.o" "build/test/out/c/unity.o" "build/test/out/c/cmock.o" -o "build/test/out/test_buss.out" -lm -lpci'
  > And exited with status: [1].
  
  
  NOTICE: If the linker reports missing symbols, the following may be to blame:
    1. Test lacks #include statements corresponding to needed source files.
    2. Project search paths do not contain source files corresponding to #include statements in the test.
    3. Test does not #include needed mocks.
  
  rake aborted!
  
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/generator.rb:151:in `rescue in generate_executable_file'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/generator.rb:137:in `generate_executable_file'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/rules_tests.rake:39:in `block in <top (required)>'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/task_invoker.rb:107:in `invoke_test_results'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/test_invoker.rb:125:in `block in setup_and_invoke'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/test_invoker.rb:51:in `each'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/test_invoker.rb:51:in `setup_and_invoke'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/rules_tests.rake:70:in `block (2 levels) in <top (required)>'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/bin/ceedling:345:in `block in <top (required)>'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/bin/ceedling:332:in `<top (required)>'
  /usr/local/bin/ceedling:23:in `load'
  /usr/local/bin/ceedling:23:in `<main>'
  
  Caused by:
  ShellExecutionException: ShellExecutionException
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/tool_executor.rb:88:in `exec'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/generator.rb:136:in `generate_executable_file'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/rules_tests.rake:39:in `block in <top (required)>'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/task_invoker.rb:107:in `invoke_test_results'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/test_invoker.rb:125:in `block in setup_and_invoke'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/test_invoker.rb:51:in `each'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/test_invoker.rb:51:in `setup_and_invoke'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/lib/ceedling/rules_tests.rake:70:in `block (2 levels) in <top (required)>'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/bin/ceedling:345:in `block in <top (required)>'
  /var/lib/gems/2.7.0/gems/ceedling-0.31.1/bin/ceedling:332:in `<top (required)>'
  /usr/local/bin/ceedling:23:in `load'
  /usr/local/bin/ceedling:23:in `<main>'
  Tasks: TOP => build/test/results/test_buss.pass => build/test/out/test_buss.out
  (See full trace by running task with --trace)
  ERROR: Ceedling Failed

Sorry. For clarity, is your situation that the following files exist:

  • bus.h
  • bus.c
  • buss.c

Or that only these two exist:

  • bus.h
  • buss.c

If it's the latter, it's easy. Your test would include the header and then specify the source file:

// test_buss.c
#include "bus.h"
TEST_FILE("buss.c")

// the rest of the file

If you're the first situation above, you're saying you want test_buss.c to use bus.h but NOT bus.c, correct?

This is going to sound silly, but you can do this:

// test_buss.c
#include "mock_bus.h"
TEST_FILE("buss.c")

// the rest of the file

The file mock_bus.h will include bus.h to give you the header you need access to, but it won't include the real bus.c. Instead, it'll include the mock... That doesn't mean you have to use the mock... you can make 0 calls to it. :)