Skip to content

Instantly share code, notes, and snippets.

@bearsh
Last active October 4, 2023 10:48
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save bearsh/75251a7cb2926ea5f58f6fad5073b3a2 to your computer and use it in GitHub Desktop.
Save bearsh/75251a7cb2926ea5f58f6fad5073b3a2 to your computer and use it in GitHub Desktop.
Cmake + vscode
{
"configurations": [
{
"name": "Local",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "gcc-x64",
"compileCommands": "${workspaceFolder}/compile_commands.json"
}
],
"version": 4
}
[
{
"name": "GCC Arm Embedded",
"toolchainFile": "${workspaceRoot}/cmake/armgcc.cmake"
}
]
buildType:
default: debug
description: Build option
choices:
debug:
short: Debug
long: Build with debugging information
buildType: Debug
release:
short: Release
long: Releaed build
buildType: Release
{
"C_Cpp.default.configurationProvider": "vector-of-bool.cmake-tools",
"cmake.buildDirectory": "${workspaceRoot}/${buildType}",
"cmake.copyCompileCommands": "${workspaceRoot}/compile_commands.json",
"files.associations": {
"*.h": "c"
},
"cmake.configureOnOpen": false,
"cortex-debug.enableTelemetry": false,
}
include("${CMAKE_CURRENT_LIST_DIR}/../toolchain.cmake" OPTIONAL)
if(EXISTS "$ENV{TOOLCHAIN_FILE}")
include("$ENV{TOOLCHAIN_FILE}")
endif()
if(DEFINED ENV{ARM_EMBEDDED_TOOLCHAIN})
SET(TOOLCHAIN_DIR $ENV{ARM_EMBEDDED_TOOLCHAIN})
endif()
# TOOLCHAIN EXTENSION
IF(WIN32)
SET(TOOLCHAIN_EXT ".exe")
ELSE()
SET(TOOLCHAIN_EXT "")
ENDIF()
# EXECUTABLE EXTENSION
SET (CMAKE_EXECUTABLE_SUFFIX ".elf")
# CMAKE_BUILD_TYPE
IF(NOT CMAKE_BUILD_TYPE MATCHES Debug)
SET (CMAKE_BUILD_TYPE Release)
ENDIF()
# TOOLCHAIN_DIR AND NANO LIBRARY
STRING(REGEX REPLACE "\\\\" "/" TOOLCHAIN_DIR "${TOOLCHAIN_DIR}")
IF(NOT TOOLCHAIN_DIR)
MESSAGE(FATAL_ERROR "No toolchain defined in toolchain.cmake! set something like:\n set(TOOLCHAIN_DIR \"PATH_TO_TOOLCHAIN\")\nin toolchain.cmake")
ENDIF()
MESSAGE(STATUS "Toolchain Directory: ${TOOLCHAIN_DIR}")
# TARGET_TRIPLET
SET(TARGET_TRIPLET "arm-none-eabi")
SET(TOOLCHAIN_BIN_DIR ${TOOLCHAIN_DIR}/bin)
SET(TOOLCHAIN_INC_DIR ${TOOLCHAIN_DIR}/${TARGET_TRIPLET}/include)
SET(TOOLCHAIN_LIB_DIR ${TOOLCHAIN_DIR}/${TARGET_TRIPLET}/lib)
SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_PROCESSOR arm)
if(CMAKE_VERSION VERSION_LESS "3.6.0")
include(CMakeForceCompiler)
CMAKE_FORCE_C_COMPILER(${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc${TOOLCHAIN_EXT} GNU)
CMAKE_FORCE_CXX_COMPILER(${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-g++${TOOLCHAIN_EXT} GNU)
else()
SET(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
SET(CMAKE_C_COMPILER ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc${TOOLCHAIN_EXT})
SET(CMAKE_CXX_COMPILER ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-g++${TOOLCHAIN_EXT})
endif()
SET(CMAKE_ASM_COMPILER ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc${TOOLCHAIN_EXT})
SET(CMAKE_OBJCOPY ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-objcopy CACHE INTERNAL "objcopy tool")
SET(CMAKE_OBJDUMP ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-objdump CACHE INTERNAL "objdump tool")
SET(CMAKE_SIZE ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-size CACHE INTERNAL "size tool")
SET(CMAKE_AR ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc-ar CACHE INTERNAL "ar tool")
SET(CMAKE_RANLIB ${TOOLCHAIN_BIN_DIR}/${TARGET_TRIPLET}-gcc-ranlib CACHE INTERNAL "ranlib tool")
SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Og -g" CACHE INTERNAL "c compiler flags debug")
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og -g" CACHE INTERNAL "cxx compiler flags debug")
SET(CMAKE_ASM_FLAGS_DEBUG "${CMAKE_ASM_FLAGS_DEBUG} -g" CACHE INTERNAL "asm compiler flags debug")
SET(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG}" CACHE INTERNAL "linker flags debug")
SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3 " CACHE INTERNAL "c compiler flags release")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 " CACHE INTERNAL "cxx compiler flags release")
SET(CMAKE_ASM_FLAGS_RELEASE "${CMAKE_ASM_FLAGS_RELEASE}" CACHE INTERNAL "asm compiler flags release")
SET(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}" CACHE INTERNAL "linker flags release")
SET(CMAKE_FIND_ROOT_PATH ${TOOLCHAIN_DIR}/${TARGET_TRIPLET} ${EXTRA_FIND_PATH})
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_DEPFILE_FLAGS_C "-MMD -MF <DEPFILE>")
SET(CMAKE_DEPFILE_FLAGS_CXX "-MMD -MF <DEPFILE>")
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
mkfile_dir := $(patsubst %/,%,$(dir $(mkfile_path)))
debug_out_dir := $(mkfile_dir)/../Debug
release_out_dir := $(mkfile_dir)/../Release
ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10...
devnul := NUL
which := where
else
devnul := /dev/null
which := which
endif
ifeq ($(GENERATOR),)
ifneq ($(shell ${which} ninja 2>${devnul}),)
GENERATOR := "Ninja"
else
GENERATOR := "Unix Makefiles"
endif
endif
all: cmake-release cmake-debug
$(release_out_dir) $(debug_out_dir):
@echo ">>> create '$(subst ${CURDIR}/,,$(abspath $@))' as it does not exist already"
@mkdir $@
cmake-release: $(release_out_dir)
@echo ">>> enter '$(subst ${CURDIR}/,,$(abspath $<))' and run 'cmake -DCMAKE_BUILD_TYPE=Release -G $(GENERATOR) ..'"
@cd $(release_out_dir) && cmake -DCMAKE_BUILD_TYPE=Release -G $(GENERATOR) ..
cmake-debug: $(debug_out_dir)
@echo ">>> enter '$(subst ${CURDIR}/,,$(abspath $<))' and run 'cmake -DCMAKE_BUILD_TYPE=Debug -G $(GENERATOR) ..'"
@cd $(debug_out_dir) && cmake -DCMAKE_BUILD_TYPE=Debug -G $(GENERATOR) ..
.PHONY: cmake-release cmake-debug
set(CMAKE_TOOLCHAIN_FILE "cmake/armgcc.cmake")
cmake_minimum_required(VERSION 3.10)
# specifiy project name
project(???)
set(C_FLAGS
"-std=gnu11"
"-mfpu=fpv4-sp-d16"
"-mcpu=cortex-m4"
"-mthumb -mabi=aapcs"
"-mfloat-abi=hard -mfpu=fpv4-sp-d16"
"-ffunction-sections -fdata-sections -fno-strict-aliasing"
"-fno-builtin -fshort-enums"
"-Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-main"
)
set(ASM_FLAGS "-g3 -mcpu=cortex-m4 -mthumb -mabi=aapcs -mfloat-abi=hard -mfpu=fpv4-sp-d16")
set(LD_FLAGS
"-mthumb"
"-mcpu=cortex-m4"
"-mfloat-abi=hard -mfpu=fpv4-sp-d16"
"-Wl,--gc-sections"
"--specs=nano.specs"
)
list(JOIN C_FLAGS " " C_FLAGS)
list(JOIN ASM_FLAGS " " ASM_FLAGS)
list(JOIN LD_FLAGS " " LD_FLAGS)
set(CMAKE_ASM_FLAGS_DEBUG "${ASM_FLAGS}")
set(CMAKE_ASM_FLAGS_RELEASE "${ASM_FLAGS}")
set(CMAKE_C_FLAGS_DEBUG "${C_FLAGS} -DDEBUG -g -Og")
set(CMAKE_C_FLAGS_RELEASE "${C_FLAGS} -DNDEBUG -O3 -g3 -flto")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${LD_FLAGS} -g -Og")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${LD_FLAGS} -O3 -g3 -flto")
# some definition
add_compile_definitions("XXX")
# compile option only for Debug build
add_compile_options("$<$<CONFIG:Debug>:-finstrument-functions>")
set(srcs
"source/startup_XXXX.s" # this must be the first (toolchain bug regarding lto (https://bugs.launchpad.net/gcc-arm-embedded/+bug/1747966))
"source/main.c"
)
set(incl
"source"
"."
)
include_directories(${incl})
set(MAIN_TARGET ${PROJECT_NAME}.elf)
add_executable(${MAIN_TARGET} ${srcs})
...
# set the full path to your arm embedded toolchain
set(TOOLCHAIN_DIR "__FULL_PATH_TO_arm-embedded-toolchain__")
@bearsh
Copy link
Author

bearsh commented May 5, 2021

replace the first _ (underscore) in the filename with a /. so my directory layout is the following:

project/
|- cmake/
  |- Makefile
  |- armgcc.cmake
|- .vscode/
  |- cmake-kits.json
  |- ...
|- source/
|- Build/
|- Debug/
|- CMakeLists.txt
|- toolchain.cmake

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment