Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions esp32-led-blink-sdk/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.29)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
idf_build_set_property(MINIMAL_BUILD ON)
project(main)
140 changes: 45 additions & 95 deletions esp32-led-blink-sdk/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,100 +1,50 @@
# Register the app as an IDF component
# ==============================================================================
# ESP-IDF Component Configuration for Swift-Based Applications
# ==============================================================================
# This CMakeLists.txt configures the "main" component of an ESP-IDF project
# that uses Embedded Swift instead of traditional C/C++.
# ==============================================================================
# ------------------------------------------------------------------------------
# Step 1: Register the component with ESP-IDF
# ------------------------------------------------------------------------------
# idf_component_register() tells the build system about this component's files
# and dependencies. Even though we're using Swift, we still need to register
# as an IDF component.
#
# Parameters:
# SRCS: C/C++ source files to compile.
# PRIV_INCLUDE_DIRS: Private header directories for this component only.
# Set to "." so the BridgingHeader.h can be found.
# PRIV_REQUIRES: Components this component depends on (linked privately):
# - swift: Provides Embedded Swift runtime and compilation support
# - esp_driver_gpio: ESP-IDF GPIO driver for controlling hardware pins
#
# IMPORTANT: All dependencies must be explicitly listed.
if(WIN32)
set(devnull NUL)
else()
set(devnull /dev/null)
endif()
idf_component_register(
SRCS /dev/null # We don't have any C++ sources
SRCS ${devnull}
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES swift esp_driver_gpio
)

idf_build_get_property(target IDF_TARGET)
idf_build_get_property(arch IDF_TARGET_ARCH)

if("${arch}" STREQUAL "xtensa")
message(FATAL_ERROR "Not supported target: ${target}")
endif()

# Extract -march and -mabi flags
set(march_flag "")
set(mabi_flag "")

# Method 1: Read from IDF's cflags response file (IDF 6.0+)
if(DEFINED IDF_TOOLCHAIN_BUILD_DIR AND EXISTS "${IDF_TOOLCHAIN_BUILD_DIR}/cflags")
file(STRINGS "${IDF_TOOLCHAIN_BUILD_DIR}/cflags" cflags_lines)
foreach(line IN LISTS cflags_lines)
if(line MATCHES "^-march=")
set(march_flag "${line}")
elseif(line MATCHES "^-mabi=")
set(mabi_flag "${line}")
endif()
endforeach()
endif()

# Method 2: Fallback to parsing CMAKE_C_FLAGS directly (older IDF versions)
if(NOT march_flag OR NOT mabi_flag)
string(REGEX MATCH "-march=[^ ]+" march_flag_fallback "${CMAKE_C_FLAGS}")
string(REGEX MATCH "-mabi=[^ ]+" mabi_flag_fallback "${CMAKE_C_FLAGS}")
if(NOT march_flag AND march_flag_fallback)
set(march_flag "${march_flag_fallback}")
endif()
if(NOT mabi_flag AND mabi_flag_fallback)
set(mabi_flag "${mabi_flag_fallback}")
endif()
endif()

# Default mabi if not found
if(NOT mabi_flag)
set(mabi_flag "-mabi=ilp32")
endif()

# Strip Espressif custom extensions not supported by Swift
if(march_flag)
string(REGEX REPLACE "_x[^ ]*" "" march_flag "${march_flag}")
endif()

# Clear the default COMPILE_OPTIONS which include a lot of C/C++ specific compiler flags that the Swift compiler will not accept
get_target_property(var ${COMPONENT_LIB} COMPILE_OPTIONS)
set_target_properties(${COMPONENT_LIB} PROPERTIES COMPILE_OPTIONS "")

