Я настраиваю проект CMAKE для сборки для цели ARM. Проект содержит подмодуль с предоставленным SDK для цели. Я создал определение библиотеки stati c для каждого драйвера в sdk с правильными зависимостями. Отдельные определения библиотек желательны, чтобы предотвратить раздувание объектного файла ненужным кодом / драйверами. Файл CMakeLists.txt в подмодуле sdk:
#############################
###### System Library #######
#############################
### System ###
add_library(S32K-SDK-SYSTEM STATIC)
## Headers ##
target_include_directories(S32K-SDK-SYSTEM PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/platform/devices"
"${CMAKE_CURRENT_SOURCE_DIR}/platform/devices/common"
"${CMAKE_CURRENT_SOURCE_DIR}/platform/devices/${CPU}/include"
"${CMAKE_CURRENT_SOURCE_DIR}/platform/devices/${CPU}/startup"
)
## Sources ##
file(GLOB SYSTEM-SOURCES -CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/platform/devices/${CPU}/startup/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/platform/devices/*.c"
)
target_sources(S32K-SDK-SYSTEM PUBLIC
${SYSTEM-SOURCES}
)
#############################
######### Drivers ###########
#############################
###########
### ADC ###
###########
add_library(S32K-SDK-ADC-DRIVER STATIC)
## Dependencies ##
target_link_libraries(S32K-SDK-ADC-DRIVER PRIVATE
S32K-SDK-SYSTEM
S32K-SDK-CLOCK-DRIVER
)
## Headers ##
target_include_directories(S32K-SDK-ADC-DRIVER PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/inc"
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/src/adc"
)
## Sources ##
file(GLOB_RECURSE ADC-DRIVER-SOURCES -CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/src/adc/*.c"
)
target_sources(S32K-SDK-ADC-DRIVER PUBLIC
${ADC-DRIVER-SOURCES}
)
#############
### Clock ###
#############
add_library(S32K-SDK-CLOCK-DRIVER STATIC)
## Dependencies ##
target_link_libraries(S32K-SDK-CLOCK-DRIVER PRIVATE
S32K-SDK-SYSTEM
S32K-SDK-INTERRUPT-DRIVER
)
## Headers ##
target_include_directories(S32K-SDK-CLOCK-DRIVER PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/inc"
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/src/clock/S32K1xx"
)
## Sources ##
file(GLOB_RECURSE CLOCK-DRIVER-SOURCES -CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/src/clock/*.c"
)
target_sources(S32K-SDK-CLOCK-DRIVER PUBLIC
${CLOCK-DRIVER-SOURCES}
)
##################
### Comparator ###
##################
add_library(S32K-SDK-COMPARATOR-DRIVER STATIC)
## Dependencies ##
target_link_libraries(S32K-SDK-COMPARATOR-DRIVER PRIVATE
S32K-SDK-SYSTEM
)
## Headers ##
target_include_directories(S32K-SDK-COMPARATOR-DRIVER PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/inc"
)
## Sources ##
file(GLOB_RECURSE COMPARATOR-DRIVER-SOURCES -CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/src/cmp/*.c"
)
target_sources(S32K-SDK-COMPARATOR-DRIVER PUBLIC
${COMPARATOR-DRIVER-SOURCES}
)
###########
### CRC ###
###########
add_library(S32K-SDK-CRC-DRIVER STATIC)
## Dependencies ##
target_link_libraries(S32K-SDK-CRC-DRIVER PRIVATE
S32K-SDK-SYSTEM
)
## Headers ##
target_include_directories(S32K-SDK-CRC-DRIVER PUBLIC
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/inc"
)
## Sources ##
file(GLOB_RECURSE CRC-DRIVER-SOURCES -CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/platform/drivers/src/crc/*.c"
)
target_sources(S32K-SDK-CRC-DRIVER PUBLIC
${CRC-DRIVER-SOURCES}
)
etc...
Пример проекта содержит единственный файл main. c с содержимым:
int main(void) {}
Я настроил "target_link_librarires" в файле CMakeLists.txt проекта, чтобы проект зависел только от "системной" библиотеки (минимальный код и определения регистров, необходимые для создания исполняемого файла для цели).
cmake_minimum_required(VERSION 3.16)
# CMake Modules Path
set(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Toolchain
set(Toolchain "${CMAKE_CURRENT_SOURCE_DIR}/toolchain")
include(toolchain)
# Project Name
project(Template VERSION 1.0)
# C++ Standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)
enable_language(ASM)
# Linker Configuration
set(LINKER_SCRIPT "${PROJECT_SOURCE_DIR}/config/S32K142_32_flash.ld")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -T ${LINKER_SCRIPT} -Xlinker -Map=${CMAKE_PROJECT_NAME}.map")
###############################
### Processor Configuration ###
###############################
# Define the processor.
set(CPU S32K142)
# Define the core.
if (${CPU} MATCHES "^S32K11")
message(STATUS "M0+ core.")
set(CORE M0+)
else ()
message(STATUS "M4 core.")
set(CORE M4)
endif()
# TODO Add Definitons
add_definitions(-DCPU_${CPU})
# Specify Compiler Flags
set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -mthumb -funsigned-char -funsigned-bitfields -fshort-enums -ffunction-sections -fdata-sections -fno-jump-tables -g -mfloat-abi=hard -Wall -Wextra -Wstrict-prototypes -Wunused -Wsign-compare")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -mthumb -funsigned-char -funsigned-bitfields -fshort-enums -ffunction-sections -fdata-sections -fno-jump-tables -g -mfloat-abi=hard -Wall -Wextra -Wstrict-prototypes -Wunused -Wsign-compare")
if(${CPU} MATCHES "^S32K11")
message(STATUS "M0+ core detected.")
set(CMAKE_C_FLAGS " ${CMAKE_C_FLAGS} -mcpu=cortex-m0 ")
set(CMAKE_CXX_FLAGS " ${CMAKE_CXX_FLAGS} -mcpu=cortex-m0 ")
else()
message(STATUS "M4 core detected.")
# TODO Should we override the default fpu option?
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=cortex-m4 -mfpu=fpv4-sp-d16")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=cortex-m4 -mfpu=fpv4-sp-d16")
endif()
# Executeable
add_executable(${PROJECT_NAME}.elf)
# Add Libraries
add_subdirectory(${PROJECT_SOURCE_DIR}/lib/sdk sdk)
target_link_libraries(${PROJECT_NAME}.elf PUBLIC
S32K-SDK-SYSTEM
)
target_include_directories(${PROJECT_NAME}.elf PRIVATE
"${PROJECT_SOURCE_DIR}/include"
)
target_sources(${PROJECT_NAME}.elf PUBLIC
"${PROJECT_SOURCE_DIR}/src/main.c"
"${PROJECT_SOURCE_DIR}/startup/startup_S32K142.S"
)
add_custom_command(TARGET ${PROJECT_NAME}.elf
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} -O ihex ${PROJECT_NAME}.elf ${PROJECT_NAME}.hex
)
Когда проект строит его правильно строит системную библиотеку и связывает целевой исполняемый файл, но затем приступает к построению всех определенных драйверов в SDK, которые, очевидно, не нужны, если целевой исполняемый файл уже был связан.
$ cmake -G "MinGW Makefiles" .. && /c/MinGW/bin/mingw32-make.exe
-- The C compiler identification is GNU 9.3.1
-- The CXX compiler identification is GNU 9.3.1
-- Check for working C compiler: C:/Users/Jon/src/S32K-Template/toolchain/windows/bin/arm-none-eabi-gcc.exe
-- Check for working C compiler: C:/Users/Jon/src/S32K-Template/toolchain/windows/bin/arm-none-eabi-gcc.exe - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: C:/Users/Jon/src/S32K-Template/toolchain/windows/bin/arm-none-eabi-g++.exe
-- Check for working CXX compiler: C:/Users/Jon/src/S32K-Template/toolchain/windows/bin/arm-none-eabi-g++.exe - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- The ASM compiler identification is GNU
-- Found assembler: C:/Users/Jon/src/S32K-Template/toolchain/windows/bin/arm-none-eabi-gcc.exe
-- M4 core.
-- M4 core detected.
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/Jon/src/S32K-Template/build
Scanning dependencies of target S32K-SDK-SYSTEM
[ 1%] Building C object sdk/CMakeFiles/S32K-SDK-SYSTEM.dir/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 1%] Building C object sdk/CMakeFiles/S32K-SDK-SYSTEM.dir/platform/devices/startup.c.obj
[ 2%] Linking C static library libS32K-SDK-SYSTEM.a
[ 2%] Built target S32K-SDK-SYSTEM
Scanning dependencies of target Template.elf
[ 2%] Building C object CMakeFiles/Template.elf.dir/src/main.c.obj
[ 3%] Building ASM object CMakeFiles/Template.elf.dir/startup/startup_S32K142.S.obj
[ 3%] Building C object CMakeFiles/Template.elf.dir/lib/sdk/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 4%] Building C object CMakeFiles/Template.elf.dir/lib/sdk/platform/devices/startup.c.obj
[ 5%] Linking C executable Template.elf
[ 5%] Built target Template.elf
Scanning dependencies of target S32K-SDK-COMPARATOR-DRIVER
[ 5%] Building C object sdk/CMakeFiles/S32K-SDK-COMPARATOR-DRIVER.dir/platform/drivers/src/cmp/cmp_driver.c.obj
[ 6%] Building C object sdk/CMakeFiles/S32K-SDK-COMPARATOR-DRIVER.dir/platform/drivers/src/cmp/cmp_hw_access.c.obj
[ 7%] Building C object sdk/CMakeFiles/S32K-SDK-COMPARATOR-DRIVER.dir/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 7%] Building C object sdk/CMakeFiles/S32K-SDK-COMPARATOR-DRIVER.dir/platform/devices/startup.c.obj
[ 8%] Linking C static library libS32K-SDK-COMPARATOR-DRIVER.a
[ 8%] Built target S32K-SDK-COMPARATOR-DRIVER
Scanning dependencies of target S32K-SDK-INTERRUPT-DRIVER
[ 8%] Building C object sdk/CMakeFiles/S32K-SDK-INTERRUPT-DRIVER.dir/platform/drivers/src/interrupt/interrupt_manager.c.obj
[ 9%] Building C object sdk/CMakeFiles/S32K-SDK-INTERRUPT-DRIVER.dir/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 10%] Building C object sdk/CMakeFiles/S32K-SDK-INTERRUPT-DRIVER.dir/platform/devices/startup.c.obj
[ 10%] Linking C static library libS32K-SDK-INTERRUPT-DRIVER.a
[ 10%] Built target S32K-SDK-INTERRUPT-DRIVER
Scanning dependencies of target S32K-SDK-CLOCK-DRIVER
[ 11%] Building C object sdk/CMakeFiles/S32K-SDK-CLOCK-DRIVER.dir/platform/drivers/src/clock/S32K1xx/clock_S32K1xx.c.obj
[ 11%] Building C object sdk/CMakeFiles/S32K-SDK-CLOCK-DRIVER.dir/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 12%] Building C object sdk/CMakeFiles/S32K-SDK-CLOCK-DRIVER.dir/platform/devices/startup.c.obj
[ 12%] Building C object sdk/CMakeFiles/S32K-SDK-CLOCK-DRIVER.dir/platform/drivers/src/interrupt/interrupt_manager.c.obj
[ 13%] Linking C static library libS32K-SDK-CLOCK-DRIVER.a
[ 13%] Built target S32K-SDK-CLOCK-DRIVER
Scanning dependencies of target S32K-SDK-ADC-DRIVER
[ 13%] Building C object sdk/CMakeFiles/S32K-SDK-ADC-DRIVER.dir/platform/drivers/src/adc/adc_driver.c.obj
[ 14%] Building C object sdk/CMakeFiles/S32K-SDK-ADC-DRIVER.dir/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 14%] Building C object sdk/CMakeFiles/S32K-SDK-ADC-DRIVER.dir/platform/devices/startup.c.obj
[ 15%] Building C object sdk/CMakeFiles/S32K-SDK-ADC-DRIVER.dir/platform/drivers/src/clock/S32K1xx/clock_S32K1xx.c.obj
[ 15%] Linking C static library libS32K-SDK-ADC-DRIVER.a
[ 15%] Built target S32K-SDK-ADC-DRIVER
etc...
Is есть ли способ настроить CMAKE, чтобы не создавать библиотеки, от которых проект не зависит? Есть ли лучший способ настроить проект, чтобы предотвратить это?