如何在C ++ Autotools项目中使用不同版本的G ++进行编译

时间:2018-12-25 09:18:25

标签: c++ g++ autotools autoconf automake

我有一个很大的autotools项目,子目录中的一部分代码使用g ++-4.9进行编译,而其他部分则使用g ++ 8.2。

我的问题是如何使用不同版本的g ++编译整个项目。

我看到一些相关的问题是要更改其他g ++编译器,而一般的答案是设置环境变量或make选项。

但是,我的问题是要同时使用g ++ 8.2和g ++ 4.9进行编译。

我希望有一些设置 Makefile.am 的解决方案,例如:

noinst_PROGRAMS=foo bar
foo_CXX_COMPILER=/usr/bin/g++-4.9

bar_CXX_COMPILER=/usr/bin/g++-8.2

编辑:

我尝试过的更多详细信息

  1. 使用auto_ptr进行编译时,子项目中的第三方库将显示很多警告“ g++-4.9 -std=c++11已过时”,但没有任何错误且执行良好。
  2. 它编译得很好,没有错误和g++-4.9 -std=c++98的警告。
  3. 即使我添加了标志g++-8.2,即使使用-std=c++98.编译,它也会大喊“错误引用...”的许多错误

我猜这是因为g++-8.2编译器无法识别auto_ptr的用法!

我更喜欢只使用一个编译器,这使问题很简单!但是,如果不能只允许使用一种情况,那么我想知道如何使用两个不同的编译器来设置Makefile.am,或者解决该编译问题的任何最佳方法!

2 个答案:

答案 0 :(得分:3)

  

我的问题是如何使用不同版本的g ++编译整个项目。

有可能,但我不建议这样做。 GNU Build System对此不提供任何支持,但是您可以看看AX_CC_FOR_BUILD如何实现一个类似的想法(使编译器既可以构建又可以宿主)。

@JohnBollinger提出的建议#2是-选择一个编译器并使用它进行编译。 您的构建的最终用户将比必须设置两个编译器更能欣赏这一点。这是我要使用的解决方案,因为GNU Build System以这种方式工作。如果由于某种原因无法对旧代码进行现代化,则可以告诉g ++-8.2从C ++的早期版本中编译代码。

想法#3基本上是将您的项目分成两个自动工具项目-一个使用旧编译器编译,另一个使用新编译器编译。也不是这个主意。

答案 1 :(得分:2)

  

我有一个很大的autotools项目,子目录中的一部分代码使用g ++-4.9进行编译,而其他部分则使用g ++ 8.2。

     

我的问题是如何使用不同版本的g ++编译整个项目。

我不建议这样做。 ABI约定可能已更改(因此,恕不建议使用不同ABI的两个不同GCC进行编译)。

实际上,我建议使用相同的(最新的)GCC构建所有项目,即使用g++ 8.2

如果项目的某些部分使用的是另一种C ++方言,则可以向其中明确传递一些-std=c++11-std=c++17选项。

因此,只需将您的项目配置为使用相同(和最新版本)的GCC。如果某些C ++方言不同,请向其传递特定的标志。参见options controlling the C++ dialect-std= option

最后,您可以考虑修补旧库的源代码以使其与C ++ 14兼容(特别是,删除所有出现的auto_ptr,并用unique_ptr等明智地替换它们。 ..)。在大多数情况下,这样做是值得的(也许已经存在该旧库的较新版本,即C ++ 14或C ++ 17)

混合使用C++ standard library的两个不同版本肯定很痛苦,应该避免。如果您坚持尝试,那么您需要痛苦地理解所有血腥细节(因此,我真的建议不要尝试)。然后阅读Drepper的How to write shared libraries论文。

另一种方法可能是让您的软件使用两个不同的processes(一个用于旧的C ++ 98源代码,另一个用于新的C ++ 14代码)并使用inter-process communication工具。这也许是最可靠的解决方案。

出于实际目的,将旧C ++ 98和新C ++ 14视为两种不同且不兼容的编程语言(C ++ 11确实是 的前辈。