Как связать универсальный ЭЛТ Windows с файлом obj, скомпилированным с помощью nasm
Окружение: Windows 10. Я использую версию MinGW ld
для связи, но я счастлив использовать визуальную студию 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
При попытке связать его с Windows CRT (ucrt.lib), я получаю следующую ошибку:
$ ld -o test.exe test.obj
test.obj:test.nasm:(.text+0x6): undefined reference to `printf'
Итак, мне нужно указать компоновщик на библиотеку 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'
Попробуем аналог с визуальным компоновщиком студии:
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
? Я понимаю, что есть соглашение о подчеркивании, но оно не понимается обоими компоновщиками.я использовал
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
появляется в списке. Значит ли это, что эта библиотека не экспортируется? Если нет, на какую библиотеку я должен ссылаться?
Согласно этой статье MS, ucrt.lib
является де-факто библиотекой для среды выполнения c и стандартной библиотеки C.
1 ответ
Благодаря комментарию Майкла Петча, похоже, мне нужно вручную связать 1 или несколько дополнительных библиотек, которые находятся в совершенно отдельном месте от ucrt.lib
библиотека. Соответствующим для printf является legacy_stdio_definitions.lib
, который я нашел в поддиректории моего каталога установки VS2017, в отличие от ucrt.lib
который находится в каталоге установки Windows SDK.
Определение printf
предоставляется встроенным в stdio.h
если макрос _NO_CRT_STDIO_INLINE
определяется, что я думаю, это обычно при сборке внутри VS Toolchain.