c++ - Arduino 链接未定义的引用

标签 c++ cmake compiler-errors arduino linker-errors

我正在尝试为小型 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    
    ...
)

当我尝试运行它时,我总是得到一个 undefined reference 错误

../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 Controller 的板,我们必须使用 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?

关于c++ - Arduino 链接未定义的引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54968445/

相关文章:

c++ - boost::thread 在终止时会自动从 boost::thread_group 中删除吗?

c++ - 如何从 Int2Type 构建 Type2Int?

c++ - 更改在 makefile 中调用的编译器

swift 3、iOS 10 - 错误 : Thread 1 Signal Sigabrt (SPRITEKIT)

c++ - 应用程序突然关闭时堆内存清理

c++ - 来自 QFile 的 QByteArray

cmake - 如何理解cmake的两个命令行选项之间的区别?

c++ - 在同一台计算机上运行多个版本的 OpenCV

c++ - 为什么会出现此错误?

java - Eclipse 说我有编译错误,但我没有 - 如何修复?