Как использовать Cmake для создания бинарных файлов с NASM - PullRequest
0 голосов
/ 03 июня 2019

Я изучаю x64 и ненавижу make, поэтому я пытаюсь заставить cmake создавать двоичные файлы с помощью NASM.

Это примерно поддерживается cmake, но документация - дерьмо. Это то, над чем я сейчас работаю, объединяя вещи из переполнения стека, а затем вырезая все, что не нарушает сборку:

cmake_minimum_required(VERSION 3.14)

set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)

project(test_project ASM_NASM)

set_source_files_properties(test.s PROPERTIES LANGUAGE ASM_NASM)
add_executable(test test.s)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    target_compile_options(test PRIVATE -g -Fdwarf)
endif()

Итак, несколько вопросов, почему я должен сказать cmake использовать ld для ссылки, и есть ли лучший способ сделать это?

Есть ли что-то вроде target_object_format, который я могу использовать, чтобы указать формат объекта вместо того, чтобы устанавливать его глобально?

Есть ли способ заставить cmake распознавать новое расширение вместо того, чтобы специально указывать ему, что каждый файл - ASM_NASM?

Ответы [ 2 ]

1 голос
/ 03 июня 2019

Глядя на источник, сборки ASM управляются только этим набором плохо документированных переменных среды .

Майкл правильно указал , что по умолчанию CMAKE_ASM_LINK_EXECUTABLE определяется как:

<CMAKE_ASM_NASM_COMPILER> <FLAGS> <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>

Это похоже на ошибку, поскольку nasm не выполняет связывание и не задокументировано, что вам нужно изменить эту переменную среды.Таким образом, чтобы использовать ld, нам нужно установить:

set(CMAKE_ASM_NASM_LINK_EXECUTABLE "ld <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS>  -o <TARGET> <LINK_LIBRARIES>")

Далее следуют расширения исходного файла, по умолчанию cmake распознает только .asm и .nasm.Если мы хотим расширить это, мы можем сделать это, используя связанную переменную окружения:

set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} s S)

Наконец, формат объекта, к сожалению, это тоже , управляемое переменной окружения , поэтому мыможно либо изменить его глобально, используя:

set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)

, либо мы можем получить более точный контроль, переопределив CMAKE_ASM_NASM_COMPILE_OBJECT и создав наше собственное свойство (я не понимаю, почему cmake не делает этогосвой собственный):

enable_language(ASM_NASM)
set(CMAKE_ASM_NASM_COMPILE_OBJECT "<CMAKE_ASM_NASM_COMPILER> <INCLUDES> <FLAGS> -o <OBJECT> <SOURCE>")

# Create a compile option that operates on ASM_NASM files
# If the target has a property NASM_OBJ_FORMAT, use it, otherwise
# use the environment variable CMAKE_ASM_NASM_OBJECT_FORMAT
add_compile_options(
    "$<$<COMPILE_LANGUAGE:ASM_NASM>:-f $<IF:$<BOOL:$<TARGET_PROPERTY:NASM_OBJ_FORMAT>>, \
    $<TARGET_PROPERTY:NASM_OBJ_FORMAT>, ${CMAKE_ASM_NASM_OBJECT_FORMAT}>>"
)


add_executable(test test.S)
set_target_properties(test PROPERTIES NASM_OBJ_FORMAT elf64)

До cmake 3.15 каждый раз, когда вы включаете ASM_NASM - enable_language() или project(), вы перезаписываете CMAKE_ASM_NASM_COMPILE_OBJECT.В версиях> 3.15 вызов enable_language() не требуется, и язык можно нормально включить в project().

Bonus, CMAKE_ASM_NASM_FLAGS_DEBUG по умолчанию пусто, поэтому не стесняйтесь устанавливать его на что-то вменяемое:

set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -Fdwarf")

Честно говоря, поддержка ASM в cmake кажется недоделанной.Это явно лучше, чем Make или Automake, но не поддерживает идиомы «современного» cmake так гладко, как хотелось бы.

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

CMake по умолчанию пытается использовать компилятор (в данном случае nasm) в качестве компоновщика. Очевидно, что nasm ничего не знает о связывании, поэтому вы должны переопределить этот параметр, указав, какой компоновщик использовать для вашего ASM_NASM языка.

Что касается указания языка для ваших исходных файлов, вы можете сделать что-то вроде этого:

set(SOURCE_FILES test.s foo.s bar.s)  # etc for all source files
set_source_files_properties(${SOURCE_FILES) PROPERTIES LANGUAGE ASM_NASM)
add_executable(test ${SOURCE_FILES})

Таким образом, вы должны перечислить все файлы только один раз.

...