|
1 | | -# Register the app as an IDF component |
| 1 | +# ============================================================================== |
| 2 | +# ESP-IDF Component Configuration for Swift-Based Applications |
| 3 | +# ============================================================================== |
| 4 | +# This CMakeLists.txt configures the "main" component of an ESP-IDF project |
| 5 | +# that uses Embedded Swift instead of traditional C/C++. |
| 6 | +# ============================================================================== |
| 7 | +# ------------------------------------------------------------------------------ |
| 8 | +# Step 1: Register the component with ESP-IDF |
| 9 | +# ------------------------------------------------------------------------------ |
| 10 | +# idf_component_register() tells the build system about this component's files |
| 11 | +# and dependencies. Even though we're using Swift, we still need to register |
| 12 | +# as an IDF component. |
| 13 | +# |
| 14 | +# Parameters: |
| 15 | +# SRCS: C/C++ source files to compile. |
| 16 | +# PRIV_INCLUDE_DIRS: Private header directories for this component only. |
| 17 | +# Set to "." so the BridgingHeader.h can be found. |
| 18 | +# PRIV_REQUIRES: Components this component depends on (linked privately): |
| 19 | +# - swift: Provides Embedded Swift runtime and compilation support |
| 20 | +# - esp_driver_gpio: ESP-IDF GPIO driver for controlling hardware pins |
| 21 | +# |
| 22 | +# IMPORTANT: All dependencies must be explicitly listed. |
2 | 23 | idf_component_register( |
3 | | - SRCS /dev/null # We don't have any C++ sources |
| 24 | + SRCS /dev/null |
4 | 25 | PRIV_INCLUDE_DIRS "." |
| 26 | + PRIV_REQUIRES swift esp_driver_gpio |
5 | 27 | ) |
6 | 28 |
|
7 | | -idf_build_get_property(target IDF_TARGET) |
8 | | -idf_build_get_property(arch IDF_TARGET_ARCH) |
9 | | - |
10 | | -if("${arch}" STREQUAL "xtensa") |
11 | | - message(FATAL_ERROR "Not supported target: ${target}") |
12 | | -endif() |
13 | | - |
14 | | -# Extract -march and -mabi flags |
15 | | -set(march_flag "") |
16 | | -set(mabi_flag "") |
17 | | - |
18 | | -# Method 1: Read from IDF's cflags response file (IDF 6.0+) |
19 | | -if(DEFINED IDF_TOOLCHAIN_BUILD_DIR AND EXISTS "${IDF_TOOLCHAIN_BUILD_DIR}/cflags") |
20 | | - file(STRINGS "${IDF_TOOLCHAIN_BUILD_DIR}/cflags" cflags_lines) |
21 | | - foreach(line IN LISTS cflags_lines) |
22 | | - if(line MATCHES "^-march=") |
23 | | - set(march_flag "${line}") |
24 | | - elseif(line MATCHES "^-mabi=") |
25 | | - set(mabi_flag "${line}") |
26 | | - endif() |
27 | | - endforeach() |
28 | | -endif() |
29 | | - |
30 | | -# Method 2: Fallback to parsing CMAKE_C_FLAGS directly (older IDF versions) |
31 | | -if(NOT march_flag OR NOT mabi_flag) |
32 | | - string(REGEX MATCH "-march=[^ ]+" march_flag_fallback "${CMAKE_C_FLAGS}") |
33 | | - string(REGEX MATCH "-mabi=[^ ]+" mabi_flag_fallback "${CMAKE_C_FLAGS}") |
34 | | - if(NOT march_flag AND march_flag_fallback) |
35 | | - set(march_flag "${march_flag_fallback}") |
36 | | - endif() |
37 | | - if(NOT mabi_flag AND mabi_flag_fallback) |
38 | | - set(mabi_flag "${mabi_flag_fallback}") |
39 | | - endif() |
40 | | -endif() |
41 | | - |
42 | | -# Default mabi if not found |
43 | | -if(NOT mabi_flag) |
44 | | - set(mabi_flag "-mabi=ilp32") |
45 | | -endif() |
46 | | - |
47 | | -# Strip Espressif custom extensions not supported by Swift |
48 | | -if(march_flag) |
49 | | - string(REGEX REPLACE "_x[^ ]*" "" march_flag "${march_flag}") |
50 | | -endif() |
51 | | - |
52 | | -# Clear the default COMPILE_OPTIONS which include a lot of C/C++ specific compiler flags that the Swift compiler will not accept |
53 | | -get_target_property(var ${COMPONENT_LIB} COMPILE_OPTIONS) |
54 | | -set_target_properties(${COMPONENT_LIB} PROPERTIES COMPILE_OPTIONS "") |
55 | | - |
56 | | -# Compute -Xcc flags to set up the C and C++ header search paths for Swift (for bridging header). |
57 | | -set(SWIFT_INCLUDES) |
58 | | -foreach(dir ${CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES}) |
59 | | - string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ") |
60 | | - string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ") |
61 | | -endforeach() |
62 | | -foreach(dir ${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}) |
63 | | - string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-Xcc ") |
64 | | - string(CONCAT SWIFT_INCLUDES ${SWIFT_INCLUDES} "-I${dir} ") |
65 | | -endforeach() |
66 | | - |
67 | | -# Swift compiler flags to build in Embedded Swift mode, optimize for size, choose the right ISA, ABI, etc. |
68 | | -target_compile_options(${COMPONENT_LIB} PUBLIC "$<$<COMPILE_LANGUAGE:Swift>:SHELL: |
69 | | - -target riscv32-none-none-eabi |
70 | | - -Xfrontend -function-sections -enable-experimental-feature Embedded -wmo -parse-as-library -Osize |
71 | | - -Xcc ${march_flag} -Xcc ${mabi_flag} -Xcc -fno-pic -Xcc -fno-pie |
72 | | - |
73 | | - -pch-output-dir /tmp |
74 | | - -Xfrontend -enable-single-module-llvm-emission |
75 | | - |
76 | | - ${SWIFT_INCLUDES} |
77 | | -
|
78 | | - -import-bridging-header ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h |
79 | | - >") |
80 | | - |
81 | | -# Enable Swift support in CMake, force Whole Module builds (required by Embedded Swift), and use "CMAKE_Swift_COMPILER_WORKS" to |
82 | | -# skip the trial compilations which don't (yet) correctly work when cross-compiling. |
83 | | -set(CMAKE_Swift_COMPILER_WORKS YES) |
84 | | -set(CMAKE_Swift_COMPILATION_MODE_DEFAULT wholemodule) |
85 | | -set(CMAKE_Swift_COMPILATION_MODE wholemodule) |
86 | | -enable_language(Swift) |
87 | | - |
88 | | -# List of Swift source files to build. |
89 | | -target_sources(${COMPONENT_LIB} |
90 | | - PRIVATE |
91 | | - Main.swift |
92 | | - LedStrip.swift |
93 | | -) |
94 | | - |
95 | | -add_custom_command( |
96 | | - TARGET ${COMPONENT_LIB} |
97 | | - POST_BUILD |
98 | | - COMMAND ${CMAKE_OBJCOPY} --remove-section .swift_modhash |
99 | | - $<TARGET_FILE:${COMPONENT_LIB}> $<TARGET_FILE:${COMPONENT_LIB}> |
| 29 | +# ------------------------------------------------------------------------------ |
| 30 | +# Step 2: Configure Embedded Swift compilation |
| 31 | +# ------------------------------------------------------------------------------ |
| 32 | +# idf_component_register_swift() is a custom function (provided by the 'swift' |
| 33 | +# component) that configures the Swift compiler for embedded systems. |
| 34 | +# |
| 35 | +# Parameters: |
| 36 | +# ${COMPONENT_LIB}: The CMake library target created by idf_component_register() |
| 37 | +# (automatically available after registration) |
| 38 | +# BRIDGING_HEADER: C header file that exposes C APIs to Swift code. |
| 39 | +# This allows Swift to call ESP-IDF C functions. |
| 40 | +# SRCS: Swift source files to compile. List all .swift files in your project. |
| 41 | +idf_component_register_swift( |
| 42 | + ${COMPONENT_LIB} |
| 43 | + BRIDGING_HEADER ${CMAKE_CURRENT_LIST_DIR}/BridgingHeader.h |
| 44 | + SRCS Main.swift LedStrip.swift |
100 | 45 | ) |
0 commit comments