Merge branch 'feature/do_not_use_link_groups' into 'master'

Do not use link groups

See merge request idf/esp-idf!4897
This commit is contained in:
Angus Gratton
2019-05-29 15:18:31 +08:00
20 changed files with 126 additions and 75 deletions

View File

@@ -31,4 +31,4 @@ register_component()
# disable --coverage for this component, as it is used as transport # disable --coverage for this component, as it is used as transport
# for gcov # for gcov
target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage") target_compile_options(${COMPONENT_LIB} PRIVATE "-fno-profile-arcs" "-fno-test-coverage")
target_link_libraries(${COMPONENT_LIB} gcov ${LIBC} ${LIBM}) target_link_libraries(${COMPONENT_LIB} gcov ${LIBC} ${LIBM} gcc)

View File

@@ -111,3 +111,9 @@ static int selected_boot_partition(const bootloader_state_t *bs)
} }
return boot_index; return boot_index;
} }
// Return global reent struct if any newlib functions are linked to bootloader
struct _reent* __getreent() {
return _GLOBAL_REENT;
}

View File

@@ -9,8 +9,8 @@ set(COMPONENT_SRCS "src/bootloader_clock.c"
if(BOOTLOADER_BUILD) if(BOOTLOADER_BUILD)
set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader") set(COMPONENT_ADD_INCLUDEDIRS "include include_bootloader")
set(COMPONENT_REQUIRES soc) #unfortunately the header directly uses SOC registers set(COMPONENT_REQUIRES spi_flash soc) #unfortunately the header directly uses SOC registers
set(COMPONENT_PRIV_REQUIRES spi_flash micro-ecc efuse) set(COMPONENT_PRIV_REQUIRES micro-ecc efuse)
list(APPEND COMPONENT_SRCS "src/bootloader_init.c" list(APPEND COMPONENT_SRCS "src/bootloader_init.c"
"src/${IDF_TARGET}/bootloader_sha.c" "src/${IDF_TARGET}/bootloader_sha.c"
"src/${IDF_TARGET}/flash_encrypt.c" "src/${IDF_TARGET}/flash_encrypt.c"

View File

@@ -2,7 +2,7 @@ set(COMPONENT_SRCS "cxx_exception_stubs.cpp"
"cxx_guards.cpp") "cxx_guards.cpp")
register_component() register_component()
target_link_libraries(${COMPONENT_LIB} stdc++) target_link_libraries(${COMPONENT_LIB} stdc++ gcc)
target_link_libraries(${COMPONENT_LIB} "-u __cxa_guard_dummy") target_link_libraries(${COMPONENT_LIB} "-u __cxa_guard_dummy")
if(NOT CONFIG_COMPILER_CXX_EXCEPTIONS) if(NOT CONFIG_COMPILER_CXX_EXCEPTIONS)

View File

@@ -88,4 +88,13 @@ else()
cpu_start.c cpu_start.c
PROPERTIES COMPILE_FLAGS PROPERTIES COMPILE_FLAGS
-fno-stack-protector) -fno-stack-protector)
if(CONFIG_SPIRAM_CACHE_WORKAROUND)
# Note: Adding as a PUBLIC compile option here causes this option to propagate to all components that depend on esp32.
#
# To handle some corner cases, the same flag is set in project_include.cmake
target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue)
# also, make sure we link with this option so correct toolchain libs are pulled in
target_link_libraries(${COMPONENT_LIB} -mfix-esp32-psram-cache-issue)
endif()
endif() endif()

View File

@@ -267,12 +267,12 @@ SECTIONS
__eh_frame = ABSOLUTE(.); __eh_frame = ABSOLUTE(.);
KEEP(*(.eh_frame)) KEEP(*(.eh_frame))
. = (. + 7) & ~ 3; . = (. + 7) & ~ 3;
/* C++ constructor and destructor tables, properly ordered: */ /* C++ constructor and destructor tables
Make a point of not including anything from crtbegin.o or crtend.o, as IDF doesn't use toolchain crt
*/
__init_array_start = ABSOLUTE(.); __init_array_start = ABSOLUTE(.);
KEEP (*crtbegin.*(.ctors)) KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors .ctors.*))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__init_array_end = ABSOLUTE(.); __init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors)) KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors)) KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))

View File

