cmake: For gcc8 use linker to find paths to libc, libm, libstdc++, etc

Removes the need to know/guess the paths to these libraries. Once we are gcc 8 only, we
can remove -nostdlib and no additional arguments are needed for system libraries.

The catch is: any time IDF overrides a symbol in the toolchain sysroot, we need
an undefined linker marker to make sure this symbol is seen by linker.
pull/3589/head
Angus Gratton 2019-04-15 13:45:08 +10:00 zatwierdzone przez Renz Christian Bagaporo
rodzic 2c12080049
commit 22514c1dd9
13 zmienionych plików z 83 dodań i 41 usunięć

Wyświetl plik

@ -31,4 +31,4 @@ register_component()
# disable --coverage for this component, as it is used as transport
# for gcov
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)

Wyświetl plik

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

Wyświetl plik

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

Wyświetl plik

@ -88,4 +88,13 @@ else()
cpu_start.c
PROPERTIES COMPILE_FLAGS
-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()

Wyświetl plik

@ -267,12 +267,12 @@ SECTIONS
__eh_frame = ABSOLUTE(.);
KEEP(*(.eh_frame))
. = (. + 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(.);
KEEP (*crtbegin.*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.* *crtbegin.*) .ctors .ctors.*))
__init_array_end = ABSOLUTE(.);
KEEP (*crtbegin.*(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.*) .dtors))

Wyświetl plik

@ -25,12 +25,7 @@ else()
)
target_linker_script(${COMPONENT_LIB} "${scripts}")
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)
else()
if(NOT CONFIG_SPIRAM_CACHE_WORKAROUND)
target_linker_script(${COMPONENT_LIB} "esp32/ld/esp32.rom.newlib-funcs.ld")
endif()

Wyświetl plik

@ -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.
They are called by other ROM functions (mostly from newlib).
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 ( _system_r = 0x4000bc10 );
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
*/

Wyświetl plik

@ -22,6 +22,7 @@ if(GCC_NOT_5_2_0)
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_syscalls_impl")
list(APPEND EXTRA_LINK_FLAGS "-u newlib_include_pthread_impl")
else()
# Remove this section when GCC 5.2.0 is no longer supported
# 'include' and 'lib' directories should also be removed.
@ -49,10 +50,10 @@ if(GCC_NOT_5_2_0)
# Toolchain libraries require code defined in this component
add_library(extra INTERFACE)
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)
else()
target_link_libraries(${COMPONENT_LIB} ${LIBC} ${LIBM})
target_link_libraries(${COMPONENT_LIB} ${LIBC} ${LIBM} gcc)
endif()
set_source_files_properties(heap.c PROPERTIES COMPILE_FLAGS -fno-builtin)

Wyświetl plik

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

Wyświetl plik

@ -3,3 +3,7 @@ set(COMPONENT_SRCS "vfs.c"
"vfs_semihost.c")
set(COMPONENT_ADD_INCLUDEDIRS "include")
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")

Wyświetl plik

@ -544,6 +544,34 @@ int esp_vfs_rename(struct _reent *r, const char *src, const char *dst)
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)
{
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;
}
void vfs_include_syscalls_impl()
{
// Linker hook function, exists to make the linker examine this fine
}

Wyświetl plik

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

Wyświetl plik

@ -4,6 +4,8 @@ set(CMAKE_C_COMPILER xtensa-esp32-elf-gcc)
set(CMAKE_CXX_COMPILER xtensa-esp32-elf-g++)
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_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")