diff --git a/CMakeLists.txt b/CMakeLists.txt index f06ae54ead..0b86ac6027 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -209,6 +209,16 @@ if(CMAKE_C_COMPILER_ID MATCHES "LLVM") list(APPEND compile_options "-fno-use-cxa-atexit") endif() +# For the transition period from 32-bit time_t to 64-bit time_t, +# auto-detect the size of this type and set corresponding variable. +include(CheckTypeSize) +check_type_size("time_t" TIME_T_SIZE) +if(TIME_T_SIZE) + idf_build_set_property(TIME_T_SIZE ${TIME_T_SIZE}) +else() + message(FATAL_ERROR "Failed to determine sizeof(time_t)") +endif() + idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND) idf_build_set_property(C_COMPILE_OPTIONS "${c_compile_options}" APPEND) idf_build_set_property(CXX_COMPILE_OPTIONS "${cxx_compile_options}" APPEND) diff --git a/Kconfig b/Kconfig index 8b566e4a79..1141d5bc37 100644 --- a/Kconfig +++ b/Kconfig @@ -104,26 +104,6 @@ mainmenu "Espressif IoT Development Framework Configuration" default 0x000E if IDF_TARGET_ESP32H2_BETA_VERSION_2 # ESP32H2-TODO: IDF-3475 default 0xFFFF - menu "SDK tool configuration" - - config SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS - bool "Toolchain supports time_t wide 64-bits" - default n - help - Enable this option in case you have a custom toolchain which supports time_t wide 64-bits. - This option checks time_t is 64-bits and disables ROM time functions - to use the time functions from the toolchain instead. - This option allows resolving the Y2K38 problem. - See "Setup Linux Toolchain from Scratch" to build - a custom toolchain which supports 64-bits time_t. - - Note: ESP-IDF does not currently come with any pre-compiled toolchain - that supports 64-bit wide time_t. - This will change in a future major release, - but currently 64-bit time_t requires a custom built toolchain. - - endmenu # SDK tool configuration - menu "Build type" diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index acdf0fca1f..57764e6174 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -57,6 +57,8 @@ else() rom_linker_script("libgcc") endif() +idf_build_get_property(time_t_size TIME_T_SIZE) + if(BOOTLOADER_BUILD) if(target STREQUAL "esp32") rom_linker_script("newlib-funcs") @@ -91,19 +93,20 @@ else() # Regular app build rom_linker_script("syscalls") if(NOT CONFIG_SPIRAM_CACHE_WORKAROUND) + # ESP32 only: these ROM functions may only be used if PSRAM cache workaround is disabled. + # Otherwise we need to link to a multilib version of libc compiled with PSRAM workaround. rom_linker_script("newlib-funcs") - if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) - # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined - # then all time functions from the ROM memory will not be linked. - # Instead, those functions can be used from the toolchain by ESP-IDF. + + if(time_t_size EQUAL 4) + # The ROM functions listed in this linker script depend on sizeof(time_t). + # Since ROM for ESP32 was compiled for 32-bit time_t, only link these functions + # if the toolchain is also using 32-bit time_t. rom_linker_script("newlib-time") - # Include in newlib nano from ROM only if SPIRAM cache workaround is disabled - # and sizeof(time_t) == 4 if(CONFIG_NEWLIB_NANO_FORMAT) + # nano formatting functions in ROM are also built for 32-bit time_t. rom_linker_script("newlib-nano") endif() - endif() endif() @@ -120,52 +123,48 @@ else() # Regular app build rom_linker_script("newlib-data") rom_linker_script("spiflash") - if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) - # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined - # then all time functions from the ROM memory will not be linked. - # Instead, those functions can be used from the toolchain by ESP-IDF. + if(time_t_size EQUAL 4) + # The ROM functions listed in this linker script depend on sizeof(time_t). + # Since ROM for ESP32-S2 was compiled for 32-bit time_t, only link these functions + # if the toolchain is also using 32-bit time_t. + rom_linker_script("newlib-time") if(CONFIG_NEWLIB_NANO_FORMAT) + # nano formatting functions in ROM are also built for 32-bit time_t. rom_linker_script("newlib-nano") endif() - - rom_linker_script("newlib-time") endif() - - # descirptors used by ROM code - target_sources(${COMPONENT_LIB} PRIVATE "esp32s2/usb_descriptors.c") - elseif(target STREQUAL "esp32s3") rom_linker_script("newlib") rom_linker_script("version") - if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) - # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined - # then all time functions from the ROM memory will not be linked. - # Instead, those functions can be used from the toolchain by ESP-IDF. + if(time_t_size EQUAL 4) + # The ROM functions listed in this linker script depend on sizeof(time_t). + # Since ROM for ESP32-S3 was compiled for 32-bit time_t, only link these functions + # if the toolchain is also using 32-bit time_t. + rom_linker_script("newlib-time") if(CONFIG_NEWLIB_NANO_FORMAT) + # nano formatting functions in ROM are also built for 32-bit time_t. rom_linker_script("newlib-nano") endif() - - rom_linker_script("newlib-time") endif() elseif(target STREQUAL "esp32c3") rom_linker_script("newlib") rom_linker_script("version") - if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) - # If SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS option is defined - # then all time functions from the ROM memory will not be linked. - # Instead, those functions can be used from the toolchain by ESP-IDF. + if(time_t_size EQUAL 4) + # The ROM functions listed in this linker script depend on sizeof(time_t). + # Since ROM for ESP32-C3 was compiled for 32-bit time_t, only link these functions + # if the toolchain is also using 32-bit time_t. + rom_linker_script("newlib-time") if(CONFIG_NEWLIB_NANO_FORMAT) + # nano formatting functions in ROM are also built for 32-bit time_t. rom_linker_script("newlib-nano") endif() - - rom_linker_script("newlib-time") endif() if(CONFIG_ESP32C3_REV_MIN_3) @@ -176,10 +175,10 @@ else() # Regular app build rom_linker_script("newlib") rom_linker_script("version") - if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") - endif() + if(CONFIG_NEWLIB_NANO_FORMAT AND time_t_size EQUAL 4) + # nano formatting functions in ROM are built for 32-bit time_t, + # only link them if the toolchain is also using 32-bit time_t and nano formatting was requested. + rom_linker_script("newlib-nano") endif() elseif(target STREQUAL "esp8684") @@ -187,10 +186,10 @@ else() # Regular app build rom_linker_script("version") rom_linker_script("mbedtls") - if(NOT CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS) - if(CONFIG_NEWLIB_NANO_FORMAT) - rom_linker_script("newlib-nano") - endif() + if(CONFIG_NEWLIB_NANO_FORMAT AND time_t_size EQUAL 4) + # nano formatting functions in ROM are built for 32-bit time_t, + # only link them if the toolchain is also using 32-bit time_t and nano formatting was requested. + rom_linker_script("newlib-nano") endif() endif() diff --git a/components/newlib/test/test_time.c b/components/newlib/test/test_time.c index 69cde042a0..7e88d39afd 100644 --- a/components/newlib/test/test_time.c +++ b/components/newlib/test/test_time.c @@ -1,4 +1,5 @@ #include +#include #include #include "unity.h" #include "driver/adc.h" @@ -446,8 +447,7 @@ TEST_CASE("test posix_timers clock_... functions", "[newlib]") test_posix_timers_clock(); } -#ifdef CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS -#include +#ifndef _USE_LONG_TIME_T static struct timeval get_time(const char *desc, char *buffer) { @@ -533,7 +533,7 @@ TEST_CASE("test time functions wide 64 bits", "[newlib]") } } -#endif // CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS +#endif // !_USE_LONG_TIME_T #if defined( CONFIG_ESP_TIME_FUNCS_USE_ESP_TIMER ) && defined( CONFIG_ESP_TIME_FUNCS_USE_RTC_TIMER ) diff --git a/components/newlib/time.c b/components/newlib/time.c index a021d15eee..73fc04e5cc 100644 --- a/components/newlib/time.c +++ b/components/newlib/time.c @@ -1,16 +1,8 @@ -// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. +/* + * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ #include #include @@ -37,12 +29,6 @@ #include "sdkconfig.h" -#ifdef CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS -_Static_assert(sizeof(time_t) == 8, "The toolchain does not support time_t wide 64-bits"); -#else -_Static_assert(sizeof(time_t) == 4, "The toolchain supports time_t wide 64-bits. Please enable CONFIG_SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS."); -#endif - #if !CONFIG_ESP_TIME_FUNCS_USE_NONE #define IMPL_NEWLIB_TIME_FUNCS 1 #endif diff --git a/components/spiffs/Kconfig b/components/spiffs/Kconfig index 56dafba146..0f20920d97 100644 --- a/components/spiffs/Kconfig +++ b/components/spiffs/Kconfig @@ -133,8 +133,8 @@ menu "SPIFFS Configuration" If the chip already has the spiffs image with the time field = 32 bits then this option cannot be applied in this case. Erase it first before using this option. - To resolve the Y2K38 problem for the spiffs, use a toolchain with support - time_t 64 bits (see SDK_TOOLCHAIN_SUPPORTS_TIME_WIDE_64_BITS). + To resolve the Y2K38 problem for the spiffs, use a toolchain with + 64-bit time_t support. menu "Debug Configuration" diff --git a/docs/en/api-reference/system/system_time.rst b/docs/en/api-reference/system/system_time.rst index f8a96dcb2d..1f7b6b95d8 100644 --- a/docs/en/api-reference/system/system_time.rst +++ b/docs/en/api-reference/system/system_time.rst @@ -130,6 +130,21 @@ To set local timezone, use the following POSIX functions: Once these steps are completed, call the standard C library function ``localtime()``, and it will return correct local time taking into account the time zone offset and daylight saving time. +64-bit ``time_t`` +----------------- + +ESP-IDF uses 32-bit ``time_t`` type by default. To address Y2K38 issue, you may need to use 64-bit ``time_t`` type when building the application. + +Currently this requires building the cross-compiler toolchain from scratch. See the instructions for building the toolchain in :doc:`/get-started/linux-setup-scratch`. To enable 64-bit ``time_t`` support in the toolchain, you need to remove the ``--enable-newlib-long-time_t`` option from the ``crosstool-NG/samples/xtensa-esp32-elf/crosstool.config`` file before building the toolchain. + +If you need to make the program compatible with both 32-bit and 64-bit ``time_t``, you may use the following methods: + +- In C or C++ source files, ``_USE_LONG_TIME_T`` preprocessor macro will be defined if 32-bit ``time_t`` is used. You need to include ```` to make this macro available. +- In CMake files, ``TIME_T_SIZE`` IDF build property will be set to the size of ``time_t``, in bytes. You may call ``idf_build_get_property(var TIME_T_SIZE)`` to get the value of this property into a CMake variable ``var``. See :ref:`build system API reference ` for more information about ``idf_build_get_property``. + +Note that the size of ``time_t`` type also affects the sizes of other types, for example ``struct timeval``, ``struct stat``, ``struct utimbuf``. + + API Reference ------------- diff --git a/docs/en/get-started/linux-setup-scratch.rst b/docs/en/get-started/linux-setup-scratch.rst index 5fdb99b50f..c3defdfa71 100644 --- a/docs/en/get-started/linux-setup-scratch.rst +++ b/docs/en/get-started/linux-setup-scratch.rst @@ -64,8 +64,6 @@ Download ``crosstool-NG`` and build it: .. include-build-file:: inc/scratch-build-code.inc -.. note:: To create a toolchain with support for 64-bit time_t, you need to remove the ``--enable-newlib-long-time_t`` option from the ``crosstool-NG/samples/xtensa-esp32-elf/crosstool.config`` file in 33 and 43 lines. - Build the toolchain:: ./ct-ng {IDF_TARGET_TOOLCHAIN_PREFIX} diff --git a/tools/ci/check_copyright_ignore.txt b/tools/ci/check_copyright_ignore.txt index f5f1911034..7841a80ae9 100644 --- a/tools/ci/check_copyright_ignore.txt +++ b/tools/ci/check_copyright_ignore.txt @@ -1396,7 +1396,6 @@ components/newlib/test/test_time.c components/newlib/test_apps/app_test.py components/newlib/test_apps/main/test_newlib_main.c components/newlib/test_apps/main/test_stdatomic.c -components/newlib/time.c components/nvs_flash/host_test/fixtures/test_fixtures.hpp components/nvs_flash/host_test/nvs_page_test/main/nvs_page_test.cpp components/nvs_flash/include/nvs.h