@@ -25,12 +25,7 @@ else()
) )
target_linker_script(${COMPONENT_LIB} "${scripts}") target_linker_script(${COMPONENT_LIB} "${scripts}")
if(CONFIG_SPIRAM_CACHE_WORKAROUND) if(NOT CONFIG_SPIRAM_CACHE_WORKAROUND)
# Note: Adding as a PUBLIC compile option here causes this option to propagate to all components that depend on esp32.
#
# To handle some corner cases, the same flag is set in project_include.cmake
target_compile_options(${COMPONENT_LIB} PUBLIC -mfix-esp32-psram-cache-issue)
else()
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-funcs.ld") target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-funcs.ld")
endif() endif()

View File

@@ -1,26 +1,3 @@
/* These ROM functions call respective entries in syscall table.
IDF implementations of these function carry different names
(usually esp_vfs_*) so we still export these functions,
in case some newlib function needs to call them.
I.e.:
open (in ROM) -> _open_r (in ROM) -> syscall table entry _open_r -> esp_vfs_open (in IDF)
*/
PROVIDE ( _close_r = 0x4000bd3c );
PROVIDE ( _exit_r = 0x4000bd28 );
PROVIDE ( _fstat_r = 0x4000bccc );
PROVIDE ( _link_r = 0x4000bc9c );
PROVIDE ( _lseek_r = 0x4000bd8c );
PROVIDE ( _open_r = 0x4000bd54 );
PROVIDE ( _read_r = 0x4000bda8 );
PROVIDE ( _rename_r = 0x4000bc28 );
PROVIDE ( _unlink_r = 0x4000bc84 );
PROVIDE ( _write_r = 0x4000bd70 );
/* These ROM functions call respective entries in the syscall table. /* These ROM functions call respective entries in the syscall table.
They are called by other ROM functions (mostly from newlib). They are called by other ROM functions (mostly from newlib).
We don't link to them directly, since in IDF there are actual We don't link to them directly, since in IDF there are actual
@@ -61,6 +38,16 @@ PROVIDE ( _realloc_r = 0x4000bbe0 );
PROVIDE ( _sbrk_r = 0x4000bce4 ); PROVIDE ( _sbrk_r = 0x4000bce4 );
PROVIDE ( _system_r = 0x4000bc10 ); PROVIDE ( _system_r = 0x4000bc10 );
PROVIDE ( _times_r = 0x4000bc40 ); PROVIDE ( _times_r = 0x4000bc40 );
PROVIDE ( _close_r = 0x4000bd3c );
PROVIDE ( _exit_r = 0x4000bd28 );
PROVIDE ( _fstat_r = 0x4000bccc );
PROVIDE ( _link_r = 0x4000bc9c );
PROVIDE ( _lseek_r = 0x4000bd8c );
PROVIDE ( _open_r = 0x4000bd54 );
PROVIDE ( _read_r = 0x4000bda8 );
PROVIDE ( _rename_r = 0x4000bc28 );
PROVIDE ( _unlink_r = 0x4000bc84 );
PROVIDE ( _write_r = 0x4000bd70 );
---> end commented out block ---> end commented out block
*/ */

View File

@@ -8,8 +8,8 @@ set(COMPONENT_SRCS
"src/wifi_init.c") "src/wifi_init.c")
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
set(COMPONENT_PRIV_INCLUDEDIRS) set(COMPONENT_PRIV_INCLUDEDIRS)
set(COMPONENT_REQUIRES) set(COMPONENT_REQUIRES wpa_supplicant smartconfig_ack)
set(COMPONENT_PRIV_REQUIRES "wpa_supplicant" "nvs_flash") set(COMPONENT_PRIV_REQUIRES "nvs_flash")
if(NOT CONFIG_ESP32_NO_BLOBS) if(NOT CONFIG_ESP32_NO_BLOBS)
set(COMPONENT_ADD_LDFRAGMENTS "linker.lf") set(COMPONENT_ADD_LDFRAGMENTS "linker.lf")
@@ -19,8 +19,20 @@ register_component()
target_link_libraries(${COMPONENT_LIB} "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}") target_link_libraries(${COMPONENT_LIB} "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}")
if(NOT CONFIG_ESP32_NO_BLOBS) if(NOT CONFIG_ESP32_NO_BLOBS)
target_link_libraries(${COMPONENT_LIB} "-L ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}") set(blobs coexist core espnow mesh net80211 phy pp rtc smartconfig wpa2 wpa wps)
target_link_libraries(${COMPONENT_LIB} coexist core espnow mesh net80211 phy pp rtc smartconfig wpa2 wpa wps) foreach(blob ${blobs})
add_library(${blob} STATIC IMPORTED)
set_property(TARGET ${blob} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib_${IDF_TARGET}/lib${blob}.a)
target_link_libraries(${COMPONENT_LIB} ${blob})
foreach(_blob ${blobs})
if(NOT _blob STREQUAL ${blob})
set_property(TARGET ${blob} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${_blob})
endif()
endforeach()
set_property(TARGET ${blob} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${COMPONENT_LIB})
endforeach()
endif() endif()
if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION) if(CONFIG_ESP32_PHY_INIT_DATA_IN_PARTITION)

