ThrowTheSwitch / Ceedling

Ruby-based unit testing and build system for C projects
http://throwtheswitch.org
Other
587 stars 247 forks source link

Undefined reference due to leading underscore for variables and functions #336

Closed austrobayer closed 5 years ago

austrobayer commented 5 years ago

Hi,

tried to run Ceedling on an existing Microchip XC16 project with the sim30 simulator. With the help of an articel from Atomic Object i was able to run a "Dummy Test" like that.

#include "unity.h"           

#include "AEB_PROTOTYPES.h"     //All-In-One header file

void setUp(void)
{

}

void tearDown(void)
{

}

/**
* @fn: test_DummyTest_AlwaysFail()
* @Description: Test will always fail
*/
void test_DummyTest_AlwaysFail(void)
{
    TEST_FAIL_MESSAGE("Dummytest will always fail!");
}

But when i try to call a function declared in the AEB_PROTOTYPES.h (or one of sub headers included) i am getting "undefined references" errors.

Example: If i try to call the function "iCanModul" which is declared in a header file included in AEB_PROTOTYPES.h i am getting the following error message: grafik

Code is nearly the same like the one above, just added the function call in test_DummyTest_AlwaysFail() function:

void test_DummyTest_AlwaysFail(void)
{
    int iRetValue = 0;

    //Call SUT
    iRetValue = iCanModul(1);

    TEST_ASSERT_EQUAL_INT16_MESSAGE(10, iRetValue, "iCanModul return value not equal R_CANMODUL(10)");
}

Somehow Ceedling/Unity,... added leading underscores to functions and variables. Or do i have some problems in my project.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: vendor/ceedling
  :default_tasks:
    - test:all

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

:environment:

:extension:
  :executable: .out

:paths:
  :test:
    - +:test/**
    - -:test/support
  :source:
    - ../../AEB/src/
  :include:
    - "C:/PROGRA~2/Microchip/xc16/v1.21/support/dsPIC33F/h"
    - "C:/PROGRA~2/Microchip/xc16/v1.21/support/generic/h"
    - ../../AEB/h/
  :support:
    - test/support

: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)
  :commmon: &common_defines
    - __dsPIC33E__
    - __dsPIC33EP256GP506__
    - UNITY_INT_WIDTH=16
    - CMOCK_MEM_INDEX_TYPE=uint16_t
    - CMOCK_MEM_PTR_AS_INT=uint16_t
    - CMOCK_MEM_ALIGN=2
    - CMOCK_MEM_SIZE=4096
    - CMOCK_MEM_STATIC
#    - TESSY
  :test:
    - *common_defines
    - TEST
  :test_preprocess:
    - *common_defines
    - TEST

:cmock:
  :mock_prefix: mock_
  :when_no_prototypes: :warn
  :enforce_strict_ordering: TRUE
  :when_ptr: :smart
  :ignore: :args_only
  :treat_externs: :include
  :plugins:
    - :ignore
    - :ignore_arg
    - :callback
    - :array
    - :expect
    - :return_thru_ptr
  :treat_as:
    uint8:    HEX8
    uint16:   HEX16
    uint32:   UINT32
    int8:     INT8
    bool:     UINT8

:gcov:
    :html_report_type: basic

#: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: xc16-gcc
    :arguments:
      - "${1}"
      - -o "${2}"
      - -c
      - -mcpu=33EP256GP506
      - -MMD
      - -MF "${3}"
      - -mno-eds-warn
      - -g
      - -O1
      - -mno-override-inline
      - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR
      - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
      - -msmart-io=1
      - -Wall
      - -msfr-warn=off
      - -Winline
  :test_linker:
    :executable: xc16-gcc
    :arguments:
      - -mcpu=33EP256GP506
      - -o "./build/release/TestBuild.out"
      - ${1}
      - -x
      - -legacy-libc
      - -Wl,--local-stack,--defsym=__MPLAB_BUILD=1,,--script="..\..\AEB\gld\AEB_p33EP256GP506.gld",--stack=16,--no-check-sections,--data-init,--pack-data,--handles,--isr,--no-gc-sections,--fill-upper=0,--stackguard=16,--no-force-link,--smart-io
  :test_fixture:
    :executable: ruby
    :name: "Microchip simulator test fixture"
    :stderr_redirect: :win #inform Ceedling what model of $stderr capture to use
    :arguments:
      - test/simulation/sim_test_fixture.rb

  :release_compiler:
   :executable: xc16-gcc
   :arguments:
      - "${1}"
      - -o "${2}"
      - -c
      - -mcpu=33EP256GP506
      - -MMD
      - -MF "${3}"
      - -mno-eds-warn
      - -g
      - -O1
      - -mno-override-inline
      - -D$: COLLECTION_DEFINES_TEST_AND_VENDOR
      - -D__dsPIC33E__
      - -I"$": COLLECTION_PATHS_TEST_SUPPORT_SOURCE_INCLUDE_VENDOR
      - -msmart-io=1
      - -Wall
      - -msfr-warn=off
      - -Winline
  :release_linker:
    :executable: xc16-gcc
    :arguments:
      - -mcpu=33EP256GP506
      - -o "./build/release/Testbuild.out"
      - ${1}
      - -x
      - -legacy-libc
      - -Wl,--local-stack,--defsym=__MPLAB_BUILD=1,,--script="..\..\AEB\gld\AEB_p33EP256GP506.gld",--stack=16,--no-check-sections,--data-init,--pack-data,--handles,--isr,--no-gc-sections,--fill-upper=0,--stackguard=16,--no-force-link,--smart-io

# 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: "${1}"  # or "-L ${1}" for example
  :common: &common_libraries []
  :test:
    - *common_libraries
  :release:
    - *common_libraries

:plugins:
  :load_paths:
    - vendor/ceedling/plugins
  :enabled:
    - stdout_pretty_tests_report
    - module_generator
...

Running tests on a Windows 7 64Bit, Microchip x 2.10 with XC16 2.10. Ceedling 0.28.2 CException 1.3.1.18 CMock 2.4.4.215 Unity 2.4.1.120

Thanks for your help :) By the way, i am loving Ceeding/Unity one of my preferred tools for unit testing.

Best regards

mvandervoord commented 5 years ago

Is the actual implementation of iCanModule in AEB_PROTOTYPES.h, AEB_PROTOTYPES.c, or somewhere else?

If the answer is the latter, you're going to need to include the corresponding header file for THAT file in order to tell Ceedling to look for he header. If there IS no corresponding header, then you can create one that includes the function prototypes, just for testing.

The believe the function name being prepended with an underscore is a red herring. If I remember correctly (and I admit it's been a couple years), I believe this is a quirk of the way the XC16 compiler preprocesses files... but it's consistent so it's not the problem you're looking for.

If that doesn't end up being the case, you might consider turning off Ceedling's preprocessor by updating your yaml file:

:project:
  :use_test_preprocessor: FALSE

If neither work. Come on back and we'll try again. ;)

austrobayer commented 5 years ago

@mvandervoord thanks a lot!

I was so confused about the leading underscore that i didnt saw the problems with the includes. After I have inserted all includes separately, no more leading underscores will be created. And yeah, architecture of the SW is horrible, but thats our problem :p

I also had to set "use_test_preprocessor: FALSE" in my project.yml and at the moment everything is running like expected :)

Thanks again.