Skip to content

Commit

Permalink
Merge branch 'feature/universal_clang_toolchain_support' into 'master'
Browse files Browse the repository at this point in the history
build: Adds support for universal Clang toolchain

Closes LLVM-79

See merge request espressif/esp-idf!20090
  • Loading branch information
gerekon committed Nov 23, 2022
2 parents 785f154 + 47c2c13 commit 8c2ae2f
Show file tree
Hide file tree
Showing 46 changed files with 598 additions and 80 deletions.
5 changes: 5 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,11 @@ cache:
fi
fi

# Install esp-clang if necessary
if [[ "$IDF_TOOLCHAIN" == "clang" ]]; then
$IDF_PATH/tools/idf_tools.py --non-interactive install esp-clang
fi

source ./export.sh

# Custom OpenOCD
Expand Down
82 changes: 82 additions & 0 deletions .gitlab/ci/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,24 @@
examples/bluetooth/hci/controller_hci_uart_esp32
examples/wifi/iperf

.build_cmake_clang_template:
extends:
- .build_cmake_template
variables:
IDF_TOOLCHAIN: clang
TEST_BUILD_OPTS_EXTRA: ""
TEST_DIR: tools/test_apps/system/cxx_pthread_bluetooth
script:
# CI specific options start from "--collect-size-info xxx". could ignore when running locally
- run_cmd python tools/ci/ci_build_apps.py $TEST_DIR -v
-t $IDF_TARGET
--copy-sdkconfig
--collect-size-info size_info.txt
--collect-app-info list_job_${CI_NODE_INDEX:-1}.json
--parallel-count ${CI_NODE_TOTAL:-1}
--parallel-index ${CI_NODE_INDEX:-1}
$TEST_BUILD_OPTS_EXTRA

.build_pytest_template:
extends:
- .build_cmake_template
Expand Down Expand Up @@ -595,6 +613,70 @@ build_test_apps_esp32c6:
IDF_TARGET: esp32c6
TEST_DIR: tools/test_apps

build_clang_test_apps_esp32:
extends:
- .build_cmake_clang_template
- .rules:build:custom_test-esp32
variables:
IDF_TARGET: esp32

build_clang_test_apps_esp32s2:
extends:
- .build_cmake_clang_template
- .rules:build:custom_test-esp32s2
variables:
IDF_TARGET: esp32s2

build_clang_test_apps_esp32s3:
extends:
- .build_cmake_clang_template
- .rules:build:custom_test-esp32s3
variables:
IDF_TARGET: esp32s3

.build_clang_test_apps_riscv:
extends:
- .build_cmake_clang_template
variables:
# For RISCV clang generates '.linker-options' sections of type 'llvm_linker_options' in asm files.
# See (https://llvm.org/docs/Extensions.html#linker-options-section-linker-options).
# Binutils gas ignores them with warning.
# TODO: LLVM-112, Use integrated assembler.
TEST_BUILD_OPTS_EXTRA: "--ignore-warning-str 'Warning: unrecognized section type'"

build_clang_test_apps_esp32c3:
extends:
- .build_clang_test_apps_riscv
- .rules:build:custom_test-esp32c3
variables:
IDF_TARGET: esp32c3

build_clang_test_apps_esp32c2:
extends:
- .build_clang_test_apps_riscv
- .rules:build:custom_test-esp32c2
# spec files and nano libc are not supported yet by esp-clang
# TODO: LLVM-197
allow_failure: true
variables:
IDF_TARGET: esp32c2

build_clang_test_apps_esp32c6:
extends:
- .build_clang_test_apps_riscv
- .rules:build:custom_test-esp32c6
# TODO: c6 builds fail in master due to missing headers
allow_failure: true
variables:
IDF_TARGET: esp32c6

build_clang_test_apps_esp32h4:
extends:
- .build_clang_test_apps_riscv
- .rules:build:custom_test-esp32h4
variables:
IDF_TARGET: esp32h4

.test_build_system_template:
stage: host_test
extends:
Expand Down
22 changes: 22 additions & 0 deletions .gitlab/ci/rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,28 @@
- <<: *if-dev-push
changes: *patterns-target_test-wifi