View File

@@ -12,16 +12,7 @@ set(COMPONENT_SRCS "heap.c"
"utime.c") "utime.c")
set(COMPONENT_ADD_INCLUDEDIRS platform_include) set(COMPONENT_ADD_INCLUDEDIRS platform_include)
if(GCC_NOT_5_2_0) if(GCC_NOT_5_2_0)
if(CONFIG_NEWLIB_NANO_FORMAT)
set(LIBC c_nano)
else()
set(LIBC c)
endif()
set(LIBM m)
if(CONFIG_SPIRAM_CACHE_WORKAROUND) if(CONFIG_SPIRAM_CACHE_WORKAROUND)
set(COMPONENT_ADD_LDFRAGMENTS esp32-spiram-rom-functions-c.lf) set(COMPONENT_ADD_LDFRAGMENTS esp32-spiram-rom-functions-c.lf)
endif() endif()
@@ -31,7 +22,7 @@ if(GCC_NOT_5_2_0)
set(EXTRA_LINK_FLAGS "-u newlib_include_locks_impl") set(EXTRA_LINK_FLAGS "-u newlib_include_locks_impl")
list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_heap_impl") list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_heap_impl")
list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_syscalls_impl") list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_syscalls_impl")
list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_pthread_impl")
else() else()
# Remove this section when GCC 5.2.0 is no longer supported # Remove this section when GCC 5.2.0 is no longer supported
# 'include' and 'lib' directories should also be removed. # 'include' and 'lib' directories should also be removed.
@@ -40,21 +31,10 @@ else()
set(LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib) set(LIB_PATH ${CMAKE_CURRENT_SOURCE_DIR}/lib)
if(CONFIG_SPIRAM_CACHE_WORKAROUND) if(CONFIG_SPIRAM_CACHE_WORKAROUND)
set(LIBC c-psram-workaround)
set(LIBM m-psram-workaround)
set(COMPONENT_ADD_LDFRAGMENTS esp32-spiram-rom-functions-psram-workaround.lf) set(COMPONENT_ADD_LDFRAGMENTS esp32-spiram-rom-functions-psram-workaround.lf)
else()
if(CONFIG_NEWLIB_NANO_FORMAT)
set(LIBC c_nano)
else()
set(LIBC c)
endif()
set(LIBM m)
endif() endif()
endif() endif()
set(COMPONENT_REQUIRES vfs) # for sys/ioctl.h set(COMPONENT_REQUIRES vfs) # for sys/ioctl.h
set(COMPONENT_PRIV_REQUIRES soc) set(COMPONENT_PRIV_REQUIRES soc)
@@ -70,10 +50,10 @@ if(GCC_NOT_5_2_0)
# Toolchain libraries require code defined in this component # Toolchain libraries require code defined in this component
add_library(extra INTERFACE) add_library(extra INTERFACE)
idf_component_get_property(newlib newlib COMPONENT_LIB) idf_component_get_property(newlib newlib COMPONENT_LIB)
target_link_libraries(extra INTERFACE ${LIBC} ${LIBM} "$<TARGET_FILE:${newlib}>") target_link_libraries(extra INTERFACE ${LIBC} ${LIBM} gcc "$<TARGET_FILE:${newlib}>")
target_link_libraries(${COMPONENT_LIB} extra) target_link_libraries(${COMPONENT_LIB} extra)
else() else()
target_link_libraries(${COMPONENT_LIB} ${LIBC} ${LIBM}) target_link_libraries(${COMPONENT_LIB} ${LIBC} ${LIBM} gcc)
endif() endif()
set_source_files_properties(heap.c PROPERTIES COMPILE_FLAGS -fno-builtin) set_source_files_properties(heap.c PROPERTIES COMPILE_FLAGS -fno-builtin)

