Skip to content
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