为啥很多项目不提供预编译的二进制文件?

Posted

技术标签:

【中文标题】为啥很多项目不提供预编译的二进制文件?【英文标题】:Why many projects don't provide a pre-compiled binary file?为什么很多项目不提供预编译的二进制文件? 【发布时间】:2020-06-11 16:04:31 【问题描述】:

这个问题对我来说已经很久了。我不经常使用 c++,而且似乎大多数 cpp 库都以 zip 文件或包含源代码的 tar 球的形式提供。

所以,问题是:

为什么那些项目不提供预编译的二进制文件?

我目前对“autoconf,make,make install,...”过程的理解是确保一切正确,然后将源代码编译成可执行文件或一些库。但是如果我们最终得到相同的东西,为什么我们每次都要编译它呢?我不是说要为编译好的库维护一个单独的项目,但是在调试和测试过程中,这些文件应该是自动生成的,为什么不把它们放到发布文件中呢?

例如:FTGL库的源码自带Visual Studio解决方案文件(.sln),如果他们用这个来开发和调试,为什么不把编译好的二进制文件放到他们的发布文件中呢?

【问题讨论】:

因为不同的操作系统和发行版需要不同的二进制文件。 嗯,你能说得更具体点吗?哪个平台、什么架构、ABI、优化级别的二进制文件?矢量指令是打开还是关闭? 另外,不同的编译器使用不同的库格式、目标文件格式、调试信息格式等 这些天我更喜欢不下载二进制文件,而是让代码支持使用 CMake 生成我的 Visual Studio(或其他 IDE)项目文件。 【参考方案1】:

平台通常有一个通用的 C ABI,它规定了符号命名、函数调用约定和其他低级细节。以 ABI 为目标的编译器可以与其他执行相同操作的编译器互操作。 Linux 库和 Windows 库不兼容,但通常可以为每个目标平台构建少量版本:一个用于 Linux,一个用于 Windows,等等。

C++ 库没有这样的标准。 Name mangling 因编译器而异。编译后的 C++ 库通常只能由相同版本的相同编译器使用。由同一编译器的不同版本编译的库甚至不一定兼容。要预先构建一个库,您必须使用几十个版本的 g++、几十个版本的 clang 等来构建......这是不切实际的。

分发 C++ 库很困难。一些常见的策略是:

    仅将库标头设置为仅使最终用户只需 #include 库标头。无需编译。

    分发头文件和源文件并要求最终用户构建库。

    在 C 中实现库并在头文件中提供 C++ 包装器。该库可供 C 和 C++ 程序使用。如果需要,可以预先构建 C 部分。

    与上一个项目符号相反,用 C++ 实现库并添加 C 包装器。包装器将定义一组独立的 extern "C" 函数,这些函数会调用 C++ 代码。

例如,Boost 混合使用了策略 1 和 2。如果您只使用 Boost 的仅标头部分,那么您所要做的就是#include 他们在程序中的标头,超级简单。如果您使用非仅标题部分,例如线程或正则表达式组件,则必须编译它们,这需要一段时间。

3 和 4 对于您不想分发代码的专有库很有用。

【讨论】:

【参考方案2】:

根据您的平台,生成的二进制文件会完全不同。例如,您可以运行 Linux、Mac 或 Windows 以及更多这些可能是 64 位或 32 位架构。

如果我将 Windows 32 位二进制文​​件传递给您,而您的系统是 64 位 Mac,则二进制文件将完全不兼容。

有些项目确实为每个平台提供了二进制文件,或者可能只为少数几个平台提供了二进制文件,但是拥有源代码仍然很棒,因为您可能希望修改它,只使用它的某些部分或简单地理解它。

【讨论】:

以上是关于为啥很多项目不提供预编译的二进制文件?的主要内容,如果未能解决你的问题,请参考以下文章

在 Cocoapods 中使用预编译时是不是可以在源代码和二进制文件之间切换

编译器

将预编译的二进制文件捆绑到电子应用程序中

conan入门:上传预编译的库(artifact)

如何将预编译的二进制文件与电子捆绑在一起

如何使用 GLFW 预编译的二进制文件编译 Visual Studio 2019 发行版