ソースを参照

cmake: allow selection of clang based toolchain

This is an experimental feature intended at the moment for ESP-IDF
developers only.

If IDF_TOOLCHAIN=clang environment variable or CMake variable is set,
use toolchain-clang-esp32xx.cmake instead of toolchain-esp32xx.cmake.

These changes aren't sufficient to actually build any IDF project with
clang; subsequent commits add a few workarounds required to do this.

Toolchain files are added for esp32 and esp32s2, which are the targets
supported in our llvm-project fork at the moment.
Ivan Grokhotkov 4 年 前
コミット
14e600801e

+ 27 - 1
tools/cmake/targets.cmake

@@ -47,8 +47,34 @@ endfunction()
 #
 macro(__target_set_toolchain)
     idf_build_get_property(idf_path IDF_PATH)
+
+    # See if Clang toolchain should be used
+    set(env_idf_toolchain $ENV{IDF_TOOLCHAIN})
+    if(NOT env_idf_toolchain)
+        # IDF_TOOLCHAIN not set in environment, see if it is set in cache
+        if(IDF_TOOLCHAIN)
+            set(env_idf_toolchain ${IDF_TOOLCHAIN})
+        else()
+            set(env_idf_toolchain gcc)
+        endif()
+    else()
+        # IDF_TOOLCHAIN set both in environment and in cache, must be the same
+        if(NOT ${IDF_TOOLCHAIN} STREQUAL ${env_idf_toolchain})
+            message(FATAL_ERROR "IDF_TOOLCHAIN in CMake cache does not match "
+                    "IDF_TOOLCHAIN environment variable. To change the toolchain, clear "
+                    "the build directory and sdkconfig file, and build the project again")
+        endif()
+    endif()
+
+    # Finally, set IDF_TOOLCHAIN in cache
+    set(IDF_TOOLCHAIN ${env_idf_toolchain} CACHE STRING "IDF Build Toolchain Type")
+
+    if(${env_idf_toolchain} STREQUAL "clang")
+        set(toolchain_type "clang-")
+    endif()
+
     # First try to load the toolchain file from the tools/cmake/directory of IDF
-    set(toolchain_file_global ${idf_path}/tools/cmake/toolchain-${IDF_TARGET}.cmake)
+    set(toolchain_file_global ${idf_path}/tools/cmake/toolchain-${toolchain_type}${IDF_TARGET}.cmake)
     if(EXISTS ${toolchain_file_global})
         set(CMAKE_TOOLCHAIN_FILE ${toolchain_file_global})
     else()

+ 16 - 0
tools/cmake/toolchain-clang-esp32.cmake

@@ -0,0 +1,16 @@
+set(CMAKE_SYSTEM_NAME Generic)
+
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_ASM_COMPILER clang)
+
+set(CMAKE_AR xtensa-esp32-elf-ar)
+set(CMAKE_RANLIB xtensa-esp32-elf-gcc-ranlib)
+set(CMAKE_OBJDUMP xtensa-esp32-elf-objdump)
+
+# -freestanding is a hack to force Clang to use its own stdatomic.h,
+# without falling back to the (incompatible) GCC stdatomic.h
+# https://github.com/espressif/llvm-project/blob/d9341b81/clang/lib/Headers/stdatomic.h#L13-L18
+set(CMAKE_C_FLAGS "--target=xtensa -mcpu=esp32 -ffreestanding" CACHE STRING "C Compiler Base Flags")
+set(CMAKE_CXX_FLAGS "--target=xtensa -mcpu=esp32 -ffreestanding" CACHE STRING "C++ Compiler Base Flags")
+set(CMAKE_ASM_FLAGS "--target=xtensa -mcpu=esp32" CACHE STRING "Assembler Base Flags")

+ 16 - 0
tools/cmake/toolchain-clang-esp32s2.cmake

@@ -0,0 +1,16 @@
+set(CMAKE_SYSTEM_NAME Generic)
+
+set(CMAKE_C_COMPILER clang)
+set(CMAKE_CXX_COMPILER clang++)
+set(CMAKE_ASM_COMPILER clang)
+
+set(CMAKE_AR xtensa-esp32-elf-ar)
+set(CMAKE_RANLIB xtensa-esp32-elf-gcc-ranlib)
+set(CMAKE_OBJDUMP xtensa-esp32-elf-objdump)
+
+# -freestanding is a hack to force Clang to use its own stdatomic.h,
+# without falling back to the (incompatible) GCC stdatomic.h
+# https://github.com/espressif/llvm-project/blob/d9341b81/clang/lib/Headers/stdatomic.h#L13-L18
+set(CMAKE_C_FLAGS "--target=xtensa -mcpu=esp32s2 -ffreestanding" CACHE STRING "C Compiler Base Flags")
+set(CMAKE_CXX_FLAGS "--target=xtensa -mcpu=esp32s2 -ffreestanding" CACHE STRING "C++ Compiler Base Flags")
+set(CMAKE_ASM_FLAGS "--target=xtensa -mcpu=esp32s2" CACHE STRING "Assembler Base Flags")