Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Discussion]How to elegantly implement ALLSYMS feat in CMake build #11875

Closed
xuxin930 opened this issue Mar 8, 2024 · 4 comments · Fixed by #12035
Closed

[Discussion]How to elegantly implement ALLSYMS feat in CMake build #11875

xuxin930 opened this issue Mar 8, 2024 · 4 comments · Fixed by #12035

Comments

@xuxin930
Copy link
Contributor

xuxin930 commented Mar 8, 2024

I planning to add ALLSYMS feature in CMake build system,
there is a issue I encountered and I hope to discuss it with you all.

Since we need to complete the final linking FIRST and then use the linked ELF to generate the symbol table.

nuttx/arch/sim/src/Makefile

Lines 354 to 365 in 53aef8e

define LINK_ALLSYMS
$(if $(CONFIG_HOST_MACOS), \
$(Q) $(TOPDIR)/tools/mkallsyms.sh noconst $(NUTTX) $(CROSSDEV) > allsyms.tmp, \
$(Q) $(TOPDIR)/tools/mkallsyms.py $(NUTTX) allsyms.tmp --orderbyname $(CONFIG_SYMTAB_ORDEREDBYNAME))
$(Q) $(call COMPILE, allsyms.tmp, allsyms$(OBJEXT), -x c)
$(if $(CONFIG_HAVE_CXX),\
$(Q) "$(CXX)" $(CFLAGS) $(LDFLAGS) -o $(NUTTX) \
$(HEADOBJ) nuttx.rel $(HOSTOBJS) $(STDLIBS) allsyms$(OBJEXT),\
$(Q) "$(CC)" $(CFLAGS) $(LDFLAGS) -o $(NUTTX) \
$(HEADOBJ) nuttx.rel $(HOSTOBJS) $(STDLIBS) allsyms$(OBJEXT))
$(Q) $(call DELFILE, allsyms.tmp allsyms$(OBJEXT))
endef

nuttx/arch/sim/src/Makefile

Lines 385 to 395 in 53aef8e

ifneq ($(CONFIG_ALLSYMS),y)
$(if $(CONFIG_HAVE_CXX),\
$(Q) "$(CXX)" $(CFLAGS) $(LDFLAGS) -o $(TOPDIR)/$@ $(HEADOBJ) nuttx.rel $(HOSTOBJS) $(STDLIBS),\
$(Q) "$(CC)" $(CFLAGS) $(LDFLAGS) -o $(TOPDIR)/$@ $(HEADOBJ) nuttx.rel $(HOSTOBJS) $(STDLIBS))
else
$(Q) # Link and generate default table
$(Q) $(if $(wildcard $(shell echo $(NUTTX))),,$(call LINK_ALLSYMS, $@))
$(Q) # Extract all symbols
$(Q) $(call LINK_ALLSYMS, $^)
$(Q) # Extract again since the table offset may changed
$(Q) $(call LINK_ALLSYMS, $^)


this means:

  1. allsyms.c is must generated after nuttx elf linking
  2. we have to execute link multiple times, at least three times

this will cause problems when using CMake,
because we cannot add dependency to a target, and this dependency also depends on this target at the same time.

              need allsyms to gen final elf with syms
nuttx       --------------------------------------->     allsyms.c
         <---------------------------------------
               need nuttx elf to export symtable 

this creates circular dependency issues.


The solution I'm currently thinking of is this:

  1. when ALLSYMS feature is enabled , add an empty allsyms.c file dependency for nuttx.
  2. add post execution process , run mkallsym and link twice

It looks a bit like this

if(CONFIG_ALLSYMS)
  file(TOUCH ${CMAKE_BINARY_DIR}/allsyms.c) 
  add_library(allsyms OBJECT)
  nuttx_add_library_internal(allsyms)
  target_compile_definitions(allsyms PRIVATE $<TARGET_PROPERTY:nuttx,NUTTX_KERNEL_DEFINITIONS>)
  target_compile_options(allsyms PRIVATE $<TARGET_PROPERTY:nuttx,NUTTX_KERNEL_COMPILE_OPTIONS>)
  target_sources(allsyms PUBLIC ${CMAKE_BINARY_DIR}/allsyms.c)
  add_dependencies(nuttx allsyms) 

  add_custom_command(
    TARGET nuttx
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E remove allsyms.c
    COMMAND ${NUTTX_DIR}/tools/mkallsyms.py ${CMAKE_BINARY_DIR}/nuttx allsyms.c
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} -t nuttx
    COMMAND ${CMAKE_COMMAND} -E remove allsyms.c
    COMMAND ${NUTTX_DIR}/tools/mkallsyms.py ${CMAKE_BINARY_DIR}/nuttx allsyms.c
    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} -t nuttx
    DEPENDS nuttx 
    WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
    COMMAND_EXPAND_LISTS) 
endif()

What I doubt is whether it is reasonable to run cmake --build during the cmake call ?
although it will ONLY re-execute the action of generating allsyms.o
Is there a better way to solve this problem that I don't know of ?

@xuxin930
Copy link
Contributor Author

xuxin930 commented Mar 8, 2024

hi @xiaoxiang781216 @anchao @raiden00pl @acassis
Do you have any suggestions? 😃

@anchao
Copy link
Contributor

anchao commented Mar 11, 2024

How about adding multiple execution targets?

add_executable(nuttx)
add_executable(nuttx_allsyms1)
add_executable(nuttx_allsyms2)

and update allsyms.o by nesting add_custom_command() POST_BUILD.

@xuxin930
Copy link
Contributor Author

How about adding multiple execution targets?

Okay let me give it a try

@xuxin930
Copy link
Contributor Author

xuxin930 commented Apr 2, 2024

How about adding multiple execution targets?

add_executable(nuttx)
add_executable(nuttx_allsyms1)
add_executable(nuttx_allsyms2)

and update allsyms.o by nesting add_custom_command() POST_BUILD.

This plan is perfect, and much better than what I designed before, 👍
@anchao thank you very much. I submitted in this PR #12035

@xiaoxiang781216 xiaoxiang781216 linked a pull request Apr 2, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants