【问题标题】:Why do I need an *.obj file when statically linking?为什么静态链接时需要 *.obj 文件?
【发布时间】:2009-05-21 01:40:22
【问题描述】:

我不确定这是为什么。我正在跨多个项目分发一个静态 *.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

【问题讨论】:

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


    【解决方案1】:

    我认为您的链接器行不正确。图书馆应该有一个.lib 后缀。所以nsglCore 应该是nsglCore-Win32-Release.lib 或者nsglCore-$(TargetPlatform)-$(ConfigurationName).lib 或者任何正确的宏扩展。

    【讨论】:

    • 20 秒后发现!看我的帖子。但是,这就是答案;)
    【解决方案2】:

    通常,静态库不会生成目标文件。您所做的是创建目标文件并将它们放入库中,然后链接器将在这些库中搜索目标文件。

    我将从 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 有)。

    【讨论】:

    • 好帖子。听起来确实像 MSVC 配置问题。
    • 感谢您提供非常有用的信息,但这并不能解决我的问题。我想知道一种避免 *.obj 依赖的方法。
    【解决方案3】:

    啊……Vis​​ual Studio 对你来说太聪明了

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

    转到配置属性 |链接器

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

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

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

    【讨论】:

      猜你喜欢
      • 2021-10-22
      • 2019-01-16
      • 1970-01-01
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多