Github Actions编译C项目时链接<stdio.h>符号失败求助
问题
我通过Github Actions使用Premake5和MsBuild编译一个C项目,编译阶段执行以下命令成功:
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.42.34433\bin\HostX86\x86\CL.exe /c /nologo /W3 /WX- /diagnostics:column /sdl- /O2 /Oi /Oy- /D NDEBUG /D _HAS_EXCEPTIONS=0 /D _WINDLL /GF /Gm- /MD /GS- /Gy /fp:fast /fp:except- /Zc:wchar_t /Zc:forScope /Zc:inline /GR- /Fo"obj\\" /Fd"obj\vc143.pdb" /external:W3 /Gd /TC /analyze- /FC /errorReport:queue /kernel /Gs1000000 ..\dllmain.c
但链接阶段执行以下命令时失败:
C:\Program Files\Microsoft Visual Studio\2022\Enterprise\VC\Tools\MSVC\14.42.34433\bin\HostX86\x86\link.exe /ERRORREPORT:QUEUE /OUT:"..\bin\dinput.dll" /INCREMENTAL:NO /NOLOGO kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST:NO /PDB:"..\bin\dinput.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /TLBID:1 /ENTRY:"DllMain" /RELEASE /DYNAMICBASE /NXCOMPAT /IMPLIB:"..\bin\dinput.lib" /MACHINE:X86 /CETCOMPAT:NO /SAFESEH:NO /kernel /SAFESEH:NO /GUARD:NO /EMITPOGOPHASEINFO /RELEASE /DEBUG:NONE /NOIMPLIB /NOEXP /IGNORE:4104 /DLL obj\dllmain.obj
报错信息如下:
2>dllmain.obj : error LNK2019: unresolved external symbol __imp__fclose referenced in function _DllMain@12 [D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.vcxproj] 2>dllmain.obj : error LNK2019: unresolved external symbol __imp__fflush referenced in function _serverCheck [D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.vcxproj] 2>dllmain.obj : error LNK2019: unresolved external symbol __imp__fopen referenced in function _DllMain@12 [D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.vcxproj] 2>dllmain.obj : error LNK2019: unresolved external symbol __imp__fputs referenced in function _serverCheck [D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.vcxproj] 2>dllmain.obj : error LNK2019: unresolved external symbol __imp____stdio_common_vfprintf referenced in function _fprintf [D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.vcxproj] 2>..\bin\dinput.dll : fatal error LNK1120: 5 unresolved externals [D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.vcxproj] 2>Done Building Project "D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.vcxproj" (default targets) -- FAILED. 1>Done Building Project "D:\a\khaldun.net-client\khaldun.net-client\build\khaldun.net-client.sln" (default targets) -- FAILED.
这是一个已有项目的分支,Github Action由他人配置,我已在主源文件中通过#include <stdio.h>引入头文件,且在本地VS2022开发者PowerShell中执行cl.exe /LD dllmain.c /link /OUT:build\dinput.dll可正常编译。此前我通过#pragma comment解决过其他导入的链接错误,现询问是否有包含stdio C函数的Windows库可显式链接。
解答
这些未解析的stdio函数属于微软C运行时库,你需要显式链接对应的库文件:
- 结合你编译命令中使用的
/MD(动态链接运行时)参数,需要链接ucrt.lib(通用C运行时)和msvcrt.lib(微软C运行时)。
具体解决方法
- 代码中添加
#pragma comment指令
在dllmain.c的头文件引入后添加:
#pragma comment(lib, "ucrt.lib") #pragma comment(lib, "msvcrt.lib")
这种方式和你之前解决其他链接错误的逻辑一致,能让编译器自动将这些库加入链接阶段。
- 修改Premake5配置
找到项目的premake5.lua脚本,在链接库列表中添加这两个库:
links { "kernel32", "user32", "gdi32", -- 保留原有库 "ucrt", "msvcrt" }
修改后MsBuild生成的链接命令会自动包含这些库,从根源解决CI编译的问题。
本地编译正常的原因
本地VS开发者PowerShell中执行cl.exe时,编译器会自动默认链接必要的C运行时库;而Github Actions里的Premake5配置遗漏了这些库的引用,导致链接阶段找不到符号。
内容的提问来源于stack exchange,提问作者Sceadu
相关产品推荐
相关产品推荐