View File

@@ -0,0 +1,22 @@
if(GCC_NOT_5_2_0)
if(CONFIG_NEWLIB_NANO_FORMAT)
set(LIBC c_nano)
else()
set(LIBC c)
endif()
set(LIBM m)
else()
if(CONFIG_SPIRAM_CACHE_WORKAROUND)
set(LIBC c-psram-workaround)
set(LIBM m-psram-workaround)
else()
if(CONFIG_NEWLIB_NANO_FORMAT)
set(LIBC c_nano)
else()
set(LIBC c)
endif()
set(LIBM m)
endif()
endif()

View File

@@ -13,3 +13,8 @@ int pthread_setcancelstate(int state, int *oldstate)
{ {
return 0; return 0;
} }
void newlib_include_pthread_impl()
{
// Linker hook, exists for no other purpose
}

View File

@@ -12,7 +12,8 @@ set(COMPONENT_SRCS "src/common/protocomm.c"
"src/transports/protocomm_console.c" "src/transports/protocomm_console.c"
"src/transports/protocomm_httpd.c") "src/transports/protocomm_httpd.c")
set(COMPONENT_PRIV_REQUIRES protobuf-c mbedtls console esp_http_server bt) set(COMPONENT_REQUIRES protobuf-c bt)
set(COMPONENT_PRIV_REQUIRES mbedtls console esp_http_server)
if(CONFIG_BT_ENABLED) if(CONFIG_BT_ENABLED)
if(CONFIG_BT_BLUEDROID_ENABLED) if(CONFIG_BT_BLUEDROID_ENABLED)

View File

@@ -3,3 +3,7 @@ set(COMPONENT_SRCS "vfs.c"
"vfs_semihost.c") "vfs_semihost.c")
set(COMPONENT_ADD_INCLUDEDIRS "include") set(COMPONENT_ADD_INCLUDEDIRS "include")
register_component() register_component()
# Some newlib syscalls are implemented in vfs.c, make sure these are always
# seen by the linker
target_link_libraries(${COMPONENT_LIB} "-u vfs_include_syscalls_impl")

View File

@@ -544,6 +544,34 @@ int esp_vfs_rename(struct _reent *r, const char *src, const char *dst)
return ret; return ret;
} }
/* Create aliases for newlib syscalls
These functions are also available in ROM as stubs which use the syscall table, but linking them
directly here saves an additional function call when a software function is linked to one, and
makes linking with -stdlib easier.
*/
int _open_r(struct _reent *r, const char * path, int flags, int mode)
__attribute__((alias("esp_vfs_open")));
ssize_t _write_r(struct _reent *r, int fd, const void * data, size_t size)
__attribute__((alias("esp_vfs_write")));
off_t _lseek_r(struct _reent *r, int fd, off_t size, int mode)
__attribute__((alias("esp_vfs_lseek")));
ssize_t _read_r(struct _reent *r, int fd, void * dst, size_t size)
__attribute__((alias("esp_vfs_read")));
int _close_r(struct _reent *r, int fd)
__attribute__((alias("esp_vfs_close")));
int _fstat_r(struct _reent *r, int fd, struct stat * st)
__attribute__((alias("esp_vfs_fstat")));
int _stat_r(struct _reent *r, const char * path, struct stat * st)
__attribute__((alias("esp_vfs_stat")));
int _link_r(struct _reent *r, const char* n1, const char* n2)
__attribute__((alias("esp_vfs_link")));
int _unlink_r(struct _reent *r, const char *path)
__attribute__((alias("esp_vfs_unlink")));
int _rename_r(struct _reent *r, const char *src, const char *dst)
__attribute__((alias("esp_vfs_rename")));
DIR* opendir(const char* name) DIR* opendir(const char* name)
{ {
const vfs_entry_t* vfs = get_vfs_for_path(name); const vfs_entry_t* vfs = get_vfs_for_path(name);
@@ -1193,3 +1221,8 @@ int esp_vfs_poll(struct pollfd *fds, nfds_t nfds, int timeout)
return ret; return ret;
} }
void vfs_include_syscalls_impl()
{
// Linker hook function, exists to make the linker examine this fine
}

View File

