logic: only use precompiled headers for compilation database commands that specify the "-include-pch" flag (issue #719)
This commit is contained in:
@@ -101,7 +101,8 @@ std::shared_ptr<IndexerCommandProvider> SourceGroupCxxCdb::getIndexerCommandProv
|
||||
|
||||
std::vector<std::wstring> compilerFlags = getBaseCompilerFlags();
|
||||
utility::append(compilerFlags, m_settings->getCompilerFlags());
|
||||
utility::append(compilerFlags, utility::getIncludePchFlags(m_settings.get()));
|
||||
|
||||
const std::vector<std::wstring> includePchFlags = utility::getIncludePchFlags(m_settings.get());
|
||||
|
||||
const std::set<FilePath> indexedHeaderPaths = utility::toSet(m_settings->getIndexedHeaderPathsExpandedAndAbsolute());
|
||||
const std::set<FilePathFilter> excludeFilters = utility::toSet(m_settings->getExcludeFiltersExpandedAndAbsolute());
|
||||
@@ -122,13 +123,17 @@ std::shared_ptr<IndexerCommandProvider> SourceGroupCxxCdb::getIndexerCommandProv
|
||||
if (filesToIndex.find(sourcePath) != filesToIndex.end() &&
|
||||
sourceFilePaths.find(sourcePath) != sourceFilePaths.end())
|
||||
{
|
||||
std::vector<std::wstring> mergedCompilerFlags;
|
||||
mergedCompilerFlags.reserve(compilerFlags.size() + command.CommandLine.size());
|
||||
for (const std::string& arg : command.CommandLine)
|
||||
std::vector<std::wstring> cdbFlags = utility::convert<std::string, std::wstring>(
|
||||
command.CommandLine,
|
||||
[](const std::string& s) { return utility::decodeFromUtf8(s); }
|
||||
);
|
||||
|
||||
utility::removeIncludePchFlag(cdbFlags);
|
||||
|
||||
if (command.CommandLine.size() != cdbFlags.size())
|
||||
{
|
||||
mergedCompilerFlags.emplace_back(utility::decodeFromUtf8(arg));
|
||||
utility::append(cdbFlags, includePchFlags);
|
||||
}
|
||||
mergedCompilerFlags.insert(mergedCompilerFlags.end(), compilerFlags.begin(), compilerFlags.end());
|
||||
|
||||
provider->addCommand(std::make_shared<IndexerCommandCxx>(
|
||||
sourcePath,
|
||||
@@ -136,7 +141,7 @@ std::shared_ptr<IndexerCommandProvider> SourceGroupCxxCdb::getIndexerCommandProv
|
||||
excludeFilters,
|
||||
std::set<FilePathFilter>(),
|
||||
FilePath(utility::decodeFromUtf8(command.Directory)),
|
||||
mergedCompilerFlags
|
||||
utility::concat(cdbFlags, compilerFlags)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "utilitySourceGroupCxx.h"
|
||||
|
||||
#include <clang/Tooling/JSONCompilationDatabase.h>
|
||||
|
||||
#include "CanonicalFilePathCache.h"
|
||||
#include "CxxCompilationDatabaseSingle.h"
|
||||
#include "CxxDiagnosticConsumer.h"
|
||||
@@ -48,6 +50,7 @@ namespace utility
|
||||
const FilePath pchOutputFilePath =
|
||||
pchDependenciesDirectoryPath.getConcatenated(pchInputFilePath.fileName()).replaceExtension(L"pch");
|
||||
|
||||
utility::removeIncludePchFlag(compilerFlags);
|
||||
compilerFlags.push_back(pchInputFilePath.wstr());
|
||||
compilerFlags.push_back(L"-emit-pch");
|
||||
compilerFlags.push_back(L"-o");
|
||||
@@ -102,6 +105,48 @@ namespace utility
|
||||
);
|
||||
}
|
||||
|
||||
bool containsIncludePchFlags(std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb)
|
||||
{
|
||||
for (const clang::tooling::CompileCommand& command : cdb->getAllCompileCommands())
|
||||
{
|
||||
if (command.CommandLine.size() != getWithRemoveIncludePchFlag(utility::convert<std::string, std::wstring>(
|
||||
command.CommandLine,
|
||||
[](const std::string& s) {return utility::decodeFromUtf8(s); }
|
||||
)).size())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::wstring> getWithRemoveIncludePchFlag(const std::vector<std::wstring>& args)
|
||||
{
|
||||
std::vector<std::wstring> ret = args;
|
||||
removeIncludePchFlag(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void removeIncludePchFlag(std::vector<std::wstring>& args)
|
||||
{
|
||||
const std::wstring includePchPrefix = L"-include-pch";
|
||||
for (size_t i = 0; i < args.size(); i++)
|
||||
{
|
||||
const std::wstring arg = utility::trim(args[i]);
|
||||
if (utility::isPrefix<std::wstring>(includePchPrefix, arg))
|
||||
{
|
||||
if (i + 1 < args.size() &&
|
||||
!utility::isPrefix<std::wstring>(L"-", utility::trim(args[i + 1])) &&
|
||||
arg == includePchPrefix)
|
||||
{
|
||||
args.erase(args.begin() + i + 1);
|
||||
}
|
||||
args.erase(args.begin() + i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::wstring> getIncludePchFlags(const SourceGroupSettingsCxx* settings)
|
||||
{
|
||||
const SourceGroupSettingsWithCxxPchOptions* pchSettings =
|
||||
|
||||
@@ -5,6 +5,12 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace clang {
|
||||
namespace tooling {
|
||||
class JSONCompilationDatabase;
|
||||
}
|
||||
}
|
||||
|
||||
class DialogView;
|
||||
class SourceGroupSettingsCxx;
|
||||
class StorageProvider;
|
||||
@@ -15,6 +21,9 @@ namespace utility
|
||||
std::shared_ptr<Task> createBuildPchTask(
|
||||
const SourceGroupSettingsCxx* settings, std::vector<std::wstring> compilerFlags,
|
||||
std::shared_ptr<StorageProvider> storageProvider, std::shared_ptr<DialogView> dialogView);
|
||||
bool containsIncludePchFlags(std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb);
|
||||
std::vector<std::wstring> getWithRemoveIncludePchFlag(const std::vector<std::wstring>& args);
|
||||
void removeIncludePchFlag(std::vector<std::wstring>& args);
|
||||
std::vector<std::wstring> getIncludePchFlags(const SourceGroupSettingsCxx* settings);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
#include "QtProjectWizardContentPathCxxPch.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "IndexerCommandCxx.h"
|
||||
#include "SourceGroupSettingsCxxCdb.h"
|
||||
#include "SourceGroupSettingsWithCxxPchOptions.h"
|
||||
#include "utility.h"
|
||||
#include "utilityFile.h"
|
||||
#include "utilitySourceGroupCxx.h"
|
||||
|
||||
QtProjectWizardContentPathCxxPch::QtProjectWizardContentPathCxxPch(
|
||||
std::shared_ptr<SourceGroupSettings> settings,
|
||||
@@ -40,6 +45,44 @@ void QtProjectWizardContentPathCxxPch::save()
|
||||
m_settingsCxxPch->setPchInputFilePathFilePath(FilePath(m_picker->getText().toStdWString()));
|
||||
}
|
||||
|
||||
bool QtProjectWizardContentPathCxxPch::check()
|
||||
{
|
||||
if (std::shared_ptr<SourceGroupSettingsCxxCdb> cdbSettings = std::dynamic_pointer_cast<SourceGroupSettingsCxxCdb>(m_settings))
|
||||
{
|
||||
const FilePath cdbPath = cdbSettings->getCompilationDatabasePathExpandedAndAbsolute();
|
||||
std::shared_ptr<clang::tooling::JSONCompilationDatabase> cdb = IndexerCommandCxx::loadCDB(cdbPath);
|
||||
if (!cdb)
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("Unable to open and read the provided compilation database file.");
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (utility::containsIncludePchFlags(cdb))
|
||||
{
|
||||
if (m_settingsCxxPch->getPchInputFilePath().empty())
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("The provided compilation database file uses precompiled headers. Please specify a Precompiled Header input file.");
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!m_settingsCxxPch->getPchInputFilePath().empty())
|
||||
{
|
||||
QMessageBox msgBox;
|
||||
msgBox.setText("The provided compilation database file does not use precompiled headers. Please do not specify a Precompiled Header input file.");
|
||||
msgBox.exec();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceGroupSettings> QtProjectWizardContentPathCxxPch::getSourceGroupSettings()
|
||||
{
|
||||
return m_settings;
|
||||
|
||||
@@ -22,6 +22,7 @@ public:
|
||||
|
||||
void load() override;
|
||||
void save() override;
|
||||
bool check() override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<SourceGroupSettings> getSourceGroupSettings() override;
|
||||
|
||||
@@ -13,6 +13,12 @@
|
||||
* Validate "Header Files & Directories to Index" contains "src" entry
|
||||
* Add "**/Foo.h" to "Excluded Files & Directories"
|
||||
* Click "Next"
|
||||
* Pick any file at "Precompiled Header File"
|
||||
* Click "Next"
|
||||
* Validate dialog appears that asks NOT to specify PCH input file
|
||||
* Click "OK"
|
||||
* Clear "Precompiled Header File"
|
||||
* Click "Next"
|
||||
* Click "Create"
|
||||
* Validate "All files" is the only option selectable
|
||||
* Click "Start"
|
||||
|
||||
@@ -21,7 +21,7 @@ cp -a $SRC_PATH/. $WORKING_COPY_PATH
|
||||
echo "[" >> $CDB_PATH
|
||||
echo " {" >> $CDB_PATH
|
||||
echo " \"directory\": \"${WORKING_COPY_PATH}\"," >> $CDB_PATH
|
||||
echo " \"command\": \"clang-tool -fms-extensions -fms-compatibility -fms-compatibility-version=19 -isystem \\\"${WORKING_COPY_SRC_PATH}/include\\\" -DCDB_FLAG -D _DEBUG -D _MT -D _DLL -D WIN32 -D _WINDOWS -D BUILD_TYPE=\\\"\\\" -D QT_WIDGETS_LIB -D QT_GUI_LIB -D QT_CORE_LIB -D QT_NETWORK_LIB -D QT_WINEXTRAS_LIB -D QT_SVG_LIB -D CMAKE_INTDIR=\\\"Debug\\\" -D _MBCS -std=c++14 \\\"${WORKING_COPY_SRC_PATH}/main.cpp\\\"\"," >> $CDB_PATH
|
||||
echo " \"command\": \"clang-tool -fms-extensions -fms-compatibility -fms-compatibility-version=19 -isystem \\\"${WORKING_COPY_SRC_PATH}/include\\\" -DCDB_FLAG -D _DEBUG -D _MT -D _DLL -D WIN32 -D _WINDOWS -D BUILD_TYPE=\\\"\\\" -D QT_WIDGETS_LIB -D QT_GUI_LIB -D QT_CORE_LIB -D QT_NETWORK_LIB -D QT_WINEXTRAS_LIB -D QT_SVG_LIB -D CMAKE_INTDIR=\\\"Debug\\\" -D _MBCS -std=c++14 -include-pch some/file/path \\\"${WORKING_COPY_SRC_PATH}/main.cpp\\\"\"," >> $CDB_PATH
|
||||
echo " \"file\": \"${WORKING_COPY_SRC_PATH}/main.cpp\"" >> $CDB_PATH
|
||||
echo " }" >> $CDB_PATH
|
||||
echo "]" >> $CDB_PATH
|
||||
|
||||
@@ -14,8 +14,11 @@
|
||||
* Add "**/Foo.h" to "Excluded Files & Directories"
|
||||
* Click "Next"
|
||||
* Click "Next"
|
||||
* Add "-DCOMPILER_FLAG" to "Additional Compiler Flags"
|
||||
* Validate dialog appears that asks to specify PCH input file
|
||||
* Click "OK"
|
||||
* Add "./src/pch.h" to "Precompiled Header File"
|
||||
* Click "Next"
|
||||
* Add "-DCOMPILER_FLAG" to "Additional Compiler Flags"
|
||||
* Add "-DPCH_FLAG" to "Precompiled Header Flags"
|
||||
* Click "Create"
|
||||
* Validate "All files" is the only option selectable
|
||||
|
||||
Reference in New Issue
Block a user