c++ - Arduino 链接未定义参考
问题描述
我正在尝试为一个小型 Arduino 项目创建一个 cmake 文件。
我使用 Arduino IDE 的输出作为起点来查找所需的文件和命令。现在我正在编译像 Arduino IDE 这样的所有源代码,然后我尝试将它们链接在一起。
在 CMake 中创建可执行文件:
add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/buttontest.cpp)
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-T${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/variants/mkrwifi1010/linker_scripts/gcc/flash_with_bootloader.ld \
-Wl,-Map,${TARGET_NAME}.ino.map --specs=nano.specs --specs=nosys.specs -mcpu=cortex-m0plus -mthumb -Wl,--cref -Wl,--check-sections \
-Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align")
target_link_libraries(
${TARGET_NAME}
wiring_digital
variant
uart
...
)
当我尝试运行它时,我总是得到一个未定义的引用错误
../libuart.a(Uart.cpp.obj):(.rodata._ZTI4Uart+0x8): undefined reference to `typeinfo for HardwareSerial'
collect2: error: ld returned 1 exit status
在我看来,链接器无法从我编译的 sercom 库中找到某些东西,但我不明白为什么。
我们在 github 上找到了 arduino-cmake 存储库,但我们不能使用该代码,因为它适用于使用 AVR 控制器的板,我们必须使用 ARM 处理器(Arduino MKR 1010 Wifi)。
任何有关链接器错误的建议将不胜感激!如果将 CMake 用于 Arduino 项目的方法存在根本缺陷,我也会感谢其他选择。
项目结构:
project
|- build/
|- buttontest/
|- CMakeLists.txt
|- src/buttontest.cpp
|-cmake/MKRWIFI1010_Toolchain.cmake
|-CMakeLists.txt
CMakeLists.txt:
set(CMAKE_TOOLCHAIN_FILE cmake/MKRWIFI1010_Toolchain.cmake)
cmake_minimum_required(VERSION 3.13)
project(buttontest)
set (ARDUINO_PACKAGES $ENV{ARDUINO_PACKAGES})
message(STATUS "${ARDUINO_PACKAGES}")
include_directories(
${ARDUINO_PACKAGES}/arduino/tools/CMSIS/4.5.0/CMSIS/Include/
${ARDUINO_PACKAGES}/arduino/tools/CMSIS-Atmel/1.1.0/CMSIS/Device/ATMEL/
${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino
${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/variants/mkrwifi1010
)
# Building common files
# Add persistent compile flags here
add_compile_options (-c -g -MMD -DF_CPU=48000000L -DARDUINO=10808 -DARDUINO_SAMD_MKRWIFI1010 -DARDUINO_ARCH_SAMD
-DUSE_ARDUINO_MKR_PIN_LAYOUT -D__SAMD21G18A__ -DUSB_VID=0x2341 -DUSB_PID=0x8054 -DUSBCON "-DUSB_MANUFACTURER=\"Arduino LLC\""
"-DUSB_PRODUCT=\"Arduino MKR WiFi 1010\"" -DUSE_BQ24195L_PMIC)
# Add temporal compile flags here
# FIXME: There must be a better way to do this, but anyway, there must be a better way to write an Arduino CMake Script...
set(CMAKE_C_FLAGS "-x assembler-with-cpp")
set_property(SOURCE ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/pulse_asm.S PROPERTY LANGUAGE C)
add_library(pulse_asm ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/pulse_asm.S)
# Remove temporal compile flags
add_compile_options (-mcpu=cortex-m0plus -mthumb -Os -Wall -Wextra -ffunction-sections -fdata-sections -nostdlib
--param max-inline-insns-single=500 -Wno-expansion-to-defined)
# C Libraries
add_library(winterrupts ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/WInterrupts.c)
set(CMAKE_C_FLAGS "-std=gnu11")
add_library(itoa ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/itoa.c)
add_library(wiring_private ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/wiring_private.c)
add_library(wiring_digital ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/wiring_digital.c)
add_library(cortex_handlers ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/cortex_handlers.c)
add_library(wiring_shift ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/wiring_shift.c)
add_library(samd21_host ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/USB/samd21_host.c)
add_library(pulse ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/pulse.c)
add_library(startup ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/startup.c)
add_library(delay ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/delay.c)
add_library(wiring ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/wiring.c)
add_library(dtostrf ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/avr/dtostrf.c)
add_library(wiring_analog ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/wiring_analog.c)
add_library(hooks ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/hooks.c)
set(CMAKE_C_FLAGS "-std=gnu++11")
# CPP Libraries
add_library(ipaddress ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/IPAddress.cpp)
add_library(wmath ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/WMath.cpp)
add_library(new ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/new.cpp)
add_library(reset ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/Reset.cpp)
add_library(sercom ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/SERCOM.cpp)
add_library(cdc ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/USB/CDC.cpp)
add_library(stream ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/Stream.cpp)
add_library(usbcore ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/USB/USBCore.cpp)
add_library(print ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/Print.cpp)
add_library(tone ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/Tone.cpp)
add_library(pluggableusb ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/USB/PluggableUSB.cpp)
add_library(wstring ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/WString.cpp)
add_library(abi ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/abi.cpp )
add_library(uart ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/Uart.cpp)
add_library(main ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/cores/arduino/main.cpp)
add_compile_options(-fno-threadsafe-statics -fno-rtti -fno-exceptions)
add_library(variant ${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/variants/mkrwifi1010/variant.cpp)
add_subdirectory(buttontest)
cmake/MKRWIFI1010_Toolchain.cmake:
set(CMAKE_SYSTEM_NAME Generic)
set (ARDUINO_PACKAGES $ENV{ARDUINO_PACKAGES})
set(CMAKE_C_COMPILER ${ARDUINO_PACKAGES}/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-gcc)
set(CMAKE_CXX_COMPILER ${ARDUINO_PACKAGES}/arduino/tools/arm-none-eabi-gcc/4.8.3-2014q1/bin/arm-none-eabi-g++)
按钮测试/CMakeLists.txt:
set(TARGET_NAME "buttontest")
link_directories(
${ARDUINO_PACKAGES}/arduino/tools/CMSIS/4.5.0/CMSIS/Lib/GCC/
{CMAKE_BINARY_DIR}
{CMAKE_BINARY_DIR}/buttontest)
add_compile_options(-fno-threadsafe-statics -fno-rtti -fno-exceptions)
add_executable(${TARGET_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/src/buttontest.cpp)
set_target_properties(${TARGET_NAME} PROPERTIES LINK_FLAGS "-T${ARDUINO_PACKAGES}/arduino/hardware/samd/1.6.20/variants/mkrwifi1010/linker_scripts/gcc/flash_with_bootloader.ld \
-Wl,-Map,${TARGET_NAME}.ino.map --specs=nano.specs --specs=nosys.specs -mcpu=cortex-m0plus -mthumb -Wl,--cref -Wl,--check-sections \
-Wl,--gc-sections -Wl,--unresolved-symbols=report-all -Wl,--warn-common -Wl,--warn-section-align")
target_link_libraries(
${TARGET_NAME} wiring_digital variant sercom uart arm_cortexM0l_math cdc pulse pulse_asm ipaddress
cortex_handlers print reset stream tone usbcore pluggableusb samd21_host winterrupts wmath wstring
abi dtostrf startup hooks itoa new wiring delay main sercom wiring_analog wiring_private wiring_shift)
解决方案
听起来您缺少 HardwareSerial 类的一个或多个虚拟成员的函数体定义。也许您错过了一个定义,例如 HAVE_HWSERIAL0?
推荐阅读
- python - Python Web Scraping (edX)
- css - CSS - 如何在移除时反转动画
- django - Django 模板:如何拆分 SplitDateTimeWidget?
- php - 使用 AJAX 将文本从文本框发送到 PHP
- html - Html 文件不读取外部 js 文件
- powershell - PowerShell/Batch 脚本重命名每个文件以包含原始名称 + 文件夹名称
- ffmpeg - 如何设置使用 ffmpeg 生成管道 mp4 的总文件持续时间?
- ef-core-2.0 - Asp.Net Boilerplate InsertAsync 方法不起作用并返回负 id
- python-3.x - Django 我想减去两个日期,比如 start_date - end_date,只需要几天
- python - 每次我运行“jupyter notebook”时,为什么我总是在mac os上得到这个?