forked from qt-creator/qt-creator
CMakePM: Proper support for Unity builds
A Unity build can be enabled by specifying CMAKE_UNITY_BUILD set to ON globally or per target bases via the UNITY_BUILD property. CMake would then add unity_NN_[cxx|c].[cxx|c] sources files that would include the existing project files. The existing project files would then be added as "headers" to the project and exported via the CMake file-api. This patch makes sure that these new "headers" are added to the Qt Creator's code model and have proper syntax highlighting, be available to plugins (e.g. Todo) and so on. Fixes: QTCREATORBUG-23635 Fixes: QTCREATORBUG-26822 Fixes: QTCREATORBUG-29080 Change-Id: Ie8dd542504f632c01f91691f8736e51be8b19a01 Reviewed-by: Alessandro Portale <alessandro.portale@qt.io> Reviewed-by: <github-actions-qt-creator@cristianadam.eu>
This commit is contained in:
@@ -332,6 +332,12 @@ bool isPchFile(const FilePath &buildDirectory, const FilePath &path)
|
|||||||
return path.isChildOf(buildDirectory) && path.fileName().startsWith("cmake_pch");
|
return path.isChildOf(buildDirectory) && path.fileName().startsWith("cmake_pch");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isUnityFile(const FilePath &buildDirectory, const FilePath &path)
|
||||||
|
{
|
||||||
|
return path.isChildOf(buildDirectory) && path.parentDir().fileName() == "Unity"
|
||||||
|
&& path.fileName().startsWith("unity_");
|
||||||
|
}
|
||||||
|
|
||||||
RawProjectParts generateRawProjectParts(const PreprocessedData &input,
|
RawProjectParts generateRawProjectParts(const PreprocessedData &input,
|
||||||
const FilePath &sourceDirectory,
|
const FilePath &sourceDirectory,
|
||||||
const FilePath &buildDirectory)
|
const FilePath &buildDirectory)
|
||||||
@@ -381,11 +387,20 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input,
|
|||||||
|
|
||||||
// Get all sources from the compiler group, except generated sources
|
// Get all sources from the compiler group, except generated sources
|
||||||
QStringList sources;
|
QStringList sources;
|
||||||
|
auto addToSources = [sourceDirectory, &sources](const QString &source) {
|
||||||
|
const FilePath sourcePath = FilePath::fromString(source);
|
||||||
|
if (sourcePath.isAbsolutePath())
|
||||||
|
sources.push_back(source);
|
||||||
|
else
|
||||||
|
sources.push_back(
|
||||||
|
sourceDirectory.pathAppended(source).absoluteFilePath().path());
|
||||||
|
};
|
||||||
|
|
||||||
for (auto idx: ci.sources) {
|
for (auto idx: ci.sources) {
|
||||||
SourceInfo si = t.sources.at(idx);
|
SourceInfo si = t.sources.at(idx);
|
||||||
if (si.isGenerated)
|
if (si.isGenerated)
|
||||||
continue;
|
continue;
|
||||||
sources.push_back(sourceDirectory.pathAppended(si.path).absoluteFilePath().path());
|
addToSources(si.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are not in a pch compiler group, add all the headers that are not generated
|
// If we are not in a pch compiler group, add all the headers that are not generated
|
||||||
@@ -393,27 +408,45 @@ RawProjectParts generateRawProjectParts(const PreprocessedData &input,
|
|||||||
return isPchFile(buildDirectory, FilePath::fromString(path));
|
return isPchFile(buildDirectory, FilePath::fromString(path));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const bool hasUnitySources = allOf(sources, [buildDirectory](const QString &path) {
|
||||||
|
return isUnityFile(buildDirectory, FilePath::fromString(path));
|
||||||
|
});
|
||||||
|
|
||||||
QString headerMimeType;
|
QString headerMimeType;
|
||||||
if (ci.language == "C")
|
QString sourceMimeType;
|
||||||
|
if (ci.language == "C") {
|
||||||
headerMimeType = CppEditor::Constants::C_HEADER_MIMETYPE;
|
headerMimeType = CppEditor::Constants::C_HEADER_MIMETYPE;
|
||||||
else if (ci.language == "CXX")
|
sourceMimeType = CppEditor::Constants::C_SOURCE_MIMETYPE;
|
||||||
|
} else if (ci.language == "CXX") {
|
||||||
headerMimeType = CppEditor::Constants::CPP_HEADER_MIMETYPE;
|
headerMimeType = CppEditor::Constants::CPP_HEADER_MIMETYPE;
|
||||||
|
sourceMimeType = CppEditor::Constants::CPP_SOURCE_MIMETYPE;
|
||||||
|
}
|
||||||
if (!hasPchSource) {
|
if (!hasPchSource) {
|
||||||
for (const SourceInfo &si : t.sources) {
|
for (const SourceInfo &si : t.sources) {
|
||||||
if (si.isGenerated)
|
if (si.isGenerated)
|
||||||
continue;
|
continue;
|
||||||
const auto mimeTypes = Utils::mimeTypesForFileName(si.path);
|
const auto mimeTypes = Utils::mimeTypesForFileName(si.path);
|
||||||
for (const auto &mime : mimeTypes)
|
for (const auto &mime : mimeTypes) {
|
||||||
if (mime.inherits(headerMimeType))
|
const bool headerType = mime.inherits(headerMimeType);
|
||||||
sources.push_back(
|
const bool sourceUnityType = hasUnitySources ? mime.inherits(sourceMimeType)
|
||||||
sourceDirectory.pathAppended(si.path).absoluteFilePath().path());
|
: false;
|
||||||
|
if (headerType || sourceUnityType)
|
||||||
|
addToSources(si.path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
sources.removeDuplicates();
|
||||||
|
|
||||||
// Set project files except pch files
|
// Set project files except pch / unity files
|
||||||
rpp.setFiles(Utils::filtered(sources, [buildDirectory](const QString &path) {
|
rpp.setFiles(Utils::filtered(sources,
|
||||||
return !isPchFile(buildDirectory, FilePath::fromString(path));
|
[buildDirectory](const QString &path) {
|
||||||
}), {}, [headerMimeType](const QString &path) {
|
return !isPchFile(buildDirectory,
|
||||||
|
FilePath::fromString(path))
|
||||||
|
&& !isUnityFile(buildDirectory,
|
||||||
|
FilePath::fromString(path));
|
||||||
|
}),
|
||||||
|
{},
|
||||||
|
[headerMimeType](const QString &path) {
|
||||||
// Similar to ProjectFile::classify but classify headers with language
|
// Similar to ProjectFile::classify but classify headers with language
|
||||||
// of compile group instead of ambiguous header
|
// of compile group instead of ambiguous header
|
||||||
if (path.endsWith(".h"))
|
if (path.endsWith(".h"))
|
||||||
@@ -561,9 +594,9 @@ void addCompileGroups(ProjectNode *targetRoot,
|
|||||||
auto node = std::make_unique<FileNode>(sourcePath, Node::fileTypeForFileName(sourcePath));
|
auto node = std::make_unique<FileNode>(sourcePath, Node::fileTypeForFileName(sourcePath));
|
||||||
node->setIsGenerated(si.isGenerated);
|
node->setIsGenerated(si.isGenerated);
|
||||||
|
|
||||||
// CMake pch files are generated at configured time, but not marked as generated
|
// CMake pch / unity files are generated at configured time, but not marked as generated
|
||||||
// so that a "clean" step won't remove them and at a subsequent build they won't exist.
|
// so that a "clean" step won't remove them and at a subsequent build they won't exist.
|
||||||
if (isPchFile(buildDirectory, sourcePath))
|
if (isPchFile(buildDirectory, sourcePath) || isUnityFile(buildDirectory, sourcePath))
|
||||||
node->setIsGenerated(true);
|
node->setIsGenerated(true);
|
||||||
|
|
||||||
// Where does the file node need to go?
|
// Where does the file node need to go?
|
||||||
|
Reference in New Issue
Block a user