1

I'm trying to write my own CMake build system for the STM32F407 on Windows. Below is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.0)

project(test_1 LANGUAGES C)

#Set the path if arm-none-eabi's bin folder is not added in the SYSTEM path environment variable

set(CMAKE_TOOLCHAIN_FILE "toolchain_stm32f407.cmake")

set_property(SOURCE startup_stm32f407xx.s PROPERTY LANGUAGE C)

set(INCLUDE_DIRECTORIES     ./inc)
include_directories(${INCLUDE_DIRECTORIES})

set(SOURCE_FILES        ./src/main.c)
add_executable(${CMAKE_PROJECT_NAME}.elf ${SOURCE_FILES})


add_custom_target(TARGET ${CMAKE_PROJECT_NAME}.elf POST_BUILD
    COMMAND ${CMAKE_SIZE} --format=berkeley "${CMAKE_PROJECT_NAME}.elf")

I have 2 toolchain files. One works properly and another one gives me an error. Erroneous toolchain file:

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR ARM)

option(LINUX OFF)

#Set the path if arm-none-eabi's bin folder is not added in the SYSTEM path environment variable
if(LINUX)
    set(ARM_TOOLCHAIN_PATH "./gcc-arm-none-eabi-9-2019-q4-major/bin")
else(LINUX)
    set(ARM_TOOLCHAIN_PATH "D:/gcc-arm-none-eabi-7-2018-q2-update/bin")
    set(EXE ".exe")
endif(LINUX)

set(LINKER_PATH "./STM32F407VGTx_FLASH.ld")

option(DEBUG ON)

set(CMAKE_C_COMPILER_WORKS ON)
set(CMAKE_CXX_COMPILER_WORKS ON)

set(CMAKE_C_COMPILER    ${ARM_TOOLCHAIN_PATH}/arm-none-eabi-gcc${EXE})
set(CMAKE_CXX_COMPILER  ${ARM_TOOLCHAIN_PATH}/arm-none-eabi-g++.exe${EXE})
set(CMAKE_ASM_COMPILER  ${ARM_TOOLCHAIN_PATH}/arm-none-eabi-as.exe${EXE})
set(CMAKE_OBJCOPY   ${ARM_TOOLCHAIN_PATH}/arm-none-eabi-objcopy${EXE})

if(DEBUG)
    set(DEBUG_FLAG "-g")
endif(DEBUG)

set(COMMON_FLAGS    "-mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 -mthumb-interwork ${DEBUG_FLAG} \
            -mcpu=cortex-m4 -march=armv7e-m \
            -Wall -fdata-sections -ffunction-section")
#Should these flags be added?: -Wall -Wextra -Wimplicit-function-declaration -Wredundant-decls -Wstrict-prototypes
#-Wundef -Wshadow
set(CMAKE_C_FLAGS       "${COMMON_FLAGS} -std=gnu99 --specs=nosys.specs")   
set(CMAKE_CXX_FLAGS     "${COMMON_FLAGS} -std=c++11 --specs=nosys.specs")
set(CMAKE_EXE_LINKER_FLAGS  "${COMMON_FLAGS} -Wl,-map=linker.map -Wl,--gc-sections" CACHE INTERNAL "")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

Error:

>cmake -H. -B_build -DCMAKE_TOOLCHAIN_FILE:PATH="toolchain_stm3
2f407.cmake"
-- The C compiler identification is unknown
CMake Error at CMakeLists.txt:3 (project):
  The CMAKE_C_COMPILER:

    D:/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-gcc.exe

  is not a full path and was not found in the PATH.

  Tell CMake where to find the compiler by setting either the environment
  variable "CC" or the CMake cache entry CMAKE_C_COMPILER to the full path to
  the compiler, or to the compiler name if it is in the PATH.


-- Configuring incomplete, errors occurred!

Properly working toolchain:(Got the toolchain file from this question:Link)

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)

set(CMAKE_C_COMPILER "arm-none-eabi-gcc.exe")
set(CMAKE_CXX_COMPILER "arm-none-eabi-g++.exe")

set(CMAKE_EXE_LINKER_FLAGS "--specs=nosys.specs" CACHE INTERNAL "")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

My questions are:

  1. I'm unable to understand what is lacking in the erroneous toolchain file which is causing that error.
  2. In CMakeLists.txt, I have set CMAKE_TOOLCHAIN_FILE to the toolchain file. But the toolchain file is not detected unless I pass it as a CLI option using "-DCMAKE_TOOLCHAIN_FILE:PATH=". What is causing this?
  3. Why does only CMAKE_EXE_LINKER_FLAGS need to be cached?

Thanks

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
Flam3blazer
  • 41
  • 1
  • 2
  • 3
  • `D:/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-gcc.exe` so does this file exists? `In CMakeLists.txt, I have set CMAKE_TOOLCHAIN_FILE to the toolchain file` It has to be set __before__ `project()`. The `project()` function actually does the sourcing of the toolchain file. `Why does only CMAKE_EXE_LINKER_FLAGS need to be cached?` they don't, remove it. And set `CMAKE_EXE_LINKER_FLAGS_INIT` from the toolchain file. `startup_stm32f407xx.s PROPERTY LANGUAGE C)` - assembly file is an assembly file not a C file. Remove it and instead set `CMAKE_ASM_COMPILER` to gcc – KamilCuk Apr 23 '20 at 20:19
  • `if(DEBUG) set(DEBUG_FLAG "-g") endif(DEBUG)` remove this - cmake has `CMAKE_BUILD_TYPE`. Don't introduce your own layers. Do not set `-std=gnu99` and `-std=c++11` from the toolchain - there are `CMAKE_C(XX)_STANDARD` variables for that. So are you compiling on `if(LINUX)` or not? Just `set` the `CMAKE_C_COMPILER` to the path to your compiler and with `set(CMAKE_C_COMPILER_WORKS ON)` it should work. – KamilCuk Apr 23 '20 at 20:23
  • You have 3 questions, and this contradicts to the intention of Stack Overflow to be Question/Answer site. Please, leave only a single question in a question post and provide more information about it, – Tsyvarev Apr 23 '20 at 20:38
  • @KamilCuk Thanks for your replies! I checked again and I had the linux version of the compiler instead of the Window exe version. I have fixed that and moved the set CMAKE_TOOLCHAIN_FILE line to above the project() statement but I am still seeing the "CMAKE_C_COMPILER is not a full path" error. Does CMAKE_C_COMPILER need to be cached? – Flam3blazer Apr 24 '20 at 03:03
  • @KamilCuk Thanks! I did not know about CMAKE_BUILD_TYPE and CMAKE_C_STANDARD variables. I've been learning about cmake just for a day and did not come across these variables. Also, I am using WIndows and wsl, that's why I'm using ```if(LINUX)``` – Flam3blazer Apr 24 '20 at 03:15

0 Answers0