gcc - CMAKE:如何防止 CMAKE 构建项目不依赖的库?
问题描述
我正在设置一个 CMAKE 项目来构建一个 ARM 目标。该项目包含一个带有为目标提供的 SDK 的子模块。我已经为 sdk 中的每个驱动程序创建了一个静态库定义,并具有正确的依赖关系。需要单独的库定义以防止使用不必要的代码/驱动程序使目标文件膨胀。sdk 子模块中的 CMakeLists.txt 文件:
#############################
###### 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) {}
我已经在项目的 CMakeLists.txt 文件中配置了“target_link_librarires”,以便项目仅依赖于“系统”库(为目标创建可执行文件所需的最少代码和寄存器定义)。
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...
有没有办法配置 CMAKE 不构建项目不依赖的库?有没有更好的方法来设置项目以防止这种情况?
解决方案
解决方案似乎是指定“目标”参数。谢谢@Stephen Newell。
$ cmake -G "MinGW Makefiles" .. && cmake --build . --target Template.elf
-- 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.
-- S32K-SDK OSIF FreeRTOS Enabled
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/Jon/src/S32K-Template/build
Scanning dependencies of target S32K-SDK-SYSTEM
[ 33%] Building C object sdk/CMakeFiles/S32K-SDK-SYSTEM.dir/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 33%] Building C object sdk/CMakeFiles/S32K-SDK-SYSTEM.dir/platform/devices/startup.c.obj
[ 33%] Linking C static library libS32K-SDK-SYSTEM.a
[ 33%] Built target S32K-SDK-SYSTEM
Scanning dependencies of target Template.elf
[ 33%] Building C object CMakeFiles/Template.elf.dir/src/main.c.obj
[ 33%] Building ASM object CMakeFiles/Template.elf.dir/startup/startup_S32K142.S.obj
[ 66%] Building C object CMakeFiles/Template.elf.dir/lib/sdk/platform/devices/S32K142/startup/system_S32K142.c.obj
[ 66%] Building C object CMakeFiles/Template.elf.dir/lib/sdk/platform/devices/startup.c.obj
[100%] Linking C executable Template.elf
[100%] Built target Template.elf
推荐阅读
- python - Pandas 为 B 列中的每个唯一值获取 A 列中唯一值的列表
- c# - 下载大尺寸 zip 时出现 System.outofmemory 异常
- mysql - 无法启动实例“xxxxx:3306”的组复制?
- aws-lambda - 将 XML 发布到 Localstack 中的 lambda 总是抛出 502 Bad Gateway
- rundeck - 在 Rundeck 中并行运行多个节点上的作业
- corda - 实施白名单的正确方法
- azure-devops - Sentry 中的 Azure DevOps 集成:关联提交
- python - python:从带有dict字段的列表中过滤对象
- javascript - Storybook Addon-Docs 不显示 Code Snipped
- xamarin.forms - 在 Listview TappedItem、Xamarin Forms 上更改 ViewCell 中某些视图的样式名称