使用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
相关产品推荐
相关产品推荐

