C ++依赖生成没有自动化的理论原因是什么?

时间:2013-01-10 17:06:27

标签: c++ build

C++ Buildsystem with ability to compile dependencies beforehand

Java有Maven,很高兴能够使用,只需指定已编译的依赖项,并存放到 Mavens 标准目录,这意味着依赖项的位置是标准化的,而不是经常使用的具有多个位置的方式(让我休息,就像任何人记住特定deps的默认安装目录)的C / C ++依赖项。

每个开发人员都必须经常查找,阅读,熟悉配置选项/构建,最后为每个依赖项编译以简单地构建项目,这对于每个开发人员来说都是非常无效的。

没有实施这个理论的理由是什么?

为什么难以用类似maven的声明格式提供以下选项的包?

version
platform (windows, linux)
src/dev/bin
shared/static
equivalent set of Boost ABI options when applicable

对于最古老的主要编程语言,必须手动访问网站并在2013年搜索出依赖关系是荒谬的。

3 个答案:

答案 0 :(得分:21)

没有任何理论上的原因。有许多实际原因。在C ++世界中有太多不同的处理方式来轻松地在依赖系统上进行标准化:

  • 实现差异 - C ++是一种复杂的语言,不同的实现在历史上有多么不同(它们如何正确处理各种中等到高级的C ++代码)。所以不能保证在特定的实现中可以构建库。
  • 平台差异 - 某些平台可能不支持例外。标准库有不同的实现,各有利弊。与Java的标准化库不同,Windows和POSIX API可能完全不同。 文件系统甚至不是标准C ++的一部分。
  • 编译差异 - 静态还是共享?调试或生产构建?是否启用可选依赖项?与具有非常稳定的字节码的Java不同,C ++缺少标准的ABI意味着代码可能无法正确链接,即使由同一编译器为同一平台构建也是如此。
  • 构建系统差异 - Makefile? (如果是这样,GNU Make,还是其他什么?)Autotools? CMake的? Visual Studio项目文件?还有别的吗?
  • 历史问题 - 由于C和C ++的时代,像zlib这样的流行库早于像Maven这样的构建系统。为什么zlib会在它正在运行的时候切换到某个假设的C ++构建系统?如果一个较新的,更高级别的库依赖于像zlib这样的库,它怎么能切换到某个假设的构建系统?

另外两个因素使事情变得复杂:

  • 在Linux中,发行版打包系统提供了开发库头文件二进制文件的标准化存储库,具有(通常)标准化的ABI以及指定项目构建依赖关系的简便方法。这些(特定于平台的)解决方案的存在减少了跨平台解决方案的推动力。
  • 利用所有这些复杂因素和预先存在的方法,任何建立标准构建系统的尝试都将遇到XKCD "Standards"中描述的问题:
    情况:共有14项竞争标准 “14?很有创意!我们需要制定一个覆盖每个人用例的通用标准。” 很快:有15个竞争标准。

所有这些都说:

未来有一些希望。例如,CMake似乎正在逐步取代其他构建系统。一些Boost开发人员已经开始Ryppl,试图做你正在描述的事情。

答案 1 :(得分:3)

(也张贴在相关问题中)

现在我正在开发一种工具,能够自动安装具有确切版本要求的C / C ++应用程序的所有依赖项:

  • 编译
  • 工具(cmake,autotools)

现在它适用于我的应用程序。 (按正确顺序安装UnitTest ++,Boost,Wt,sqlite,cmake)

这个名为“C ++版本管理器”的工具(灵感来自优秀的ruby版本管理器)以bash编码并托管在github上:https://github.com/Offirmo/cvm

欢迎任何意见和建议。

答案 2 :(得分:1)

好吧,首先关闭一个解决所有依赖关系的系统默认情况下不会提高效率,但可能会降低你的工作效率。

关于语言之间的差异我会说在Java中你有软件包,当你需要组织并给你的代码提供有限的范围时,它们很方便,在C ++中你没有相同的概念。 在C ++中,所有可以解决符号的库对于编译器都是足够好的,库的唯一真正要求是拥有一定的ABI并解决所需的符号,没有自动化的方法可以让你选择正确的库,也解决了一个符号,这只是将你的功能与实际实现联系起来的问题,这甚至不会让你认为正确的链接阶段会使你的应用工作。

为此,您可以添加重要的变量,例如库版本,同一库的不同实现以及具有相同方法名称的不同库。

一个例子是Mesa库VS来自官方驱动程序的opengl lib,或者你想要的提供多个版本的lib,每个都可以解决所有符号但是可能有一个比其他人更成熟的版本和你可以要求编译器选择正确的编译器,因为它们本身就是一样的。