【问题标题】:How to enable C++14 with older Qt? Qmake incompatible with C++14如何使用旧 Qt 启用 C++14? Qmake 与 C++14 不兼容
【发布时间】:2018-02-05 03:30:52
【问题描述】:

我有 Qt 5.2.1(使用 gcc 4.8.2 编译)和 gcc 4.9.4 (mingw-w64) 编译器。

C++11 工作正常。总是有,即使是 4.8.2 编译器。

我需要一些 C++14 特性。我想使用最新的编译器,但对 ABI 更改的关注让我得到了 4.9.2。 gcc 4.9.2 应该支持 make_unique 和 C++14。

我的问题是我似乎无法在 Qt Creator 中获得 C++14 支持。

尝试添加到 pro 文件...没有用。

CONFIG += c++14 

尝试添加到 pro 文件...没有用:

QMAKE_CXXFLAGS_CXX14 = -std=c++14

尝试添加到 pro 文件...没有用:

QMAKE_CXXFLAGS_CXX14 = -std=c++14
QMAKE_CXXFLAGS_GNUCXX14 = -std=c++14

尝试添加到 pro 文件...没有用:

win32-g++ {
   QMAKE_CXXFLAGS_CXX14 = -std=c++14
   QMAKE_CXXFLAGS_GNUCXX14 = -std=c++14
}

尝试向此添加/编辑 win32-g++ makespec 文件...不起作用

QMAKE_CXXFLAGS_CXX11 = -std=c++0x
QMAKE_CXXFLAGS_CXX14 = -std=c++14
QMAKE_CXXFLAGS_GNUCXX14 = -std=c++14

尝试向此添加/编辑 win32-g++ makespec 文件...不起作用

QMAKE_CXXFLAGS_CXX14 = -std=c++14
QMAKE_CXXFLAGS_GNUCXX14 = -std=c++14

尝试向此添加/编辑 win32-g++ makespec 文件...不起作用

QMAKE_CXXFLAGS_CXX11 = -std=c++14
QMAKE_CXXFLAGS_CXX14 = -std=c++14
QMAKE_CXXFLAGS_GNUCXX14 = -std=c++14

尝试向此添加/编辑 win32-g++ makespec 文件...不起作用

QMAKE_CXXFLAGS_CXX11 = -std=c++14

我相信 QMake 是问题所在。当然,我不确定。

编辑 -- 添加更多输入

专业文件

#-------------------------------------------------
#
# Project created by QtCreator 2018-02-05T13:02:30
#
#-------------------------------------------------

QMAKE_CXXFLAGS += -std=c++1y

QT       += core

QT       -= gui

TARGET = test2
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app


SOURCES += main.cpp

测试代码

#include <QCoreApplication>
#include <iostream>
#include <memory>

using namespace std;

class A{
public:
    A(){cout << "ctorA " << endl;}
    ~A(){cout << "dtorA " << endl;}
};

class X{
    A arr[10];
};

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    { unique_ptr<X> upX = make_unique<X>(); }

    return a.exec();
}

编译器输出

