如何link Windows universal CRT to obj file compiled with nasm
How to link Windows universal CRT to obj file compiled with nasm
环境:Windows 10. 我碰巧使用 ld
的 MinGW 版本进行 linking,但我很高兴使用 visual studio link.exe
如果它能让事情变得更简单。
我在nasm中有以下基本程序:
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
并且使用
构建良好
nasm -f win32 test.nasm
当试图 link 它到 windows CRT (ucrt.lib) 时,我收到以下错误:
$ ld -o test.exe test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'
好的,所以我需要将 linker 指向 ucrt 库:
$ ld -o test.exe /c/Program\ Files\ \(x86\)/Windows\
Kits/10/Lib/10.0.14393.0/ucrt/x86/ucrt.lib test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'
尝试使用 visual studio linker 的等价物:
d:\Code\nasm>link -out:test.exe -entry:main -subsystem:console test.obj
Microsoft (R) Incremental Linker Version 14.10.25017.0
Copyright (C) Microsoft Corporation. All rights reserved.
test.obj : error LNK2001: unresolved external symbol _printf
test.exe : fatal error LNK1120: 1 unresolved externals
这提出了几个问题:
为什么其中一个试图找到 printf
而另一个 _printf
?我知道有一个下划线约定,但 link 两个人似乎都不理解。
我用objdump -t
查看了ucrt.lib文件中的符号。我不会粘贴整个列表,但它包含如下条目:
[ 4](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp____conio_common_vcprintf
[ 5](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 ___conio_common_vcprintf
[ 4](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp____conio_common_vcprintf_p
printf
和 _printf
均未出现在列表中。这是否意味着它不是由该库导出的?如果不是,我应该 linking 哪个图书馆?
根据this MS article,ucrt.lib
是c运行时和C标准库的实际库。
感谢 Michael Petch 的评论,看来我需要手动 link 1 个或多个额外的库,这些库位于与 ucrt.lib
库完全不同的位置。与 printf 相关的是 legacy_stdio_definitions.lib
,我在 VS2017 安装目录的子目录深处找到了它,而不是 Windows SDK 安装目录中的 ucrt.lib
。
printf
的定义在 stdio.h
中内联提供,除非定义了宏 _NO_CRT_STDIO_INLINE
,我猜这通常是在 VS 工具链内部构建时定义的。
环境:Windows 10. 我碰巧使用 ld
的 MinGW 版本进行 linking,但我很高兴使用 visual studio link.exe
如果它能让事情变得更简单。
我在nasm中有以下基本程序:
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
并且使用
构建良好nasm -f win32 test.nasm
当试图 link 它到 windows CRT (ucrt.lib) 时,我收到以下错误:
$ ld -o test.exe test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'
好的,所以我需要将 linker 指向 ucrt 库:
$ ld -o test.exe /c/Program\ Files\ \(x86\)/Windows\
Kits/10/Lib/10.0.14393.0/ucrt/x86/ucrt.lib test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'
尝试使用 visual studio linker 的等价物:
d:\Code\nasm>link -out:test.exe -entry:main -subsystem:console test.obj
Microsoft (R) Incremental Linker Version 14.10.25017.0
Copyright (C) Microsoft Corporation. All rights reserved.
test.obj : error LNK2001: unresolved external symbol _printf
test.exe : fatal error LNK1120: 1 unresolved externals
这提出了几个问题:
为什么其中一个试图找到
printf
而另一个_printf
?我知道有一个下划线约定,但 link 两个人似乎都不理解。我用
objdump -t
查看了ucrt.lib文件中的符号。我不会粘贴整个列表,但它包含如下条目:
[ 4](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp____conio_common_vcprintf
[ 5](sec 3)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 ___conio_common_vcprintf
[ 4](sec 1)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 __imp____conio_common_vcprintf_p
printf
和 _printf
均未出现在列表中。这是否意味着它不是由该库导出的?如果不是,我应该 linking 哪个图书馆?
根据this MS article,ucrt.lib
是c运行时和C标准库的实际库。
感谢 Michael Petch 的评论,看来我需要手动 link 1 个或多个额外的库,这些库位于与 ucrt.lib
库完全不同的位置。与 printf 相关的是 legacy_stdio_definitions.lib
,我在 VS2017 安装目录的子目录深处找到了它,而不是 Windows SDK 安装目录中的 ucrt.lib
。
printf
的定义在 stdio.h
中内联提供,除非定义了宏 _NO_CRT_STDIO_INLINE
,我猜这通常是在 VS 工具链内部构建时定义的。