Make error with CppUTest - libCppUTest.a error adding symbols

335 Views Asked by At

I am trying to create a project folder structure based on CMake, using the gcc-arm-none-eabi toolchain, and that can use QEMU (arm) to run CppUTest.

Right now, my folder structure look like this:

project/
├── app/
│   ├── src/
│   │   └── main.cpp
│   ├── tests/
│   │   ├── CMakeLists.txt
│   │   ├── FooTest.cpp
│   │   └── main.cpp
│   ├── CMakeLists.txt
│   └── runCMake.sh
├── libraries/
│   ├── errortype/
│   │   ├── include/
│   │   ├── src/
│   │   └── CMakeLists.txt
│   ├── math/
│   │   ├── include/
│   │   ├── src/
│   │   └── CMakeLists.txt
│   └── prediction/
│       ├── include/
│       ├── src/
│       └── CMakeLists.txt
└── scripts/
    └── cmake/
        ├── PreTargetDef.cmake
        ├── PostTargetDef.cmake
        └── toolchain.cmake

The app/CMakeLists.txt:

### PROJECT INITIALIZATION
cmake_minimum_required(VERSION 3.19)
project(hello-arm)

### SET TOOLCHAIN
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/../scripts/cmake/toolchain.cmake)

### CUSTOM CMAKE SCRIPTS
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/../scripts/cmake")
include(PreTargetDef)

### APPLICATION SOURCES
file(GLOB ${PROJECT_NAME}_SRC
    "src/main.cpp"
)

### CREATE EXECUTABLE
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_SRC})

### LIBRARIES TARGET INCLUDE DIRECTORIES
target_include_directories(${PROJECT_NAME} PUBLIC ${LIBERRORTYPE_INCLUDE_DIRS})

### CUSTOM CMAKE SCRIPT
include(PostTargetDef)

### OPTIONALLY COMPILE TESTS
option(COMPILE_TESTS "Compile the tests" OFF)
if(COMPILE_TESTS)
  add_subdirectory(tests)
endif(COMPILE_TESTS)

Toolchain.cmake:

cmake_minimum_required (VERSION 3.6)

#set(CMAKE_CROSSCOMPILING 1)
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(TRIPLE "arm-none-eabi")

unset(TOOLCHAIN_GCC_PROGRAM CACHE)
find_program(TOOLCHAIN_GCC_PROGRAM "${TRIPLE}-gcc" NO_DEFAULT_PATH HINTS ${ARM_CORTEX_COMPILER_PATH} $ENV{ARM_CORTEX_COMPILER_PATH})

get_filename_component(TOOLCHAIN_ROOT ${TOOLCHAIN_GCC_PROGRAM} DIRECTORY)
get_filename_component(EXE_EXT ${TOOLCHAIN_GCC_PROGRAM} EXT)

# To create static libraries suitable for link-time optimization (LTO),
# use gcc-ar and gcc-ranlib instead of ar and ranlib. See gcc -flto option
set(CMAKE_C_COMPILER       "${TOOLCHAIN_ROOT}/${TRIPLE}-gcc${EXE_EXT}"         CACHE FILEPATH "gcc" FORCE)
set(CMAKE_CXX_COMPILER     "${TOOLCHAIN_ROOT}/${TRIPLE}-g++${EXE_EXT}"         CACHE FILEPATH "g++" FORCE)
set(CMAKE_OBJCOPY          "${TOOLCHAIN_ROOT}/${TRIPLE}-objcopy${EXE_EXT}"     CACHE FILEPATH "objcopy" FORCE)
set(CMAKE_OBJDUMP          "${TOOLCHAIN_ROOT}/${TRIPLE}-objdump${EXE_EXT}"     CACHE FILEPATH "objdump" FORCE)
set(CMAKE_RANLIB           "${TOOLCHAIN_ROOT}/${TRIPLE}-gcc-ranlib${EXE_EXT}"  CACHE FILEPATH "ranlib" FORCE)
set(CMAKE_STRIP            "${TOOLCHAIN_ROOT}/${TRIPLE}-strip${EXE_EXT}"       CACHE FILEPATH "strip" FORCE)
set(CMAKE_AR               "${TOOLCHAIN_ROOT}/${TRIPLE}-gcc-ar${EXE_EXT}"      CACHE FILEPATH "ar" FORCE)
set(CMAKE_AS               "${TOOLCHAIN_ROOT}/${TRIPLE}-as${EXE_EXT}"          CACHE FILEPATH "as" FORCE)

