apple / swift-embedded-examples

A collection of example projects using Embedded Swift
Apache License 2.0
722 stars 49 forks source link

[Question] `undefined reference to '_swift_exceptionPersonality'` while building a project for pi pico #49

Closed Helloyunho closed 3 months ago

Helloyunho commented 3 months ago

I'm trying to move my original C++ code to Swift. Since my project uses TinyUSB for HID keyboard control, I decided to copy paste some codes from pico-blink-sdk.

Here's what CMakeLists.txt looks like:

cmake_minimum_required(VERSION 3.13)

include(pico_sdk_import.cmake)

project(PROJECT_NAME_HERE_project C CXX ASM)
set(CMAKE_C_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
pico_sdk_init()

if(APPLE)
execute_process(COMMAND xcrun -f swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
execute_process(COMMAND which swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()

add_executable(PROJECT_NAME_HERE)

target_include_directories(PROJECT_NAME_HERE PUBLIC ${CMAKE_CURRENT_LIST_DIR})

target_link_libraries(PROJECT_NAME_HERE
    pico_stdlib
    pico_unique_id
    tinyusb_device
    tinyusb_board
    ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
)

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
    COMMAND
        ${SWIFTC}
        -target armv6m-none-none-eabi -Xcc -mfloat-abi=soft -Xcc -fshort-enums
        -Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library
        -cxx-interoperability-mode=default
        -Xcc -std=c++17
        $$\( echo '$<TARGET_PROPERTY:PROJECT_NAME_HERE,INCLUDE_DIRECTORIES>' | tr '\;' '\\n' | sed -e 's/\\\(.*\\\)/-Xcc -I\\1/g' \)
        $$\( echo '${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}'             | tr ' '  '\\n' | sed -e 's/\\\(.*\\\)/-Xcc -I\\1/g' \)
        -import-bridging-header ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
        ${CMAKE_CURRENT_LIST_DIR}/Main.swift
        -c -o ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
    DEPENDS
        ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
        ${CMAKE_CURRENT_LIST_DIR}/Main.swift
)
add_custom_target(PROJECT_NAME_HERE-swiftcode DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o)

add_dependencies(PROJECT_NAME_HERE PROJECT_NAME_HERE-swiftcode)
pico_add_extra_outputs(PROJECT_NAME_HERE)

And here's my incomplete Swift code(Main.swift):

let BUTTON_PINS: [UInt32] = [0, 1, 2, 3, 4, 5, 6, 7]
let LED_PINS: [UInt32] = [8, 9, 10, 11, 12, 13, 14, 15]

let DEFAULT_LED_PIN: UInt32 = 25

let DEBOUNCE_DELAY_MS: UInt32 = 5

let KEYS: [String] = ["d", "f", "g", "h", "j", "c", "b", "\n"]

let SERIAL = "SERIAL"

// Set up the USB device descriptor for HID
var DESC_DEVICE = tusb_desc_device_t(
    bLength: 18,
    bDescriptorType: 0x01,  // TUSB_DESC_DEVICE
    bcdUSB: 0x0200,
    bDeviceClass: 0x00,
    bDeviceSubClass: 0x00,
    bDeviceProtocol: 0x00,
    bMaxPacketSize0: UInt8(CFG_TUD_ENDPOINT0_SIZE),
    idVendor: 0x1209,
    idProduct: 0x6a6a,
    bcdDevice: 0x0100,
    iManufacturer: 0x01,
    iProduct: 0x02,
    iSerialNumber: 0x03,
    bNumConfigurations: 0x01
)

@main
struct Main {
    static func main() {
        board_init()
    }
}

public func tud_descriptor_device_cb() -> UnsafePointer<tusb_desc_device_t> {
    return withUnsafePointer(to: &DESC_DEVICE, { $0 })
}

Here's the file structure:

src
├── BridgingHeader.h
├── CMakeLists.txt
├── LICENSE
├── Main.swift
├── README.md
├── includes
│   ├── tusb_config.h
│   └── usb_descriptors.h
├── pico_sdk_import.cmake -> /Users/helloyunho/pico-sdk/external/pico_sdk_import.cmake
├── original_code.cpp
└── tusb_config.h

Now when I build it, everything compiles but fails at linking:

/Applications/ArmGNUToolchain/13.3.rel1/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: warning: /Applications/ArmGNUToolchain/13.3.rel1/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.3.1/thumb/v6-m/nofp/crtn.o: missing .note.GNU-stack section implies executable stack
/Applications/ArmGNUToolchain/13.3.rel1/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: NOTE: This behaviour is deprecated and will be removed in a future version of the linker
/Applications/ArmGNUToolchain/13.3.rel1/arm-none-eabi/bin/../lib/gcc/arm-none-eabi/13.3.1/../../../../arm-none-eabi/bin/ld: _swiftcode.o:(.ARM.extab.text.$s10_swiftcode4MainV4mainyyFZ+0x0): undefined reference to `_swift_exceptionPersonality'
Helloyunho commented 3 months ago

So pro tip for anyone who gets this kind of error: seems like pico-sdk that's released a week ago has major change that Swift is yet to follow, using 1.5.1 sdk worked without issue