【问题标题】:Visual Studio: Build a pure static C++ Library ("no dependencies")Visual Studio:构建纯静态 C++ 库(“无依赖关系”)
【发布时间】:2022-01-07 06:03:36
【问题描述】:

我正在尝试构建一个静态库作为其他人可以使用的版本(无论他们是否调试自己的代码,他们都应该能够使用它)。另一方面,我的库应该包含任何调试符号左右。我只想发布头文件和 .lib 文件(没有 .dll 左右)。

lib 的用户应该能够毫不费力地使用他的运行时环境和构建风格(调试或发布)。

Visual Studio 甚至可以做到这一点吗?
[==> 我已经读过,有些用户转而使用 gcc 构建这种库]

我尝试了几种情况,但总是遇到“_ITERATOR_DEBUG_LEVEL”冲突左右。运行时库的静态链接似乎也不是解决方案,但还有什么? 是否可以关闭所有引用并让包含库的项目决定使用什么运行时?

即使这个问题与以下问题相似,我也没有在那里找到正确的答案: Pure static C++ Library (no dependency of MSVC C++ runtime) 或在这里 Microsoft Visual Studio ~ C/C++ Runtime Library ~ Static/dynamic linking

【问题讨论】:

  • 如果您希望用户链接到 Release 或 Debug,那么您不会发布一个库,您将拥有多个库,例如分别为 foo.libfoo_d.lib_ITERATOR_DEBUG_LEVEL 就是其中一个原因,还有优化、内联等。还要考虑您将支持哪种平台和架构(x64、Win32)。这通常是为什么(在开源情况下)人们改为提供 CMake 文件,以便用户可以以与其当前构建配置兼容的方式构建和链接到您的代码。
  • 您的纯静态 C++ 库是否使用纯 C 公共 ABI?如果它不使用 C ABI 作为公共 API 防火墙,那么您应该将纯 C++ 库作为源代码发布。因为正如 Titus Winters 所说,“从源头构建一切,同时使用相同的标志。”纯静态 C++ 库将强制项目使用与库相同的标志和相同的编译器......这也适用于调试或非标志。
  • 在 msvc 中,标准库在调试模式下的实现与在发布模式下的实现不同。迭代器更大,可以调试...
  • 如果您的 C++ 库使用公共 C ABI 并隐藏私有 C++ 实现细节,那么您无需提供比公共函数和公共返回值更多的信息。
  • 你也不应该delete(或free)你的用户new(或malloc),反之亦然,除非你确定它们具有与您完全相同的 C++ 运行时版本。如果你分配了一些东西并返回给用户一个指向它的指针,你还应该为这个对象提供一个释放函数。如果您和您的用户都使用g++clang++,则上述几乎都不是问题。然后,您可以混合和匹配编译器版本和调试模式,并在您的公共 API 中公开尽可能多的 C++,

标签: c++ visual-studio static-libraries


【解决方案1】:

解决方案如下(如@drescherjm 和@Eljay 所述):

如果仅使用“C ABI”并暴露给“外部”(头文件),您可以使用 VisualStudio(当前为 VS2019)构建静态库(.lib 文件),这些库可在调试和发布环境中使用.

“C ABI”并不意味着不能使用 C++ 功能,它意味着没有“std::*”函数/容器/等。可以使用。
既不能作为函数参数,也不能作为类成员。

#ifndef LIB_STATIC_H__
#define LIB_STATIC_H__

#include <stdint.h>

class MyLib
{
public:
    MyLib();
    ~MyLib();
    uint64_t TestFunc(char* param, uint32_t x);
};

#endif

这会起作用,但这不会:

#ifndef LIB_STATIC_H__
#define LIB_STATIC_H__

#include <stdint.h>
#include <string>

class MyLib
{
public:
    MyLib();
    ~MyLib();
    uint64_t TestFunc(char* param, uint32_t x);
private:
    std::string m_MyString;
};

#endif

上述示例有效,因为在包含 LIB 的程序中没有使用 std::* 功能(此处未显示)。

但是如果你需要在静态库之外使用 std::* 函数/模板,仍然存在 _ITERATOR_DEBUG_LEVEL 冲突......

【讨论】:

  • PIMPL 还可以帮助将标准库的实现细节和使用移出公共接口。
  • 在header中暴露无所谓,静态库中不能使用标准库句号
  • @AlanBirtles:根据我自己的测试,这不是真的。我只是使用 std::string 在示例类的 CTOR 中生成和输出一个字符串,而不向外部暴露某些东西,这很有效。静态库在调试和发布不同项目时可以正常使用。
  • 好吧,我做了一个类似的实验,但没有奏效,与 OP 出现相同的 _ITERATOR_DEBUG_LEVEL 错误
  • 啊,是的,没有发现你的实验和我的实验之间的区别
猜你喜欢
  • 2017-04-08
  • 2011-06-06
  • 2018-06-13
  • 1970-01-01
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多