Link 一个程序到一个静态库,将自己链接到另一个库
Link a program to a static library, linking itself to another library
我正在尝试在 Windows (VS2015) 上创建一个可以读取多种文件格式的程序 (C++)。
为此,我创建了一个解决方案,其中包含一个用于 MyProgram 的项目(这是主程序)和一个用于 MyLibrary 的项目(其中包含多个用于不同文件格式的解析器)。
在 MyProgram 中,我根据程序输入创建了一些解析器 objects。
一切正常。
但是,我尝试创建一个新的文件格式解析器 (NiftiParser),它使用我下载并编译(作为静态库)的外部库 nifticlib。
所以我创建了我的 NiftiParser class,它实现了一些方法,并且在内部调用了 nifticlib。
我在项目属性中添加了 include 目录和 library 目录,并且编译没有错误。
然后我得到了一个已经创建的Parser.lib。
然而,当我尝试编译 MyProgram 时,我得到一个关于 nifticlib 库的一些函数没有被解析的错误:
1>------ Build started: Project: Parser, Configuration: Debug x64 ------
1> nifti_parser.cc
1> Parser.vcxproj -> C:\Users\Laurent\Documents\C++-build\Projects\Parser\Debug\Parser.lib
2>------ Build started: Project: MyProgram, Configuration: Debug x64 ------
2>Parser.lib(nifti_parser.obj) : error LNK2019: unresolved external symbol nifti_image_read referenced in function "public: __cdecl NiftiParser::NiftiParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0NiftiParser@@QEAA@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
2>C:\Users\Laurent\Documents\C++-build\Projects\Debug\MyProgram.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 1 succeeded, 1 failed, 3 up-to-date, 0 skipped ==========
我不确定为什么会这样。我试图将include路径和nifticlib的库目录添加到MyProgram项目中,但我仍然遇到一些问题。
我不确定 Visual Studio 的 compilation/linking 过程是什么(我曾经在 Linux 上工作)。
在我看来,只有当项目是静态库时才会编译项目,而 linking 部分只会在我尝试编译程序本身时发生。
我说得对吗?
此外,我不确定 nifticlib 应该放在哪里 link。应该到 Parser.lib(我在其中使用库的函数)还是直接到程序?
谢谢。
PS:我还注意到我的 nifticlib 安装目录只包含 headers 和 .lib。我是否也需要在其中包含 .cpp,或者函数是否已包含在 .lib 中?
编辑: 好吧,显然将某些东西构建为静态库并没有 link 它对任何东西,所以这可能就是为什么我没有遇到任何编译问题Parser.lib,因为它不link到nifticlib,但是MyProgram需要它。
那么我应该只在我的 Parser 项目中包含 nitficlib 的 include 目录,并将 Parser.lib 和 nifticlib 放在我的 MyProgram 项目中吗?
Visual Studio 的 compilation/linking 与 Linux 工具链中发生的事情没有太大区别。当您制作二进制文件(可执行文件或动态库)时,必须解析所有外部符号。在 GCC 中,您必须向 linker 指明这些库。命令行选项 -lmath
将告诉 linker 从为库搜索设置的路径之一加载 libmath.a 并在构建可执行文件时使用它图片。
同样,在VS中不仅需要设置库目录的路径,还需要明确指明库文件。这通常在项目属性 -> 链接器 -> 输入 -> 附加依赖项上完成。请注意,在 Windows 中,您只需输入完整的库名称 (MyLib.lib),而不是 lib 和.a
另请注意,在 Windows 中,您不能 link 动态库 (.dll) 的二进制文件。您将需要一个导入库 (.lib)。
创建静态库时,工具链不解析外部引用。这就是为什么你 .lib 没有引用 nifticlib 就编译得很好的原因。
至于linknifticlib应该放在哪里,要看情况。如果只有你的 MyLibrary 将永远使用 nifticlib 的功能,那么 link 它与你的静态库是明智的。但是,如果有一天您希望直接在 MyProgram 中使用 nifticlib 中的某些函数,则可能会在 link 时发生冲突。在这种情况下,只有在构建 MyProgram 时才需要 link nifticlib。
经验法则可以这样表述:
- 如果只有 MyLibrary 使用 headers 的 nifticlib,link 你的图书馆与第三方
- 如果 MyProgram 也使用了 nifticlib 的 headers(并且实际调用了它们的函数),那么在构建 MyProgram 时最好 link nifticlib
这里描述的不严格,还有比较复杂的情况,但基本都是这样。
不,当您从另一个项目 linking 到该库时,您不需要构建静态库时使用的 cpp 文件。 .cpp 库的内容已经以 object 代码的形式包含在静态库文件中。
编辑: 如果您确实希望 link 您的静态库与来自另一个静态库的外部对象,您需要转到项目属性 -> 图书管理员 ->常规 -> 附加依赖项并将外部 .lib 放在那里
我正在尝试在 Windows (VS2015) 上创建一个可以读取多种文件格式的程序 (C++)。 为此,我创建了一个解决方案,其中包含一个用于 MyProgram 的项目(这是主程序)和一个用于 MyLibrary 的项目(其中包含多个用于不同文件格式的解析器)。 在 MyProgram 中,我根据程序输入创建了一些解析器 objects。
一切正常。
但是,我尝试创建一个新的文件格式解析器 (NiftiParser),它使用我下载并编译(作为静态库)的外部库 nifticlib。
所以我创建了我的 NiftiParser class,它实现了一些方法,并且在内部调用了 nifticlib。 我在项目属性中添加了 include 目录和 library 目录,并且编译没有错误。 然后我得到了一个已经创建的Parser.lib。
然而,当我尝试编译 MyProgram 时,我得到一个关于 nifticlib 库的一些函数没有被解析的错误:
1>------ Build started: Project: Parser, Configuration: Debug x64 ------
1> nifti_parser.cc
1> Parser.vcxproj -> C:\Users\Laurent\Documents\C++-build\Projects\Parser\Debug\Parser.lib
2>------ Build started: Project: MyProgram, Configuration: Debug x64 ------
2>Parser.lib(nifti_parser.obj) : error LNK2019: unresolved external symbol nifti_image_read referenced in function "public: __cdecl NiftiParser::NiftiParser(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (??0NiftiParser@@QEAA@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z)
2>C:\Users\Laurent\Documents\C++-build\Projects\Debug\MyProgram.exe : fatal error LNK1120: 1 unresolved externals
========== Build: 1 succeeded, 1 failed, 3 up-to-date, 0 skipped ==========
我不确定为什么会这样。我试图将include路径和nifticlib的库目录添加到MyProgram项目中,但我仍然遇到一些问题。
我不确定 Visual Studio 的 compilation/linking 过程是什么(我曾经在 Linux 上工作)。
在我看来,只有当项目是静态库时才会编译项目,而 linking 部分只会在我尝试编译程序本身时发生。 我说得对吗?
此外,我不确定 nifticlib 应该放在哪里 link。应该到 Parser.lib(我在其中使用库的函数)还是直接到程序?
谢谢。
PS:我还注意到我的 nifticlib 安装目录只包含 headers 和 .lib。我是否也需要在其中包含 .cpp,或者函数是否已包含在 .lib 中?
编辑: 好吧,显然将某些东西构建为静态库并没有 link 它对任何东西,所以这可能就是为什么我没有遇到任何编译问题Parser.lib,因为它不link到nifticlib,但是MyProgram需要它。 那么我应该只在我的 Parser 项目中包含 nitficlib 的 include 目录,并将 Parser.lib 和 nifticlib 放在我的 MyProgram 项目中吗?
Visual Studio 的 compilation/linking 与 Linux 工具链中发生的事情没有太大区别。当您制作二进制文件(可执行文件或动态库)时,必须解析所有外部符号。在 GCC 中,您必须向 linker 指明这些库。命令行选项 -lmath
将告诉 linker 从为库搜索设置的路径之一加载 libmath.a 并在构建可执行文件时使用它图片。
同样,在VS中不仅需要设置库目录的路径,还需要明确指明库文件。这通常在项目属性 -> 链接器 -> 输入 -> 附加依赖项上完成。请注意,在 Windows 中,您只需输入完整的库名称 (MyLib.lib),而不是 lib 和.a
另请注意,在 Windows 中,您不能 link 动态库 (.dll) 的二进制文件。您将需要一个导入库 (.lib)。
创建静态库时,工具链不解析外部引用。这就是为什么你 .lib 没有引用 nifticlib 就编译得很好的原因。
至于linknifticlib应该放在哪里,要看情况。如果只有你的 MyLibrary 将永远使用 nifticlib 的功能,那么 link 它与你的静态库是明智的。但是,如果有一天您希望直接在 MyProgram 中使用 nifticlib 中的某些函数,则可能会在 link 时发生冲突。在这种情况下,只有在构建 MyProgram 时才需要 link nifticlib。
经验法则可以这样表述:
- 如果只有 MyLibrary 使用 headers 的 nifticlib,link 你的图书馆与第三方
- 如果 MyProgram 也使用了 nifticlib 的 headers(并且实际调用了它们的函数),那么在构建 MyProgram 时最好 link nifticlib
这里描述的不严格,还有比较复杂的情况,但基本都是这样。
不,当您从另一个项目 linking 到该库时,您不需要构建静态库时使用的 cpp 文件。 .cpp 库的内容已经以 object 代码的形式包含在静态库文件中。
编辑: 如果您确实希望 link 您的静态库与来自另一个静态库的外部对象,您需要转到项目属性 -> 图书管理员 ->常规 -> 附加依赖项并将外部 .lib 放在那里