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