swift-embedded-examples icon indicating copy to clipboard operation
swift-embedded-examples copied to clipboard

Pico 2.0.0 SDK build errors (RP2040 & RP2350 RISC-V)

Open iCMDdev opened this issue 1 year ago • 12 comments

I'm getting the following build error with the Pico 2.0.0 SDK when compiling the blink example for RP2040, and I'm not sure if this is an SDK error or something related to the current CMakeLists.txt:

pico-sdk/src/rp2_common/hardware_base/include/hardware/address_mapped.h:177:10: error: 'hardware/structs/accessctrl.h' file not found
175 | #if !PICO_RP2040
176 | // include this here to avoid the check in every other hardware/structs header that needs it
177 | #include "hardware/structs/accessctrl.h"
    |          `- error: 'hardware/structs/accessctrl.h' file not found
178 | #endif
179 | 

Clearly, something's off: it seems that even though I'm compiling for RP2040, the #if !PICO_RP2040 fails. Does anybody else experience this?

The hardware/structs/accessctrl.h file is indirectly included by pico/stdlib.h.

Potential(?) duplicate of #49.

iCMDdev avatar Sep 03 '24 18:09 iCMDdev

I think I finally figured it out, at least partially. It seems that add_dependencies(swift-blinky swift-blinky-swiftcode) in CMakeLists.txt causes it. Removing it fixes the issue for me, but I'm not sure it's a good idea to do this, since then cmake won't gurantee that the Swift code is compiled before linking.

Edit: it actually doesn't seem to fix it? It's a pretty strange behavior..

iCMDdev avatar Sep 03 '24 19:09 iCMDdev

I also opened this issue on the Pico SDK repo: raspberrypi/pico-sdk#1917.

iCMDdev avatar Sep 08 '24 08:09 iCMDdev

After discussing this issue on the Pico SDK repo I realized this is caused by not passing the Pico SDK compiler definitions to swiftc. This is because Pico SDK doesn't manage the swift compilation itself - it doesn't add the required flags to the custom command .

One thing we can do to make this work is gather compiler flags from Pico SDK automatically, and then provide them to the Swift compiler:

cmake_minimum_required(VERSION 3.13)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
include(hacky_cmake_helper.cmake) # https://github.com/raspberrypi/pico-playground/blob/9930bb057b7272176fbcd924b1d5856dfbc07503/standalone/static_sdk/hacky_cmake_helper.cmake

project(swift-blinky)
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()


set(SWIFT_TARGET "armv6m-none-none-eabi") # default for rp2040

if(PICO_PLATFORM STREQUAL "rp2350-arm-s")
    message(STATUS "PICO_PLATFORM is set to rp2350-arm-s, using armv7em")
    set(SWIFT_TARGET "armv7em-none-none-eabi")
elseif(PICO_PLATFORM STREQUAL "rp2350-riscv")
    # Untested, gives PICO-SDK errors when building
    message(WARNING "PICO_PLATFORM is set to rp2350-riscv, using riscv32 (untested). It is recommended to use rp2350-arm-s.")
    set(SWIFT_TARGET "riscv32-none-none-eabi")
endif()

add_executable(swift-blinky)

target_link_libraries(swift-blinky
    pico_stdlib hardware_uart hardware_gpio
)


# Gather compile definitions from Pico SDK
gather_vars(COMPILE_DEFINITIONS INTERFACE_COMPILE_DEFINITIONS _touched_cd swift-blinky)
list(REMOVE_DUPLICATES COMPILE_DEFINITIONS)
List(PREPEND COMPILE_DEFINITIONS "") # -Xcc -D
string(REPLACE "$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>" "$<TARGET_PROPERTY:swift-blinky,PICO_TARGET_BINARY_TYPE>" COMPILE_DEFINITIONS "${COMPILE_DEFINITIONS}")
string(REPLACE ";" " -Xcc -D" COMPILE_DEFINITIONS "${COMPILE_DEFINITIONS}")

# Save compile definitions to swiftc_flags.txt (this way, CMake will do the generator expression evaluation)
file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/swiftc_flags.txt CONTENT "${COMPILE_DEFINITIONS}")

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
    COMMAND
        ${SWIFTC}
        -target ${SWIFT_TARGET} -Xcc -mfloat-abi=soft -Xcc -fshort-enums
        @${CMAKE_BINARY_DIR}/swiftc_flags.txt # add compiler definitions
        -Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library
        $$\( echo '$<TARGET_PROPERTY:swift-blinky,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(swift-blinky-swiftcode DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o)

target_link_libraries(swift-blinky
    ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
)
add_dependencies(swift-blinky swift-blinky-swiftcode)
pico_add_extra_outputs(swift-blinky)

Where hacky_cmake_helper.cmake is this file from the Raspberry Pi pico-playground repo.

This modification should be done to all Pico SDK examples regardless if they're currently working or not. Quoting from the Pico-SDK issue I mentioned earlier (raspberrypi/pico-sdk#1917):

The swift-embedded should be using the compile definitions for the headers the same as for the regular build, or you may get inconsistencies - this was the case before, but here you now have a compile failure rather than potential silent weirdness

What do you think? How should this be implemented? I can submit a PR following your suggestions.

iCMDdev avatar Sep 09 '24 07:09 iCMDdev

I also managed to run the pico-blink-sdk example on the RP2350 RISC-V cores using this, but it currently depends on an SDK change (raspberrypi/pico-sdk#1922).

To make it work, I've also made some small changes to CMakeLists.txt to add the correct -mabi and -march flags for RISC-V, respectively the -mfloat-abi=soft flag for ARM, based on the PICO_PLATFORM variable.

cmake_minimum_required(VERSION 3.13)
include($ENV{PICO_SDK_PATH}/external/pico_sdk_import.cmake)
include(hacky_cmake_helper.cmake)

project(swift-blinky)
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()


set(SWIFT_TARGET "armv6m-none-none-eabi") # default for rp2040
list(APPEND CLANG_ARCH_ABI_FLAGS "-Xcc") 

if(PICO_PLATFORM STREQUAL "rp2350-arm-s")
    message(STATUS "PICO_PLATFORM is set to rp2350-arm-s, using armv7em")
    set(SWIFT_TARGET "armv7em-none-none-eabi")
    list(APPEND CLANG_ARCH_ABI_FLAGS "-mfloat-abi=soft")
elseif(PICO_PLATFORM STREQUAL "rp2040")
    message(STATUS "PICO_PLATFORM is set to RP2040, using armv6m")
    list(APPEND CLANG_ARCH_ABI_FLAGS "-mfloat-abi=soft")
elseif(PICO_PLATFORM STREQUAL "rp2350-riscv")
    message(STATUS "PICO_PLATFORM is set to rp2350-riscv, using riscv32.")
    set(SWIFT_TARGET "riscv32-none-none-eabi")
    list(APPEND CLANG_ARCH_ABI_FLAGS "-march=rv32imac_zicsr_zifencei_zba_zbb_zbs_zbkb" "-Xcc" "-mabi=ilp32")
endif()

add_executable(swift-blinky)

target_link_libraries(swift-blinky
    pico_stdlib hardware_uart hardware_gpio
)

gather_vars(COMPILE_DEFINITIONS INTERFACE_COMPILE_DEFINITIONS _touched_cd swift-blinky)
list(REMOVE_DUPLICATES COMPILE_DEFINITIONS)
list(PREPEND COMPILE_DEFINITIONS "") # -Xcc -D
string(REPLACE "$<TARGET_PROPERTY:PICO_TARGET_BINARY_TYPE>" "$<TARGET_PROPERTY:swift-blinky,PICO_TARGET_BINARY_TYPE>" COMPILE_DEFINITIONS "${COMPILE_DEFINITIONS}")
string(REPLACE ";" " -Xcc -D" COMPILE_DEFINITIONS "${COMPILE_DEFINITIONS}")


file(GENERATE OUTPUT ${CMAKE_BINARY_DIR}/swiftc_flags.txt CONTENT "${COMPILE_DEFINITIONS}")


add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
    COMMAND
        ${SWIFTC}
        -target ${SWIFT_TARGET} -Xcc -fshort-enums
        @${CMAKE_BINARY_DIR}/swiftc_flags.txt
        ${CLANG_ARCH_ABI_FLAGS}
        -Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library
        $$\( echo '$<TARGET_PROPERTY:swift-blinky,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(swift-blinky-swiftcode DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o)


target_link_libraries(swift-blinky
    ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
)
add_dependencies(swift-blinky swift-blinky-swiftcode)
pico_add_extra_outputs(swift-blinky)

Let me know what you think. I can submit a PR following your suggestions.

iCMDdev avatar Sep 11 '24 10:09 iCMDdev

The Pico SDK issue was fixed, and the PR was merged to the SDK develop branch. It will be released in the master branch with SDK version 2.0.1.

iCMDdev avatar Sep 11 '24 15:09 iCMDdev

I also have this working for a pico_w but target_link_libraries requires the following additions: target_link_libraries(swift-blinky pico_stdlib hardware_uart hardware_gpio pico_lwip_arch pico_cyw43_arch_none )

gary-atkinson avatar Sep 16 '24 10:09 gary-atkinson

I also have this working for a pico_w but target_link_libraries requires the following additions:

target_link_libraries(swift-blinky

pico_stdlib hardware_uart hardware_gpio pico_lwip_arch pico_cyw43_arch_none

)

Doesn't the pico-w-blink-sdk example have these dependencies already (but still lacks the 2.0.0 SDK flags)?

I guess we could merge the 2 pico SDK examples together and add the additional Pico-W specific dependencies if a Pico W is used (using the PICO_BOARD variable).

iCMDdev avatar Sep 16 '24 10:09 iCMDdev

Doesn't the pico-w-blink-sdk example have these dependencies already (but still lacks the 2.0.0 SDK flags)?

Yes it does, I was just pointing out for anyone who is using a pico_w.

I guess we could merge the 2 pico SDK examples together and add the additional Pico-W specific dependencies if a Pico W is used (using the PICO_BOARD variable).

For the CMakeLists yes, but the Main.swift files are rather different.

gary-atkinson avatar Sep 16 '24 10:09 gary-atkinson

For the CMakeLists yes, but the Main.swift files are rather different.

Oh right, forgot about that.

iCMDdev avatar Sep 16 '24 11:09 iCMDdev

Thanks for this. Would be helpful if this got merged into main or addressed by the Apple team somehow.

emileakbarzadeh avatar Oct 06 '24 13:10 emileakbarzadeh

So what should I do to make it work? I tried develop version of pico-sdk and changed CMakeLists.txt, but I still get - error: 'hardware/structs/accessctrl.h' file not found

Flatout73 avatar Oct 07 '24 00:10 Flatout73

@Flatout73 You only need the Pico SDK develop branch for RISC-V mode on the new RP2350. What you’ll (also) need regardless of platform is to change the CMakeLists.txt to this and also copy this file from the Raspberry Pi pico-playground repo to your project’s root.

I have an example of this in my fork.

@emileakbarzadeh I think I’ll make a PR in the near future but I didn’t find the time for it. I wanted to find another way of doing this without the BSD-licensed file from the Raspberry Pi repo, since I don’t think it would be convenient to have this licensed that way / I’m not sure if that would be approved.

iCMDdev avatar Oct 07 '24 04:10 iCMDdev