cmake: порядок связи внешних (сгенерированных) и скомпилированных объектов и библиотек - PullRequest
2 голосов
/ 11 июня 2019

Я играю с голым металлом x86 и наткнулся на препятствие, портирующее мою сборку с простых make-файлов на cmake.

В моем make-файле мои объекты определены так:

LINK_LIST=\
$(LDFLAGS) \
$(ARCHDIR)/crti.o \
$(ARCHDIR)/crtbegin.o \
$(KERNEL_OBJS) \
$(LIBS) \
$(ARCHDIR)/crtend.o \
$(ARCHDIR)/crtn.o \

crtbegin.o и crtend.o 'генерируются', то есть предоставлены моим кросс-компилятором (флаг -print-file-name).$ (LIBS) - это флаги -l, например -lgcc и т. Д. Так как это передается непосредственно компоновщику, порядок соответствует указанному.

Моя цель cmake определяется следующим образом:

ADD_EXECUTABLE(loader 
    "${INIT_SRC}"
    "${INIT_OBJ}"
    "${PLATFORM_SRCS}"
    "${ISA_SRCS}"
    "${GENERIC_SRCS}"
    "${FINI_OBJ}"
    "${FINI_SRC}")

INIT_OBJ и FINI_OBJ имеют EXTERNAL_OBJECT и GENERATED, установленный в true в свойствах исходного файла.Глядя на командную строку при запуске сгенерированного make-файла, я вижу, что все исходные файлы находятся в указанном порядке, но объекты init и fini являются последними в списке.

Вот результирующая командная строка (отредактировано для краткости):

i686-elf-gcc -nostdlib -ffreestanding -nostdinc -T linker.ld -lgcc crti.s.obj boot.s.obj loader.c.obj crtn.s.obj crtbegin.o crtend.o -o loader

Флаг -lgcc явно указан в моих LINK_FLAGS, и это тоже то, что я хотел бы изменить.

Поэтому у меня есть несколько вопросов по этому поводу.:

  1. Почему cmake не использует порядок для двух внешних объектных файлов, а использует его для скомпилированных?

  2. Какя могу сказать cmake обрабатывать эти объекты так же, как те, которые приходят из моих источников?

  3. Как я могу получить полный клон установки, которую я имею в моем Makefile (с флагами библиотекимежду моими объектными файлами)

Я также проверил CMAKE_C_LINK_EXECUTABLE, но, похоже, для достижения этого не хватает гранулярности / контроля над параметрами компоновщика.

я использую cmake 3.10.2 в Ubuntu.

И еще один (не по теме) вопрос о cmake:

.S не рассматривается как стандартное расширение файла сборки.Я попытался добавить его с помощью LIST(APPEND CMAKE_ASM-ATT_SOURCE_FILE_EXTENSIONS S), и он добавляет его просто отлично, однако файлы по-прежнему не компилируются, пока я не изменю его на .s.У кого-нибудь еще была такая проблема?

Спасибо!

1 Ответ

0 голосов
/ 11 июня 2019

Объекты crtbegin.o и crtend.o, которые предъявляют особые требования к позиции в команде ссылки, могут рассматриваться как часть toolchain . Если вы решите это, то вы можете установить переменную CMAKE_C_LINK_EXECUTABLE, чтобы отразить это конкретное значение:

SET(ARCHDIR "<...>")
# Object 'crtbegin.o' will be linked before all other objects and libraries.
# Object 'crtend.o' will be linked after all other objects and libraries.
SET(CMAKE_C_LINK_EXECUTABLE "<CMAKE_C_COMPILER> <FLAGS> <CMAKE_C_LINK_FLAGS> 
    <LINK_FLAGS>
    ${ARCHDIR}/crtbegin.o
    <OBJECTS> -o <TARGET> <LINK_LIBRARIES>
    ${ARCHDIR}/crtend.o")

Эта настройка должна быть сделана в файле цепочки инструментов, который передается в cmake с опцией -DCMAKE_TOOLCHAIN=<path/to/toolchain/file>.

С таким набором инструментов в CMakeLists.txt вы можете просто написать

ADD_EXECUTABLE(loader ${PLATFORM_SRCS} ${ISA_SRCS} ${GENERIC_SRCS})

Используя переменную CMAKE_C_LINK_EXECUTABLE, вы также можете позиционировать такие опции, как

-nostdlib -ffreestanding -nostdinc -T linker.ld -lgcc

, которые тоже очень связаны с набором инструментов.

Смотрите также эту рассылку: https://cmake.org/pipermail/cmake/2010-June/037641.html.

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