如何使用Cmake与NASM生成二进制文件 [英] How to use Cmake to build binaries with NASM

查看:586
本文介绍了如何使用Cmake与NASM生成二进制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习x64,但我讨厌make,所以我试图让cmake用NASM构建二进制文件.

I'm learning x64 and I hate make, so I'm trying to get cmake to build binaries with NASM.

cmake大致支持此功能,但是文档很糟糕.这就是我现在正在通过将堆栈溢出中的内容整理在一起,然后切掉所有不会破坏构建的东西而进行的工作:

This is roughly supported by cmake but the documentation is crap. This is what I have working right now by cobbling together stuff from stack overflow and then cutting out everything that doesn't break the build:

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进行链接,并且有更好的方法吗?

So a few questions, why do I have to tell cmake to use ld to link and is there a better way to do it?

是否可以使用target_object_format的行来指定对象格式,而不是全局设置?

Is there something along the lines of target_object_format I can use to specify the object format instead of setting it globally?

是否有一种方法可以使cmake识别新的扩展名,而不是专门告诉它每个文件都是ASM_NASM?

Is there a way to make cmake recognize a new extension instead of specifically telling it each file is ASM_NASM?

推荐答案

从源头来看,ASM构建仅由

Looking at the source, ASM builds are controlled only by this set of poorly documented environment variables.

Michael正确指出,默认情况下,CMAKE_ASM_LINK_EXECUTABLE定义为:

Michael correctly pointed out that by default, CMAKE_ASM_LINK_EXECUTABLE is defined to:

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

这感觉像是个错误,因为nasm不会链接,也没有记录您需要更改此环境变量.因此,要使用ld,我们需要设置:

This feels like a bug, since nasm doesn't do linking and it's not documented that you need to change this environment variable. So to use ld we need to set:

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

接下来是源文件扩展名,默认情况下为 cmake仅识别.asm.nasm .如果要扩展它,可以使用关联的环境变量来实现:

Next up is the source file extensions, by default cmake only recognizes .asm and .nasm. If we want to extend this, we can do so by using the associated environment variable:

set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} s S)

最后一个对象格式,不幸的是,它也是

Lastly the object format, unfortunately this too is controlled by an environment variable, so we can either change it globally by using:

set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)

或者我们可以通过重新定义CMAKE_ASM_NASM_COMPILE_OBJECT并创建我们自己的属性来获得更精细的控制(我不明白为什么cmake本身不能做到这一点):

Or we can get more fine grained control by redefining CMAKE_ASM_NASM_COMPILE_OBJECT and creating our own property (I don't understand why this isn't done by cmake on its own):

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之前,每次通过enable_language()project()启用ASM_NASM时,都会覆盖CMAKE_ASM_NASM_COMPILE_OBJECT.在版本> 3.15中,不需要enable_language()调用,并且可以在project()中正常启用该语言.

Prior to cmake 3.15, everytime you enable ASM_NASM through enable_language() or project() you'll overwrite CMAKE_ASM_NASM_COMPILE_OBJECT. In versions >3.15 the enable_language() call isn't necessary and the language can be enabled normally in project().

奖金,CMAKE_ASM_NASM_FLAGS_DEBUG默认为空,请随时将其设置为合理:

Bonus, CMAKE_ASM_NASM_FLAGS_DEBUG is empty by default so feel free to set it to something sane:

set(CMAKE_ASM_NASM_FLAGS_DEBUG "-g -Fdwarf")

老实说,cmake中对ASM的支持似乎有些不成熟.显然,它比Make或Automake更好,但不像您希望的那样平滑地支持现代" cmake的成语.

Honestly, the ASM support in cmake seems half-baked. It's clearly better than Make or Automake, but doesn't support the idioms of "modern" cmake as smoothly as you would like.

这篇关于如何使用Cmake与NASM生成二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