]> granicus.if.org Git - esp-idf/commitdiff
cmake: For gcc8 use linker to find paths to libc, libm, libstdc++, etc
authorAngus Gratton <angus@espressif.com>
Mon, 15 Apr 2019 03:45:08 +0000 (13:45 +1000)
committerRenz Christian Bagaporo <renz@espressif.com>
Tue, 28 May 2019 04:54:37 +0000 (12:54 +0800)
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.

13 files changed:
components/app_trace/CMakeLists.txt
components/bootloader/subproject/main/bootloader_start.c
components/cxx/CMakeLists.txt
components/esp32/CMakeLists.txt
components/esp32/ld/esp32.project.ld.in
components/esp_rom/CMakeLists.txt
components/esp_rom/esp32/ld/esp32.rom.syscalls.ld
components/newlib/CMakeLists.txt
components/newlib/pthread.c
components/vfs/CMakeLists.txt
components/vfs/vfs.c
tools/cmake/build.cmake
tools/cmake/toolchain-esp32.cmake

index b504469b612448fe7a919102e66b0aa47bd68bce..741f4db41ad54f15a8b274211da40ed34e1ebba2 100644 (file)
@@ -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)
index 780c1326ec208a75e9cfdb024768b24e51083639..7a7e76aa6b613fa82513cb3b2963310cd436baf9 100644 (file)
@@ -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;
+}
+
index cb5609d2a98598658c508093fec80e6ae1ffff67..f1f9b35c2593758ab72acb86338cd6374358f8f1 100644 (file)
@@ -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)
index c8816fc388cf07b33a19390435562cec299dab36..3710237896022e873b9cfa8294fd84608ddbed47 100644 (file)
@@ -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()
index 6b10c86948f65423e8e0d8894e2ffdcafe30693b..a38abce64a0e956e631fe89edc458f0d98eec0c5 100644 (file)
@@ -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))
index 468819a22757bb94661655c8f3cfbf8380abbc8f..88a230c6a889ecb1734640dc7bffe3dccf216020 100644 (file)
@@ -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()
 
index 811d879dd48165efeef226d954f537f728f54f8d..9819556fc2079f72e77c2092db59420c5dadbb8c 100644 (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.
    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
 */
index 0d64914949a034af7b60d851b36724aaca7ab3a3..8d5724cc4c22e631d5d5b727dd9fa2d5cbd96b38 100644 (file)
@@ -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)
index c917a22abe7fae8f32248ac80fd4818988642a06..3c982f483adf0dc86ae81ede1dff3866994e89d8 100644 (file)
@@ -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
+}
index 816e7a6d83652371325647fef9a0d1b4c1130399..1d8fb06ec05aa2426cc0f0f9e3dad3e6631d0a09 100644 (file)
@@ -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")
index c64d831f7e1e9a1479d7981dcd5e801a1d9dcaee..19f081c5a3d8de3f0d2ccb297c0f1ce0b1e0424b 100644 (file)
@@ -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
+}
index 306486c165c030dfd2a7dfbc9589940c0fe7ab46..585d26e19505a86d9ac7ec21d6a13b8f99145906 100644 (file)
@@ -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)
 
index b311d7ab62ab9b3f76da0e8f1f0ec6dda0e518f0..b63ae5a8668dceed4654af8d8daf76cedd43fb50 100644 (file)
@@ -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")