为何设置x64架构后链接器仍在x86目录查找LIBCMT.lib?
环境配置
Windows 10
目标
我找到一款用于S7协议通信的libnodave库,正尝试通过修改后的Makefile编译x64架构的示例程序。
问题
尽管已设置x64库目录(VER=64),但链接器仍在x86目录中查找LIBCMT.lib,这是为什么?将VER=86设置为x86时一切正常。
链接日志关键部分:
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x86\LIBCMT.lib : warning LNK4272: library machine type 'x86' conflicts with target machine type 'x64'
Makefile内容:
# # Makefile to build a Windows Version of LIBNODAVE using MSVC++ from Microsoft. # # The directory where the tools are: VCPATH=C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705 SDKPATH=C:\Program Files (x86)\Windows Kits\10 VER=64 CC="$(VCPATH)\bin\Hostx$(VER)\x$(VER)\cl" LL="$(VCPATH)\bin\Hostx$(VER)\x$(VER)\link" CFLAGS= -I"$(VCPATH)\include" -I"$(SDKPATH)\Include\10.0.20348.0\um" -I"$(SDKPATH)\Include\10.0.20348.0\shared" -I"$(SDKPATH)\Include\10.0.20348.0\ucrt" -c -DBCCWIN -DDAVE_LITTLE_ENDIAN -TC LLFLAGS= /LIBPATH:"$(VCPATH)\lib\x$(VER)" /LIBPATH:"$(SDKPATH)\Lib\10.0.20348.0\ucrt\x$(VER)" /LIBPATH:"$(SDKPATH)\Lib\10.0.20348.0\um\x$(VER)" /DEF:libnodave.DEF PROGRAMS=testISO_TCP.exe testISO_TCPload.exe LIBRARIES=libnodave.dll all: $(LIBRARIES) $(PROGRAMS) libnodave.dll: nodave.obj setportw.obj openSocketw.obj openS7online.obj $(LL) $(LLFLAGS) /DLL nodave.obj setportw.obj openSocketw.obj openS7online.obj "$(SDKPATH)\Lib\10.0.20348.0\um\x$(VER)\WS2_32.Lib" /OUT:libnodave.dll testISO_TCP.exe: nodave.obj openSocketw.obj testISO_TCP.obj $(LL) $(LFLAGS) testISO_TCP.obj openSocketw.obj nodave.obj "$(SDKPATH)\Lib\10.0.20348.0\um\x$(VER)\WS2_32.Lib" /OUT:$@ testISO_TCPload.exe: nodave.obj openSocketw.obj testISO_TCPload.obj $(LL) $(LFLAGS) testISO_TCPload.obj openSocketw.obj nodave.obj "$(SDKPATH)\Lib\10.0.20348.0\um\x$(VER)\WS2_32.Lib" /out:testISO_TCPload.exe # # delete all but the sources: # clean: del /f /q *.tds *.il? *.obj *.map *.lib *.dll *.exe *.exp distclean: del /f /q *.tds *.il? *.obj *.map nodave.obj: nodave.c nodave.h $(CC) $(CFLAGS) -DDOEXPORT nodave.c setportw.obj: setportw.c $(CC) $(CFLAGS) -DDOEXPORT setportw.c openSocketw.obj: openSocketw.c $(CC) $(CFLAGS) -DDOEXPORT openSocketw.c openS7online.obj: openS7online.c openS7online.h $(CC) $(CFLAGS) -DDOEXPORT openS7online.c s7fake.obj: s7fake.c $(CC) $(CFLAGS) -DDOEXPORT s7fake.c
问题原因及修复方案
核心问题:变量名拼写错误
编译testISO_TCP.exe和testISO_TCPload.exe时,链接命令里误用了未定义的LFLAGS变量,而非正确的LLFLAGS。由于LFLAGS未定义,链接器无法读取你配置的x64库路径,只能默认去x86目录查找库文件,最终引发架构冲突警告。
修复步骤
直接修改Makefile中两个示例程序的链接规则:
- 将
testISO_TCP.exe规则里的$(LFLAGS)替换为$(LLFLAGS) - 将
testISO_TCPload.exe规则里的$(LFLAGS)替换为$(LLFLAGS)
修改后的规则如下:
testISO_TCP.exe: nodave.obj openSocketw.obj testISO_TCP.obj $(LL) $(LLFLAGS) testISO_TCP.obj openSocketw.obj nodave.obj "$(SDKPATH)\Lib\10.0.20348.0\um\x$(VER)\WS2_32.Lib" /OUT:$@ testISO_TCPload.exe: nodave.obj openSocketw.obj testISO_TCPload.obj $(LL) $(LLFLAGS) testISO_TCPload.obj openSocketw.obj nodave.obj "$(SDKPATH)\Lib\10.0.20348.0\um\x$(VER)\WS2_32.Lib" /out:testISO_TCPload.exe
额外建议
- 编译前执行
make clean清理旧的x86目标文件,避免残留的32位obj干扰64位编译 - 可在
LLFLAGS中添加/MACHINE:X64,显式指定目标架构,进一步确保编译正确性:LLFLAGS= /LIBPATH:"$(VCPATH)\lib\x$(VER)" /LIBPATH:"$(SDKPATH)\Lib\10.0.20348.0\ucrt\x$(VER)" /LIBPATH:"$(SDKPATH)\Lib\10.0.20348.0\um\x$(VER)" /DEF:libnodave.DEF /MACHINE:X64
内容的提问来源于stack exchange,提问作者PiotrBzdrega
相关产品推荐
相关产品推荐