.rules:build:custom_test-esp32h4:
rules:
- <<: *if-revert-branch
when: never
- <<: *if-protected
- <<: *if-label-build
- <<: *if-label-custom_test
- <<: *if-label-custom_test_esp32h4
- <<: *if-label-target_test
- <<: *if-dev-push
changes: *patterns-build_components
- <<: *if-dev-push
changes: *patterns-build_system
- <<: *if-dev-push
changes: *patterns-custom_test
- <<: *if-dev-push
changes: *patterns-downloadable-tools
- <<: *if-dev-push
changes: *patterns-target_test-i154
- <<: *if-dev-push
changes: *patterns-target_test-wifi

.rules:build:custom_test-esp32s2:
rules:
- <<: *if-revert-branch
Expand Down
16 changes: 13 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,19 @@ if(CMAKE_C_COMPILER_ID MATCHES "Clang")
# Disable Clang warnings for atomic operations with access size
# more then 4 bytes
list(APPEND compile_options "-Wno-atomic-alignment")
# several warnings in wpa_supplicant component
list(APPEND compile_options "-Wno-unused-but-set-variable")
# Clang also produces many -Wunused-function warnings which GCC doesn't.
# However these aren't treated as errors.
list(APPEND compile_options "-Wno-unused-function")
# many warnings in bluedroid code
# warning: field 'hdr' with variable sized type 'BT_HDR' not at the end of a struct or class is a GNU extension
list(APPEND compile_options "-Wno-gnu-variable-sized-type-not-at-end")
# several warnings in bluedroid code
list(APPEND compile_options "-Wno-constant-logical-operand")
# warning: '_Static_assert' with no message is a C2x extension
list(APPEND compile_options "-Wno-c2x-extensions")
# warning on xMPU_SETTINGS for esp32s2 has size 0 for C and 1 for C++
list(APPEND compile_options "-Wno-extern-c-compat")
endif()
# More warnings may exist in unit tests and example projects.

Expand Down Expand Up @@ -171,7 +182,6 @@ endif()
# GCC-specific options
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
list(APPEND compile_options "-fstrict-volatile-bitfields"
"-Wno-error=unused-but-set-variable"
)
endif()

Expand Down Expand Up @@ -205,7 +215,7 @@ if(CMAKE_C_COMPILER_ID MATCHES "GNU")
list(APPEND compile_options "-fno-tree-switch-conversion")
endif()

if(CMAKE_C_COMPILER_ID MATCHES "LLVM")
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
list(APPEND compile_options "-fno-use-cxa-atexit")
endif()

Expand Down
6 changes: 5 additions & 1 deletion components/bt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,11 @@ if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE AND CONFIG_BT_NIMBLE_ENABLED)
endif()

