1

TL;DR: Is there a way to specify custom link order when CMake managed dependencies seems not enough?

I'm developing a toy OS for fun and having trouble linking in the GCC crt* files responsible for calling global constructors. I read that objects must be linked in this exact order: crti.o crtbegin.o mykernel.o crtend.o crtn.o, but don't know how to enforce that exact order using CMake.

I'm aware that by target_link_libraries(), CMake automatically manages the link order, but it does not guarantee any specific order, namely put crtbegin.o before and crtend.o after.

Currently I'm using the work-around below and it becomes infeasible if you try to link in more libraries. This is my temporary solution:

add_library(crti OBJECT path/to/crti.s)
add_library(crtn OBJECT path/to/crtn.s)

# the actual target
add_executable(awesome_kernel
    myAwesomeKernel.cc
)

add_dependencies(myAwesomeKernel crti crtn)
set_property(TARGET myAwesomeKernel APPEND PROPERTY LINK_DEPENDS path/to/crti.s)
set_property(TARGET myAwesomeKernel APPEND PROPERTY LINK_DEPENDS path/to/crtn.s)
set_property(TARGET myAwesomeKernel APPEND PROPERTY LINK_DEPENDS path/to/linker_script)

# custom link line
set(CMAKE_C_LINK_EXECUTABLE "${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -T path/to/linker_script CMakeFiles/crti.dir/crti.s.obj ${CRTBEGIN_OBJ} <OBJECTS> ${CRTEND_OBJ} CMakeFiles/crtn.dir/crtn.s.obj -o myAwesomeKernel")
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_C_COMPILER} ${CMAKE_C_FLAGS} -T path/to/linker_script CMakeFiles/crti.dir/crti.s.obj ${CRTBEGIN_OBJ} <OBJECTS> ${CRTEND_OBJ} CMakeFiles/crtn.dir/crtn.s.obj -o myAwesomeKernel")

However, it's awkward and unable to link other libraries to myAwesomeKernel without compromising the desired link line. (Yes, you could use target_link_libraries() but it left you without the ability to put your programs between crtbegin.o and crtend.o)

Aside: something bothers me..

  1. How to get rid of hard-coded CMakeFiles/crti.dir/crti.s.obj? Generator expression (to get target file) is not supported inside set command.
  2. In the custom link line, how does <OBJECTS> work? Why does it get expanded to target executable?
3
  • create crtbegin, crtend, kernell libraries and then target_link_libraries(crtbegin kernell) target_link_libraries(kernell crntend) ? Commented Aug 5 at 12:15
  • 3
    I think this might be an X/Y problem. You seem like you need to have specific sections in a specific order in memory so the labels are properly around the init structures for the C runtime library. This is probably best solved by specifying all this in the linker descriptor file rather than trying to hope the link order is going to do the right thing. Commented Aug 5 at 14:34
  • Guess I should not abuse CMake for that. Commented Oct 26 at 13:44

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.