Я пытаюсь создать приветственный мир в архитектуре рук, используя CMake с эта цепочка инструментов
Мой main.c
int main()
{
char *str = "Hello World";
return 0;
}
И мой CMakeLists.txt
cmake_minimum_required(VERSION 3.4)
SET(PROJ_NAME arm-hello-world-nostdlib)
PROJECT(${PROJ_NAME})
# Include directories with headers
#---------------------------------------------------#
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include )
# Source
#---------------------------------------------------#
FILE(GLOB ${PROJ_NAME}_SRC
"src/*.c"
)
FILE(GLOB ${PROJ_NAME}_HEADERS
"include/*.h"
)
# Create Exe
#---------------------------------------------------#
ADD_EXECUTABLE(${PROJ_NAME} ${${PROJ_NAME}_SRC} ${${PROJ_NAME}_HEADERS})
# Specify libraries or flags to use when linking a given target.
#---------------------------------------------------#
TARGET_LINK_LIBRARIES(${PROJ_NAME} -nostdlib --specs=rdimon.specs -lm -lrdimon)
Эта конфигурация запускает предупреждение:
[100%] Linking C executable arm-hello-world-nostdlib
/usr/lib/gcc/arm-none-eabi/5.2.0/../../../../arm-none-eabi/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000008000
И выполнение двоичного файла с помощью qemu приводит к сбою выполнения:
qemu-arm arm-hello-world-nostdlib
qemu: uncaught target signal 4 (Illegal instruction) - core dumped
Illegal instruction (core dumped)
Без флага --nostdlib работает отлично, и команда
arm-none-eabi-objdump -s arm-hello-world-nostdlib
Показать много информации в двоичном формате, компиляция с флагом показывает только:
samples/helloworld-nostdlib/arm-hello-world-nostdlib: file format elf32-littlearm
Contents of section .text:
8000 80b483b0 00af044b 7b600023 18460c37 .......K{`.#.F.7
8010 bd465df8 047b7047 1c800000 .F]..{pG....
Contents of section .rodata:
801c 48656c6c 6f20576f 726c6400 Hello World.
Contents of section .comment:
0000 4743433a 20284665 646f7261 20352e32 GCC: (Fedora 5.2
0010 2e302d33 2e666332 33292035 2e322e30 .0-3.fc23) 5.2.0
0020 00 .
Contents of section .ARM.attributes:
0000 41380000 00616561 62690001 2e000000 A8...aeabi......
0010 05436f72 7465782d 4d340006 0d074d09 .Cortex-M4....M.
0020 020a0612 04140115 01170318 0119011a ................
0030 011b011c 011e0622 01 .......".
Мне не нужны библиотеки stl в моем двоичном файле, но я думаю, что мне не хватает ассемблерного кода, чтобы найти точку входа. Как добавить вручную?
Обновление: согласно документу GNU Linker для -nostdlib:
Не используйте при компоновке стандартные системные файлы запуска или библиотеки. Никакие файлы запуска и только указанные вами библиотеки не будут переданы компоновщику, а параметры, определяющие компоновку системных библиотек, такие как -static-libgcc или -shared-libgcc, игнорируются.
В качестве альтернативы, если кто-то не хочет использовать стандартную библиотеку, он может использовать флаг -nodefaultlibs.
Не используйте стандартные системные библиотеки при линковке. Компоновщику передаются только указанные вами библиотеки, а параметры, определяющие компоновку системных библиотек, такие как -static-libgcc или -shared-libgcc, игнорируются. Обычно используются стандартные файлы запуска, если не используется параметр -nostartfiles.
Компилятор может генерировать вызовы memcmp, memset, memcpy и memmove. Эти записи обычно разрешаются записями в libc. Эти точки входа должны предоставляться через какой-либо другой механизм, если указан этот параметр.
Кстати, мне нужен способ создания и добавления файлов запуска, возможный способ в это руководство, но я добавляю вознаграждение, чтобы получить ответ на мой вопрос и иметь общее решение для всех. Я считаю это полезным для людей, которые хотят настраивать и изучать файлы кросс-компиляции, сборки и запуска.
Обновление 2
Использование ассемблерного кода start.S:
.text
.align 4
.global _start
.global _exit
_start:
mov fp, #0 /* frame pointer */
ldr a1, [sp] /* 1st arg = argc */
add a2, sp, #4 /* 2nd arg = argv */
bl main
_exit:
mov r7, #1 /* __NR_exit */
swi 0
.type _start,function
.size _start,_exit-_start
.type _exit,function
.size _exit,.-_exit
указать точку входа, предоставленную arsv, и выполнить компиляцию с помощью команды:
arm-none-eabi-gcc -nostdlib -o main main.c start.S
кажется, работает правильно. Обновление CMakeLists.txt:
#Directly works:
#arm-none-eabi-gcc -nostdlib -o main main.c start.S
cmake_minimum_required(VERSION 3.4)
SET(PROJ_NAME arm-hello-world-nostdlib)
# Assembler files (.S) in the source list are ignored completely by CMake unless we
# “enable” the assembler by telling CMake in the project definition that we’re using assembly
# files. When we enable assembler, CMake detects gcc as the assembler rather than as – this
# is good for us because we then only need one set of compilation flags.
PROJECT(${PROJ_NAME} C ASM)
# Include directories with headers
#---------------------------------------------------#
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/include )
# Source
#---------------------------------------------------#
FILE(GLOB ${PROJ_NAME}_SRC
"src/start.S"
"src/*.c"
)
FILE(GLOB ${PROJ_NAME}_HEADERS
"include/*.h"
)
# Create Exe
#---------------------------------------------------#
ADD_EXECUTABLE(${PROJ_NAME} ${${PROJ_NAME}_SRC} ${${PROJ_NAME}_HEADERS} )
# Specify libraries or flags to use when linking a given target.
#---------------------------------------------------#
TARGET_LINK_LIBRARIES(${PROJ_NAME} -nostdlib --specs=rdimon.specs -lm -lrdimon)
Если у вас возникают проблемы со связыванием, такие как:
arm-none-eabi/bin/ld: error: CMakeFiles/arm-hello-world-nostdlib.dir/src/main.c.obj: Conflicting CPU architectures 1/13
Это проблема с набором инструментов, для cortex-a9 работает с использованием:
set(CMAKE_C_FLAGS
"${CMAKE_C_FLAGS}"
"-mcpu=cortex-a9 -march=armv7-a -mthumb"
"-mfloat-abi=softfp -mfpu=fpv4-sp-d16"
)
-nostdlib
с-lc
. Вы должны решить, нужна ли вам libc, и в этом случае не используйте-nostdlib
, или если она вам не нужна, то не используйте-lc
и установите точку входа с помощью опции компоновщика. - person Jester   schedule 01.04.2016-e main
. - person Jester   schedule 01.04.2016-e main
, вам нужно настроить стек и, возможно, предоставитьargv
иargc
, а также любую инициализацию библиотечного типа, которая может понадобиться вашему приложению. Кроме того, если вы работаете в такой ОС, как Linux (или BSD), вам нужно вызватьexit(main_return_value);
. - person artless noise   schedule 02.04.2016-nostdlib
вы не получите в своем коде стандартную библиотеку c++. - person arrowd   schedule 04.04.2016