2015-06-23 47 views
-1

場景:
我在兩臺不同的機器上構建軟件。
其中一臺機器具有完全符合C++ 11版本g++
其他沒有。如何根據我的g ++編譯器的版本來防止不同的編譯?

機器1(Linux)的:

$ g++ --version 
g++ (Ubuntu 5.1.0-0ubuntu11~14.04.1) 5.1.0 
Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

機2臺(的Windows使用Cygwin):

$ g++ --version 
g++ (GCC) 4.9.2 
Copyright (C) 2014 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

我穿過這兩款機器構建C++軟件支持所有回到C++ 98。

然而,如果它們是可用C++的較新的功能將被使用。
(有問題的軟件是C++ Catch單元測試)。

問題:
我有一個通用的生成文件,將生成此軟件。在Cygwin上成功建立軟件。在Linux上,使用較新的編譯器無法編譯,因爲我認爲它會檢測編譯器的版本並嘗試使用更現代的C++功能。

這裏是一眼目的錯誤的轉儲。大多隻是nullptr_t有關。也許是與模板扣除額(不完全確定)新的規則:

catch.hpp:833:17: error: ‘nullptr_t’ in namespace ‘std’ does not name a type 
    inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; } 
       ^
catch.hpp:954:58: error: ‘template<Catch::Internal::Operator Op, class T> bool Catch::Internal::compare’ conflicts with a previous declaration 
    template<Operator Op, typename T> bool compare(std::nullptr_t, T* rhs) { 
                 ^
catch.hpp:948:44: note: previous declaration ‘namespace Catch::Internal { }::compare’ 
    template<Operator Op, typename T> bool compare(T* lhs, int rhs) { 
              ^
catch.hpp:954:53: error: ‘nullptr_t’ is not a member of ‘std’ 
    template<Operator Op, typename T> bool compare(std::nullptr_t, T* rhs) { 
                ^
catch.hpp:954:70: error: expected primary-expression before ‘*’ token 
    template<Operator Op, typename T> bool compare(std::nullptr_t, T* rhs) { 
                    ^
catch.hpp:954:72: error: ‘rhs’ was not declared in this scope 
    template<Operator Op, typename T> bool compare(std::nullptr_t, T* rhs) { 
                     ^
catch.hpp:954:76: error: expression list treated as compound expression in initializer [-fpermissive] 
    template<Operator Op, typename T> bool compare(std::nullptr_t, T* rhs) { 
                      ^
catch.hpp:954:44: warning: variable templates only available with -std=c++14 or -std=gnu++14 
    template<Operator Op, typename T> bool compare(std::nullptr_t, T* rhs) { 
              ^
catch.hpp:954:78: error: expected ‘;’ before ‘{’ token 
    template<Operator Op, typename T> bool compare(std::nullptr_t, T* rhs) { 
                      ^
catch.hpp:957:66: error: ‘std::nullptr_t’ has not been declared 
    template<Operator Op, typename T> bool compare(T* lhs, std::nullptr_t) { 
                   ^
catch.hpp:957:44: error: redefinition of ‘template<Catch::Internal::Operator Op, class T> bool Catch::Internal::compare(T*, int)’ 
    template<Operator Op, typename T> bool compare(T* lhs, std::nullptr_t) { 
              ^
catch.hpp:948:44: note: ‘template<Catch::Internal::Operator Op, class T> bool Catch::Internal::compare(T*, int)’ previously declared here 
    template<Operator Op, typename T> bool compare(T* lhs, int rhs) { 
              ^
In file included from main.cpp:2:0: 
catch.hpp:1088:38: error: ‘std::string Catch::toString’ redeclared as different kind of symbol 
std::string toString(std::nullptr_t); 
            ^
catch.hpp:1085:13: note: previous declaration ‘std::string Catch::toString(unsigned char)’ 
std::string toString(unsigned char value); 
      ^
catch.hpp:1088:23: error: ‘nullptr_t’ is not a member of ‘std’ 
std::string toString(std::nullptr_t); 
        ^
In file included from main.cpp:2:0: 
catch.hpp:7336:38: error: ‘std::string Catch::toString’ redeclared as different kind of symbol 
std::string toString(std::nullptr_t) { 
            ^
In file included from main.cpp:2:0: 
catch.hpp:1232:13: note: previous declaration ‘template<class T, class Allocator> std::string Catch::toString(const std::vector<_Tp, _Alloc>&)’ 
std::string toString(std::vector<T,Allocator> const& v) { 
      ^
In file included from main.cpp:2:0: 
catch.hpp:7336:23: error: ‘nullptr_t’ is not a member of ‘std’ 
std::string toString(std::nullptr_t) { 

這可以通過確保g++獲取與--std=c++11標誌編譯很容易地固定在Linux機器上。但是,我不希望兩臺機器上有兩個單獨的makefile。我無法將--std=c++11標誌添加到兩個版本,因爲版本4.9尚未具有該標誌。

問:
如何使用不同版本的g++相同的命令啓用交叉編譯?代碼根據g++版本的不同而不同 - 在這種情況下,有時需要傳遞std標誌。

附加:
我試着給g++--std=c++98兩個版本,但它仍然無法在Linux構建。這裏的目標是在兩臺機器上使用相同的命令。

+0

在Windows中可以使用的MinGW 64.支持'STD = C++ 11'選項。 –

+3

'--std = C++ 11'被添加回[GCC 4.7](https://gcc.gnu.org/projects/cxx0x.html)。 – MSalters

+0

在Makefile中使用條件警衛有什麼問題? – jxh

回答

0

在Windows平臺上,我建議使用斯蒂芬Lavavej的Nuwen Distro。唯一的障礙是你不能使用std::thread設施,但boost::thread提供了一個幾乎無縫的選擇。

0

在Windows上,我建議切換到MSYS2特別是如果你需要C++ 11的支持。最新版本已經有了mingw64 g ++ 4.9.2。我能夠使用C++ 11/boost/python大量構建我的Ubuntu項目,但我無法在Cygwin或MSVC2015 RC上完成此項目。MSYS2有它的包管理器叫做pacman,它是apt-get/yum的一種。

有相當多的預建東西,你可以檢查here可用性。

非常緊湊引進here