Acsor
December 23, 2019, 9:16pm
1
I am setting up a cross-compiling C project targeting two micro architectures, inspired by ARM and MIPS. Without loss of generality, I’ll focus on the micro ARM architecture, where the compile instructions I was given are
arm-none-eabi-gcc <COMPILE_FLAGS> -o hello.o hello.c
arm-none-eabi-gcc <COMPILE_FLAGS> -o termprint.o termprint.c
arm-none-eabi-gcc <COMPILE_FLAGS> -o crtso.o ./uarm/crtso.s
arm-none-eabi-gcc <COMPILE_FLAGS> -o libuarm.o ./uarm/libuarm.s
arm-none-eabi-ld <LINK_FLAGS> -o kernel.uarm hello.o termprint.o crtso.o libuarm.o
I have tried to reproduce these instructions with CMake in the following snippet
# Project include, source and library dirs for uarm-related files
set(BKA_UARM_INC ${PROJECT_SOURCE_DIR}/${BKA_INC}/uarm)
set(BKA_UARM_SRC ${PROJECT_SOURCE_DIR}/${BKA_SRC}/uarm)
set(CFLAGS_UARM -mcpu=arm7tdmi)
set(LDFLAGS_UARM "-G 0 -nostdlib -T ${BKA_UARM_SRC}/elf32ltsarm.h.uarmcore.x")
add_compile_options(${CFLAGS_UARM})
add_library(libuarm OBJECT ${BKA_UARM_SRC}/libuarm.s)
add_library(crtso OBJECT ${BKA_UARM_SRC}/crtso.s)
target_include_directories(libuarm PRIVATE ${BKA_UARM_INC})
add_executable(kernel.uarm ${BKA_SRC}/phase0.c)
target_link_libraries(kernel.uarm crtso libuarm io)
set_property(TARGET kernel.uarm PROPERTY LINK_FLAGS ${LDFLAGS_UARM})
but they fail rather badly. Indeed, by choosing make
as the build-system, I do
$ make VERBOSE=1 kernel.uarm
and get
[ 80%] Linking C executable kernel.uarm
/usr/bin/cmake -E cmake_link_script CMakeFiles/kernel.uarm.dir/link.txt --verbose=3
/usr/local/bin/arm-none-eabi-gcc -rdynamic -G 0 -nostdlib -T /home/acsor/Software/BiKaya/src/uarm/elf32ltsarm.h.uarmcore.x CMakeFiles/kernel.uarm.dir/src/phase0.c.o CMakeFiles/crtso.dir/src/uarm/crtso.s.o CMakeFiles/libuarm.dir/src/uarm/libuarm.s.o CMakeFiles/io.dir/src/io.c.o -o kernel.uarm
arm-linux-gnu-gcc: error: 0: No such file or directory
arm-linux-gnu-gcc: error: unrecognized command line option ‘-G’
This obviously is due to CMake running the compiler prior to linking, which does not recognize the -G
option. My real intention here though is to completely skip the arm-linux-gnu-gcc
invocation, and simply feed the linker likeso
arm-none-eabi-ld <LINK_FLAGS> -o kernel.uarm hello.o termprint.o crtso.o libuarm.o
Can I redefine the compile steps in some way? If not, any other way of properly compiling and linking my execuables will be very appreciated.
Use the -Wl
option of GCC. Example:
set(LDFLAGS_UARM "-Wl,-G,0,-nostdlib,-T,${BKA_UARM_SRC}/elf32ltsarm.h.uarmcore.x")
Edit: simplified by removing duplicate -Wl
options
Use preferably target_link_options
which supports advanced capabilties (genex and “LINKER:” prefix). So we have:
target_link_options (kernel.uarm PRIVATE "LINKER:-G,0,-nostdlib,-${BKA_UARM_SRC}/elf32ltsarm.h.uarmcore.x")
Acsor
December 23, 2019, 10:59pm
4
Both the previous solutions give rise to a fresh new error – and it’s exactly the same
$ make VERBOSE=1 kernel.uarm
...
/usr/bin/cmake -E cmake_link_script CMakeFiles/kernel.uarm.dir/link.txt --verbose=1
/usr/local/bin/arm-none-eabi-gcc -rdynamic "-Wl,-G,0,-nostdlib,-T /home/acsor/Software/BiKaya/src/uarm/elf32ltsarm.h.uarmcore.x" CMakeFiles/kernel.uarm.dir/src/phase0.c.o CMakeFiles/crtso.dir/src/uarm/crtso.s.o CMakeFiles/libuarm.dir/src/uarm/libuarm.s.o CMakeFiles/io.dir/src/io.c.o -o kernel.uarm
/usr/bin/arm-linux-gnu-ld: cannot find crt1.o: No such file or directory
/usr/bin/arm-linux-gnu-ld: cannot find crti.o: No such file or directory
...
I wish I could do that, but I want to support at least up to version 3.7.2
which doesn’t come with target_link_options()
.
Acsor
December 23, 2019, 11:05pm
5
Just to mention it, one solution I can quite work with is the following. One small flaw is that relies on capabilities only recently introduced, so I can’t use with on some lab. computers running CMake 3.7.2
.
add_custom_target(
kernel.uarm
DEPENDS crtso libuarm io phase0
COMMAND ${CMAKE_C_LINKER} ${LDFLAGS_UARM}
$<TARGET_OBJECTS:crtso> $<TARGET_OBJECTS:libuarm>
$<TARGET_OBJECTS:io> $<TARGET_OBJECTS:phase0>
-o kernel.uarm
)
Acsor
December 25, 2019, 10:35pm
6
Update: despite profused efforts, it appears the link process is still looking for the standard C library.
I updated the uarm.cmake
file likeso
# Project include, source and library dirs for uarm-related files
set(BKA_UARM_INC ${PROJECT_SOURCE_DIR}/${BKA_INC}/uarm)
set(BKA_UARM_SRC ${PROJECT_SOURCE_DIR}/${BKA_SRC}/uarm)
set(CFLAGS_UARM -nostdlib -O0 -mcpu=arm7tdmi)
set(LDFLAGS_UARM "-Wl,-G,0,-nostdlib,-T,${BKA_UARM_SRC}/elf32ltsarm.h.uarmcore.x")
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "")
add_executable(
kernel.uarm
${BKA_SRC}/phase0.c ${BKA_UARM_SRC}/libuarm.s ${BKA_UARM_SRC}/crtso.s ${BKA_SRC}/io.c
)
target_include_directories(kernel.uarm PRIVATE ${BKA_UARM_INC})
set_property(TARGET kernel.uarm PROPERTY COMPILE_OPTIONS ${CFLAGS_UARM})
set_property(TARGET kernel.uarm PROPERTY LINK_FLAGS ${LDFLAGS_UARM})
and tried to run with
$ make VERBOSE=1 kernel.uarm
...
/usr/bin/arm-none-eabi-gcc -Wl,-G,0,-nostdlib,-T,/home/students/acsor/08574-Sistemi-Operativi/BiKaya/src/uarm/elf32ltsarm.h.uarmcore.x CMakeFiles/kernel.uarm.dir/src/phase0.c.o CMakeFiles/kernel.uarm.dir/src/uarm/libuarm.s.o CMakeFiles/kernel.uarm.dir/src/uarm/crtso.s.o CMakeFiles/kernel.uarm.dir/src/io.c.o -o kernel.uarm
/usr/lib/gcc/arm-none-eabi/5.4.1/../../../arm-none-eabi/lib/libc.a(lib_a-exit.o): In function `exit':
/build/newlib-XAuz1P/newlib-2.4.0.20160527/build/arm-none-eabi/newlib/libc/stdlib/../../../../../newlib/libc/stdlib/exit.c:70: undefined reference to `_exit'
...
Maybe try passing -nostdlib
to GCC itself rather than to the linker? So then you would have:
set(LDFLAGS_UARM "-nostdlib -Wl,-G,0,-T,${BKA_UARM_SRC}/elf32ltsarm.h.uarmcore.x")
Acsor
December 26, 2019, 5:35pm
8
Love you! It works flawlessly, but only on the micro ARM architecture.