静态链接时为什么需要* .obj文件?

时间:2009-05-21 01:40:22

标签: c++ visual-studio-2008 static-linking

我不知道为什么会这样。我在多个项目中分发静态* .lib,但是这个静态lib会生成许多* .obj文件。好像我需要用* .lib分发那些* .obj文件。否则,我收到此错误:

1>LINK : fatal error LNK1181: cannot open input file 'nsglCore.obj'

这是为什么?有没有办法将数据包含在* .lib中的* .obj文件中?也许是编译器中的一个开关?

这是我对静态库的配置:

C / C ++

/Od /GT /D "WIN32" /D "NDEBUG" /D "_LIB" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /MD /Yu"stdafx.hpp" /Fp"e:\Development\Projects\nsGameLib\Source\Core\Intermediate\nsglCore-Win32-Release.pch" /Fo"e:\Development\Projects\nsGameLib\Source\Core\Intermediate\\" /Fd"e:\Development\Projects\nsGameLib\Source\Core\Intermediate\vc90-Release.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt

/OUT:"e:\Development\Projects\nsGameLib\Source\Core\Output\nsglCore-Win32-Release.lib" /NOLOGO /LTCG

这是我使用静态库的项目配置:

C / C ++

/O2 /Oi /I "E:\Development\Projects\nsGameLib\Samples\\DummyEngine\\" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /FD /EHsc /MD /Gy /Fo"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\\" /Fd"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\vc90-Release.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt

链接器

/OUT:"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Output\SampleOnlyCore-Win32-Release.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:"E:\Development\Projects\nsGameLib\Samples\..\Deployment\Libraries" /MANIFEST /MANIFESTFILE:"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\SampleOnlyCore-Win32-Release.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"e:\Development\Projects\nsGameLib\Samples\OnlyCore\Intermediate\SampleOnlyCore-Win32-Release.pdb" /SUBSYSTEM:WINDOWS /OPT:REF /OPT:ICF /LTCG /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT nsglCore  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

3 个答案:

答案 0 :(得分:5)

我认为您的链接器行不正确。该库应该有一个.lib后缀。因此,nsglCore应为nsglCore-Win32-Release.libnsglCore-$(TargetPlatform)-$(ConfigurationName).lib或正确的宏扩展。

答案 1 :(得分:4)

通常,静态库生成目标文件。你要做的是创建目标文件并将它们放在一个库中,然后链接器将搜索那些库中的目标文件。

我将从UNIXy命令行的角度进行解释,因为这样做更简单(我不知道VS在做基本的事情之前做了什么)。

用于创建可执行文件的示例命令行是:

gcc -c -o prog.o prog.c
gcc -o prog prog.o -L/libdir -lstdc

第一行只是从C文件创建一个目标文件。第二行通过将对象文件拉到一起来创建可执行文件,通常遵循以下规则集:

  • 明确列出的所有.o文件都已关联。
  • 完成后,您可以在库中搜索满足引用但未定义的符号的其他对象。

例如,假设您的prog.c包含行printf("hello\n");。这将导致您的prog.o文件包含对printf的引用尚未满足。

链接器将搜索指定的库,直到它满足该引用。在这种情况下,它将搜索/libdir/libstdc.ext格式的所有文件,其中:

  • /libdir来自您的-L选项(搜索库的路径)。
  • /lib是常数。
  • stdc是要搜索的库的名称(来自-l)。
  • ext是一个或多个扩展程序(.a, .so, .sl等)。

找到符号后,将链接该对象文件以解析它。这可能会导致出现更多不满足的符号,例如/libdir/libstdc.a(printf.o)引用/libdir/libstdc.a(putch.o)

您的特定问题可能是由于您尝试直接链接目标文件而不是搜索库。 VS应该有项目选项来指定目标文件,库搜索路径库名称(对于最新版本我不确定,但我知道早期版本的MSVC确实如此)。

答案 2 :(得分:3)

啊......视觉工作室对你来说太聪明了

转到包含lib的项目,右键单击属性

转到配置属性|接头

靠近底部:使用库依赖项输入 - 设置为否

这是一个直接获取.obj文件的Visual Studio选项,而不是.lib文件。我想这是为了避免链接步骤,从而加快编译速度。

通常,您应该将创建lib文件的项目设置为使用它的项目的依赖项(在该属性窗口的公共属性下)。然后,您打开链接库Dependancies。这在大多数情况下效果很好。