#SET(CMAKE_EXE_LINKER_FLAGS_INIT   "--specs=nosys.specs -Wl,-gc-sections -nostdlib -static-libgcc -static-libstdc++ -nostartfiles")
set(CMAKE_EXE_LINKER_FLAGS_INIT   " --specs=nosys.specs ")
string(APPEND CMAKE_C_FLAGS_INIT   " ")
string(APPEND CMAKE_C_FLAGS_INIT_DEBUG   " ")
string(APPEND CMAKE_CXX_FLAGS_INIT   " ")
string(APPEND CMAKE_CXX_FLAGS_INIT_DEBUG   " ")

set(SHARED_LIBS OFF)
set(STATIC_LIBS ON)

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH )
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH )

PreTargetDef.cmake:

### ENABLE LANGUAGES
enable_language(C)
enable_language(CXX)
enable_language(ASM)

### COMPILE TARGET TYPE
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

### CREATE BUILD DIRECTORY IF NOT ALREADY DONE
file(MAKE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../build)

### OPTIONS
set(APP_ROOT ${CMAKE_SOURCE_DIR}/src)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_C_STANDARD 99)
set(CMAKE_EXE_LINKER_FLAGS --specs=rdimon.specs)

### COMPILE OPTIONS
list(APPEND COMPILE_OPTIONS
    -mthumb
    -mcpu=cortex-a9
    -mfloat-abi=softfp
    -mfpu=fpv4-sp-d16
    -flto
    -lm
    -lc
    -lrdimon
    -Wall
    $<$<CONFIG:RELEASE>:-g3>
    $<$<CONFIG:RELEASE>:-Os>
)

add_compile_options(
  ${COMPILE_OPTIONS}
)

### ADD SUBDIRECTORIES FOR LIBRARIES
get_filename_component(COMMON_LIBRARIES_ROOT "${CMAKE_SOURCE_DIR}/../libraries/" ABSOLUTE)
get_filename_component(COMMON_LIBRARIES_BUILD_ROOT "${CMAKE_BINARY_DIR}/common_libraries/" ABSOLUTE)

add_subdirectory(${COMMON_LIBRARIES_ROOT}/errortype/src     ${COMMON_LIBRARIES_BUILD_ROOT}/errortype)
add_subdirectory(${COMMON_LIBRARIES_ROOT}/math/src      ${COMMON_LIBRARIES_BUILD_ROOT}/math)
add_subdirectory(${COMMON_LIBRARIES_ROOT}/prediction/src ${COMMON_LIBRARIES_BUILD_ROOT}/prediction)

set( LIBS
    prediction
    errortype
)

PostTargetDef.cmake:

### TARGET LINK LIBRARY
target_link_libraries(
    ${PROJECT_NAME}
    ${COMPILE_OPTIONS}
    -Wl,-static
    -Wl,--start-group
    ${LIBS}
    -Wl,--end-group
)

And, tests/ CMakeLists.txt:

# (1) Look for installed version of CppUTest
if(DEFINED ENV{CPPUTEST_HOME})
    message(STATUS "Using CppUTest home: $ENV{CPPUTEST_HOME}")
    set(CPPUTEST_INCLUDE_DIRS $ENV{CPPUTEST_HOME}/include)
    set(CPPUTEST_LIBRARIES $ENV{CPPUTEST_HOME}/lib)
    set(CPPUTEST_LDFLAGS CppUTest CppUTestExt)
else()
    find_package(PkgConfig REQUIRED)
    pkg_search_module(CPPUTEST REQUIRED cpputest>=3.8)
    message(STATUS "Found CppUTest version ${CPPUTEST_VERSION}")
endif()

# (2) Our unit tests sources
set(TEST_APP_NAME ${PROJECT_NAME}_tests)
set(TEST_SOURCES
    mocks/IFooMock.cpp
    FooTest.cpp
    main.cpp
)

# (3) Take care of include directories
include_directories(${CPPUTEST_INCLUDE_DIRS} ../src/)
link_directories(${CPPUTEST_LIBRARIES})

