You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用GNU工具链编译STM32项目遇flex scanner读取失败问题求教

STM32 CMake项目链接错误:ld: read in flex scanner failed 排查

错误信息

/opt/gcc-arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.2.1/../../../../arm-none-eabi/bin/ld: read in flex scanner failed
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Drone.elf.dir/build.make:1151: Drone.elf] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Drone.elf.dir/all] Error 2

原CMake配置

cmake_minimum_required(VERSION 3.10)

project(Drone NONE)

set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)

# output compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

#language
enable_language(C ASM)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)

# add startup file
set(STARTUP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/CORE/startup_stm32f401xe.s)
set(OS_CPU_A_FILE ${CMAKE_CURRENT_SOURCE_DIR}/os/os_cpu_a.s)

# add .h
set(LINKER_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/CORE/STM32F401RETx_FLASH.ld)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/CORE)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/FWLIB/inc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/HARDWARE/inc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/SYSTEM/inc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/USER/inc)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/os/inc)

# add .c
file(GLOB SOURCE 
"${CMAKE_CURRENT_SOURCE_DIR}/USER/src/*.c" 
"${CMAKE_CURRENT_SOURCE_DIR}/FWLIB/src/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/HARDWARE/src/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/SYSTEM/src/*.c"
"${CMAKE_CURRENT_SOURCE_DIR}/os/src/*.c" 
)
set(SOURCE_FILES ${SOURCE})

# set compiler and linker
set(CMAKE_C_COMPILER /opt/gcc-arm-none-eabi/bin/arm-none-eabi-gcc)
set(CMAKE_ASM_COMPILER /opt/gcc-arm-none-eabi/bin/arm-none-eabi-gcc)                                                        
set(CMAKE_LINKER /opt/gcc-arm-none-eabi/bin/arm-none-eabi-ld)

add_definitions(-DSTM32F401xx -DUSE_STDPERIPH_DRIVER)

# 设置编译选项
set(CMAKE_C_FLAGS "-mthumb -mcpu=cortex-m4 -std=c99 -g -Os \
    -ffunction-sections -fdata-sections -Wall -Wextra \
    -Wno-self-assign -Wno-unused-parameter -Wno-empty-body")
# set(CMAKE_CXX_FLAGS "-mthumb -mcpu=cortex-m4 -std=gnu++17 -g -Os -ffunction-sections -fdata-sections -Wall -Wextra")
set(CMAKE_ASM_FLAGS "-mthumb -mcpu=cortex-m4 -g -x assembler-with-cpp")

# 设置链接选项
set(CMAKE_EXE_LINKER_FLAGS "-mthumb -mabi=aapcs -mcpu=cortex-m4 \
    --specs=nano.specs --specs=nosys.specs -u _printf_float -u _scanf_float \
    -Wl,--gc-sections -Wl,-Map=${PROJECT_NAME}.map -T${LINKER_SCRIPT}")

# ${OS_CPU_A_FILE}
# 添加可执行文件
add_executable(${PROJECT_NAME}.elf ${SOURCE_FILES} ${STARTUP_FILE} ${OS_CPU_A_FILE})
target_link_libraries(${PROJECT_NAME}.elf -Wl,-Map=${PROJECT_NAME}.map -Wl,--gc-sections -Wl,--print-memory-usage -Wl,-lc -lm)

用户尝试

已确认链接脚本无错误、路径正确,删除CMAKE_EXE_LINKER_FLAGS中的-T${LINKER_SCRIPT}可暂时解决问题,但担心项目异常,改用如下配置:

add_link_options(-mcpu=cortex-m4 -mthumb -DSTM32F401xx -T${CMAKE_SOURCE_DIR}/STM32F401RETx_FLASH.ld --specs=nano.specs -u _printf_float -lc -lm -Wl,-Map=${CMAKE_SOURCE_DIR}/build/${CMAKE_PROJECT_NAME}.map,--cref -Wl,--gc-sections)

问题根源及修正方案

1. 错误指定CMAKE_LINKER

GCC ARM工具链推荐使用arm-none-eabi-gcc作为链接驱动,而非直接调用ld。gcc会自动处理标准库依赖顺序、启动文件链接等隐式逻辑,直接指定ld作为链接器会导致参数传递不完整,触发解析错误。

修正:移除手动设置CMAKE_LINKER的行:

# set(CMAKE_LINKER /opt/gcc-arm-none-eabi/bin/arm-none-eabi-ld)

2. 链接选项重复配置

原配置中,CMAKE_EXE_LINKER_FLAGS和target_link_libraries重复传递了-Wl,-Map、-Wl,--gc-sections等参数,同时target_link_libraries中混合了链接器选项和库依赖(-lc -lm),导致链接器收到冲突/冗余参数,引发flex scanner解析失败。

修正:拆分链接选项与库依赖,使用目标导向的配置方式(现代CMake最佳实践):

add_executable(${PROJECT_NAME}.elf ${SOURCE_FILES} ${STARTUP_FILE} ${OS_CPU_A_FILE})

# 用target_link_options传递链接器专属选项
target_link_options(${PROJECT_NAME}.elf PRIVATE
    -mthumb -mabi=aapcs -mcpu=cortex-m4
    --specs=nano.specs --specs=nosys.specs
    -u _printf_float -u _scanf_float
    -Wl,--gc-sections
    -Wl,-Map=${PROJECT_NAME}.map
    -T${LINKER_SCRIPT}
    -Wl,--print-memory-usage
)

# target_link_libraries仅传递库依赖
target_link_libraries(${PROJECT_NAME}.elf PRIVATE
    -lc -lm
)

3. 全局链接选项的弊端

原配置使用全局的CMAKE_EXE_LINKER_FLAGS,会影响所有目标;改用add_link_options虽能解决问题,但仍属于全局配置。优先使用target_link_options可精准控制单个目标的链接参数,避免全局污染。

内容的提问来源于stack exchange,提问作者lcy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 10:05:57