14:01:39: Running steps for project test2...
14:01:39: Configuration unchanged, skipping qmake step.
14:01:39: Starting: "C:\DTOOLS\QtLib5.2.1-QtCreator3.0.1__T-Win-64b_B-gcc4.8.2-seh-posix-opengl\QtSDK-x86_64\bin\mingw32-make.exe" 
C:/DTOOLS/QtLib5.2.1-QtCreator3.0.1__T-Win-64b_B-gcc4.8.2-seh-posix-opengl/QtSDK-x86_64/bin/mingw32-make -f Makefile.Release
mingw32-make[1]: Entering directory 'C:/DEV/test2'
g++ -c -march=nocona -mtune=core2 -pipe -fno-keep-inline-dllexport -std=c++1y -O2 -frtti -Wall -Wextra -fexceptions -mthreads -DUNICODE -DQT_NO_DEBUG -DQT_CORE_LIB -I. -I"..\..\DTOOLS\QtLib5.2.1-QtCreator3.0.1__T-Win-64b_B-gcc4.8.2-seh-posix-opengl\QtSDK-x86_64\include" -I"..\..\DTOOLS\QtLib5.2.1-QtCreator3.0.1__T-Win-64b_B-gcc4.8.2-seh-posix-opengl\QtSDK-x86_64\include\QtCore" -I"release" -I"..\..\DTOOLS\QtLib5.2.1-QtCreator3.0.1__T-Win-64b_B-gcc4.8.2-seh-posix-opengl\QtSDK-x86_64\mkspecs\win32-g++" -o release\main.o main.cpp
main.cpp: In function 'int main(int, char**)':
main.cpp:21:27: error: 'make_unique' was not declared in this scope
     { unique_ptr<X> upX = make_unique<X>(); }
                           ^
main.cpp:21:40: error: expected primary-expression before '>' token
     { unique_ptr<X> upX = make_unique<X>(); }
                                        ^
main.cpp:21:42: error: expected primary-expression before ')' token
     { unique_ptr<X> upX = make_unique<X>(); }
                                          ^
Makefile.Release:177: recipe for target 'release/main.o' failed
mingw32-make[1]: *** [release/main.o] Error 1
mingw32-make[1]: Leaving directory 'C:/DEV/test2'
Makefile:34: recipe for target 'release' failed
mingw32-make: *** [release] Error 2
14:01:40: The process "C:\DTOOLS\QtLib5.2.1-QtCreator3.0.1__T-Win-64b_B-gcc4.8.2-seh-posix-opengl\QtSDK-x86_64\bin\mingw32-make.exe" exited with code 2.
Error while building/deploying project test2 (kit: QtLib5.2.1_t-Win-64b_B-gcc9.9.4)
When executing step 'Make'
14:01:40: Elapsed time: 00:01.

【问题讨论】:

  • 您可能应该更新到最新版本。在线安装程序使升级变得非常容易。

标签: qt c++14 qt-creator qmake qt5.2


【解决方案1】:

我在我的一个项目中使用它。在.pro 文件中:

CONFIG += c++14

# Qt 5.3 and lower doesn't recognize "c++14". Use c++11 and then replace
# the compiler flags with c++14.
contains(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 4) {
    CONFIG += c++11
    QMAKE_CXXFLAGS_CXX11 = $$replace(QMAKE_CXXFLAGS_CXX11, "std=c\+\+11", "std=c++1y")
    QMAKE_CXXFLAGS_CXX11 = $$replace(QMAKE_CXXFLAGS_CXX11, "std=c\+\+0x", "std=c++1y")
}

# Qt 4 doesn't even know about C++11, so just add c++14 directly.
contains(QT_MAJOR_VERSION, 4) {
    QMAKE_CXXFLAGS += -std=c++1y
}

如果你不关心 Qt4,请删除最后一部分。

显然这只适用于 GCC 和 Clang。其他编译器需要不同的处理方式。

