Глядя на источник, сборки 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 так гладко, как хотелось бы.