【发布时间】:2015-10-10 12:12:44
【问题描述】:
我想使用 CMake 构建过程在 C++ 中对我的 Tiva C 系列 LaunchPad 板进行编程。我下载了一个简单的示例来闪烁我使用 make 构建的 RGB LED,我希望能够使用 cmake 开始一个更大的项目。
这是示例中提供的 Makefile:
# Tiva Makefile
# #####################################
#
# Part of the uCtools project
# uctools.github.com
#
#######################################
# user configuration:
#######################################
# TARGET: name of the output file
TARGET = firmware
# MCU: part number to build for
MCU = TM4C123GH6PM
# SOURCES: list of input source sources
SOURCES = main.c startup_gcc.c
# INCLUDES: list of includes, by default, use Includes directory
INCLUDES = -IInclude
# OUTDIR: directory to use for output
OUTDIR = build
# TIVAWARE_PATH: path to tivaware folder
TIVAWARE_PATH = ../tivaware
# LD_SCRIPT: linker script
LD_SCRIPT = $(MCU).ld
# define flags
CFLAGS = -g -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
CFLAGS +=-Os -ffunction-sections -fdata-sections -MD -std=c99 -Wall
CFLAGS += -pedantic -DPART_$(MCU) -c -I$(TIVAWARE_PATH)
CFLAGS += -DTARGET_IS_BLIZZARD_RA1
LDFLAGS = -T $(LD_SCRIPT) --entry ResetISR --gc-sections
#######################################
# end of user configuration
#######################################
#
#######################################
# binaries
#######################################
CC = arm-none-eabi-gcc
LD = arm-none-eabi-ld
OBJCOPY = arm-none-eabi-objcopy
RM = rm -f
MKDIR = mkdir -p
#######################################
# list of object files, placed in the build directory regardless of source path
OBJECTS = $(addprefix $(OUTDIR)/,$(notdir $(SOURCES:.c=.o)))
# default: build bin
all: $(OUTDIR)/$(TARGET).bin
$(OUTDIR)/%.o: src/%.c | $(OUTDIR)
$(CC) -o $@ $^ $(CFLAGS)
$(OUTDIR)/a.out: $(OBJECTS)
$(LD) -o $@ $^ $(LDFLAGS)
$(OUTDIR)/$(TARGET).bin: $(OUTDIR)/a.out
$(OBJCOPY) -O binary $< $@
# create the output directory
$(OUTDIR):
$(MKDIR) $(OUTDIR)
clean:
-$(RM) $(OUTDIR)/*
.PHONY: all clean
我的第一个基于它的 CMakeLists.txt 文件:
project(firmware)
cmake_minimum_required(VERSION 2.8)
# this one is important
set(CMAKE_SYSTEM_NAME Generic)
#this one not so much
#set(CMAKE_SYSTEM_VERSION 1)
# specify the toolchain
set(TOOLCHAIN_PREFIX ${PROJECT_SOURCE_DIR}/../toolchain/bin/arm-none-eabi-)
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}g++)
set(CMAKE_OBJCOPY ${TOOLCHAIN_PREFIX}objcopy)
set(CMAKE_AR ${TOOLCHAIN_PREFIX}ar)
# set compiler flags
set(MCU TM4C123GH6PM)
set(COMMON_FLAGS "-mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp \
-ffunction-sections -fdata-sections -pedantic \
-MD -DPART_${MCU} -DTARGET_IS_BLIZZARD_RA1")
set(CMAKE_C_FLAGS_DEBUG "-g -Wall ${COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS_DEBUG "-g -Wall -std=c++11 ${COMMON_FLAGS}")
set(CMAKE_C_FLAGS_RELEASE "-O2 -DNOTEST ${COMMON_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -std=c++11 -DNOTEST ${COMMON_FLAGS}")
# search for programs in the build host directories
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# add TivaWare header files to the project
include_directories(${PROJECT_SOURCE_DIR}/../tivaware)
# add source files to the project
aux_source_directory(. SRC_LIST)
add_executable(${PROJECT_NAME} ${SRC_LIST})
# set linker flags
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
set_target_properties(${PROJECT_NAME}
PROPERTIES
LINK_FLAGS "-T ${MCU}.ld --entry ResetISR --gc-sections"
)
# define objcopy macro
macro(OBJCOPY_FILE EXE_NAME)
set(FO ${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME}.bin)
set(FI ${CMAKE_CURRENT_BINARY_DIR}/${EXE_NAME})
message(STATUS ${FO})
add_custom_command(
OUTPUT ${FO}
COMMAND ${CMAKE_OBJCOPY}
ARGS -O binary -I elf32-little ${FI} ${FO}
DEPENDS ${FI}
)
get_filename_component(TGT "${EXE_NAME}" NAME)
add_custom_target("target-objcopy_${TGT}" ALL DEPENDS ${FO} VERBATIM)
get_directory_property(extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES)
set_directory_properties(
PROPERTIES
ADDITIONAL_MAKE_CLEAN_FILES "${extra_clean_files};${FO}"
)
set_source_files_properties("${FO}" PROPERTIES GENERATED TRUE)
endmacro(OBJCOPY_FILE)
# set the objcopy for binary file
objcopy_file(${PROJECT_NAME})
它通过了 CMake 步骤,但是当我尝试使用 make 进行编译时,我得到了
arm-none-eabi-g++: error: unrecognized command line option '--gc-sections'
我猜链接器标志应该与arm-none-eabi-ld 一起使用。我该怎么做?
编辑1:
我仍然不知道如何设置正确的链接器 exe 和标志,但我发现 CMake 在firmware.dir/link.txt 中生成了一个文件。它的内容是
~/Documents/crh-2016/src/tiva/firmware/../toolchain/bin/arm-none-eabi-g++ -O2 -std=c++11 -fno-exceptions -DNOTEST -mthumb -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -ffunction-sections -fdata-sections -pedantic -MD -DPART_TM4C123GH6PM -DTARGET_IS_BLIZZARD_RA1 -T ~/Documents/crh-2016/src/tiva/firmware/TM4C123GH6PM.ld --entry ResetISR --gc-sections CMakeFiles/firmware.dir/main.cpp.o CMakeFiles/firmware.dir/startup_gcc.cpp.o -o firmware
我将其编辑为我想要临时解决的问题
~/Documents/crh-2016/src/tiva/firmware/../toolchain/bin/arm-none-eabi-ld -T ~/Documents/crh-2016/src/tiva/firmware/TM4C123GH6PM.ld --entry ResetISR --gc-sections CMakeFiles/firmware.dir/main.cpp.o CMakeFiles/firmware.dir/startup_gcc.cpp.o -o firmware
但似乎 LD 不喜欢 G++ 生成的 .o 文件,因为 make 说
toolchain/bin/arm-none-eabi-ld: warning: cannot find entry symbol ResetISR; defaulting to 00000000
【问题讨论】:
-
您可以使用
CMAKE_CXX_LINK_EXECUTABLE变量将链接器调用更改为ld(参见例如我的答案here)。 -
好的,它在我的 link.txt 文件中添加了 ld exe,但我无法设置链接器标志。我在你的回答中使用
CMAKE_EXE_LINKER_FLAGS,但它什么也没做:/ -
-Wl,XXX告诉 gcc 将XXX直接传递给链接器,而不是试图理解它。
标签: c++ makefile cmake microcontroller