How to use Cmake to build binaries with NASM

こ雲淡風輕ζ 提交于 2020-06-12 12:16:35

问题


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

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()

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?

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

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


回答1:


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

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>

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>")

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)

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)

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().

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")

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.




回答2:


CMake defaults to trying to use the compiler (in this case nasm) as the linker. Obviously nasm doesn't know anything about linking, so you have to override that setting by specifying which linker to use for your ASM_NASM language.

As for specifying the language for your source files, you could do something like this:

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})

That way you only have to list all the files once.



来源:https://stackoverflow.com/questions/56420035/how-to-use-cmake-to-build-binaries-with-nasm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!