Skip to content

Pico SDK - Fix Compiler Definitions & RISC-V RP2350 support #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Nov 8, 2024
67 changes: 62 additions & 5 deletions pico-blink-sdk/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,81 @@ 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")
list(APPEND CLANG_ARCH_ABI_FLAGS "-Xcc" "-mfloat-abi=soft")
elseif(PICO_PLATFORM STREQUAL "rp2040")
message(STATUS "PICO_PLATFORM is set to RP2040, using armv6m")
list(APPEND CLANG_ARCH_ABI_FLAGS "-Xcc" "-mfloat-abi=soft")
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.")
message(STATUS "PICO_PLATFORM is set to rp2350-riscv, using riscv32.")
set(SWIFT_TARGET "riscv32-none-none-eabi")
list(APPEND CLANG_ARCH_ABI_FLAGS "-Xcc" "-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 compile definitions from all dependencies

set_property(GLOBAL PROPERTY visited_targets "")
set_property(GLOBAL PROPERTY compilerdefs_list "")

function(gather_compile_definitions_recursive target)
# Get the current value of visited_targets
get_property(visited_targets GLOBAL PROPERTY visited_targets)

# make sure we don't visit the same target twice
# and that we don't visit the special generator expressions
if (${target} MATCHES "\\$<" OR ${target} MATCHES "::@" OR ${target} IN_LIST visited_targets)
return()
endif()

# Append the target to visited_targets
list(APPEND visited_targets ${target})
set_property(GLOBAL PROPERTY visited_targets "${visited_targets}")

# Get the current value of compilerdefs_list
get_property(compilerdefs_list GLOBAL PROPERTY compilerdefs_list)

get_target_property(target_definitions ${target} INTERFACE_COMPILE_DEFINITIONS)
if (target_definitions)
# Append the target definitions to compilerdefs_list
list(APPEND compilerdefs_list ${target_definitions})
set_property(GLOBAL PROPERTY compilerdefs_list "${compilerdefs_list}")
endif()

get_target_property(target_linked_libs ${target} INTERFACE_LINK_LIBRARIES)
if (target_linked_libs)
foreach(linked_target ${target_linked_libs})
# Recursively gather compile definitions from dependencies
gather_compile_definitions_recursive(${linked_target})
endforeach()
endif()
endfunction()

gather_compile_definitions_recursive(swift-blinky)
get_property(COMPILE_DEFINITIONS GLOBAL PROPERTY compilerdefs_list)

# Parse compiler definitions into a format that swiftc can understand
list(REMOVE_DUPLICATES COMPILE_DEFINITIONS)
list(PREPEND COMPILE_DEFINITIONS "")
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}")

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
COMMAND
${SWIFTC}
-target ${SWIFT_TARGET} -Xcc -mfloat-abi=soft -Xcc -fshort-enums
-target ${SWIFT_TARGET} -Xcc -fshort-enums
${COMPILE_DEFINITIONS}
${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' \)
Expand All @@ -40,8 +97,8 @@ add_custom_command(
)
add_custom_target(swift-blinky-swiftcode DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o)


target_link_libraries(swift-blinky
pico_stdlib hardware_uart hardware_gpio
${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
)
add_dependencies(swift-blinky swift-blinky-swiftcode)
Expand Down
7 changes: 4 additions & 3 deletions pico-blink-sdk/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ This example demonstrates how to integrate with the Pico SDK which is using CMak

- A Raspberry Pi Pico (non-W) board. If you have a Pico W instead, refer to the [pico-w-blink-sdk](../pico-w-blink-sdk) sample instead.
- Follow the setup steps at https://datasheets.raspberrypi.com/pico/getting-started-with-pico.pdf, in particular you'll need:
- A checkout of the [pico-sdk](https://github.com/raspberrypi/pico-sdk.git), with git submodules checked out.
- A checkout of the [pico-sdk](https://github.com/raspberrypi/pico-sdk.git), with git submodules checked out. If you'd like to try RISC-V support for RP2350, you'll need Pico SDK 2.0.1 or later (currently in the *development branch only*).
- A checkout of the [pico-examples](https://github.com/raspberrypi/pico-examples.git).
- CMake.
- The [Arm Embedded Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads).
- The [Arm Embedded Toolchain](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads), or the RISC-V tollchain if you want to build for the RISC-V cores on the RP2350.
- Before trying to use Swift with the Pico SDK, make sure your environment works and can build the provided C/C++ sample projects, in particular:
- Try building and running the "blink" example from pico-examples written in C.

Expand All @@ -25,8 +25,9 @@ This example demonstrates how to integrate with the Pico SDK which is using CMak
$ cd pico-blink-sdk
$ export TOOLCHAINS='<toolchain-identifier>'
$ export PICO_BOARD='<board-name>' # Examples: pico, pico2
$ export PICO_PLATFORM='<optional-platform-name>' # Optional; useful if you'd like to compile for RISC-V. Examples: rp2040, rp2350-arm-s, rp2350-riscv
$ export PICO_SDK_PATH='<path-to-your-pico-sdk>'
$ export PICO_TOOLCHAIN_PATH='<path-to-the-arm-toolchain>' # A default `brew` install will be located at `/Applications/ArmGNUToolchain/[version]/arm-none-eabi`
$ export PICO_TOOLCHAIN_PATH='<path-to-the-compiler-toolchain>' # A default `brew` install will be located at `/Applications/ArmGNUToolchain/[version]/arm-none-eabi`. This can also be a RISC-V toolchain for the RP2350.
$ cmake -B build -G Ninja .
$ cmake --build build
```
Expand Down
52 changes: 51 additions & 1 deletion pico-w-blink-sdk/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,62 @@ execute_process(COMMAND which swiftc OUTPUT_VARIABLE SWIFTC OUTPUT_STRIP_TRAILIN
endif()

add_executable(swift-blinky)
target_link_libraries(swift-blinky
pico_stdlib hardware_uart hardware_gpio pico_lwip_arch pico_cyw43_arch_none
)

# Gather compile definitions from all dependencies
set_property(GLOBAL PROPERTY visited_targets "")
set_property(GLOBAL PROPERTY compilerdefs_list "")

function(gather_compile_definitions_recursive target)
# Get the current value of visited_targets
get_property(visited_targets GLOBAL PROPERTY visited_targets)

# make sure we don't visit the same target twice
# and that we don't visit the special generator expressions
if (${target} MATCHES "\\$<" OR ${target} MATCHES "::@" OR ${target} IN_LIST visited_targets)
return()
endif()

# Append the target to visited_targets
list(APPEND visited_targets ${target})
set_property(GLOBAL PROPERTY visited_targets "${visited_targets}")

# Get the current value of compilerdefs_list
get_property(compilerdefs_list GLOBAL PROPERTY compilerdefs_list)

get_target_property(target_definitions ${target} INTERFACE_COMPILE_DEFINITIONS)
if (target_definitions)
# Append the target definitions to compilerdefs_list
list(APPEND compilerdefs_list ${target_definitions})
set_property(GLOBAL PROPERTY compilerdefs_list "${compilerdefs_list}")
endif()

get_target_property(target_linked_libs ${target} INTERFACE_LINK_LIBRARIES)
if (target_linked_libs)
foreach(linked_target ${target_linked_libs})
# Recursively gather compile definitions from dependencies
gather_compile_definitions_recursive(${linked_target})
endforeach()
endif()
endfunction()

gather_compile_definitions_recursive(swift-blinky)
get_property(COMPILE_DEFINITIONS GLOBAL PROPERTY compilerdefs_list)

# Parse compiler definitions into a format that swiftc can understand
list(REMOVE_DUPLICATES COMPILE_DEFINITIONS)
list(PREPEND COMPILE_DEFINITIONS "") # adds a semicolon at the beginning
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}")

add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
COMMAND
${SWIFTC}
-target armv6m-none-none-eabi -Xcc -mfloat-abi=soft -Xcc -fshort-enums
${COMPILE_DEFINITIONS}
-Xcc -DCYW43_LWIP
-Xcc -DPICO_CYW43_ARCH_THREADSAFE_BACKGROUND
-Xcc -I$ENV{PICO_SDK_PATH}/lib/lwip/src/include
Expand All @@ -33,7 +84,6 @@ add_custom_command(
add_custom_target(swift-blinky-swiftcode DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o)

target_link_libraries(swift-blinky
pico_stdlib hardware_uart hardware_gpio pico_lwip_arch pico_cyw43_arch_none
${CMAKE_CURRENT_BINARY_DIR}/_swiftcode.o
)
add_dependencies(swift-blinky swift-blinky-swiftcode)
Expand Down