CMake - связать проект с C объектными файлами времени выполнения в правильном порядке - PullRequest
0 голосов
/ 25 февраля 2020

Имеется C файлов времени выполнения / запуска: crt0.o, crti.o, crtbegin.ocrtend.o, crtn.o.

  • crtbegin.o и crtend.o предоставлено инструментарием (G CC)
  • crt0.o, crti.o и crtn.o реализованы мной в рамках моего проекта.

Проект о запуске исполняемый файл на i686 без поддержки, поэтому без ОС.

Проблема заключается в связывании конечного исполняемого файла - порядок, в котором объектные файлы проекта связаны со всеми файлами времени выполнения C, описанными выше имеет значение.

Моя система сборки - CMake, где я использую команду target_sources для определения исходных файлов, используемых (скомпилированных и затем связанных вместе) для исполняемого файла:

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
)

проблема в том, что G CC не связывается с crtbegin.o и crtend.o, хотя его можно найти в моем наборе инструментов:

  • toolchain/i686-elf/lib/gcc/i686-elf/10.0.1/crtbegin.o
  • toolchain/i686-elf/lib/gcc/i686-elf/10.0.1/crtend.o

Не могли бы вы посоветовать мне, как вызвать компоновщик со всеми необходимыми аргументами в правильном порядке из CMake? Я ожидаю команду ссылки, аналогичную

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

Обратите внимание на порядок C исполняемых файлов. Я упростил структуру директорий всех файлов, но здесь необходимо уловить критический момент.

Заранее большое спасибо всем, кто хочет мне помочь ... Мартин

ОБНОВЛЕНИЕ :

Я пытался исследовать больше параллельно, ожидая каких-либо советов здесь, и многообещающий способ, похоже, использует CMAKE_CXX_LINK_EXECUTABLE для определения спецификаций проекта c правила сборки для связывания.

В моем проекте используется файл цепочки инструментов, который устанавливается перед оператором root / main project (). В рамках подпроекта я установил CMAKE_CXX_LINK_EXECUTABLE, и, похоже, он не имеет последствий для других подпроектов. Вот почему я называю это многообещающим, хотя все это еще не работает.

Мой план состоит в том, чтобы создать библиотеку объектов из трех спецификаций проекта c C исполняемых файлов crt0.o, crti.o и crtn.o, чтобы удалить их из <OBJECTS>, сделать проект зависимым от этой библиотеки объектов, но управлять файлами времени выполнения вручную в рамках правила построения ссылок.

Как вы думаете, этот способ успешно завершится? Я опубликую результаты, как только у меня будет немного ...

1 Ответ

0 голосов
/ 27 февраля 2020

Благодаря @KamilCuk я успешно запустил его. Вот решение, которое я принял (для использования любым, кто пытается решить ту же проблему)

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" )

Пожалуйста, имейте в виду, что приведенный выше код не является решением для копирования и вставки, но завершено, работает над используется как руководство / вдохновение, чтобы делать такие вещи:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...