diff --git a/.gitlab/ci/host-test.yml b/.gitlab/ci/host-test.yml index 741d47ea70..f2ab6b89d2 100644 --- a/.gitlab/ci/host-test.yml +++ b/.gitlab/ci/host-test.yml @@ -352,6 +352,38 @@ test_pytest_linux: --ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME} --app-info-filepattern \"list_job_*.txt\" +test_pytest_macos: + extends: + - .host_test_template + - .before_script:build:macos + tags: + - macos_shell + artifacts: + paths: + - XUNIT_RESULT.xml + - pytest-embedded/ + - "**/build*/build_log.txt" + reports: + junit: XUNIT_RESULT.xml + variables: + PYTEST_IGNORE_COLLECT_IMPORT_ERROR: "1" + script: + - run_cmd python tools/ci/ci_build_apps.py components examples tools/test_apps -vv + --target linux + --pytest-apps + -m \"host_test and macos_shell\" + --collect-app-info "list_job_${CI_JOB_NAME_SLUG}.txt" + --modified-components ${MR_MODIFIED_COMPONENTS} + --modified-files ${MR_MODIFIED_FILES} + - python tools/ci/get_known_failure_cases_file.py + - run_cmd pytest + --target linux + -m \"host_test and macos_shell\" + --junitxml=XUNIT_RESULT.xml + --ignore-result-files ${KNOWN_FAILURE_CASES_FILE_NAME} + --app-info-filepattern \"list_job_*.txt\" + + test_idf_pytest_plugin: extends: - .host_test_template diff --git a/components/efuse/linux/esp_efuse_utility.c b/components/efuse/linux/esp_efuse_utility.c index de62292242..25c69d0cad 100644 --- a/components/efuse/linux/esp_efuse_utility.c +++ b/components/efuse/linux/esp_efuse_utility.c @@ -89,7 +89,7 @@ esp_err_t esp_efuse_utility_burn_chip_opt(bool ignore_coding_errors, bool verify // This function reads EFUSE_BLKx_WDATAx_REG registers, and checks possible to write these data with RS coding scheme. // The RS coding scheme does not require data changes for the encoded data. esp32s2 has special registers for this. // They will be filled during the burn operation. -esp_err_t esp_efuse_utility_apply_new_coding_scheme() +esp_err_t esp_efuse_utility_apply_new_coding_scheme(void) { // start with EFUSE_BLK1. EFUSE_BLK0 - always uses EFUSE_CODING_SCHEME_NONE. for (int num_block = EFUSE_BLK1; num_block < EFUSE_BLK_MAX; num_block++) { diff --git a/components/esp_app_format/CMakeLists.txt b/components/esp_app_format/CMakeLists.txt index 95e20d0341..27a3d2ffd6 100644 --- a/components/esp_app_format/CMakeLists.txt +++ b/components/esp_app_format/CMakeLists.txt @@ -11,7 +11,13 @@ idf_component_register(SRCS ${src} if(NOT BOOTLOADER_BUILD) # esp_app_desc structure is added as an undefined symbol because otherwise the # linker will ignore this structure as it has no other files depending on it. - target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc") + if(CONFIG_IDF_TARGET_LINUX AND CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin") + # On MacOS, the linker expects the exact mangled symbol name (with leading underscore) + # to be present in the object file. + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u _esp_app_desc") + else() + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc") + endif() if(CONFIG_APP_PROJECT_VER_FROM_CONFIG) # Ignore current PROJECT_VER (which was set in project.cmake) diff --git a/components/esp_app_format/esp_app_desc.c b/components/esp_app_format/esp_app_desc.c index 60d5bbd823..e40c9fd5a7 100644 --- a/components/esp_app_format/esp_app_desc.c +++ b/components/esp_app_format/esp_app_desc.c @@ -20,7 +20,11 @@ static const char *TAG = "app_init"; #endif // Application version info +#if defined(__APPLE__) && CONFIG_IDF_TARGET_LINUX +const __attribute__((weak)) __attribute__((section("__RODATA_DESC,.rodata_desc"))) esp_app_desc_t esp_app_desc = { +#else const __attribute__((weak)) __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = { +#endif /* #if defined(__APPLE__) && CONFIG_IDF_TARGET_LINUX */ .magic_word = ESP_APP_DESC_MAGIC_WORD, #ifdef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR .version = "", diff --git a/components/log/src/linux/log_timestamp.c b/components/log/src/linux/log_timestamp.c index 04fc51d433..f341c0e5a2 100644 --- a/components/log/src/linux/log_timestamp.c +++ b/components/log/src/linux/log_timestamp.c @@ -17,4 +17,8 @@ uint32_t esp_log_early_timestamp(void) return milliseconds; } -uint32_t esp_log_timestamp(void) __attribute__((alias("esp_log_early_timestamp"))); +// Avoid using __attribute(alias) here since linux target builds on MacOS fail to compile. +uint32_t esp_log_timestamp(void) +{ + return esp_log_early_timestamp(); +} diff --git a/examples/get-started/hello_world/pytest_hello_world.py b/examples/get-started/hello_world/pytest_hello_world.py index caeeff16b7..3524fd9495 100644 --- a/examples/get-started/hello_world/pytest_hello_world.py +++ b/examples/get-started/hello_world/pytest_hello_world.py @@ -1,6 +1,5 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD +# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD # SPDX-License-Identifier: CC0-1.0 - import hashlib import logging from typing import Callable @@ -27,6 +26,13 @@ def test_hello_world_linux(dut: IdfDut) -> None: dut.expect('Hello world!') +@pytest.mark.linux +@pytest.mark.host_test +@pytest.mark.macos_shell +def test_hello_world_macos(dut: IdfDut) -> None: + dut.expect('Hello world!') + + def verify_elf_sha256_embedding(app: QemuApp, sha256_reported: str) -> None: sha256 = hashlib.sha256() with open(app.elf_file, 'rb') as f: diff --git a/tools/ci/idf_pytest/constants.py b/tools/ci/idf_pytest/constants.py index 89f3bbe1c1..2886b3ac0a 100644 --- a/tools/ci/idf_pytest/constants.py +++ b/tools/ci/idf_pytest/constants.py @@ -46,6 +46,7 @@ SPECIAL_MARKERS = { ENV_MARKERS = { # special markers 'qemu': 'build and test using qemu, not real target', + 'macos_shell': 'tests should be run on macos hosts', # single-dut markers 'generic': 'tests should be run on generic runners', 'flash_suspend': 'support flash suspend feature', diff --git a/tools/ci/idf_pytest/plugin.py b/tools/ci/idf_pytest/plugin.py index b2e04402c4..d88370792b 100644 --- a/tools/ci/idf_pytest/plugin.py +++ b/tools/ci/idf_pytest/plugin.py @@ -141,7 +141,7 @@ class IdfPytestEmbedded: def pytest_collectstart(self) -> None: # mock the optional packages while collecting locally - if not os.getenv('CI_JOB_ID'): + if not os.getenv('CI_JOB_ID') or os.getenv('PYTEST_IGNORE_COLLECT_IMPORT_ERROR') == '1': # optional packages required by test scripts for p in [ 'scapy', diff --git a/tools/ci/ignore_build_warnings.txt b/tools/ci/ignore_build_warnings.txt index 5c208435de..ca30cdaf9b 100644 --- a/tools/ci/ignore_build_warnings.txt +++ b/tools/ci/ignore_build_warnings.txt @@ -39,3 +39,5 @@ warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in .*/examples/protocol warning: unknown kconfig symbol 'SPIRAM' assigned to 'y' in .*/examples/protocols/https_request/sdkconfig.ci.ssldyn warning: unknown kconfig symbol 'UNITY_FREERTOS_STACK_SIZE' assigned to '12288' in .*/components/bt/test_apps/sdkconfig.defaults warning: unknown kconfig symbol 'WPA3_SAE' assigned to 'y' in .*/components/wpa_supplicant/test_apps/sdkconfig.defaults +ld: warning: ignoring duplicate libraries +archive library: .+ the table of contents is empty