Martin Kopecký
Martin Kopecký

Reputation: 1010

CMake - Link project with C runtime object files in correct order

There are C runtime / startup files: crt0.o, crti.o, crtbegin.ocrtend.o, crtn.o.

The project is about running the executable on i686 bare metal so without the OS.

The problem is witin the linking of the final executable - The order in which the project object files are linked with all the C runtime files above matters.

My build system is CMake where I use target_sources command to define the source files used (compiled and then linked together) for the executable:

set( BARE_METAL app.bin )
add_executable( ${BARE_METAL} "" )

target_sources( ${BARE_METAL}
  PRIVATE
    boot.s  # contains symbols analogical to crt0.s
    crti.s
    crtn.s
    a.cpp
    b.cpp
    # … other files go here
)
target_link_options( ${BARE_METAL}
  PUBLIC
    -t linker.ld
    -nostdlib
    -nostartfiles
)
target_link_libraries( ${BARE_METAL}
  PUBLIC
    support
)

The problem is GCC is not linking with crtbegin.o and crtend.o even though it can be found in my toolchain:

Could you please advise me how to invoke the linker with all the required arguments in correct order from CMake? I would expect a link command analogical to

./i686-elf-ld -t linker.ld -nostdlib -nostartfiles boot.o crti.o crtbegin.o a.o b.o -libsupport.a crtend.o crtn.o

Please notice the order of C runtime files. I have simplified the direktory structures of all the files but the crucial point should be cought here.

Many thanks in advance to anyone willing to help me… Martin

UPDATE:

I tried to investigate more in parallel waiting for any kind of advise here and the promising way seems to be using CMAKE_CXX_LINK_EXECUTABLE to define project specific build rule for linking.

My project uses toolchain file which is being set before the root/main project() statement. Within the subproject I set the CMAKE_CXX_LINK_EXECUTABLE and it seems to work having no consequence on other subprojects. That's why I call it promissing although the whole thing does not work yet.

My plan is to create an object library out of the three project specific C runtime files crt0.o, crti.o and crtn.o to remove them from <OBJECTS>, make the project depend on this object library but manage the runtime files manually within the link build rule.

Do you think this way would successfully end? I will post the results once I have some...

Upvotes: 2

Views: 1700

Answers (1)

Martin Kopeck&#253;
Martin Kopeck&#253;

Reputation: 1010

Thanks to @KamilCuk I have successfully made it running. Here is the solution I made (to be used by anyone trying to solve the same issue)

project( Bare_Metal LANGUAGES CXX C ASM )

set( BARE_METAL app.bin )
set( BARE_METAL_CRTS app-crts )

add_library( ${BARE_METAL_CRTS} OBJECT
    boot.s  # contains symbols analogical to crt0.s
    crti.s
    crtn.s
)

add_executable( ${BARE_METAL} "" )

target_sources( ${BARE_METAL}
  PRIVATE
    a.cpp
    b.cpp
    # … other files go here
)
target_link_options( ${BARE_METAL}
  PUBLIC
    -t linker.ld
    -nostdlib
    -nostartfiles
)
target_link_libraries( ${BARE_METAL}
  PUBLIC
    support
)

# This ensures the boot.o crti.o, crtn.o to be build prior to BARE_METAL target
add_dependencies( ${BARE_METAL} ${BARE_METAL_CRTS} )

# Ask GCC to get the full path name of crtbegin. and crtend.o
execute_process( COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtbegin.o OUTPUT_VARIABLE CRTBEGIN_O OUTPUT_STRIP_TRAILING_WHITESPACE )
execute_process( COMMAND ${CMAKE_CXX_COMPILER} -print-file-name=crtend.o OUTPUT_VARIABLE CRTEND_O OUTPUT_STRIP_TRAILING_WHITESPACE)

# Set linker executable to be used - navigate to the toolchain used (might be setup in toolchain file)
set( BARE_METAL_LINKER ${BARE_METAL_TOOLCHAIN_ROOT}/bin/${CMAKE_TARGET_PROCESSOR}-elf-ld )

set( CMAKE_CXX_LINK_EXECUTABLE "${BARE_METAL_LINKER} <CMAKE_C_LINK_FLAGS> <FLAGS> <LINK_FLAGS> boot.obj crti.obj ${REVOLTA_CRTBEGIN} <OBJECTS> -o <TARGET> <LINK_LIBRARIES> ${REVOLTA_CRTEND} crtn.obj" )

Please keep in mind the code above is not copy-and-paste solution but is complete, working to be used as guide/inspiration to do such stuff :)

Upvotes: 5

Related Questions