2016-01-11 21:09:06 +01:00
|
|
|
/****************************************************************************
|
|
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
|
|
|
** Contact: https://www.qt.io/licensing/
|
2016-01-11 21:09:06 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator.
|
|
|
|
|
**
|
|
|
|
|
** Commercial License Usage
|
|
|
|
|
** Licensees holding valid commercial Qt licenses may use this file in
|
|
|
|
|
** accordance with the commercial license agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
2016-01-15 14:57:40 +01:00
|
|
|
** a written agreement between you and The Qt Company. For licensing terms
|
|
|
|
|
** and conditions see https://www.qt.io/terms-conditions. For further
|
|
|
|
|
** information use the contact form at https://www.qt.io/contact-us.
|
2016-01-11 21:09:06 +01:00
|
|
|
**
|
2016-01-15 14:57:40 +01:00
|
|
|
** GNU General Public License Usage
|
|
|
|
|
** Alternatively, this file may be used under the terms of the GNU
|
|
|
|
|
** General Public License version 3 as published by the Free Software
|
|
|
|
|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
|
|
|
|
** included in the packaging of this file. Please review the following
|
|
|
|
|
** information to ensure the GNU General Public License requirements will
|
|
|
|
|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
2016-01-11 21:09:06 +01:00
|
|
|
**
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
|
|
#include "compileroptionsbuilder.h"
|
|
|
|
|
|
2018-08-23 15:45:33 +02:00
|
|
|
#include "cppmodelmanager.h"
|
2018-12-19 18:37:02 +01:00
|
|
|
#include "headerpathfilter.h"
|
2018-08-23 15:45:33 +02:00
|
|
|
|
2017-09-27 10:32:52 +02:00
|
|
|
#include <coreplugin/icore.h>
|
|
|
|
|
|
2018-11-30 10:34:05 +01:00
|
|
|
#include <projectexplorer/headerpath.h>
|
2018-08-14 13:07:04 +02:00
|
|
|
#include <projectexplorer/project.h>
|
2018-11-30 10:34:05 +01:00
|
|
|
#include <projectexplorer/projectexplorerconstants.h>
|
|
|
|
|
#include <projectexplorer/projectmacro.h>
|
2017-09-27 10:32:52 +02:00
|
|
|
|
2020-08-29 23:34:18 +03:00
|
|
|
#include <utils/algorithm.h>
|
2019-01-09 18:31:20 +01:00
|
|
|
#include <utils/cpplanguage_details.h>
|
2018-01-24 11:19:58 +01:00
|
|
|
#include <utils/fileutils.h>
|
2017-11-17 14:13:55 +01:00
|
|
|
#include <utils/qtcassert.h>
|
2020-06-16 16:32:50 +02:00
|
|
|
#include <utils/stringutils.h>
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2016-07-01 15:07:32 +02:00
|
|
|
#include <QDir>
|
2016-10-10 17:31:19 +02:00
|
|
|
#include <QRegularExpression>
|
2019-02-12 09:46:25 +01:00
|
|
|
#include <QtGlobal>
|
2016-07-01 15:07:32 +02:00
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
namespace CppTools {
|
|
|
|
|
|
2018-11-30 10:34:05 +01:00
|
|
|
static const char defineOption[] = "-D";
|
|
|
|
|
static const char undefineOption[] = "-U";
|
|
|
|
|
|
|
|
|
|
static const char includeUserPathOption[] = "-I";
|
2019-01-21 15:07:04 +01:00
|
|
|
static const char includeUserPathOptionWindows[] = "/I";
|
2018-11-30 10:34:05 +01:00
|
|
|
static const char includeSystemPathOption[] = "-isystem";
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
static const char includeFileOptionGcc[] = "-include";
|
|
|
|
|
static const char includeFileOptionCl[] = "/FI";
|
2018-11-30 10:34:05 +01:00
|
|
|
|
|
|
|
|
static QByteArray macroOption(const ProjectExplorer::Macro ¯o)
|
|
|
|
|
{
|
|
|
|
|
switch (macro.type) {
|
2019-01-11 15:32:12 +01:00
|
|
|
case ProjectExplorer::MacroType::Define:
|
|
|
|
|
return defineOption;
|
|
|
|
|
case ProjectExplorer::MacroType::Undefine:
|
|
|
|
|
return undefineOption;
|
|
|
|
|
default:
|
|
|
|
|
return QByteArray();
|
2018-11-30 10:34:05 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static QByteArray toDefineOption(const ProjectExplorer::Macro ¯o)
|
|
|
|
|
{
|
|
|
|
|
return macro.toKeyValue(macroOption(macro));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static QString defineDirectiveToDefineOption(const ProjectExplorer::Macro ¯o)
|
|
|
|
|
{
|
|
|
|
|
const QByteArray option = toDefineOption(macro);
|
|
|
|
|
return QString::fromUtf8(option);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
QStringList XclangArgs(const QStringList &args)
|
|
|
|
|
{
|
|
|
|
|
QStringList options;
|
|
|
|
|
for (const QString &arg : args) {
|
|
|
|
|
options.append("-Xclang");
|
|
|
|
|
options.append(arg);
|
|
|
|
|
}
|
|
|
|
|
return options;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList clangArgsForCl(const QStringList &args)
|
|
|
|
|
{
|
|
|
|
|
QStringList options;
|
|
|
|
|
for (const QString &arg : args)
|
|
|
|
|
options.append("/clang:" + arg);
|
|
|
|
|
return options;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-14 13:07:04 +02:00
|
|
|
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
|
2018-08-23 15:45:33 +02:00
|
|
|
UseSystemHeader useSystemHeader,
|
2018-11-30 12:15:07 +01:00
|
|
|
UseTweakedHeaderPaths useTweakedHeaderPaths,
|
2018-11-30 11:02:49 +01:00
|
|
|
UseLanguageDefines useLanguageDefines,
|
2019-01-31 10:16:28 +01:00
|
|
|
UseBuildSystemWarnings useBuildSystemWarnings,
|
2018-11-30 10:34:05 +01:00
|
|
|
const QString &clangVersion,
|
2020-08-24 10:46:58 +02:00
|
|
|
const QString &clangIncludeDirectory)
|
2018-08-23 15:45:33 +02:00
|
|
|
: m_projectPart(projectPart)
|
2018-10-09 14:26:47 +02:00
|
|
|
, m_useSystemHeader(useSystemHeader)
|
2018-11-30 12:15:07 +01:00
|
|
|
, m_useTweakedHeaderPaths(useTweakedHeaderPaths)
|
2018-11-30 11:02:49 +01:00
|
|
|
, m_useLanguageDefines(useLanguageDefines)
|
2019-01-31 10:16:28 +01:00
|
|
|
, m_useBuildSystemWarnings(useBuildSystemWarnings)
|
2018-11-30 10:34:05 +01:00
|
|
|
, m_clangVersion(clangVersion)
|
2020-08-24 10:46:58 +02:00
|
|
|
, m_clangIncludeDirectory(clangIncludeDirectory)
|
2017-09-27 10:32:52 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 10:34:05 +01:00
|
|
|
QStringList CompilerOptionsBuilder::build(ProjectFile::Kind fileKind,
|
|
|
|
|
UsePrecompiledHeaders usePrecompiledHeaders)
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2017-09-27 10:32:52 +02:00
|
|
|
m_options.clear();
|
2019-01-08 16:22:39 +01:00
|
|
|
evaluateCompilerFlags();
|
2017-09-27 10:32:52 +02:00
|
|
|
|
2018-05-03 11:08:54 +02:00
|
|
|
if (fileKind == ProjectFile::CHeader || fileKind == ProjectFile::CSource) {
|
2019-01-09 18:31:20 +01:00
|
|
|
QTC_ASSERT(m_projectPart.languageVersion <= Utils::LanguageVersion::LatestC,
|
2018-05-03 11:08:54 +02:00
|
|
|
return QStringList(););
|
|
|
|
|
}
|
2018-04-30 10:20:22 +02:00
|
|
|
|
2018-10-31 12:06:08 +01:00
|
|
|
if (fileKind == ProjectFile::CXXHeader || fileKind == ProjectFile::CXXSource) {
|
2019-01-09 18:31:20 +01:00
|
|
|
QTC_ASSERT(m_projectPart.languageVersion > Utils::LanguageVersion::LatestC,
|
2018-10-31 12:06:08 +01:00
|
|
|
return QStringList(););
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
addCompilerFlags();
|
2018-07-10 15:53:51 +02:00
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
addSyntaxOnly();
|
2017-09-27 10:32:52 +02:00
|
|
|
addWordWidth();
|
|
|
|
|
addTargetTriple();
|
2019-01-09 13:56:00 +01:00
|
|
|
updateFileLanguage(fileKind);
|
|
|
|
|
addLanguageVersionAndExtensions();
|
2020-08-29 23:34:18 +03:00
|
|
|
addMsvcExceptions();
|
2017-09-27 10:32:52 +02:00
|
|
|
|
2018-06-11 12:52:04 +02:00
|
|
|
addIncludedFiles(m_projectPart.includedFiles); // GCC adds these before precompiled headers.
|
2019-01-08 16:22:39 +01:00
|
|
|
addPrecompiledHeaderOptions(usePrecompiledHeaders);
|
|
|
|
|
addProjectConfigFileInclude();
|
|
|
|
|
|
|
|
|
|
addMsvcCompatibilityVersion();
|
2019-01-11 15:50:39 +01:00
|
|
|
addProjectMacros();
|
2017-09-27 10:32:52 +02:00
|
|
|
undefineClangVersionMacrosForMsvc();
|
|
|
|
|
undefineCppLanguageFeatureMacrosForMsvc2015();
|
2017-11-21 13:28:55 +01:00
|
|
|
addDefineFunctionMacrosMsvc();
|
2017-09-27 10:32:52 +02:00
|
|
|
|
|
|
|
|
addHeaderPathOptions();
|
|
|
|
|
|
|
|
|
|
addExtraOptions();
|
|
|
|
|
|
2018-09-17 15:31:50 +02:00
|
|
|
insertWrappedQtHeaders();
|
2020-07-09 09:44:39 +02:00
|
|
|
insertWrappedMingwHeaders();
|
2018-08-23 15:45:33 +02:00
|
|
|
|
2017-09-27 10:32:52 +02:00
|
|
|
return options();
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
void CompilerOptionsBuilder::add(const QString &arg, bool gccOnlyOption)
|
|
|
|
|
{
|
|
|
|
|
add(QStringList{arg}, gccOnlyOption);
|
|
|
|
|
}
|
|
|
|
|
|
2021-07-01 17:12:55 +02:00
|
|
|
void CompilerOptionsBuilder::prepend(const QString &arg)
|
|
|
|
|
{
|
|
|
|
|
m_options.prepend(arg);
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
void CompilerOptionsBuilder::add(const QStringList &args, bool gccOnlyOptions)
|
|
|
|
|
{
|
|
|
|
|
m_options.append((gccOnlyOptions && isClStyle()) ? clangArgsForCl(args) : args);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::addSyntaxOnly()
|
|
|
|
|
{
|
|
|
|
|
isClStyle() ? add("/Zs") : add("-fsyntax-only");
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-13 10:22:16 +01:00
|
|
|
QStringList createLanguageOptionGcc(ProjectFile::Kind fileKind, bool objcExt)
|
2018-07-10 15:53:51 +02:00
|
|
|
{
|
2018-11-30 10:34:05 +01:00
|
|
|
QStringList options;
|
2018-07-10 15:53:51 +02:00
|
|
|
|
|
|
|
|
switch (fileKind) {
|
|
|
|
|
case ProjectFile::Unclassified:
|
|
|
|
|
case ProjectFile::Unsupported:
|
|
|
|
|
break;
|
|
|
|
|
case ProjectFile::CHeader:
|
|
|
|
|
if (objcExt)
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "objective-c-header";
|
2018-07-10 15:53:51 +02:00
|
|
|
else
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "c-header";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
case ProjectFile::CXXHeader:
|
|
|
|
|
default:
|
|
|
|
|
if (!objcExt) {
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "c++-header";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
Q_FALLTHROUGH();
|
|
|
|
|
case ProjectFile::ObjCHeader:
|
|
|
|
|
case ProjectFile::ObjCXXHeader:
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "objective-c++-header";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ProjectFile::CSource:
|
|
|
|
|
if (!objcExt) {
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "c";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
Q_FALLTHROUGH();
|
|
|
|
|
case ProjectFile::ObjCSource:
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "objective-c";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
case ProjectFile::CXXSource:
|
|
|
|
|
if (!objcExt) {
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "c++";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
Q_FALLTHROUGH();
|
|
|
|
|
case ProjectFile::ObjCXXSource:
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "objective-c++";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
case ProjectFile::OpenCLSource:
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "cl";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
case ProjectFile::CudaSource:
|
2018-11-30 10:34:05 +01:00
|
|
|
options += "cuda";
|
2018-07-10 15:53:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 10:34:05 +01:00
|
|
|
if (!options.isEmpty())
|
|
|
|
|
options.prepend("-x");
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2018-11-30 10:34:05 +01:00
|
|
|
return options;
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2016-10-17 17:15:15 +02:00
|
|
|
void CompilerOptionsBuilder::addWordWidth()
|
|
|
|
|
{
|
|
|
|
|
const QString argument = m_projectPart.toolChainWordWidth == ProjectPart::WordWidth64Bit
|
2018-12-04 09:19:59 +01:00
|
|
|
? QLatin1String("-m64")
|
|
|
|
|
: QLatin1String("-m32");
|
2016-10-17 17:15:15 +02:00
|
|
|
add(argument);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-08 14:19:23 +02:00
|
|
|
void CompilerOptionsBuilder::addTargetTriple()
|
|
|
|
|
{
|
2019-01-11 15:32:12 +01:00
|
|
|
// Only "--target=" style is accepted in both g++ and cl driver modes.
|
|
|
|
|
if (!m_projectPart.toolChainTargetTriple.isEmpty())
|
|
|
|
|
add("--target=" + m_projectPart.toolChainTargetTriple);
|
2016-04-08 14:19:23 +02:00
|
|
|
}
|
|
|
|
|
|
2017-12-15 15:28:13 +01:00
|
|
|
void CompilerOptionsBuilder::addExtraCodeModelFlags()
|
|
|
|
|
{
|
|
|
|
|
// extraCodeModelFlags keep build architecture for cross-compilation.
|
|
|
|
|
// In case of iOS build target triple has aarch64 archtecture set which makes
|
|
|
|
|
// code model fail with CXError_Failure. To fix that we explicitly provide architecture.
|
2019-01-11 15:32:12 +01:00
|
|
|
add(m_projectPart.extraCodeModelFlags);
|
2017-12-15 15:28:13 +01:00
|
|
|
}
|
|
|
|
|
|
2018-12-17 12:06:57 +01:00
|
|
|
void CompilerOptionsBuilder::addPicIfCompilerFlagsContainsIt()
|
|
|
|
|
{
|
|
|
|
|
if (m_projectPart.compilerFlags.contains("-fPIC"))
|
|
|
|
|
add("-fPIC");
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-08 16:22:39 +01:00
|
|
|
void CompilerOptionsBuilder::addCompilerFlags()
|
|
|
|
|
{
|
2019-01-11 15:32:12 +01:00
|
|
|
add(m_compilerFlags.flags);
|
2019-01-08 16:22:39 +01:00
|
|
|
}
|
|
|
|
|
|
2020-08-29 23:34:18 +03:00
|
|
|
void CompilerOptionsBuilder::addMsvcExceptions()
|
|
|
|
|
{
|
|
|
|
|
if (!m_clStyle)
|
|
|
|
|
return;
|
|
|
|
|
if (Utils::anyOf(m_projectPart.toolChainMacros, [](const ProjectExplorer::Macro ¯o) {
|
|
|
|
|
return macro.key == "_CPPUNWIND";
|
|
|
|
|
})) {
|
|
|
|
|
enableExceptions();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-19 11:58:24 +01:00
|
|
|
void CompilerOptionsBuilder::enableExceptions()
|
|
|
|
|
{
|
|
|
|
|
// With "--driver-mode=cl" exceptions are disabled (clang 8).
|
|
|
|
|
// This is most likely due to incomplete exception support of clang.
|
|
|
|
|
// However, as we need exception support only in the frontend,
|
|
|
|
|
// enabling them explicitly should be fine.
|
|
|
|
|
if (m_projectPart.languageVersion > ::Utils::LanguageVersion::LatestC)
|
|
|
|
|
add("-fcxx-exceptions");
|
|
|
|
|
add("-fexceptions");
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-09 09:44:39 +02:00
|
|
|
void CompilerOptionsBuilder::insertWrappedQtHeaders()
|
|
|
|
|
{
|
2020-10-28 12:10:55 +01:00
|
|
|
if (m_useTweakedHeaderPaths == UseTweakedHeaderPaths::Yes)
|
|
|
|
|
insertWrappedHeaders(wrappedQtHeadersIncludePath());
|
2020-07-09 09:44:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::insertWrappedMingwHeaders()
|
|
|
|
|
{
|
|
|
|
|
insertWrappedHeaders(wrappedMingwHeadersIncludePath());
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-17 15:31:50 +02:00
|
|
|
static QString creatorResourcePath()
|
|
|
|
|
{
|
|
|
|
|
#ifndef UNIT_TESTS
|
2021-04-22 16:15:26 +02:00
|
|
|
return Core::ICore::resourcePath().toString();
|
2018-09-17 15:31:50 +02:00
|
|
|
#else
|
2018-09-26 14:10:35 +02:00
|
|
|
return QDir::toNativeSeparators(QString::fromUtf8(QTC_RESOURCE_DIR ""));
|
2018-09-17 15:31:50 +02:00
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-09 09:44:39 +02:00
|
|
|
void CompilerOptionsBuilder::insertWrappedHeaders(const QStringList &relPaths)
|
2018-09-17 15:31:50 +02:00
|
|
|
{
|
2018-11-30 12:15:07 +01:00
|
|
|
if (m_useTweakedHeaderPaths == UseTweakedHeaderPaths::No)
|
2018-10-30 10:14:43 +01:00
|
|
|
return;
|
2020-07-09 09:44:39 +02:00
|
|
|
if (relPaths.isEmpty())
|
|
|
|
|
return;
|
2018-10-30 10:14:43 +01:00
|
|
|
|
2020-07-09 09:44:39 +02:00
|
|
|
QStringList args;
|
|
|
|
|
for (const QString &relPath : relPaths) {
|
|
|
|
|
static const QString baseDir = creatorResourcePath() + "/cplusplus";
|
|
|
|
|
const QString fullPath = baseDir + '/' + relPath;
|
|
|
|
|
QTC_ASSERT(QDir(fullPath).exists(), continue);
|
|
|
|
|
args << includeUserPathOption << QDir::toNativeSeparators(fullPath);
|
|
|
|
|
}
|
2018-09-17 15:31:50 +02:00
|
|
|
|
|
|
|
|
const int index = m_options.indexOf(QRegularExpression("\\A-I.*\\z"));
|
|
|
|
|
if (index < 0)
|
2020-07-09 09:44:39 +02:00
|
|
|
add(args);
|
2018-09-17 15:31:50 +02:00
|
|
|
else
|
2020-07-09 09:44:39 +02:00
|
|
|
m_options = m_options.mid(0, index) + args + m_options.mid(index);
|
2018-09-17 15:31:50 +02:00
|
|
|
}
|
|
|
|
|
|
2016-10-17 13:20:29 +02:00
|
|
|
void CompilerOptionsBuilder::addHeaderPathOptions()
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2018-12-19 18:37:02 +01:00
|
|
|
HeaderPathFilter filter{m_projectPart,
|
|
|
|
|
m_useTweakedHeaderPaths,
|
|
|
|
|
m_clangVersion,
|
2020-08-24 10:46:58 +02:00
|
|
|
m_clangIncludeDirectory};
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2018-12-19 18:37:02 +01:00
|
|
|
filter.process();
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2018-12-19 18:37:02 +01:00
|
|
|
using ProjectExplorer::HeaderPath;
|
|
|
|
|
using ProjectExplorer::HeaderPathType;
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2021-02-15 10:03:57 +01:00
|
|
|
for (const HeaderPath &headerPath : qAsConst(filter.userHeaderPaths))
|
2019-01-17 15:27:36 +01:00
|
|
|
addIncludeDirOptionForPath(headerPath);
|
2021-02-15 10:03:57 +01:00
|
|
|
for (const HeaderPath &headerPath : qAsConst(filter.systemHeaderPaths))
|
2019-01-17 15:27:36 +01:00
|
|
|
addIncludeDirOptionForPath(headerPath);
|
|
|
|
|
|
2020-11-25 16:28:28 +01:00
|
|
|
if (m_useTweakedHeaderPaths != UseTweakedHeaderPaths::No) {
|
2019-01-17 15:27:36 +01:00
|
|
|
QTC_CHECK(!m_clangVersion.isEmpty()
|
|
|
|
|
&& "Clang resource directory is required with UseTweakedHeaderPaths::Yes.");
|
2019-01-11 15:32:12 +01:00
|
|
|
|
2019-01-17 15:27:36 +01:00
|
|
|
// Exclude all built-in includes and Clang resource directory.
|
|
|
|
|
m_options.prepend("-nostdinc++");
|
|
|
|
|
m_options.prepend("-nostdinc");
|
2019-01-11 15:32:12 +01:00
|
|
|
|
2021-02-15 10:03:57 +01:00
|
|
|
for (const HeaderPath &headerPath : qAsConst(filter.builtInHeaderPaths))
|
2019-01-17 15:27:36 +01:00
|
|
|
addIncludeDirOptionForPath(headerPath);
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-11 15:57:16 +01:00
|
|
|
void CompilerOptionsBuilder::addIncludeFile(const QString &file)
|
2018-06-11 12:52:04 +02:00
|
|
|
{
|
2021-01-11 15:57:16 +01:00
|
|
|
if (QFile::exists(file)) {
|
|
|
|
|
add({isClStyle() ? QLatin1String(includeFileOptionCl)
|
|
|
|
|
: QLatin1String(includeFileOptionGcc),
|
|
|
|
|
QDir::toNativeSeparators(file)});
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-06-11 12:52:04 +02:00
|
|
|
|
2021-01-11 15:57:16 +01:00
|
|
|
void CompilerOptionsBuilder::addIncludedFiles(const QStringList &files)
|
|
|
|
|
{
|
2018-06-11 12:52:04 +02:00
|
|
|
for (const QString &file : files) {
|
2021-01-11 15:57:16 +01:00
|
|
|
if (m_projectPart.precompiledHeaders.contains(file))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
addIncludeFile(file);
|
2018-06-11 12:52:04 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-11-30 10:34:05 +01:00
|
|
|
void CompilerOptionsBuilder::addPrecompiledHeaderOptions(UsePrecompiledHeaders usePrecompiledHeaders)
|
2016-11-02 12:21:54 +03:00
|
|
|
{
|
2021-01-11 15:57:16 +01:00
|
|
|
if (usePrecompiledHeaders == UsePrecompiledHeaders::No)
|
|
|
|
|
return;
|
|
|
|
|
|
2018-11-30 10:34:05 +01:00
|
|
|
for (const QString &pchFile : m_projectPart.precompiledHeaders) {
|
2021-01-11 15:57:16 +01:00
|
|
|
addIncludeFile(pchFile);
|
2016-11-02 12:21:54 +03:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:50:39 +01:00
|
|
|
void CompilerOptionsBuilder::addProjectMacros()
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2019-11-27 09:05:49 +01:00
|
|
|
static const int useMacros = qEnvironmentVariableIntValue("QTC_CLANG_USE_TOOLCHAIN_MACROS");
|
|
|
|
|
|
2020-08-24 11:21:24 +02:00
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::CUSTOM_TOOLCHAIN_TYPEID
|
|
|
|
|
|| m_projectPart.toolchainType.name().contains("BareMetal")
|
|
|
|
|
|| useMacros) {
|
2019-11-27 09:05:49 +01:00
|
|
|
addMacros(m_projectPart.toolChainMacros);
|
2020-08-24 11:21:24 +02:00
|
|
|
}
|
2019-11-27 09:05:49 +01:00
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
addMacros(m_projectPart.projectMacros);
|
2016-07-07 11:45:46 +02:00
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
void CompilerOptionsBuilder::addMacros(const ProjectExplorer::Macros ¯os)
|
2016-07-07 11:45:46 +02:00
|
|
|
{
|
2018-11-30 10:34:05 +01:00
|
|
|
QStringList options;
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
for (const ProjectExplorer::Macro ¯o : macros) {
|
|
|
|
|
if (excludeDefineDirective(macro))
|
2016-01-11 21:09:06 +01:00
|
|
|
continue;
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
const QString defineOption = defineDirectiveToDefineOption(macro);
|
2018-11-30 10:34:05 +01:00
|
|
|
if (!options.contains(defineOption))
|
|
|
|
|
options.append(defineOption);
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
add(options);
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-09 13:56:00 +01:00
|
|
|
void CompilerOptionsBuilder::updateFileLanguage(ProjectFile::Kind fileKind)
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2019-01-11 15:32:12 +01:00
|
|
|
if (isClStyle()) {
|
|
|
|
|
QString option;
|
|
|
|
|
if (ProjectFile::isC(fileKind))
|
|
|
|
|
option = "/TC";
|
|
|
|
|
else if (ProjectFile::isCxx(fileKind))
|
|
|
|
|
option = "/TP";
|
|
|
|
|
else
|
2019-01-21 08:33:03 +01:00
|
|
|
return; // Do not add anything if we haven't set a file kind yet.
|
2019-01-11 15:32:12 +01:00
|
|
|
|
|
|
|
|
int langOptIndex = m_options.indexOf("/TC");
|
|
|
|
|
if (langOptIndex == -1)
|
|
|
|
|
langOptIndex = m_options.indexOf("/TP");
|
|
|
|
|
if (langOptIndex == -1)
|
|
|
|
|
add(option);
|
|
|
|
|
else
|
|
|
|
|
m_options[langOptIndex] = option;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-08 09:49:02 +02:00
|
|
|
const bool objcExt = m_projectPart.languageExtensions
|
2019-01-09 18:31:20 +01:00
|
|
|
& Utils::LanguageExtension::ObjectiveC;
|
2016-01-11 21:09:06 +01:00
|
|
|
const QStringList options = createLanguageOptionGcc(fileKind, objcExt);
|
2018-07-10 15:53:51 +02:00
|
|
|
if (options.isEmpty())
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
QTC_ASSERT(options.size() == 2, return;);
|
|
|
|
|
int langOptIndex = m_options.indexOf("-x");
|
2018-11-30 10:34:05 +01:00
|
|
|
if (langOptIndex == -1)
|
2019-01-11 15:32:12 +01:00
|
|
|
add(options);
|
2018-11-30 10:34:05 +01:00
|
|
|
else
|
2018-07-10 15:53:51 +02:00
|
|
|
m_options[langOptIndex + 1] = options[1];
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-09 13:56:00 +01:00
|
|
|
void CompilerOptionsBuilder::addLanguageVersionAndExtensions()
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2019-01-09 18:31:20 +01:00
|
|
|
using Utils::LanguageExtension;
|
|
|
|
|
using Utils::LanguageVersion;
|
2018-10-08 09:49:02 +02:00
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
if (m_compilerFlags.isLanguageVersionSpecified)
|
|
|
|
|
return;
|
2018-04-30 10:20:22 +02:00
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
QString option;
|
|
|
|
|
if (isClStyle()) {
|
2019-01-08 16:22:39 +01:00
|
|
|
switch (m_projectPart.languageVersion) {
|
2019-01-11 15:32:12 +01:00
|
|
|
default:
|
2019-01-08 16:22:39 +01:00
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX14:
|
2019-01-11 15:32:12 +01:00
|
|
|
option = "/std:c++14";
|
2019-01-08 16:22:39 +01:00
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX17:
|
2019-01-11 15:32:12 +01:00
|
|
|
option = "/std:c++17";
|
2019-01-08 16:22:39 +01:00
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX2a:
|
2019-01-11 15:32:12 +01:00
|
|
|
option = "/std:c++latest";
|
2019-01-08 16:22:39 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
if (!option.isEmpty()) {
|
|
|
|
|
add(option);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Continue in case no cl-style option could be chosen.
|
|
|
|
|
}
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
const Utils::LanguageExtensions languageExtensions = m_projectPart.languageExtensions;
|
|
|
|
|
const bool gnuExtensions = languageExtensions & LanguageExtension::Gnu;
|
2018-11-09 14:21:43 +01:00
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
switch (m_projectPart.languageVersion) {
|
|
|
|
|
case LanguageVersion::C89:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu89") : QLatin1String("-std=c89"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::C99:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu99") : QLatin1String("-std=c99"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::C11:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu11") : QLatin1String("-std=c11"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::C18:
|
|
|
|
|
// Clang 6, 7 and current trunk do not accept "gnu18"/"c18", so use the "*17" variants.
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu17") : QLatin1String("-std=c17"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX11:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu++11") : QLatin1String("-std=c++11"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX98:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu++98") : QLatin1String("-std=c++98"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX03:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu++03") : QLatin1String("-std=c++03"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX14:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu++14") : QLatin1String("-std=c++14"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX17:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu++17") : QLatin1String("-std=c++17"));
|
|
|
|
|
break;
|
|
|
|
|
case LanguageVersion::CXX2a:
|
|
|
|
|
option = (gnuExtensions ? QLatin1String("-std=gnu++2a") : QLatin1String("-std=c++2a"));
|
|
|
|
|
break;
|
2019-03-21 17:55:24 +01:00
|
|
|
case LanguageVersion::None:
|
|
|
|
|
break;
|
2019-01-08 16:22:39 +01:00
|
|
|
}
|
2016-01-11 21:09:06 +01:00
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
add(option, /*gccOnlyOption=*/true);
|
2016-01-11 21:09:06 +01:00
|
|
|
}
|
|
|
|
|
|
2016-04-11 11:53:50 +02:00
|
|
|
static QByteArray toMsCompatibilityVersionFormat(const QByteArray &mscFullVer)
|
|
|
|
|
{
|
|
|
|
|
return mscFullVer.left(2)
|
|
|
|
|
+ QByteArray(".")
|
|
|
|
|
+ mscFullVer.mid(2, 2);
|
|
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
static QByteArray msCompatibilityVersionFromDefines(const ProjectExplorer::Macros ¯os)
|
2016-04-11 11:53:50 +02:00
|
|
|
{
|
2017-02-07 15:00:38 +01:00
|
|
|
for (const ProjectExplorer::Macro ¯o : macros) {
|
|
|
|
|
if (macro.key == "_MSC_FULL_VER")
|
2016-04-11 11:53:50 +02:00
|
|
|
return toMsCompatibilityVersionFormat(macro.value);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QByteArray();
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-10 11:41:26 +01:00
|
|
|
QByteArray CompilerOptionsBuilder::msvcVersion() const
|
|
|
|
|
{
|
|
|
|
|
const QByteArray version = msCompatibilityVersionFromDefines(m_projectPart.toolChainMacros);
|
|
|
|
|
return !version.isEmpty() ? version
|
|
|
|
|
: msCompatibilityVersionFromDefines(m_projectPart.projectMacros);
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 11:53:50 +02:00
|
|
|
void CompilerOptionsBuilder::addMsvcCompatibilityVersion()
|
|
|
|
|
{
|
2018-11-30 15:12:33 +01:00
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
|
|
|
|
|| m_projectPart.toolchainType == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID) {
|
2019-01-10 11:41:26 +01:00
|
|
|
const QByteArray msvcVer = msvcVersion();
|
|
|
|
|
if (!msvcVer.isEmpty())
|
|
|
|
|
add(QLatin1String("-fms-compatibility-version=") + msvcVer);
|
2016-04-11 11:53:50 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2016-04-11 17:34:02 +02:00
|
|
|
static QStringList languageFeatureMacros()
|
|
|
|
|
{
|
2017-06-15 17:40:32 +02:00
|
|
|
// CLANG-UPGRADE-CHECK: Update known language features macros.
|
2017-09-29 13:46:53 +02:00
|
|
|
// Collected with the following command line.
|
|
|
|
|
// * Use latest -fms-compatibility-version and -std possible.
|
|
|
|
|
// * Compatibility version 19 vs 1910 did not matter.
|
|
|
|
|
// $ clang++ -fms-compatibility-version=19 -std=c++1z -dM -E D:\empty.cpp | grep __cpp_
|
2018-11-30 10:34:05 +01:00
|
|
|
static const QStringList macros{
|
|
|
|
|
"__cpp_aggregate_bases",
|
|
|
|
|
"__cpp_aggregate_nsdmi",
|
|
|
|
|
"__cpp_alias_templates",
|
|
|
|
|
"__cpp_aligned_new",
|
|
|
|
|
"__cpp_attributes",
|
|
|
|
|
"__cpp_binary_literals",
|
|
|
|
|
"__cpp_capture_star_this",
|
|
|
|
|
"__cpp_constexpr",
|
2020-11-17 22:53:59 +01:00
|
|
|
"__cpp_constexpr_in_decltype",
|
2018-11-30 10:34:05 +01:00
|
|
|
"__cpp_decltype",
|
|
|
|
|
"__cpp_decltype_auto",
|
|
|
|
|
"__cpp_deduction_guides",
|
|
|
|
|
"__cpp_delegating_constructors",
|
|
|
|
|
"__cpp_digit_separators",
|
|
|
|
|
"__cpp_enumerator_attributes",
|
|
|
|
|
"__cpp_exceptions",
|
|
|
|
|
"__cpp_fold_expressions",
|
|
|
|
|
"__cpp_generic_lambdas",
|
|
|
|
|
"__cpp_guaranteed_copy_elision",
|
|
|
|
|
"__cpp_hex_float",
|
|
|
|
|
"__cpp_if_constexpr",
|
2019-04-04 14:50:10 +02:00
|
|
|
"__cpp_impl_destroying_delete",
|
2018-11-30 10:34:05 +01:00
|
|
|
"__cpp_inheriting_constructors",
|
|
|
|
|
"__cpp_init_captures",
|
|
|
|
|
"__cpp_initializer_lists",
|
|
|
|
|
"__cpp_inline_variables",
|
|
|
|
|
"__cpp_lambdas",
|
|
|
|
|
"__cpp_namespace_attributes",
|
|
|
|
|
"__cpp_nested_namespace_definitions",
|
|
|
|
|
"__cpp_noexcept_function_type",
|
|
|
|
|
"__cpp_nontype_template_args",
|
|
|
|
|
"__cpp_nontype_template_parameter_auto",
|
|
|
|
|
"__cpp_nsdmi",
|
|
|
|
|
"__cpp_range_based_for",
|
|
|
|
|
"__cpp_raw_strings",
|
|
|
|
|
"__cpp_ref_qualifiers",
|
|
|
|
|
"__cpp_return_type_deduction",
|
|
|
|
|
"__cpp_rtti",
|
|
|
|
|
"__cpp_rvalue_references",
|
|
|
|
|
"__cpp_static_assert",
|
|
|
|
|
"__cpp_structured_bindings",
|
|
|
|
|
"__cpp_template_auto",
|
|
|
|
|
"__cpp_threadsafe_static_init",
|
|
|
|
|
"__cpp_unicode_characters",
|
|
|
|
|
"__cpp_unicode_literals",
|
|
|
|
|
"__cpp_user_defined_literals",
|
|
|
|
|
"__cpp_variable_templates",
|
|
|
|
|
"__cpp_variadic_templates",
|
|
|
|
|
"__cpp_variadic_using",
|
2016-04-11 17:34:02 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
return macros;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::undefineCppLanguageFeatureMacrosForMsvc2015()
|
|
|
|
|
{
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
|
|
|
|
&& m_projectPart.isMsvc2015Toolchain) {
|
2017-09-29 13:46:53 +02:00
|
|
|
// Undefine the language feature macros that are pre-defined in clang-cl,
|
|
|
|
|
// but not in MSVC's cl.exe.
|
2018-11-30 10:34:05 +01:00
|
|
|
const QStringList macroNames = languageFeatureMacros();
|
|
|
|
|
for (const QString ¯oName : macroNames)
|
|
|
|
|
add(undefineOption + macroName);
|
2016-04-11 17:34:02 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:18:28 +01:00
|
|
|
void CompilerOptionsBuilder::addDefineFunctionMacrosMsvc()
|
|
|
|
|
{
|
2018-11-30 10:34:05 +01:00
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
2020-11-26 11:13:55 +01:00
|
|
|
addMacros({{"__FUNCSIG__", "\"void __cdecl someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580(void)\""},
|
|
|
|
|
{"__FUNCTION__", "\"someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580\""},
|
|
|
|
|
{"__FUNCDNAME__", "\"?someLegalAndLongishFunctionNameThatWorksAroundQTCREATORBUG-24580@@YAXXZ\""}});
|
2018-11-30 10:34:05 +01:00
|
|
|
}
|
2017-11-21 12:18:28 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
void CompilerOptionsBuilder::addIncludeDirOptionForPath(const ProjectExplorer::HeaderPath &path)
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2019-01-11 15:32:12 +01:00
|
|
|
if (path.type == ProjectExplorer::HeaderPathType::Framework) {
|
2019-01-17 11:54:05 +01:00
|
|
|
QTC_ASSERT(!isClStyle(), return;);
|
2019-01-11 15:32:12 +01:00
|
|
|
add({"-F", QDir::toNativeSeparators(path.path)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool systemPath = false;
|
|
|
|
|
if (path.type == ProjectExplorer::HeaderPathType::BuiltIn) {
|
|
|
|
|
systemPath = true;
|
|
|
|
|
} else if (path.type == ProjectExplorer::HeaderPathType::System) {
|
|
|
|
|
if (m_useSystemHeader == UseSystemHeader::Yes)
|
|
|
|
|
systemPath = true;
|
|
|
|
|
} else {
|
|
|
|
|
// ProjectExplorer::HeaderPathType::User
|
|
|
|
|
if (m_useSystemHeader == UseSystemHeader::Yes
|
|
|
|
|
&& !path.path.startsWith(m_projectPart.project->rootProjectDirectory().toString())) {
|
|
|
|
|
systemPath = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (systemPath) {
|
|
|
|
|
add({includeSystemPathOption, QDir::toNativeSeparators(path.path)}, true);
|
|
|
|
|
return;
|
2017-02-07 15:00:38 +01:00
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
add({includeUserPathOption, QDir::toNativeSeparators(path.path)});
|
2016-11-02 12:21:54 +03:00
|
|
|
}
|
|
|
|
|
|
2017-02-07 15:00:38 +01:00
|
|
|
bool CompilerOptionsBuilder::excludeDefineDirective(const ProjectExplorer::Macro ¯o) const
|
2016-01-11 21:09:06 +01:00
|
|
|
{
|
2018-09-27 10:18:44 +02:00
|
|
|
// Avoid setting __cplusplus & co as this might conflict with other command line flags.
|
|
|
|
|
// Clang should set __cplusplus based on -std= and -fms-compatibility-version version.
|
2018-10-09 14:26:47 +02:00
|
|
|
static const auto languageDefines = {"__cplusplus",
|
|
|
|
|
"__STDC_VERSION__",
|
|
|
|
|
"_MSC_BUILD",
|
|
|
|
|
"_MSVC_LANG",
|
|
|
|
|
"_MSC_FULL_VER",
|
|
|
|
|
"_MSC_VER"};
|
2018-11-30 11:02:49 +01:00
|
|
|
if (m_useLanguageDefines == UseLanguageDefines::No
|
2018-10-09 14:26:47 +02:00
|
|
|
&& std::find(languageDefines.begin(),
|
|
|
|
|
languageDefines.end(),
|
|
|
|
|
macro.key) != languageDefines.end()) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
2018-09-27 10:18:44 +02:00
|
|
|
|
2017-11-06 16:00:25 +01:00
|
|
|
// Ignore for all compiler toolchains since LLVM has it's own implementation for
|
|
|
|
|
// __has_include(STR) and __has_include_next(STR)
|
|
|
|
|
if (macro.key.startsWith("__has_include"))
|
2016-01-11 21:09:06 +01:00
|
|
|
return true;
|
|
|
|
|
|
2016-10-31 15:25:59 +01:00
|
|
|
// If _FORTIFY_SOURCE is defined (typically in release mode), it will
|
|
|
|
|
// enable the inclusion of extra headers to help catching buffer overflows
|
|
|
|
|
// (e.g. wchar.h includes wchar2.h). These extra headers use
|
|
|
|
|
// __builtin_va_arg_pack, which clang does not support (yet), so avoid
|
|
|
|
|
// including those.
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::GCC_TOOLCHAIN_TYPEID
|
2017-02-07 15:00:38 +01:00
|
|
|
&& macro.key == "_FORTIFY_SOURCE") {
|
2016-10-31 15:25:59 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-11-01 14:37:57 +01:00
|
|
|
// MinGW 6 supports some fancy asm output flags and uses them in an
|
|
|
|
|
// intrinsics header pulled in by windows.h. Clang does not know them.
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID
|
2017-02-07 15:00:38 +01:00
|
|
|
&& macro.key == "__GCC_ASM_FLAG_OUTPUTS__") {
|
2016-11-01 14:37:57 +01:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2020-07-09 09:44:39 +02:00
|
|
|
QStringList CompilerOptionsBuilder::wrappedQtHeadersIncludePath() const
|
2018-08-23 15:45:33 +02:00
|
|
|
{
|
2020-07-09 09:44:39 +02:00
|
|
|
if (m_projectPart.qtVersion == Utils::QtVersion::None)
|
|
|
|
|
return {};
|
|
|
|
|
return {"wrappedQtHeaders", "wrappedQtHeaders/QtCore"};
|
|
|
|
|
}
|
2018-08-23 15:45:33 +02:00
|
|
|
|
2020-07-09 09:44:39 +02:00
|
|
|
QStringList CompilerOptionsBuilder::wrappedMingwHeadersIncludePath() const
|
|
|
|
|
{
|
|
|
|
|
if (m_projectPart.toolchainType != ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID)
|
|
|
|
|
return {};
|
|
|
|
|
return {"wrappedMingwHeaders"};
|
2018-08-23 15:45:33 +02:00
|
|
|
}
|
|
|
|
|
|
2017-09-27 10:32:52 +02:00
|
|
|
void CompilerOptionsBuilder::addProjectConfigFileInclude()
|
|
|
|
|
{
|
|
|
|
|
if (!m_projectPart.projectConfigFile.isEmpty()) {
|
2019-01-11 15:32:12 +01:00
|
|
|
add({isClStyle() ? QLatin1String(includeFileOptionCl) : QLatin1String(includeFileOptionGcc),
|
|
|
|
|
QDir::toNativeSeparators(m_projectPart.projectConfigFile)});
|
2017-09-27 10:32:52 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CompilerOptionsBuilder::undefineClangVersionMacrosForMsvc()
|
|
|
|
|
{
|
|
|
|
|
if (m_projectPart.toolchainType == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID) {
|
2019-01-10 11:41:26 +01:00
|
|
|
const QByteArray msvcVer = msvcVersion();
|
|
|
|
|
if (msvcVer.toFloat() < 14.f) {
|
|
|
|
|
// Original fix was only for msvc 2013 (version 12.0)
|
|
|
|
|
// Undefying them for newer versions is not necessary and breaks boost.
|
2019-01-15 08:30:54 +01:00
|
|
|
static const QStringList macroNames {
|
2019-01-10 11:41:26 +01:00
|
|
|
"__clang__",
|
|
|
|
|
"__clang_major__",
|
|
|
|
|
"__clang_minor__",
|
|
|
|
|
"__clang_patchlevel__",
|
|
|
|
|
"__clang_version__"
|
|
|
|
|
};
|
|
|
|
|
|
2019-01-15 08:30:54 +01:00
|
|
|
for (const QString ¯oName : macroNames)
|
|
|
|
|
add(undefineOption + macroName);
|
2019-01-10 11:41:26 +01:00
|
|
|
}
|
2017-09-27 10:32:52 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-11 18:05:28 +01:00
|
|
|
void CompilerOptionsBuilder::reset()
|
|
|
|
|
{
|
|
|
|
|
m_options.clear();
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-08 16:22:39 +01:00
|
|
|
// Some example command lines for a "Qt Console Application":
|
|
|
|
|
// CMakeProject: -fPIC -std=gnu++11
|
|
|
|
|
// QbsProject: -m64 -fPIC -std=c++11 -fexceptions
|
|
|
|
|
// QMakeProject: -pipe -Whello -g -std=gnu++11 -Wall -W -D_REENTRANT -fPIC
|
|
|
|
|
void CompilerOptionsBuilder::evaluateCompilerFlags()
|
|
|
|
|
{
|
2019-02-12 09:46:25 +01:00
|
|
|
static QStringList userBlackList = QString::fromLocal8Bit(
|
|
|
|
|
qgetenv("QTC_CLANG_CMD_OPTIONS_BLACKLIST"))
|
2020-07-21 10:19:36 +02:00
|
|
|
.split(';', Qt::SkipEmptyParts);
|
2019-02-12 09:46:25 +01:00
|
|
|
|
2020-06-26 13:59:38 +02:00
|
|
|
const Utils::Id &toolChain = m_projectPart.toolchainType;
|
2019-01-11 15:32:12 +01:00
|
|
|
bool containsDriverMode = false;
|
2019-01-21 15:07:04 +01:00
|
|
|
bool skipNext = false;
|
2019-10-11 15:01:09 +02:00
|
|
|
const QStringList allFlags = m_projectPart.compilerFlags + m_projectPart.extraCodeModelFlags;
|
|
|
|
|
for (const QString &option : allFlags) {
|
2019-01-21 15:07:04 +01:00
|
|
|
if (skipNext) {
|
|
|
|
|
skipNext = false;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-12 09:46:25 +01:00
|
|
|
if (userBlackList.contains(option))
|
|
|
|
|
continue;
|
|
|
|
|
|
2019-06-25 16:28:27 +02:00
|
|
|
// TODO: Make it possible that the clang binary/driver ignores unknown options,
|
|
|
|
|
// as it is done for libclang/clangd (not checking for OPT_UNKNOWN).
|
|
|
|
|
if (toolChain == ProjectExplorer::Constants::MINGW_TOOLCHAIN_TYPEID) {
|
|
|
|
|
if (option == "-fkeep-inline-dllexport" || option == "-fno-keep-inline-dllexport")
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 10:16:28 +01:00
|
|
|
// Ignore warning flags as these interfere with our user-configured diagnostics.
|
2019-01-11 15:32:12 +01:00
|
|
|
// Note that once "-w" is provided, no warnings will be emitted, even if "-Wall" follows.
|
2019-01-31 10:16:28 +01:00
|
|
|
if (m_useBuildSystemWarnings == UseBuildSystemWarnings::No
|
|
|
|
|
&& (option.startsWith("-w", Qt::CaseInsensitive)
|
|
|
|
|
|| option.startsWith("/w", Qt::CaseInsensitive) || option.startsWith("-pedantic"))) {
|
2019-01-11 15:32:12 +01:00
|
|
|
// -w, -W, /w, /W...
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-11 14:56:16 +02:00
|
|
|
// As we always set the target explicitly, filter out target args.
|
|
|
|
|
if (!m_projectPart.toolChainTargetTriple.isEmpty()) {
|
|
|
|
|
if (option.startsWith("--target="))
|
|
|
|
|
continue;
|
|
|
|
|
if (option == "-target") {
|
|
|
|
|
skipNext = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-21 15:07:04 +01:00
|
|
|
if (option == includeUserPathOption || option == includeSystemPathOption
|
|
|
|
|
|| option == includeUserPathOptionWindows) {
|
|
|
|
|
skipNext = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
if (option.startsWith("-O", Qt::CaseSensitive) || option.startsWith("/O", Qt::CaseSensitive)
|
2019-01-21 15:07:04 +01:00
|
|
|
|| option.startsWith("/M", Qt::CaseSensitive)
|
|
|
|
|
|| option.startsWith(includeUserPathOption)
|
|
|
|
|
|| option.startsWith(includeSystemPathOption)
|
|
|
|
|
|| option.startsWith(includeUserPathOptionWindows)) {
|
2019-01-11 15:32:12 +01:00
|
|
|
// Optimization and run-time flags.
|
|
|
|
|
continue;
|
2019-01-08 16:22:39 +01:00
|
|
|
}
|
2019-01-11 15:32:12 +01:00
|
|
|
|
2018-06-11 12:52:04 +02:00
|
|
|
// These were already parsed into ProjectPart::includedFiles.
|
|
|
|
|
if (option == includeFileOptionCl || option == includeFileOptionGcc) {
|
|
|
|
|
skipNext = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-04 11:07:53 +01:00
|
|
|
if (option.startsWith("/Y", Qt::CaseSensitive)
|
|
|
|
|
|| (option.startsWith("/F", Qt::CaseSensitive) && option != "/F")) {
|
|
|
|
|
// Precompiled header flags.
|
|
|
|
|
// Skip also the next option if it's not glued to the current one.
|
|
|
|
|
if (option.size() > 3)
|
|
|
|
|
skipNext = true;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
// Check whether a language version is already used.
|
|
|
|
|
QString theOption = option;
|
2019-06-25 10:03:26 +02:00
|
|
|
if (theOption.startsWith("-std=") || theOption.startsWith("--std=")) {
|
2019-01-11 15:32:12 +01:00
|
|
|
m_compilerFlags.isLanguageVersionSpecified = true;
|
|
|
|
|
theOption.replace("=c18", "=c17");
|
|
|
|
|
theOption.replace("=gnu18", "=gnu17");
|
|
|
|
|
} else if (theOption.startsWith("/std:") || theOption.startsWith("-std:")) {
|
|
|
|
|
m_compilerFlags.isLanguageVersionSpecified = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (theOption.startsWith("--driver-mode=")) {
|
|
|
|
|
if (theOption.endsWith("cl"))
|
|
|
|
|
m_clStyle = true;
|
|
|
|
|
containsDriverMode = true;
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-02 13:57:07 +02:00
|
|
|
// Transfrom the "/" starting commands into "-" commands, which if
|
|
|
|
|
// unknown will not cause clang to fail because it thinks
|
|
|
|
|
// it's a missing file.
|
|
|
|
|
if (theOption.startsWith("/") &&
|
|
|
|
|
(toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID ||
|
|
|
|
|
toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)) {
|
|
|
|
|
theOption[0] = '-';
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-11 15:32:12 +01:00
|
|
|
m_compilerFlags.flags.append(theOption);
|
2019-01-08 16:22:39 +01:00
|
|
|
}
|
2019-01-11 15:32:12 +01:00
|
|
|
|
|
|
|
|
if (!containsDriverMode
|
|
|
|
|
&& (toolChain == ProjectExplorer::Constants::MSVC_TOOLCHAIN_TYPEID
|
|
|
|
|
|| toolChain == ProjectExplorer::Constants::CLANG_CL_TOOLCHAIN_TYPEID)) {
|
|
|
|
|
m_clStyle = true;
|
|
|
|
|
m_compilerFlags.flags.prepend("--driver-mode=cl");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CompilerOptionsBuilder::isClStyle() const
|
|
|
|
|
{
|
|
|
|
|
return m_clStyle;
|
2019-01-08 16:22:39 +01:00
|
|
|
}
|
|
|
|
|
|
2016-01-11 21:09:06 +01:00
|
|
|
} // namespace CppTools
|