assembly - 如何使用 Cmake 用 NASM 构建二进制文件

标签 assembly cmake nasm

我正在学习 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?

最佳答案

查看源代码,ASM 构建仅由 this set of poorly documented environment variables 控制。

Michael correctly pointed out 默认情况下,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 only recognizes .asm and .nasm 。如果我们想扩展它,我们可以通过使用关联的环境变量来实现:
set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} s S)

最后是对象格式,不幸的是这也是 controlled by an environment variable ,所以我们可以使用以下方法全局更改它:
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_NASMenable_language() 启用 project() 时,都会覆盖 CMAKE_ASM_NASM_COMPILE_OBJECT 。在版本 >3.15 中,不需要 enable_language() 调用,并且可以在 project() 中正常启用该语言。

奖励,CMAKE_ASM_NASM_FLAGS_DEBUG 默认为空,所以可以随意将其设置为合理的:
set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -Fdwarf")

老实说,cmake 中的 ASM 支持似乎是半生不熟的。它显然比 Make 或 Automake 更好,但并不像您希望的那样流畅地支持“现代”cmake 的习语。

关于assembly - 如何使用 Cmake 用 NASM 构建二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56420035/

相关文章:

c++ - 编译器误区

assembly - i386 指令 "div ah"毫无意义吗?

cmake - 未知的 CMake 命令 "ExternalProject_Add"

assembly - 在汇编器中写入文件

windows - 连续几个int3

javascript - LMC 改变 y 值

assembly - 从内存中注册的 MOV 不适用于 nasm 中的 BITS 32

linux - 使用 NASM 在 Assembly 中添加 2 个输入的数字

c++ - 将具有循环链接依赖性的 makefile 转换为 CMake

c++ - CMake 和 Visual Studio 构建错误