How do I add C or C++ files to the project that can be used in Embedded Swift (ESP32)?
I'm exploring the Embedded Swift Sample Projects (ESP32 LED Strip) esp32-led-strip-sdk
I have existing code that I want to add, but I haven't been able to get Embedded Swift to compile with non-Swift C/C++ code.
In the CMakeLists.txt it looks like I need to modify two areas:
# Register the app as an IDF component
idf_component_register(
SRCS /dev/null # We don't have any C++ sources
PRIV_INCLUDE_DIRS "."
LDFRAGMENTS "linker.lf"
)
and
# List of Swift source files to build.
target_sources(${COMPONENT_LIB}
PRIVATE
Main.swift
LedStrip.swift
)
I attempted to expose it, but I don't really understand how it needs to be formatted with CMake and ESP IDF.
BridgingHeader.h
#include "print_float.h"
CMakeLists.txt
# List of Swift source files to build.
target_sources(${COMPONENT_LIB}
PRIVATE
src/print_float.cpp
Main.swift
LedStrip.swift
Format.swift
)
I get errors as it is not seeing the C++ function: undefined reference to printFloat
[1/6] Performing build step for 'bootloader'
[1/1] cd /Users/paulsolt/dev/embedded/LED/build/bootloader/esp-idf/esptool_py && /Users/paulsolt/.espressif/python_env/idf5.2_py3.12_env/bin/python /Users/paulsolt/esp/esp-idf/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x0 /Users/paulsolt/dev/embedded/LED/build/bootloader/bootloader.bin
Bootloader binary size 0x54b0 bytes. 0x2b50 bytes (34%) free.
[4/6] Linking CXX executable main.elf
FAILED: main.elf
...
/Users/paulsolt/.espressif/tools/riscv32-esp-elf/esp-13.2.0_20230928/riscv32-esp-elf/bin/../lib/gcc/riscv32-esp-elf/13.2.0/../../../../riscv32-esp-elf/bin/ld: esp-idf/main/libmain.a(Main.swift.obj): in function `.Lpcrel_hi1':
Main.swift.obj:(.text.$s10__idf_main04app_B0yyF+0x3c): undefined reference to `printFloat'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.
Ok I figured out how to add C files to my project, but it looks like I need to add a separate step to compile C++ files into an object file before they can be linked with Swift.
I haven't figured out C++ code yet ...
I added two folders under my main folder:
main/
include/
print_float.h
src/
print_float.c
Then I updated the CMakeLists.txt to grab all the source files in the folder, so that I don't need to keep updating the CmakeLists.txt if I add files.
file(GLOB_RECURSE SOURCES "src/*.c")
message(SOURCES="${SOURCES}") # Prints out the source files added
idf_component_register(
# SRCS /dev/null # We don't have any C++ sources
SRCS ${SOURCES}
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "."
LDFRAGMENTS "linker.lf"
)
I dont have any pointers on how to do this, but whatever you do figure out would be good to push back to embedded examples so others can follow your lead!
@rauhul I attempted to use these guides for Swift and C++, but I don't understand how the ESP32 IDF components and Swift/C++ build settings mix together.
I attempted to merge the CMakeLists.txt settings, but I couldn't get anything to build.
That second link makes it sound like I just need the -cxx-interoperability-mode=default build setting to make it build with swiftc, but the module map and layout of the C++ code may still be important from the previous link.