# Compute -Xcc flags to set up the C and C++ header search paths for Swift (for bridging header).
set(SWIFT_INCLUDES)
foreach(dir ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
endforeach()
foreach(dir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
endforeach()

# Swift compiler flags to build in Embedded Swift mode, optimize for size, choose the right ISA, ABI, etc.
target_compile_options(${COMPONENT_LIB} PUBLIC "$<$<COMPILE_LANGUAGE:Swift>:SHELL:
-target riscv32-none-none-eabi
-Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library -Osize
-Xcc ${march_flag} -Xcc ${mabi_flag} -Xcc -fno-pic -Xcc -fno-pie

-pch-output-dir /tmp
-Xfrontend -enable-single-module-llvm-emission

${SWIFT_INCLUDES}

-import-bridging-header ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
>")

# Enable Swift support in CMake, force Whole Module builds (required by Embedded Swift), and use "CMAKE_Swift_COMPILER_WORKS" to
# skip the trial compilations which don't (yet) correctly work when cross-compiling.
set(CMAKE_Swift_COMPILER_WORKS YES)
set(CMAKE_Swift_COMPILATION_MODE_DEFAULT wholemodule)
set(CMAKE_Swift_COMPILATION_MODE wholemodule)
enable_language(Swift)

# List of Swift source files to build.
target_sources(${COMPONENT_LIB}
PRIVATE
Main.swift
Led.swift
)

add_custom_command(
TARGET ${COMPONENT_LIB}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} --remove-section .swift_modhash
$<TARGET_FILE:${COMPONENT_LIB}> $<TARGET_FILE:${COMPONENT_LIB}>
# ------------------------------------------------------------------------------
# Step 2: Configure Embedded Swift compilation
# ------------------------------------------------------------------------------
# idf_component_register_swift() is a custom function (provided by the 'swift'
# component) that configures the Swift compiler for embedded systems.
#
# Parameters:
# ${COMPONENT_LIB}: The CMake library target created by idf_component_register()
# (automatically available after registration)
# BRIDGING_HEADER: C header file that exposes C APIs to Swift code.
# This allows Swift to call ESP-IDF C functions.
# SRCS: Swift source files to compile. List all .swift files in your project.
idf_component_register_swift(
${COMPONENT_LIB}
BRIDGING_HEADER ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
SRCS Main.swift Led.swift
)
2 changes: 2 additions & 0 deletions esp32-led-blink-sdk/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dependencies:
espressif/idf_swift: "^1.0.0"
1 change: 0 additions & 1 deletion esp32-led-blink-sdk/sdkconfig.defaults

This file was deleted.

1 change: 1 addition & 0 deletions esp32-led-strip-sdk/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
cmake_minimum_required(VERSION 3.29)

include($ENV{IDF_PATH}/tools/cmake/project.cmake)
idf_build_set_property(MINIMAL_BUILD ON)
project(main)
140 changes: 45 additions & 95 deletions esp32-led-strip-sdk/main/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,100 +1,50 @@
# Register the app as an IDF component
# ==============================================================================
# ESP-IDF Component Configuration for Swift-Based Applications
# ==============================================================================
# This CMakeLists.txt configures the "main" component of an ESP-IDF project
# that uses Embedded Swift instead of traditional C/C++.
# ==============================================================================
# ------------------------------------------------------------------------------
# Step 1: Register the component with ESP-IDF
# ------------------------------------------------------------------------------
# idf_component_register() tells the build system about this component's files
# and dependencies. Even though we're using Swift, we still need to register
# as an IDF component.
#
# Parameters:
# SRCS: C/C++ source files to compile.
# PRIV_INCLUDE_DIRS: Private header directories for this component only.
# Set to "." so the BridgingHeader.h can be found.
# PRIV_REQUIRES: Components this component depends on (linked privately):
# - swift: Provides Embedded Swift runtime and compilation support
# - esp_driver_gpio: ESP-IDF GPIO driver for controlling hardware pins
#
# IMPORTANT: All dependencies must be explicitly listed.
if(WIN32)
set(devnull NUL)
else()
set(devnull /dev/null)
endif()
idf_component_register(
SRCS /dev/null # We don't have any C++ sources
SRCS ${devnull}
PRIV_INCLUDE_DIRS "."
PRIV_REQUIRES swift esp_driver_gpio
)

idf_build_get_property(target IDF_TARGET)
idf_build_get_property(arch IDF_TARGET_ARCH)

if("${arch}" STREQUAL "xtensa")
message(FATAL_ERROR "Not supported target: ${target}")
endif()

# Extract -march and -mabi flags
set(march_flag "")
set(mabi_flag "")

# Method 1: Read from IDF's cflags response file (IDF 6.0+)
if(DEFINED IDF_TOOLCHAIN_BUILD_DIR AND EXISTS "${IDF_TOOLCHAIN_BUILD_DIR}/cflags")
file(STRINGS "${IDF_TOOLCHAIN_BUILD_DIR}/cflags" cflags_lines)
foreach(line IN LISTS cflags_lines)
if(line MATCHES "^-march=")
set(march_flag "${line}")
elseif(line MATCHES "^-mabi=")
set(mabi_flag "${line}")
endif()
endforeach()
endif()

# Method 2: Fallback to parsing CMAKE_C_FLAGS directly (older IDF versions)
if(NOT march_flag OR NOT mabi_flag)
string(REGEX MATCH "-march=[^ ]+" march_flag_fallback "${CMAKE_C_FLAGS}")
string(REGEX MATCH "-mabi=[^ ]+" mabi_flag_fallback "${CMAKE_C_FLAGS}")
if(NOT march_flag AND march_flag_fallback)
set(march_flag "${march_flag_fallback}")
endif()
if(NOT mabi_flag AND mabi_flag_fallback)
set(mabi_flag "${mabi_flag_fallback}")
endif()
endif()

# Default mabi if not found
if(NOT mabi_flag)
set(mabi_flag "-mabi=ilp32")
endif()

# Strip Espressif custom extensions not supported by Swift
if(march_flag)
string(REGEX REPLACE "_x[^ ]*" "" march_flag "${march_flag}")
endif()

# Clear the default COMPILE_OPTIONS which include a lot of C/C++ specific compiler flags that the Swift compiler will not accept
get_target_property(var ${COMPONENT_LIB} COMPILE_OPTIONS)
set_target_properties(${COMPONENT_LIB} PROPERTIES COMPILE_OPTIONS "")

# Compute -Xcc flags to set up the C and C++ header search paths for Swift (for bridging header).
set(SWIFT_INCLUDES)
foreach(dir ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES})
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
endforeach()
foreach(dir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES})
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ")
string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ")
endforeach()

# Swift compiler flags to build in Embedded Swift mode, optimize for size, choose the right ISA, ABI, etc.
target_compile_options(${COMPONENT_LIB} PUBLIC "$<$<COMPILE_LANGUAGE:Swift>:SHELL:
-target riscv32-none-none-eabi
-Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library -Osize
-Xcc ${march_flag} -Xcc ${mabi_flag} -Xcc -fno-pic -Xcc -fno-pie

-pch-output-dir /tmp
-Xfrontend -enable-single-module-llvm-emission

${SWIFT_INCLUDES}

-import-bridging-header ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
>")

# Enable Swift support in CMake, force Whole Module builds (required by Embedded Swift), and use "CMAKE_Swift_COMPILER_WORKS" to
# skip the trial compilations which don't (yet) correctly work when cross-compiling.
set(CMAKE_Swift_COMPILER_WORKS YES)
set(CMAKE_Swift_COMPILATION_MODE_DEFAULT wholemodule)
set(CMAKE_Swift_COMPILATION_MODE wholemodule)
enable_language(Swift)

# List of Swift source files to build.
target_sources(${COMPONENT_LIB}
PRIVATE
Main.swift
LedStrip.swift
)

add_custom_command(
TARGET ${COMPONENT_LIB}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} --remove-section .swift_modhash
$<TARGET_FILE:${COMPONENT_LIB}> $<TARGET_FILE:${COMPONENT_LIB}>
# ------------------------------------------------------------------------------
# Step 2: Configure Embedded Swift compilation
# ------------------------------------------------------------------------------
# idf_component_register_swift() is a custom function (provided by the 'swift'
# component) that configures the Swift compiler for embedded systems.
#
# Parameters:
# ${COMPONENT_LIB}: The CMake library target created by idf_component_register()
# (automatically available after registration)
# BRIDGING_HEADER: C header file that exposes C APIs to Swift code.
# This allows Swift to call ESP-IDF C functions.
# SRCS: Swift source files to compile. List all .swift files in your project.
idf_component_register_swift(
${COMPONENT_LIB}
BRIDGING_HEADER ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h
SRCS Main.swift LedStrip.swift
)
1 change: 1 addition & 0 deletions esp32-led-strip-sdk/main/idf_component.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
dependencies:
espressif/idf_swift: "^1.0.0"
espressif/led_strip: "^3.0.2"
1 change: 0 additions & 1 deletion esp32-led-strip-sdk/sdkconfig.defaults

This file was deleted.

Loading