RPI Pico子项目构建失败:ld.exe提示二进制信息需在前256字节
问题分析:Pico SDK多子项目构建出现
multiple definition错误 错误日志
[build] Starting build [proc] Executing command: "C:\Program Files\Raspberry Pi\Pico SDK v1.5.1\cmake\bin\cmake.EXE" --build d:/_svn/compass/AVR/AMPER_BATERIA_PICO/build --config Debug --target all -- [build] [1/2 50% :: 0.133] Building C object GENET_CORE_PICO/CMakeFiles/GENET_CORE.dir/GENet_Core.c.obj [build] [2/2 100% :: 0.293] Linking CXX executable Amper_Bateria.elf [build] FAILED: Amper_Bateria.elf [...a lot of build output here...] [build] C:/Program Files/Raspberry Pi/Pico SDK v1.5.1/pico-sdk/src/rp2_common/hardware_base/include/hardware/address_mapped.h:122: multiple definition of `adc_init'; GENET_CORE_PICO/CMakeFiles/GENET_CORE.dir/C_/Program_Files/Raspberry_Pi/Pico_SDK_v1.5.1/pico-sdk/src/rp2_common/hardware_adc/adc.c.obj:C:/Program Files/Raspberry Pi/Pico SDK v1.5.1/pico-sdk/src/rp2_common/hardware_base/include/hardware/address_mapped.h:122: first defined here [proc] The command: "C:\Program Files\Raspberry Pi\Pico SDK v1.5.1\cmake\bin\cmake.EXE" --build d:/_svn/compass/AVR/AMPER_BATERIA_PICO/build --config Debug --target all -- exited with code: 1 [build] c:/progra~2/gnuarm~1/102021~1.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: Binary info must be in first 256 bytes of the binary [build] collect2.exe: error: ld returned 1 exit status [build] ninja: build stopped: subcommand failed. [driver] Build completed: 00:00:00.569 [build] Build finished with exit code 1
主项目CMakeLists.txt代码
cmake_minimum_required(VERSION 3.13) include(pico_sdk_import.cmake) project(Amper_Bateria C CXX ASM) set(srcDir D:/_svn/compass/AVR/AMPER_BATERIA_PICO) add_subdirectory(GENET_CORE_PICO) pico_sdk_init() set(SOURCES userland.c userland.h) add_executable(Amper_Bateria ${SOURCES}) target_link_directories(Amper_Bateria PRIVATE ${coreDir}) pico_add_extra_outputs(Amper_Bateria) target_include_directories(Amper_Bateria PRIVATE GENET_CORE_PICO) target_link_directories(Amper_Bateria PRIVATE GENET_CORE_PICO) target_link_libraries(Amper_Bateria PRIVATE GENET_CORE pico_stdlib hardware_adc pico_multicore hardware_timer)
子项目GENET_CORE_PICO/CMakeLists.txt代码
cmake_minimum_required(VERSION 3.13) include(pico_sdk_import.cmake) project(GENET_CORE C CXX ASM) pico_sdk_init() add_library(GENET_CORE OBJECT GENet_Core.c GENet_Core.h GENet_ISR_LIB.c GENet_ISR_LIB.h ds18b20_TIMER_DRIVER.c ds18b20_TIMER_DRIVER.h crc8_16.c checksum.h ) target_link_libraries(GENET_CORE pico_stdlib hardware_adc)
问题原因
- Pico SDK重复初始化:主项目和子项目都调用了
pico_sdk_init(),导致SDK的硬件组件(比如hardware_adc)被多次链接,出现符号重复定义(如adc_init)。 - OBJECT库的依赖管理不当:子项目的OBJECT库直接链接了
hardware_adc等SDK组件,主项目再次链接这些组件时,就会重复引入相同的符号。 - 冗余的链接配置:主项目中的
target_link_directories属于冗余配置,CMake通过target_link_libraries链接库时会自动处理路径,无需手动指定。
修复方案
修改主项目CMakeLists.txt
只在主项目中初始化SDK,清理冗余配置,统一管理所有依赖:
cmake_minimum_required(VERSION 3.13) include(pico_sdk_import.cmake) project(Amper_Bateria C CXX ASM) # 仅在主项目初始化Pico SDK pico_sdk_init() add_subdirectory(GENET_CORE_PICO) set(SOURCES userland.c userland.h) add_executable(Amper_Bateria ${SOURCES}) pico_add_extra_outputs(Amper_Bateria) target_include_directories(Amper_Bateria PRIVATE GENET_CORE_PICO) # 统一链接子项目库和所有SDK依赖 target_link_libraries(Amper_Bateria PRIVATE GENET_CORE pico_stdlib hardware_adc pico_multicore hardware_timer )
修改子项目CMakeLists.txt
移除重复的SDK初始化,OBJECT库仅管理自身源码,依赖通过主项目传递:
cmake_minimum_required(VERSION 3.13) project(GENET_CORE C CXX ASM) # 构建OBJECT库,只包含自身源码 add_library(GENET_CORE OBJECT GENet_Core.c GENet_Core.h GENet_ISR_LIB.c GENet_ISR_LIB.h ds18b20_TIMER_DRIVER.c ds18b20_TIMER_DRIVER.h crc8_16.c checksum.h ) # 仅添加SDK头文件依赖,或通过PRIVATE传递依赖给主项目 target_link_libraries(GENET_CORE PRIVATE pico_stdlib hardware_adc)
说明
修改后,SDK只会被初始化一次,所有依赖由主项目统一管理,避免了符号重复定义的问题。OBJECT库的依赖会通过CMake的依赖传递机制正确传递给主项目,不会出现重复链接的情况。
内容的提问来源于stack exchange,提问作者bajtec
相关产品推荐
相关产品推荐

