Problems with adding CppUTest to existing project

Sysprogs forums Forums VisualGDB Problems with adding CppUTest to existing project

  • This topic has 8 replies, 2 voices, and was last updated 1 year ago by GeneM.
Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #34823
    GeneM
    Participant

    Tonight was the night I was going to try to figure out how to add a unit test framework to an existing VisualGDB C++ project so I was very pleased to see the Using the CppUTest framework with STM32 devices tutorial.  I ran through it and it worked fine although I did have to check the “Exclude sampling profiler code” option in the Fast Semihosting and Embedded Profile framework like usual.  I went through it again only as a MSBuild project instead of an Advanced CMake project and that worked fine also.  I added my MSBuild unit test project to an existing MSBuild project and it worked fine also.  My understanding is I should be able to #include .hpp files from my main project in my unit test project and build unit tests for the functions in the file I #included.  When I #include a very simple .hpp file, I get a lot of errors (see attached file).  I’m using VisualGDB version 5.6R9 (build 4777).  And I have C++17 with GNU extensions for the language standard. Here’s the #include file I’m trying to add to the unit test project.

    #pragma once

    #include <string>

    namespace CPFUtils
    {
    std::string getField(std::string inString, std::string delimiter, uint32_t desiredFieldNum);
    }

    and the .cpp file

    #include "CPFUtilities.hpp"

    std::string CPFUtils::getField(std::string inString, std::string delimiter, uint32_t desiredFieldNum)
    {
    int currentFieldNum = 0;

    int end = inString.find(delimiter);
    while (end != -1)
    {
    inString.erase(inString.begin(), inString.begin() + end + 1);
    end = inString.find(delimiter);
    if (currentFieldNum == desiredFieldNum - 1)
    break;
    else
    currentFieldNum++;
    }
    return inString.substr(0, end);
    }

    I’m sure I’m doing something dumb but I could use some help figuring it out.

    Thanks

     

    Attachments:
    You must be logged in to view attached files.
    #34829
    support
    Keymaster

    Hi,

    The embedded unit test projects are completely separate from other projects. So just including a header file from a different project will not work in most cases. You would need to also have the correct preprocessor macros, include paths, sources, libraries and other relevant settings.

    It is not specific to VisualGDB or unit tests – a good starting point would be to create a new embedded application (non-test) from scratch, move the relevant sources there and fix the build errors. Once you get it working, the same steps will work for a unit test project.

    #34835
    GeneM
    Participant

    I did what I think you suggested:  I built a new project from scratch, I used the LEDBlink example from the Embedded Project Wizard.  It built and ran just fine.  I added the existing CPFUtilities.hpp and CPFUtilities.cpp” files to the project and a #include “CPFUtilities.hpp” line and it built and ran fine also.  I built a new Basic CppUTest Demo (HAL) project and it built and ran just fine.  When I added the CPFUtilities.hpp and .cpp files and the #include “CPFUtilities.hpp” line just like I did for the LEDBlink example project, I got the same errors I attached to the my first post. I tried adding the CPFUtiliities files with the add existing button in the solution explorer and selecting the files in the top level CPF project folder.  I also tried copying the CPFUtilities files into the CppUTestTutorial project folder and got  the same errors both ways.

    My CPFUtilities .hpp file is pretty simple.  It only include <string> and <stdint.h>.

    The first error “declaration of ‘operator new’ as non-function’ shows up in the “new” file which is “The -*- C++ -*- dynamic memory management header”.

    The next error ‘no matching function for call to ‘operator new(const char[73], int)’ shows up in the “MemoryLeakDetectorNewMacros.h” file.

    Based on these facts, it doesn’t seem like a simple program that #includes CPFUtilities doesn’t need these additional files but the CppUTest project does.  I’m just guessing but it seems like the CppUTestTutorial doesn’t know where to look for some missing header files.

     

    #34836
    GeneM
    Participant

    New piece of information: I built a Tiny Embedded test project, I was able to add my CPFUtilities Files and this test ran as expected.  The first one passed and the second one failed.

    TEST(DemoTestGroup, MyTest)
    {
    //this should pass
    std::string returnField = CPFUtils::getField("field0,field1,field2,field3", ",", 2);
    STRCMP_EQUAL("field2", returnField.c_str());
    
    //this should fail
    returnField = CPFUtils::getField("field0,field1,field2,field3", ",", 3);
    STRCMP_EQUAL("field2", returnField.c_str());
    }
    
    • This reply was modified 1 year, 2 months ago by GeneM.
    • This reply was modified 1 year ago by support.
    • This reply was modified 1 year ago by support.
    #34878
    GeneM
    Participant

    I’d still like to figure out how to use CppUTest with my project.  As noted above, I can use the Tiny Embedded Test framework quite nicely.  Any suggestions about what I need to do differently to use CppUTest will be appreciated.   Thanks.

    #34879
    support
    Keymaster

    Hi,

    Based on what you described, including a specific header file from your project into a CPPUtest project results in a build error. VisualGDB doesn’t crash or do anything unexpected – it reports the build error as it is supposed to.

    In general, VisualGDB cannot automatically fix errors in the code, or automatically make different libraries compatible. It’s up to the user to make sure the code they are trying to build does not contain errors, and that different pieces they are trying to put together are compatible.

    You can try exporting the build command line used by VisualGDB into a batch file as shown here and building it manually. Once you reproduce the same build error, you can troubleshoot it just as if it was a regular CMake C++ project not involving VisualGDB.

    #35060
    GeneM
    Participant

    I’m still a little confused about how to use TinyEmbeddedTests with my main embedded C/C++ project.  I’ve built a new unit test project per the tutorial and it runs fine.  I’ve added that project to the VGDB solution that has the main project I’m working on.  I’m trying to get the unit test project to find the header and source files from my main project so I can write unit tests for the functions in the main project without having to copy them into the unit test project.  I’ve add the main project folder to the “Additional Include Directories” and the “Additional System Include Directories” in the C/C++ Project Properties of the unit test project.  I’ve also added the main project folder to the “Library Search Directories” in the Linker Project properties.  However when I #include one of the .hpp files from my main project to my unit test project, VGDB doesn’t automatically find it.  VGDB does pop up the window asking if I want to include it and pointing at where it found the header file.  I can tell VGDB to add that .hpp file and my project builds.  But when I add a call to one of the functions declared in the .hpp file and defined in the .cpp file of the same name in the same folder as the .hpp file, VGDB gives me an undefined reference error which I think means it can’t find the .cpp file with the function I’m calling.  Here’s the error:

    c:/sysgcc/arm-eabi/bin/../lib/gcc/arm-none-eabi/12.2.1/../../../../arm-none-eabi/bin/ld.exe: VisualGDB/Debug/TinyEmbeddedTestsTests.o: in function `TestInstance_CPFTestGroup_SuccessfulTest1::run()’:
    C:\Users\gene\Documents\CPF\Software\CPF2023Aug15\CPFsom\VGDBProject\TinyEmbeddedTests/TinyEmbeddedTestsTests.cpp:38: undefined reference to `CPFUtils::getField(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned long)’
    Build failed: arm-none-eabi-g++.exe exited with code 1
    collect2.exe: error: ld returned 1 exit status

    Here are some specific questions:

    Q1: Is my approach of having a main project and a unit test project an appropriate approach?  If not, what is the preferred approach?

    Q2: What is the correct way to tell the unit test project where to look for additional header and source files in the main project without having to maintain a separate copy in each project? Do I have to manually “Add existing item” for every .cpp file in my main project into my unit test project? If so, it there a way to automate this process?

    Q3: By looking at the .vcxproj file, it looks like adding the top level main project folder to the “Additional Include Directories” all the subdirectories got added also.  Is that correct?  If so, is it just the way VGDB works that it asks me if I want to include a new #include header file the first time?

    Thanks for all the help

    • This reply was modified 1 year ago by GeneM.
    • This reply was modified 1 year ago by GeneM.
    • This reply was modified 1 year ago by support.
    • This reply was modified 1 year ago by support.
    • This reply was modified 1 year ago by support.
    #35089
    support
    Keymaster

    Please make sure you have a solid understanding of the following topics:

    • How include search paths work, and how they are different from adding header files to Solution Explorer. We have a tutorial on this here, but you can find plenty of information from other sources as well.
    • How C linking works, what are object files, libraries, library search directories and how symbol definitions are different from declarations in header files. We have another tutorial on this here.

    These are fundamental C topics, and most VisualGDB features are designed assuming that the user is familiar with them. Trying to edit various files and using features like Header Discovery without understanding these will only cause cascades of increasingly strange errors.

    Specifically to your questions:

    1. This is the correct approach.
    2. You can try using the “Add->Import folder recursively” command in the context menu or shared items projects.
    3. Adding the top-level folder to the include search directories should not automatically add subdirectories.
    #35090
    GeneM
    Participant

    Thanks, that’s just what I need.  I’m trying to build up a solid understanding of the topics you mentioned (and a lot of other topics) and this information will help a lot.

Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.