【讨论】:

  • Nikos,我在哪里进行这些更改。我应该将 contains 块放入哪些文件?这是一些令人印象深刻的信息。您是如何获得这些知识的? :)
  • @code 你把它放在你的项目文件中,在初始条目之后。这是我的样子:github.com/realnc/qtads/blob/master/qtads.pro。至于我是怎么知道的,我不确定。我从 2002 年左右开始就一直在使用 Qt,我想这意味着我知道自己的方法 :-)
  • 谢谢尼科斯。我仍在尝试解决此问题。事实证明,Qt 和 QtCreator 的工作方式存在根深蒂固的问题。 Qt Creator GUI 意味着您可以创建将 diff Qt 构建与 diff 编译器相结合的工具包(显然存在限制......我只是想用较新的 GCC 4.9.3 编译器重新连接使用 gcc 4.8.2 构建的 QT 库...ABI 兼容)。但是这是错误的。它不能这样做。也许较新的 QT Creators 可以……但我的测试表明 Creator 3.0.1 要么有问题,要么构思错误。打包 Qt 库的方式是使用 GCC 箱、库和头文件...使其...
  • 无法与不同版本的编译器重新组合。您可以尝试通过 Creator GUI 执行此操作,但它只会忽略您指向的编译器,并默认使用与其文件捆绑的 gcc。我什至尝试手动覆盖与其捆绑的 gcc 文件,但它仍然无法正常工作。 sys 路径中没有任何内容。一团糟。不应该这么难。 Qt 打包方案看起来像是一团散布在树层次结构中的编译器文件。不是很即插即用。也许他们在新版本中对此进行了改进。
  • @code 我建议完全卸载您当前的 Creator 和 Qt,删除所有剩余部分,同时删除您的 appdata 中的配置文件,然后下载在线安装程序,这将使您保持最新状态轻松升级到新版本。对我来说,听起来您使用的是过时的版本,而且您的配置也很混乱。
【解决方案2】:

您使用了错误的变量,以下应该可以工作并且是4.9支持的最高级别

QMAKE_CXXFLAGS += -std=c++1y

【讨论】:

  • 能否详细说明。我到底应该把什么放在哪里。我将 QMAKE_CXXFLAGS += -std=c++1y 放入 PRO 文件中,但它不起作用。
  • 它在 make_unique 上狂吠……说它不是 std 的成员。
  • 如果取出 QT 行并在命令行使用 g++ 编译,代码可以工作。
  • 您是否在更改 pro 文件和构建代码之前运行了 qmake?在 QT Creator 中,构建菜单中有一个运行 qmake 选项,您必须手动执行此操作,它不会为您执行此操作。
  • 一般来说, pro 文件中的顺序并不重要,但我更喜欢在文件的早期保留这些标志。
【解决方案3】:

根据this Qt 发布时间表,我们有 5.2 之前的 C++14,它于 2014 年 12 月 15 日发布。虽然 GCC 4.8.2 支持 C++14 的某些子集,但不是 C++14兼容的编译器。 Check 谈 GCC 中的 C++ 标准支持。

您很可能需要将 Qt 至少升级到 5.4 才能启用CONFIG += c++14 配置,而且编译器需要比 GCC 4.8.2 更新,最好至少是 GCC 5+。

尝试使用-std=gnu++1y,它的目标是激活早期 GCC 中的 C++ 14 功能。

【讨论】:

  • 你说的是真的。这就是我将编译器升级到 4.9.4 的原因,它确实支持我需要的 C++14 功能(尤其是 make_unique)。我还读到 Qt 5.4 做了一些事情来启用 CONFIG += c++14 配置,但由于许可证限制,我无法使用高于 5.3.2 的 Qt。这就是我问这个问题的原因。似乎问题出在 Qmake 或 makespec 之类的东西上。尽管有编译器支持,但 c++14 无法轻松启用。
  • * 但由于许可证限制,我无法使用高于 5.3.2 的 Qt * 听起来很奇怪。那是什么执照?我为具有商业 Qt 许可证的组织工作,我们只是在需要时获得新版本。那是我工作的第二个拥有相同 Qt 商业许可证的组织。
  • 此处未在商业许可下使用它。 LGPL 2.1。只要您不修改 Qt 并动态链接到它,它就允许闭源开发。每位开发者每年都负担不起 6000 美元来获得商业许可。 5.3.2 是 LGPL 2.1 下的最后一个 Qt。
  • 我刚刚更新了我的答案:尝试使用-std=gnu++1y,它的目标是激活早期 GCC 中的 C++ 14 功能。
猜你喜欢
  • 2018-10-29
  • 1970-01-01
  • 2014-05-22
  • 2017-07-31
  • 2014-11-25
  • 2017-04-24
  • 2021-01-29
  • 2022-11-10
相关资源
最近更新 更多