summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2020-05-25 14:40:47 (GMT)
committerKitware Robot <kwrobot@kitware.com>2020-05-25 14:40:56 (GMT)
commit15b9b41d72d1de2299dbfd9e4f05c456b7a9124e (patch)
tree04a423ef2278228cd3cf31ac51b3a76e1d0ace64
parent54baf639652a0590825fef4f600645919ef13913 (diff)
parent9f6d40ee23113f1317e54d662316752adb9f368e (diff)
downloadCMake-15b9b41d72d1de2299dbfd9e4f05c456b7a9124e.zip
CMake-15b9b41d72d1de2299dbfd9e4f05c456b7a9124e.tar.gz
CMake-15b9b41d72d1de2299dbfd9e4f05c456b7a9124e.tar.bz2
Merge topic 'fileApiAddPrecompileHeadersBacktrace'
9f6d40ee23 fileapi: Extend codemodel targets with PRECOMPILE_HEADERS b698764a31 Tests: Add a PCH example to RunCMake.FileAPI codemodel-v2 b3812c0e54 Tests: Fix indentation in RunCMake.FileAPI cxx_exe.json 9c48804b69 PCH: Fix source group of per-architecture PCH headers Acked-by: Kitware Robot <kwrobot@kitware.com> Merge-request: !4684
-rw-r--r--Help/manual/cmake-file-api.7.rst16
-rw-r--r--Source/cmFileAPI.cxx2
-rw-r--r--Source/cmFileAPICodemodel.cxx30
-rw-r--r--Source/cmSourceFile.h2
-rw-r--r--Tests/RunCMake/CMakeLists.txt3
-rw-r--r--Tests/RunCMake/CommandLine/E_capabilities-stdout.txt2
-rw-r--r--Tests/RunCMake/FileAPI/RunCMakeTest.cmake2
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-check.py34
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json23
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json161
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json237
-rw-r--r--Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json206
-rw-r--r--Tests/RunCMake/FileAPI/cxx/CMakeLists.txt2
-rw-r--r--Tests/RunCMake/FileAPI/empty.h0
14 files changed, 712 insertions, 8 deletions
diff --git a/Help/manual/cmake-file-api.7.rst b/Help/manual/cmake-file-api.7.rst
index 12eecd9..91be31d 100644
--- a/Help/manual/cmake-file-api.7.rst
+++ b/Help/manual/cmake-file-api.7.rst
@@ -899,6 +899,22 @@ with members:
an unsigned integer 0-based index into the ``backtraceGraph``
member's ``nodes`` array.
+ ``precompileHeaders``
+ Optional member that is present when :command:`target_precompile_headers`
+ or other command invocations set :prop_tgt:`PRECOMPILE_HEADERS` on the
+ target. The value is a JSON array with an entry for each header. Each
+ entry is a JSON object with members:
+
+ ``header``
+ Full path to the precompile header file.
+
+ ``backtrace``
+ Optional member that is present when a CMake language backtrace to
+ the :command:`target_precompile_headers` or other command invocation
+ that added this precompiled header is available. The value is an
+ unsigned integer 0-based index into the ``backtraceGraph`` member's
+ ``nodes`` array.
+
``defines``
Optional member that is present when there are preprocessor definitions.
The value is a JSON array with an entry for each definition. Each
diff --git a/Source/cmFileAPI.cxx b/Source/cmFileAPI.cxx
index a56ad22..594969b 100644
--- a/Source/cmFileAPI.cxx
+++ b/Source/cmFileAPI.cxx
@@ -665,7 +665,7 @@ std::string cmFileAPI::NoSupportedVersion(
// The "codemodel" object kind.
-static unsigned int const CodeModelV2Minor = 0;
+static unsigned int const CodeModelV2Minor = 1;
void cmFileAPI::BuildClientRequestCodeModel(
ClientRequest& r, std::vector<RequestVersion> const& versions)
diff --git a/Source/cmFileAPICodemodel.cxx b/Source/cmFileAPICodemodel.cxx
index b983b21..b7daebe 100644
--- a/Source/cmFileAPICodemodel.cxx
+++ b/Source/cmFileAPICodemodel.cxx
@@ -278,12 +278,14 @@ struct CompileData
std::string Sysroot;
std::vector<JBT<std::string>> Flags;
std::vector<JBT<std::string>> Defines;
+ std::vector<JBT<std::string>> PrecompileHeaders;
std::vector<IncludeEntry> Includes;
friend bool operator==(CompileData const& l, CompileData const& r)
{
return (l.Language == r.Language && l.Sysroot == r.Sysroot &&
l.Flags == r.Flags && l.Defines == r.Defines &&
+ l.PrecompileHeaders == r.PrecompileHeaders &&
l.Includes == r.Includes);
}
};
@@ -313,6 +315,10 @@ struct hash<CompileData>
result = result ^ hash<std::string>()(i.Value) ^
hash<Json::ArrayIndex>()(i.Backtrace.Index);
}
+ for (auto const& i : in.PrecompileHeaders) {
+ result = result ^ hash<std::string>()(i.Value) ^
+ hash<Json::ArrayIndex>()(i.Backtrace.Index);
+ }
return result;
}
};
@@ -369,6 +375,7 @@ class Target
Json::Value DumpPaths();
Json::Value DumpCompileData(CompileData const& cd);
Json::Value DumpInclude(CompileData::IncludeEntry const& inc);
+ Json::Value DumpPrecompileHeader(JBT<std::string> const& header);
Json::Value DumpDefine(JBT<std::string> const& def);
Json::Value DumpSources();
Json::Value DumpSource(cmGeneratorTarget::SourceAndKind const& sk,
@@ -825,6 +832,11 @@ void Target::ProcessLanguage(std::string const& lang)
this->ToJBT(i),
this->GT->IsSystemIncludeDirectory(i.Value, this->Config, lang));
}
+ std::vector<BT<std::string>> precompileHeaders =
+ this->GT->GetPrecompileHeaders(this->Config, lang);
+ for (BT<std::string> const& pch : precompileHeaders) {
+ cd.PrecompileHeaders.emplace_back(this->ToJBT(pch));
+ }
}
Json::ArrayIndex Target::AddSourceGroup(cmSourceGroup* sg, Json::ArrayIndex si)
@@ -980,6 +992,9 @@ CompileData Target::MergeCompileData(CompileData const& fd)
// All compile groups share the sysroot of the target.
cd.Sysroot = td.Sysroot;
+ // All compile groups share the precompile headers of the target.
+ cd.PrecompileHeaders = td.PrecompileHeaders;
+
// Use target-wide flags followed by source-specific flags.
cd.Flags.reserve(td.Flags.size() + fd.Flags.size());
cd.Flags.insert(cd.Flags.end(), td.Flags.begin(), td.Flags.end());
@@ -1130,6 +1145,13 @@ Json::Value Target::DumpCompileData(CompileData const& cd)
}
result["defines"] = std::move(defines);
}
+ if (!cd.PrecompileHeaders.empty()) {
+ Json::Value precompileHeaders = Json::arrayValue;
+ for (JBT<std::string> const& pch : cd.PrecompileHeaders) {
+ precompileHeaders.append(this->DumpPrecompileHeader(pch));
+ }
+ result["precompileHeaders"] = std::move(precompileHeaders);
+ }
return result;
}
@@ -1145,6 +1167,14 @@ Json::Value Target::DumpInclude(CompileData::IncludeEntry const& inc)
return include;
}
+Json::Value Target::DumpPrecompileHeader(JBT<std::string> const& header)
+{
+ Json::Value precompileHeader = Json::objectValue;
+ precompileHeader["header"] = header.Value;
+ this->AddBacktrace(precompileHeader, header.Backtrace);
+ return precompileHeader;
+}
+
Json::Value Target::DumpDefine(JBT<std::string> const& def)
{
Json::Value define = Json::objectValue;
diff --git a/Source/cmSourceFile.h b/Source/cmSourceFile.h
index e527069..e2dfdc1 100644
--- a/Source/cmSourceFile.h
+++ b/Source/cmSourceFile.h
@@ -159,7 +159,7 @@ private:
"\\.(C|F|M|c|c\\+\\+|cc|cpp|cxx|cu|f|f90|for|fpp|ftn|m|mm|" \
"rc|def|r|odl|idl|hpj|bat)$"
-#define CM_PCH_REGEX "cmake_pch\\.(h|hxx)$"
+#define CM_PCH_REGEX "cmake_pch(_[^.]+)?\\.(h|hxx)$"
#define CM_RESOURCE_REGEX "\\.(pdf|plist|png|jpeg|jpg|storyboard|xcassets)$"
diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt
index 0f94e4e..5f3f38b 100644
--- a/Tests/RunCMake/CMakeLists.txt
+++ b/Tests/RunCMake/CMakeLists.txt
@@ -203,7 +203,8 @@ endif()
add_RunCMake_test(ExternalData)
add_RunCMake_test(FeatureSummary)
add_RunCMake_test(FPHSA)
-add_RunCMake_test(FileAPI -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE})
+add_RunCMake_test(FileAPI -DPYTHON_EXECUTABLE=${PYTHON_EXECUTABLE}
+ -DCMAKE_CXX_COMPILER_ID=${CMAKE_CXX_COMPILER_ID})
add_RunCMake_test(FindBoost)
add_RunCMake_test(FindLua)
add_RunCMake_test(FindOpenGL)
diff --git a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
index b4b170e..03286f1 100644
--- a/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
+++ b/Tests/RunCMake/CommandLine/E_capabilities-stdout.txt
@@ -1 +1 @@
-^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":0}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$
+^{"fileApi":{"requests":\[{"kind":"codemodel","version":\[{"major":2,"minor":1}]},{"kind":"cache","version":\[{"major":2,"minor":0}]},{"kind":"cmakeFiles","version":\[{"major":1,"minor":0}]}]},"generators":\[.*\],"serverMode":true,"version":{.*}}$
diff --git a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
index 8cdc00c..4449ff1 100644
--- a/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
+++ b/Tests/RunCMake/FileAPI/RunCMakeTest.cmake
@@ -23,7 +23,7 @@ function(check_python case)
endif()
file(GLOB index ${RunCMake_TEST_BINARY_DIR}/.cmake/api/v1/reply/index-*.json)
execute_process(
- COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py" "${index}"
+ COMMAND ${PYTHON_EXECUTABLE} "${RunCMake_SOURCE_DIR}/${case}-check.py" "${index}" "${CMAKE_CXX_COMPILER_ID}"
RESULT_VARIABLE result
OUTPUT_VARIABLE output
ERROR_VARIABLE output
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-check.py b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
index 9ee0c20..a3dd9ff 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-check.py
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-check.py
@@ -12,7 +12,7 @@ def read_codemodel_json_data(filename):
def check_objects(o, g):
assert is_list(o)
assert len(o) == 1
- check_index_object(o[0], "codemodel", 2, 0, check_object_codemodel(g))
+ check_index_object(o[0], "codemodel", 2, 1, check_object_codemodel(g))
def check_backtrace(t, b, backtrace):
btg = t["backtraceGraph"]
@@ -404,6 +404,23 @@ def check_target(c):
missing_exception=lambda e: "Include path: %s" % e["path"],
extra_exception=lambda a: "Include path: %s" % a["path"])
+ if "precompileHeaders" in expected:
+ expected_keys.append("precompileHeaders")
+
+ def check_precompile_header(actual, expected):
+ assert is_dict(actual)
+ expected_keys = ["backtrace", "header"]
+ check_backtrace(obj, actual["backtrace"], expected["backtrace"])
+
+ assert sorted(actual.keys()) == sorted(expected_keys)
+
+ check_list_match(lambda a, e: matches(a["header"], e["header"]),
+ actual["precompileHeaders"], expected["precompileHeaders"],
+ check=check_precompile_header,
+ check_exception=lambda a, e: "Precompile header: %s" % a["header"],
+ missing_exception=lambda e: "Precompile header: %s" % e["header"],
+ extra_exception=lambda a: "Precompile header: %s" % a["header"])
+
if expected["defines"] is not None:
expected_keys.append("defines")
@@ -561,6 +578,20 @@ def gen_check_targets(c, g, inSource):
read_codemodel_json_data("targets/generated_exe.json"),
]
+ if cxx_compiler_id in ['Clang', 'AppleClang', 'GNU', 'Intel', 'MSVC', 'Embarcadero'] and g["name"] != "Xcode":
+ for e in expected:
+ if e["name"] == "cxx_exe":
+ if matches(g["name"], "^(Visual Studio |Ninja Multi-Config)"):
+ precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_multigen.json")
+ else:
+ if ';' in os.environ.get("CMAKE_OSX_ARCHITECTURES", ""):
+ precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader_2arch.json")
+ else:
+ precompile_header_data = read_codemodel_json_data("targets/cxx_exe_precompileheader.json")
+ e["compileGroups"] = precompile_header_data["compileGroups"]
+ e["sources"] = precompile_header_data["sources"]
+ e["sourceGroups"] = precompile_header_data["sourceGroups"]
+
if not os.path.exists(os.path.join(reply_dir, "..", "..", "..", "..", "ipo_enabled.txt")):
for e in expected:
try:
@@ -715,6 +746,7 @@ def check_object_codemodel(g):
check_object_codemodel_configuration(c, g, inSource)
return _check
+cxx_compiler_id = sys.argv[2]
assert is_dict(index)
assert sorted(index.keys()) == ["cmake", "objects", "reply"]
check_objects(index["objects"], index["cmake"]["generator"])
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
index 7631837..e7ab55b 100644
--- a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe.json
@@ -43,17 +43,36 @@
],
"includes": null,
"defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
"compileCommandFragments": [
{
"fragment" : "TargetCompileOptions",
- "backtrace": [
+ "backtrace": [
{
"file": "^cxx/CMakeLists\\.txt$",
"line": 17,
"command": "target_compile_options",
"hasParent": true
},
- {
+ {
"file" : "^cxx/CMakeLists\\.txt$",
"line": null,
"command": null,
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json
new file mode 100644
index 0000000..5a0f770
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader.json
@@ -0,0 +1,161 @@
+{
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment": "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment": "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "sources": [
+ {
+ "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Precompile Header File",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ "^empty\\.cxx$"
+ ]
+ },
+ {
+ "name": "Precompile Header File",
+ "sourcePaths": [
+ ".*/cmake_pch(_[^.]+)?\\.hxx$"
+ ]
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json
new file mode 100644
index 0000000..9455748
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_2arch.json
@@ -0,0 +1,237 @@
+{
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment": "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment": "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment": "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "sources": [
+ {
+ "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Precompile Header File",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*/cmake_pch(_[^.]+)?\\.hxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Precompile Header File",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ "^empty\\.cxx$"
+ ]
+ },
+ {
+ "name": "Precompile Header File",
+ "sourcePaths": [
+ ".*/cmake_pch(_[^.]+)?\\.hxx$",
+ ".*/cmake_pch(_[^.]+)?\\.hxx$"
+ ]
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json
new file mode 100644
index 0000000..9f6ffcc
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/codemodel-v2-data/targets/cxx_exe_precompileheader_multigen.json
@@ -0,0 +1,206 @@
+{
+ "compileGroups": [
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment": "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "language": "CXX",
+ "sourcePaths": [
+ "^empty\\.cxx$"
+ ],
+ "includes": null,
+ "defines": null,
+ "precompileHeaders": [
+ {
+ "header": ".*empty\\.h$",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 21,
+ "command": "target_precompile_headers",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "compileCommandFragments": [
+ {
+ "fragment": "TargetCompileOptions",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 17,
+ "command": "target_compile_options",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "sources": [
+ {
+ "path": ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": "^empty\\.cxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Source Files",
+ "compileGroupLanguage": "CXX",
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": 5,
+ "command": "add_executable",
+ "hasParent": true
+ },
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*/Debug/cmake_pch(_[^.]+)?\\.hxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Precompile Header File",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*/Release/cmake_pch(_[^.]+)?\\.hxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Precompile Header File",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*/MinSizeRel/cmake_pch(_[^.]+)?\\.hxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Precompile Header File",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ },
+ {
+ "path": ".*/RelWithDebInfo/cmake_pch(_[^.]+)?\\.hxx$",
+ "isGenerated": null,
+ "sourceGroupName": "Precompile Header File",
+ "compileGroupLanguage": null,
+ "backtrace": [
+ {
+ "file": "^cxx/CMakeLists\\.txt$",
+ "line": null,
+ "command": null,
+ "hasParent": false
+ }
+ ]
+ }
+ ],
+ "sourceGroups": [
+ {
+ "name": "Source Files",
+ "sourcePaths": [
+ ".*cmake_pch(_[^.]+)?(\\.hxx)?\\.cxx$",
+ "^empty\\.cxx$"
+ ]
+ },
+ {
+ "name": "Precompile Header File",
+ "sourcePaths": [
+ ".*/Debug/cmake_pch(_[^.]+)?\\.hxx$",
+ ".*/Release/cmake_pch(_[^.]+)?\\.hxx$",
+ ".*/MinSizeRel/cmake_pch(_[^.]+)?\\.hxx$",
+ ".*/RelWithDebInfo/cmake_pch(_[^.]+)?\\.hxx$"
+ ]
+ }
+ ]
+}
diff --git a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
index b0564f5..fa51195 100644
--- a/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
+++ b/Tests/RunCMake/FileAPI/cxx/CMakeLists.txt
@@ -17,3 +17,5 @@ target_link_libraries(cxx_static_exe PRIVATE cxx_static_lib)
target_compile_options(cxx_exe PUBLIC TargetCompileOptions)
target_link_options(cxx_exe PUBLIC TargetLinkOptions)
target_link_directories(cxx_exe PUBLIC "${CMAKE_BINARY_DIR}/TargetLinkDir")
+
+target_precompile_headers(cxx_exe PUBLIC ../empty.h)
diff --git a/Tests/RunCMake/FileAPI/empty.h b/Tests/RunCMake/FileAPI/empty.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Tests/RunCMake/FileAPI/empty.h