如何使用Cmake与NASM生成二进制文件 [英] How to use Cmake to build binaries with 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?
推荐答案
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屋!