@@ -454,8 +454,6 @@ The order of components in the ``BUILD_COMPONENTS`` variable determines other or
- Order that :ref:`project_include.cmake` files are included into the project. - Order that :ref:`project_include.cmake` files are included into the project.
- Order that the list of header paths is generated for compilation (via ``-I`` argument). (Note that for a given component's source files, only that component's dependency's header paths are passed to the compiler.) - Order that the list of header paths is generated for compilation (via ``-I`` argument). (Note that for a given component's source files, only that component's dependency's header paths are passed to the compiler.)
- Order that component object archives are passed to the linker (note that the build system also passes ``--start-group`` and ``--end-group`` to the linker to allow cycles in linker dependencies, however the basic order is determined by ``BUILD_COMPONENTS``.
Build Process Internals Build Process Internals
======================= =======================

View File

@@ -451,7 +451,6 @@ ESP-IDF 构建系统会在命令行中添加以下 C 预处理器定义:
- 项目导入 :ref:`project_include.cmake` 文件的顺序。 - 项目导入 :ref:`project_include.cmake` 文件的顺序。
- 生成用于编译(通过 ``-I`` 参数)的头文件路径列表的顺序。请注意,对于给定组件的源文件,仅需将该组件的依赖组件的头文件路径告知编译器。 - 生成用于编译(通过 ``-I`` 参数)的头文件路径列表的顺序。请注意,对于给定组件的源文件,仅需将该组件的依赖组件的头文件路径告知编译器。
- 组件目标归档文件传递给链接器的顺序。请注意,构建系统还会将 ``--start-group````--end-group`` 传递给链接器,以允许链接依赖存在闭环,但其基本顺序还是由 ``BUILD_COMPONENTS`` 决定的。
构建的内部过程 构建的内部过程
============== ==============

View File

@@ -454,10 +454,10 @@ macro(idf_build_process target)
set(ESP_PLATFORM 1) set(ESP_PLATFORM 1)
idf_build_set_property(COMPILE_DEFINITIONS "-DESP_PLATFORM" APPEND) idf_build_set_property(COMPILE_DEFINITIONS "-DESP_PLATFORM" APPEND)
__build_process_project_includes()
# Perform component processing (inclusion of project_include.cmake, adding component # Perform component processing (inclusion of project_include.cmake, adding component
# subdirectories, creating library targets, linking libraries, etc.) # subdirectories, creating library targets, linking libraries, etc.)
__build_process_project_includes()
idf_build_get_property(idf_path IDF_PATH) idf_build_get_property(idf_path IDF_PATH)
add_subdirectory(${idf_path} ${build_dir}/esp-idf) add_subdirectory(${idf_path} ${build_dir}/esp-idf)

View File

@@ -356,8 +356,6 @@ macro(project project_name)
add_executable(${project_elf} "${project_elf_src}") add_executable(${project_elf} "${project_elf_src}")
add_dependencies(${project_elf} _project_elf_src) add_dependencies(${project_elf} _project_elf_src)
target_link_libraries(${project_elf} "-Wl,--start-group")
if(test_components) if(test_components)
target_link_libraries(${project_elf} "-Wl,--whole-archive") target_link_libraries(${project_elf} "-Wl,--whole-archive")
foreach(test_component ${test_components}) foreach(test_component ${test_components})

View File

@@ -4,6 +4,8 @@ set(CMAKE_C_COMPILER xtensa-esp32-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++) set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++)
set(CMAKE_ASM_COMPILER xtensa-esp32-elf-gcc) set(CMAKE_ASM_COMPILER xtensa-esp32-elf-gcc)
set(CMAKE_EXE_LINKER_FLAGS "-nostdlib" CACHE STRING "Linker Base Flags")
set(CMAKE_C_FLAGS "-mlongcalls -Wno-frame-address" CACHE STRING "C Compiler Base Flags") set(CMAKE_C_FLAGS "-mlongcalls -Wno-frame-address" CACHE STRING "C Compiler Base Flags")
set(CMAKE_CXX_FLAGS "-mlongcalls -Wno-frame-address" CACHE STRING "C++ Compiler Base Flags") set(CMAKE_CXX_FLAGS "-mlongcalls -Wno-frame-address" CACHE STRING "C++ Compiler Base Flags")
# Can be removed after gcc 5.2.0 support is removed (ref GCC_NOT_5_2_0)
set(CMAKE_EXE_LINKER_FLAGS "-nostdlib" CACHE STRING "Linker Base Flags")