Reputation: 1010
There are C runtime / startup files: crt0.o
, crti.o
, crtbegin.o
… crtend.o
, crtn.o
.
crtbegin.o
and crtend.o
are provided by the toolchain (GCC)crt0.o
, crti.o
and crtn.o
are implemented by myself in my
project scope.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:
toolchain/i686-elf/lib/gcc/i686-elf/10.0.1/crtbegin.o
toolchain/i686-elf/lib/gcc/i686-elf/10.0.1/crtend.o
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
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