if(NOT CMAKE_BUILD_EARLY_EXPANSION)
set(jump_table_opts "-fjump-tables")
if(NOT (CMAKE_C_COMPILER_ID MATCHES "Clang") )
set(jump_table_opts "${jump_table_opts} -ftree-switch-conversion")
endif()
set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/host/bluedroid/bta/hf_ag/bta_ag_cmd.c"
"${CMAKE_CURRENT_LIST_DIR}/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c"
PROPERTIES COMPILE_FLAGS "-fjump-tables -ftree-switch-conversion")
PROPERTIES COMPILE_FLAGS "${jump_table_opts}")
endif()
2 changes: 1 addition & 1 deletion components/bt/controller/esp32/bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ static xt_handler set_isr_hlevel_wrapper(int mask, xt_handler f, void *arg)
static void IRAM_ATTR interrupt_hlevel_disable(void)
{
assert(xPortGetCoreID() == CONFIG_BTDM_CTRL_PINNED_TO_CORE);
assert(hli_cb.nested != ~0);
assert(hli_cb.nested != UCHAR_MAX);
uint32_t status = hli_intr_disable();
if (hli_cb.nested++ == 0) {
hli_cb.status = status;
Expand Down
2 changes: 1 addition & 1 deletion components/bt/host/bluedroid/api/esp_gap_ble_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -550,7 +550,7 @@ esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
if((param_type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY) && ( value == NULL || len < sizeof(uint8_t) || len > sizeof(uint32_t))) {
return ESP_ERR_INVALID_ARG;
}
if((param_type == ESP_BLE_SM_SET_STATIC_PASSKEY)) {
if(param_type == ESP_BLE_SM_SET_STATIC_PASSKEY) {
uint32_t passkey = 0;
for(uint8_t i = 0; i < len; i++)
{
Expand Down
8 changes: 4 additions & 4 deletions components/bt/host/bluedroid/stack/btm/btm_devctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -898,14 +898,14 @@ tBTM_STATUS BTM_EnableTestMode(void)
}

/* put device to connectable mode */
if (!BTM_SetConnectability(BTM_CONNECTABLE, BTM_DEFAULT_CONN_WINDOW,
BTM_DEFAULT_CONN_INTERVAL) == BTM_SUCCESS) {
if (BTM_SetConnectability(BTM_CONNECTABLE, BTM_DEFAULT_CONN_WINDOW,
BTM_DEFAULT_CONN_INTERVAL) != BTM_SUCCESS) {
return BTM_NO_RESOURCES;
}

/* put device to discoverable mode */
if (!BTM_SetDiscoverability(BTM_GENERAL_DISCOVERABLE, BTM_DEFAULT_DISC_WINDOW,
BTM_DEFAULT_DISC_INTERVAL) == BTM_SUCCESS) {
if (BTM_SetDiscoverability(BTM_GENERAL_DISCOVERABLE, BTM_DEFAULT_DISC_WINDOW,
BTM_DEFAULT_DISC_INTERVAL) != BTM_SUCCESS) {
return BTM_NO_RESOURCES;
}

Expand Down
14 changes: 12 additions & 2 deletions components/cxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ if(NOT CONFIG_CXX_EXCEPTIONS)
endforeach()
endif()

target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ gcc)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
# libstdc++ depends on C library, so it should appear later in link order.
# Otherwise we get undefined references for esp-clang toolchain.
target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ c gcc)
else()
target_link_libraries(${COMPONENT_LIB} PUBLIC stdc++ gcc)
endif()
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxa_guard_dummy")

# Force libpthread to appear later than libstdc++ in link line since libstdc++ depends on libpthread.
Expand All @@ -50,7 +56,11 @@ target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxa_guard_dummy")
idf_component_get_property(pthread pthread COMPONENT_LIB)
idf_component_get_property(cxx cxx COMPONENT_LIB)
add_library(stdcpp_pthread INTERFACE)
target_link_libraries(stdcpp_pthread INTERFACE stdc++ $<TARGET_FILE:${pthread}>)
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
target_link_libraries(stdcpp_pthread INTERFACE stdc++ c $<TARGET_FILE:${pthread}>)
else()
target_link_libraries(stdcpp_pthread INTERFACE stdc++ $<TARGET_FILE:${pthread}>)
endif()
target_link_libraries(${COMPONENT_LIB} PUBLIC stdcpp_pthread)
add_library(libgcc_cxx INTERFACE)
target_link_libraries(libgcc_cxx INTERFACE gcc $<TARGET_FILE:${cxx}>)
Expand Down
8 changes: 4 additions & 4 deletions components/cxx/cxx_guards.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ static size_t s_static_init_max_waiting_count = 0; //!< maximum ever va
#endif

extern "C" int __cxa_guard_acquire(__guard* pg);
extern "C" void __cxa_guard_release(__guard* pg);
extern "C" void __cxa_guard_abort(__guard* pg);
extern "C" void __cxa_guard_release(__guard* pg) throw();
extern "C" void __cxa_guard_abort(__guard* pg) throw();
extern "C" void __cxa_guard_dummy(void);

/**
Expand Down Expand Up @@ -167,7 +167,7 @@ extern "C" int __cxa_guard_acquire(__guard* pg)
return ret;
}

extern "C" void __cxa_guard_release(__guard* pg)
extern "C" void __cxa_guard_release(__guard* pg) throw()
{
guard_t* g = reinterpret_cast<guard_t*>(pg);
const auto scheduler_started = xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED;
Expand All @@ -189,7 +189,7 @@ extern "C" void __cxa_guard_release(__guard* pg)
}
}

extern "C" void __cxa_guard_abort(__guard* pg)
extern "C" void __cxa_guard_abort(__guard* pg) throw()
{
guard_t* g = reinterpret_cast<guard_t*>(pg);
const auto scheduler_started = xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,8 +267,9 @@ static esp_err_t essl_spi_update_tx_buffer_num(void *arg, uint32_t wait_ms);
esp_err_t essl_spi_init_dev(essl_handle_t *out_handle, const essl_spi_config_t *init_config)
{
ESP_RETURN_ON_FALSE(init_config->spi, ESP_ERR_INVALID_STATE, TAG, "Check SPI initialization first");
ESP_RETURN_ON_FALSE(init_config->tx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
ESP_RETURN_ON_FALSE(init_config->rx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
// for esp32-s2 SOC_SPI_MAXIMUM_BUFFER_SIZE is 72, so compiler warns that comparisons of 'tx/rx_sync_reg' are always true
ESP_RETURN_ON_FALSE((uint32_t)init_config->tx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
ESP_RETURN_ON_FALSE((uint32_t)init_config->rx_sync_reg <= (SOC_SPI_MAXIMUM_BUFFER_SIZE - 1) * 4, ESP_ERR_INVALID_ARG, TAG, "GPSPI supports %d-byte-width internal registers", SOC_SPI_MAXIMUM_BUFFER_SIZE);
ESP_RETURN_ON_FALSE(init_config->tx_sync_reg != init_config->rx_sync_reg, ESP_ERR_INVALID_ARG, TAG, "Should use different word of registers for synchronization");

essl_spi_context_t *context = calloc(1, sizeof(essl_spi_context_t));
Expand Down
4 changes: 4 additions & 0 deletions components/efuse/esp32c2/esp_efuse_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
uint8_t block_rs[12];
efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
#pragma GCC diagnostic pop
Expand Down Expand Up @@ -148,7 +150,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
if (!correct_written_data || coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
#pragma GCC diagnostic pop
Expand Down
4 changes: 4 additions & 0 deletions components/efuse/esp32c3/esp_efuse_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
uint8_t block_rs[12];
efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
#pragma GCC diagnostic pop
Expand Down Expand Up @@ -177,7 +179,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
if (!correct_written_data || coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
#pragma GCC diagnostic pop
Expand Down
4 changes: 4 additions & 0 deletions components/efuse/esp32c6/esp_efuse_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
uint8_t block_rs[12];
efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
#pragma GCC diagnostic pop
Expand Down Expand Up @@ -162,7 +164,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
if (!correct_written_data || coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
#pragma GCC diagnostic pop
Expand Down
4 changes: 4 additions & 0 deletions components/efuse/esp32h4/esp_efuse_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
uint8_t block_rs[12];
efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
#pragma GCC diagnostic pop
Expand Down Expand Up @@ -162,7 +164,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
if (!correct_written_data || coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
#pragma GCC diagnostic pop
Expand Down
4 changes: 4 additions & 0 deletions components/efuse/esp32s2/esp_efuse_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
uint8_t block_rs[12];
efuse_hal_rs_calculate((void *)range_write_addr_blocks[num_block].start, block_rs);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_CHECK_VALUE0_REG, block_rs, sizeof(block_rs));
#pragma GCC diagnostic pop
Expand Down Expand Up @@ -162,7 +164,9 @@ esp_err_t esp_efuse_utility_burn_chip(void)
if (!correct_written_data || coding_error_occurred) {
ESP_LOGW(TAG, "BLOCK%d: next retry to fix an error [%d/3]...", num_block, repeat_burn_op);
#pragma GCC diagnostic push
#ifndef __clang__
#pragma GCC diagnostic ignored "-Wstringop-overflow"
#endif
#pragma GCC diagnostic ignored "-Warray-bounds"
memcpy((void *)EFUSE_PGM_DATA0_REG, (void *)backup_write_data, sizeof(backup_write_data));
#pragma GCC diagnostic pop
Expand Down
Loading

0 comments on commit 8c2ae2f

Please sign in to comment.