我有一个很大的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
编辑:
我尝试过的更多详细信息:
auto_ptr
进行编译时,子项目中的第三方库将显示很多警告“ g++-4.9 -std=c++11
已过时”,但没有任何错误且执行良好。 g++-4.9 -std=c++98
的警告。g++-8.2
,即使使用-std=c++98.
编译,它也会大喊“错误引用...”的许多错误我猜这是因为g++-8.2
编译器无法识别auto_ptr
的用法!
我更喜欢只使用一个编译器,这使问题很简单!但是,如果不能只允许使用一种情况,那么我想知道如何使用两个不同的编译器来设置Makefile.am,或者解决该编译问题的任何最佳方法!
答案 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确实是 的前辈。