# (4) Build the unit tests objects and link then with the app library
add_executable(${TEST_APP_NAME} ${TEST_SOURCES})
target_link_libraries(${TEST_APP_NAME}
    ${CPPUTEST_LDFLAGS}
    ${COMPILE_OPTIONS}
    -Wl,-static
    -Wl,--start-group
    ${LIBS}
    -Wl,--end-group
)

Doing cmake -DARM_CORTEX_COMPILER_PATH="/path/to/gcc-arm-bin/" -DCOMPILE_TESTS=ON $PROJECT_PATH creates a Makefile in the build folder for the main application and a second one under the build/tests folder. Running make produces a hello-arm file for the main app that runs under qemu-arm hello-arm just fine. But come time to make the tests/ part, I get the following error (make VERBOSE=1):

[ 91%] Building CXX object tests/CMakeFiles/hello-arm_tests.dir/main.cpp.obj
cd /home/tester/Documents/hello-qemu-arm/build/release/tests && /home/tester/miniconda3/envs/hello-qemu/bin/arm-none-eabi-g++  -I/home/tester/miniconda3/envs/hello-qemu/include -I/home/tester/Documents/hello-qemu-arm/application/tests/../src -I/home/tester/Documents/hello-qemu-arm/libraries/prediction/src/include -I/home/tester/Documents/hello-qemu-arm/build/release/common_libraries/prediction/src-config/include -I/home/tester/Documents/hello-qemu-arm/libraries/types/src/include -I/home/tester/Documents/hello-qemu-arm/build/release/common_libraries/types/src-config/include -I/home/tester/Documents/hello-qemu-arm/libraries/math/src/include -I/home/tester/Documents/hello-qemu-arm/build/release/common_libraries/math/src-config/include -I/home/tester/Documents/hello-qemu-arm/libraries/errortype/src/include -I/home/tester/Documents/hello-qemu-arm/build/release/common_libraries/errortype/src-config/include -I/home/tester/Documents/hello-qemu-arm/build/include -I/home/tester/Documents/hello-qemu-arm/libraries/etl/src/include -I/home/tester/Documents/hello-qemu-arm/libraries/etl/src/../config -O3 -DNDEBUG -mthumb -mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -flto -lm -lc -lrdimon -Wall -g3 -Os -std=gnu++17 -MD -MT tests/CMakeFiles/hello-arm_tests.dir/main.cpp.obj -MF CMakeFiles/hello-arm_tests.dir/main.cpp.obj.d -o CMakeFiles/hello-arm_tests.dir/main.cpp.obj -c /home/tester/Documents/hello-qemu-arm/application/tests/main.cpp
[100%] Linking CXX executable hello-arm_tests
cd /home/tester/Documents/hello-qemu-arm/build/release/tests && /home/tester/miniconda3/envs/hello-qemu/bin/cmake -E cmake_link_script CMakeFiles/hello-arm_tests.dir/link.txt --verbose=1
/home/tester/miniconda3/envs/hello-qemu/bin/arm-none-eabi-g++ -O3 -DNDEBUG --specs=rdimon.specs "CMakeFiles/hello-arm_tests.dir/mocks/IFooMock.cpp.obj" "CMakeFiles/hello-arm_tests.dir/FooTest.cpp.obj" "CMakeFiles/hello-arm_tests.dir/main.cpp.obj" -o hello-arm_tests   -L/home/tester/miniconda3/envs/hello-qemu/lib  -lCppUTest -lCppUTestExt -mthumb -mcpu=cortex-a9 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -flto -lm -lc -lrdimon -Wall -g3 -Os -Wl,-static -Wl,--start-group ../common_libraries/prediction/libprediction.a ../common_libraries/errortype/liberrortype.a -Wl,--end-group 
/home/tester/miniconda3/envs/hello-qemu/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld: /home/tester/miniconda3/envs/hello-qemu/lib/libCppUTest.a: error adding symbols: file format not recognized
collect2: error: ld returned 1 exit status
make[2]: *** [tests/CMakeFiles/hello-arm_tests.dir/build.make:131: tests/hello-arm_tests] Error 1
make[2]: Leaving directory '/home/tester/Documents/hello-qemu-arm/build/release'
make[1]: *** [CMakeFiles/Makefile2:296: tests/CMakeFiles/hello-arm_tests.dir/all] Error 2
make[1]: Leaving directory '/home/tester/Documents/hello-qemu-arm/build/release'
make: *** [Makefile:91: all] Error 2
0

There are 0 best solutions below