如何让CMake编译一个纯程序集静态共享库?

xam8gpfp  于 2023-02-23  发布在  其他
关注(0)|答案(2)|浏览(231)

bounty将在5天后过期。回答此问题可获得+50的声誉奖励。avighnac正在寻找来自声誉良好来源的答案:如果你能在答案中包含一个完整的例子,包括项目结构和每个相关文件的内容,那就太好了。

这是图书馆。图书馆。

section .text

global return_number
return_number:
  mov eax, 10
  ret

我可以很容易地使用命令行创建一个共享的静态库:

nasm -f elf64 -o library.o library.asm
ld -shared -o libreturn_number.so library.o
ar rcs libreturn_number.a library.o

但是,使用CMake会出现问题。CMakeLists.txt:

enable_language(ASM_NASM)

project(mylibrary)

set(CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY "<CMAKE_ASM_NASM_COMPILER> <CMAKE_SHARED_LIBRARY_CREATE_ASM_NASM_FLAGS> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>")

add_library(mylibrary_static STATIC library.asm)
add_library(mylibrary_shared SHARED library.asm)

静态库工作得非常好,但是共享库会抛出一些奇怪的错误。

CMakeFiles/mylibrary_shared.dir/library.asm.o:1: error: label or instruction expected at start of line
CMakeFiles/mylibrary_shared.dir/library.asm.o:10: error: label or instruction expected at start of line
CMakeFiles/mylibrary_shared.dir/library.asm.o:11: error: label or instruction expected at start of line
CMakeFiles/mylibrary_shared.dir/library.asm.o:12: error: label or instruction expected at start of line
CMakeFiles/mylibrary_shared.dir/library.asm.o:31: warning: label alone on a line without a colon ...

"o“文件中的几乎每一行。

sczxawaw

sczxawaw1#

自定义工具链设置最好在 * 工具链文件 * 中完成。您可以为NASM编写一个工具链文件,并在默认情况下将其附加到项目中,如下所示:

cmake/nasm-toolchain.cmake

# Allow the user to override the object format at the command line
if (NOT DEFINED CMAKE_ASM_NASM_OBJECT_FORMAT)
  set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)
endif ()

# Determine the ld-compatible emulation mode flags, given the
# nasm output format
if (CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "elf64")
  set(extra_flags "-m elf_x86_64")
elseif (CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "elfx32")
  set(extra_flags "-m elf32_x86_64")
elseif (CMAKE_ASM_NASM_OBJECT_FORMAT MATCHES "elf(32)?")
  set(extra_flags "-m elf_i386")
else ()
  set(extra_flags "")
endif ()

set(CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY
    "<CMAKE_LINKER> -shared ${extra_flags} <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")

注意,此处使用<CMAKE_LINKER>是为了允许使用例如lldmold

CMakeLists.txt

cmake_minimum_required(VERSION 3.25)

# Set the toolchain file by default because our use of NASM
# requires special configuration.
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_LIST_DIR}/cmake/nasm-toolchain.cmake"
    CACHE STRING "")

project(example LANGUAGES ASM_NASM)

##
# Project code

add_library(mylib library.asm)

注意,对于many reasons,最好避免为共享库和静态库创建单独的目标,而使用BUILD_SHARED_LIBS
∮ ∮ ∮ ∮ ∮一米六一分
同上,但为完整起见,在此复制:

section .text

global return_number
return_number:
  mov eax, 10
  ret

构建输出:

共享库(64位):

$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=YES
-- The ASM_NASM compiler identification is NASM
-- Found assembler: /usr/bin/nasm
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
$ cmake --build build/ --verbose
[1/2] /usr/bin/nasm -Dmylib_EXPORTS   -MD CMakeFiles/mylib.dir/library.asm.o.d -MT CMakeFiles/mylib.dir/library.asm.o -f elf64 -o CMakeFiles/mylib.dir/library.asm.o /home/alex/test/library.asm
[2/2] : && /usr/bin/ld -shared -m elf_x86_64  CMakeFiles/mylib.dir/library.asm.o -o libmylib.so   && :

共享库(32位):

$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=YES -DCMAKE_ASM_NASM_OBJECT_FORMAT=elf32
-- The ASM_NASM compiler identification is NASM
-- Found assembler: /usr/bin/nasm
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
$ cmake --build build/ --verbose
[1/2] /usr/bin/nasm -Dmylib_EXPORTS   -MD CMakeFiles/mylib.dir/library.asm.o.d -MT CMakeFiles/mylib.dir/library.asm.o -f elf32 -o CMakeFiles/mylib.dir/library.asm.o /home/alex/test/library.asm
[2/2] : && /usr/bin/ld -shared -m elf_i386  CMakeFiles/mylib.dir/library.asm.o -o libmylib.so   && :

静态库:

$ cmake -G Ninja -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=NO
-- The ASM_NASM compiler identification is NASM
-- Found assembler: /usr/bin/nasm
-- Configuring done
-- Generating done
-- Build files have been written to: /home/alex/test/build
$ cmake --build build/ --verbose
[1/2] /usr/bin/nasm    -MD CMakeFiles/mylib.dir/library.asm.o.d -MT CMakeFiles/mylib.dir/library.asm.o -f elf64 -o CMakeFiles/mylib.dir/library.asm.o /home/alex/test/library.asm
[2/2] : && /usr/bin/ar cr libmylib.a  CMakeFiles/mylib.dir/library.asm.o  && /usr/bin/ranlib libmylib.a && :
mm5n2pyu

mm5n2pyu2#

问题是你试图使用nasm编译器来链接对象二进制文件,你应该使用ld链接器甚至gcc,所以nasm正在读取对象文件并说wtf是这样的!
下面的解决方案使用的是与上面相同的asm文件。
对于64位,CMakeLists.txt为

cmake_minimum_required(VERSION 3.12)
set(CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY
  "ld -lc -shared  <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")
set(CMAKE_ASM_NASM_OBJECT_FORMAT elf64)

project(mylibrary)

enable_language(ASM_NASM)

add_library(mylibrary_shared SHARED library.asm)
$ cmake ..
-- The ASM_NASM compiler identification is NASM
-- Found assembler: /usr/bin/nasm
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: ../build
$ make
-- Configuring done
-- Generating done
-- Build files have been written to: /home/hbucher/git/nasm/build
[ 50%] Building ASM_NASM object CMakeFiles/mylibrary_shared.dir/library.asm.o
[100%] Linking ASM_NASM shared library libmylibrary_shared.so
$ ldd libmylibrary_shared.so 
        linux-vdso.so.1 (0x00007ffffb59e000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8bf8822000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8bf8a4a000)

对于32位:

cmake_minimum_required(VERSION 3.12)
set(CMAKE_ASM_NASM_CREATE_SHARED_LIBRARY
  "ld -lc -shared -m elf_i386 <CMAKE_ASM_NASM_LINK_FLAGS> <LINK_FLAGS> <OBJECTS> -o <TARGET> <LINK_LIBRARIES>")

project(mylibrary)

enable_language(ASM_NASM)

add_library(mylibrary_shared SHARED library.asm)

生产

$ cmake ..
-- The ASM_NASM compiler identification is NASM
-- Found assembler: /usr/bin/nasm
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
$ make 
[ 50%] Building ASM_NASM object CMakeFiles/mylibrary_shared.dir/library.asm.o
[100%] Linking ASM_NASM shared library libmylibrary_shared.so
[100%] Built target mylibrary_shared
$ ldd libmylibrary_shared.so 
        linux-gate.so.1 (0xf7f39000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xf7d10000)
        /lib/ld-linux.so.2 (0xf7f3b000)

相关问题