This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 77f263b4fa3096d488dc12f9e098e29aff3f8687
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Aug 28 18:35:28 2026 +0200

    cmake: Build FDPIC modules the way the make build does.
    
    The same two differences as in common/Toolchain.defs: the compiler is told
    -mfdpic -fPIC, and the module link is done by an arm-uclinuxfdpiceabi
    linker.
    
    That linker is not the one that links the firmware, so the module link needs
    a variable of its own.  CMAKE_ELF_LD is the ordinary linker unless the
    architecture sets it, which arm does under CONFIG_FDPIC.
    
    The linker script needs nothing here: it is generated from
    libs/libc/elf/gnu-elf.ld.in, which both build systems preprocess, and the
    FDPIC segments are already in it.
    
    -r is now conditional on CONFIG_PIC being off, which is what
    common/Toolchain.defs has always done and the cmake build did not: a
    position independent module is linked as an executable, and an FDPIC one as
    a shared object, so neither wants it.
    
    -fno-use-cxa-atexit mirrors CXXELFFLAGS for the same reason it was added
    there.
    
    Configured and built mps3-an547:picostest with CONFIG_FDPIC through cmake 
and
    ninja: the modules in bin/ are ARM FDPIC with two PT_LOAD segments.
    
    Signed-off-by: Marco Casaroli <[email protected]>
---
 arch/arm/src/cmake/elf.cmake      | 45 ++++++++++++++++++++++++++++++++-------
 cmake/nuttx_add_application.cmake | 12 +++++++++--
 2 files changed, 47 insertions(+), 10 deletions(-)

diff --git a/arch/arm/src/cmake/elf.cmake b/arch/arm/src/cmake/elf.cmake
index 7108aa4c174..91b1037d631 100644
--- a/arch/arm/src/cmake/elf.cmake
+++ b/arch/arm/src/cmake/elf.cmake
@@ -27,17 +27,46 @@ nuttx_mod_compile_options(-fvisibility=hidden -mlong-calls)
 nuttx_elf_compile_options_ifdef(CONFIG_UNWINDER_ARM -fno-unwind-tables
                                 -fno-asynchronous-unwind-tables)
 
-# An ELF module needs r9 as its PIC base, so it must not also have the register
-# fixed: GCC rejects that pair with "unable to use 'r9' for PIC register".  
This
-# mirrors CELFFLAGS in common/Toolchain.defs, which filters --fixed-r9 back out
-# of the inherited CFLAGS for the same reason.
+if(CONFIG_FDPIC)
 
-nuttx_elf_compile_options_ifdef(CONFIG_PIC -mpic-register=r9)
+  # An FDPIC module is a shared object whose two segments the loader places
+  # independently.  The stock compiler emits correct FDPIC objects for both C
+  # and C++, so only the link needs the arm-uclinuxfdpiceabi linker: the stock
+  # one carries the armelf emulation alone and would turn every import into a
+  # jump slot where the ABI wants a function descriptor.
 
-nuttx_elf_link_options_ifdef(
-  CONFIG_PIC --unresolved-symbols=ignore-in-object-files --emit-relocs)
+  if(NOT FDPIC_CROSSDEV)
+    set(FDPIC_CROSSDEV arm-uclinuxfdpiceabi-)
+  endif()
+
+  set(CMAKE_ELF_LD
+      "${FDPIC_CROSSDEV}ld"
+      CACHE INTERNAL "Linker for FDPIC modules")
+
+  nuttx_elf_compile_options(-mfdpic -fPIC -Wa,--noexecstack)
+
+  nuttx_elf_link_options(-m armelf_linux_fdpiceabi -shared -z now)
+
+elseif(CONFIG_PIC)
+
+  # An ELF module needs r9 as its PIC base, so it must not also have the
+  # register fixed: GCC rejects that pair with "unable to use 'r9' for PIC
+  # register".  This mirrors CELFFLAGS in common/Toolchain.defs, which filters
+  # --fixed-r9 back out of the inherited CFLAGS for the same reason.
 
-nuttx_elf_link_options_ifdef(CONFIG_BINFMT_ELF_RELOCATABLE -r)
+  nuttx_elf_compile_options(-mpic-register=r9)
+
+  nuttx_elf_link_options(--unresolved-symbols=ignore-in-object-files
+                         --emit-relocs)
+
+endif()
+
+# Not with CONFIG_PIC: there the module is linked as an executable, which is
+# what common/Toolchain.defs does too.
+
+if(CONFIG_BINFMT_ELF_RELOCATABLE AND NOT CONFIG_PIC)
+  nuttx_elf_link_options(-r)
+endif()
 
 nuttx_mod_link_options(-r)
 
diff --git a/cmake/nuttx_add_application.cmake 
b/cmake/nuttx_add_application.cmake
index 4864eaedbd6..bf4b626ce93 100644
--- a/cmake/nuttx_add_application.cmake
+++ b/cmake/nuttx_add_application.cmake
@@ -149,7 +149,15 @@ function(nuttx_add_application)
         if(TARGET STARTUP_OBJS)
           add_dependencies(${TARGET} STARTUP_OBJS)
         endif()
-        if(NOT "${CMAKE_LD}" MATCHES "gcc$")
+        # A module may need a different linker from the one that links the
+        # firmware: an FDPIC module does, because the stock linker cannot
+        # produce one.  CMAKE_ELF_LD is that linker, and it is the ordinary one
+        # unless the architecture says otherwise.
+
+        if(NOT CMAKE_ELF_LD)
+          set(CMAKE_ELF_LD ${CMAKE_LD})
+        endif()
+        if(NOT "${CMAKE_ELF_LD}" MATCHES "gcc$")
           set(USE_LINKER True)
         endif()
         if(STACKSIZE)
@@ -179,7 +187,7 @@ function(nuttx_add_application)
           POST_BUILD
           COMMAND
             # add default link option
-            ${CMAKE_LD} -T ${NUTTX_BINARY_DIR}/gnu-elf.ld
+            ${CMAKE_ELF_LD} -T ${NUTTX_BINARY_DIR}/gnu-elf.ld
             # add global MOD link option if dynlib link
             
$<$<BOOL:${DYNLIB_ELF_MODE}>:$<TARGET_PROPERTY:nuttx_global,NUTTX_MOD_APP_LINK_OPTIONS>>
             # add global ELF link option if m&kernel link

Reply via email to