-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[Driver] -include: deprecate probing .gch #67084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Changes
(not sure what projects actually do this with Clang) But it can often get in the way 0 when GCC and Clang are mixed as the file Full diff: https://github.com/llvm/llvm-project/pull/67084.diff 11 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 477a40630f11097..cf2a18c9ccaec06 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -43,6 +43,8 @@ C/C++ Language Potentially Breaking Changes
- The default extension name for PCH generation (``-c -xc-header`` and ``-c
-xc++-header``) is now ``.pch`` instead of ``.gch``.
+- ``-include a.h`` now no longer probes ``a.h.gch``. Change the extension name
+ to ``.pch`` or use ``-include-pch a.h.gch``.
C++ Specific Potentially Breaking Changes
-----------------------------------------
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 40e60585a8b8d6e..4390603e183b4de 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1271,23 +1271,13 @@ void Clang::AddPreprocessingOptions(Compilation &C, const JobAction &JA,
bool IsFirstImplicitInclude = !RenderedImplicitInclude;
RenderedImplicitInclude = true;
- bool FoundPCH = false;
SmallString<128> P(A->getValue());
// We want the files to have a name like foo.h.pch. Add a dummy extension
// so that replace_extension does the right thing.
P += ".dummy";
llvm::sys::path::replace_extension(P, "pch");
- if (D.getVFS().exists(P))
- FoundPCH = true;
- if (!FoundPCH) {
- llvm::sys::path::replace_extension(P, "gch");
- if (D.getVFS().exists(P)) {
- FoundPCH = true;
- }
- }
-
- if (FoundPCH) {
+ if (D.getVFS().exists(P)) {
if (IsFirstImplicitInclude) {
A->claim();
CmdArgs.push_back("-include-pch");
diff --git a/clang/test/ClangScanDeps/Inputs/modules-pch-common-submodule/cdb_pch.json b/clang/test/ClangScanDeps/Inputs/modules-pch-common-submodule/cdb_pch.json
index dc2fc550b019194..f27d24045889a03 100644
--- a/clang/test/ClangScanDeps/Inputs/modules-pch-common-submodule/cdb_pch.json
+++ b/clang/test/ClangScanDeps/Inputs/modules-pch-common-submodule/cdb_pch.json
@@ -1,7 +1,7 @@
[
{
"directory": "DIR",
- "command": "clang -x c-header DIR/pch.h -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -o DIR/pch.h.gch",
+ "command": "clang -x c-header DIR/pch.h -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -o DIR/pch.h.pch",
"file": "DIR/pch.h"
}
]
diff --git a/clang/test/ClangScanDeps/Inputs/modules-pch-common-via-submodule/cdb_pch.json b/clang/test/ClangScanDeps/Inputs/modules-pch-common-via-submodule/cdb_pch.json
index dc2fc550b019194..f27d24045889a03 100644
--- a/clang/test/ClangScanDeps/Inputs/modules-pch-common-via-submodule/cdb_pch.json
+++ b/clang/test/ClangScanDeps/Inputs/modules-pch-common-via-submodule/cdb_pch.json
@@ -1,7 +1,7 @@
[
{
"directory": "DIR",
- "command": "clang -x c-header DIR/pch.h -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -o DIR/pch.h.gch",
+ "command": "clang -x c-header DIR/pch.h -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -o DIR/pch.h.pch",
"file": "DIR/pch.h"
}
]
diff --git a/clang/test/ClangScanDeps/Inputs/modules-pch/cdb_pch.json b/clang/test/ClangScanDeps/Inputs/modules-pch/cdb_pch.json
index dc2fc550b019194..f27d24045889a03 100644
--- a/clang/test/ClangScanDeps/Inputs/modules-pch/cdb_pch.json
+++ b/clang/test/ClangScanDeps/Inputs/modules-pch/cdb_pch.json
@@ -1,7 +1,7 @@
[
{
"directory": "DIR",
- "command": "clang -x c-header DIR/pch.h -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -o DIR/pch.h.gch",
+ "command": "clang -x c-header DIR/pch.h -fmodules -gmodules -fimplicit-module-maps -fmodules-cache-path=DIR/cache -o DIR/pch.h.pch",
"file": "DIR/pch.h"
}
]
diff --git a/clang/test/ClangScanDeps/modules-pch-common-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-submodule.c
index 22ed757c26dea19..afa3f8812e9e4d7 100644
--- a/clang/test/ClangScanDeps/modules-pch-common-submodule.c
+++ b/clang/test/ClangScanDeps/modules-pch-common-submodule.c
@@ -94,7 +94,7 @@
// CHECK-TU: ],
// CHECK-TU: "file-deps": [
// CHECK-TU-NEXT: "[[PREFIX]]/tu.c",
-// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch"
+// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.pch"
// CHECK-TU-NEXT: ],
// CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c"
// CHECK-TU-NEXT: }
diff --git a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c
index 0681a68df1fd475..93aa22891d2a2d8 100644
--- a/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c
+++ b/clang/test/ClangScanDeps/modules-pch-common-via-submodule.c
@@ -91,7 +91,7 @@
// CHECK-TU: ],
// CHECK-TU: "file-deps": [
// CHECK-TU-NEXT: "[[PREFIX]]/tu.c",
-// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch"
+// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.pch"
// CHECK-TU-NEXT: ],
// CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c"
// CHECK-TU-NEXT: }
diff --git a/clang/test/ClangScanDeps/modules-pch.c b/clang/test/ClangScanDeps/modules-pch.c
index 0f61dd5ecf18c73..3e8471b810a5752 100644
--- a/clang/test/ClangScanDeps/modules-pch.c
+++ b/clang/test/ClangScanDeps/modules-pch.c
@@ -14,7 +14,7 @@
// RUN: cat %t/result_pch.json | sed 's:\\\\\?:/:g' | FileCheck %s -DPREFIX=%/t -check-prefix=CHECK-PCH
//
// Check we didn't build the PCH during dependency scanning.
-// RUN: not cat %/t/pch.h.gch
+// RUN: not cat %/t/pch.h.pch
//
// CHECK-PCH: {
// CHECK-PCH-NEXT: "modules": [
@@ -129,7 +129,7 @@
// CHECK-TU: ],
// CHECK-TU: "file-deps": [
// CHECK-TU-NEXT: "[[PREFIX]]/tu.c",
-// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.gch"
+// CHECK-TU-NEXT: "[[PREFIX]]/pch.h.pch"
// CHECK-TU-NEXT: ],
// CHECK-TU-NEXT: "input-file": "[[PREFIX]]/tu.c"
// CHECK-TU-NEXT: }
@@ -179,7 +179,7 @@
// CHECK-TU-WITH-COMMON: ],
// CHECK-TU-WITH-COMMON: "file-deps": [
// CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/tu_with_common.c",
-// CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/pch.h.gch"
+// CHECK-TU-WITH-COMMON-NEXT: "[[PREFIX]]/pch.h.pch"
// CHECK-TU-WITH-COMMON-NEXT: ],
// CHECK-TU-WITH-COMMON-NEXT: "input-file": "[[PREFIX]]/tu_with_common.c"
// CHECK-TU-WITH-COMMON-NEXT: }
diff --git a/clang/test/Index/cindex-from-source.m b/clang/test/Index/cindex-from-source.m
index 5ea8504d673e76b..7216302f5825008 100644
--- a/clang/test/Index/cindex-from-source.m
+++ b/clang/test/Index/cindex-from-source.m
@@ -1,5 +1,5 @@
// REQUIRES: native
-// RUN: c-index-test -write-pch %t.pfx.h.gch -x objective-c-header %S/Inputs/cindex-from-source.h
+// RUN: c-index-test -write-pch %t.pfx.h.pch -x objective-c-header %S/Inputs/cindex-from-source.h
// RUN: c-index-test -test-load-source local %s -include %t.pfx.h > %t
// RUN: FileCheck %s < %t
// CHECK: cindex-from-source.m:{{.*}}:{{.*}}: StructDecl=s0:{{.*}}:{{.*}}
diff --git a/clang/test/PCH/pch-dir.c b/clang/test/PCH/pch-dir.c
index afdd7b1f4f307c2..68875fcb4f8a3ff 100644
--- a/clang/test/PCH/pch-dir.c
+++ b/clang/test/PCH/pch-dir.c
@@ -1,9 +1,9 @@
-// RUN: rm -rf %t.h.gch
-// RUN: mkdir -p %t.h.gch
+// RUN: rm -rf %t.h.pch
+// RUN: mkdir -p %t.h.pch
//
-// RUN: %clang -x c-header %S/pch-dir.h -DFOO=foo -o %t.h.gch/c.gch
-// RUN: %clang -x c-header %S/pch-dir.h -DFOO=bar -o %t.h.gch/cbar.gch
-// RUN: %clang -x c++-header -std=c++98 %S/pch-dir.h -o %t.h.gch/cpp.gch
+// RUN: %clang -x c-header %S/pch-dir.h -DFOO=foo -o %t.h.pch/c.pch
+// RUN: %clang -x c-header %S/pch-dir.h -DFOO=bar -o %t.h.pch/cbar.pch
+// RUN: %clang -x c++-header -std=c++98 %S/pch-dir.h -o %t.h.pch/cpp.pch
// RUN: %clang -include %t.h -DFOO=foo -fsyntax-only %s -Xclang -print-stats 2> %t.clog
// RUN: FileCheck -check-prefix=CHECK-C %s < %t.clog
// RUN: %clang -include %t.h -DFOO=bar -fsyntax-only %s -Xclang -ast-print > %t.cbarlog
@@ -20,7 +20,7 @@
// RUN: FileCheck -check-prefix=CHECK-NO-SUITABLE %s < %t.missinglog2
// Don't crash if the precompiled header file is missing.
-// RUN: not %clang_cc1 -include-pch %t.h.gch -DFOO=baz -fsyntax-only %s -print-stats 2> %t.missinglog
+// RUN: not %clang_cc1 -include-pch %t.h.pch -DFOO=baz -fsyntax-only %s -print-stats 2> %t.missinglog
// RUN: FileCheck -check-prefix=CHECK-NO-SUITABLE %s < %t.missinglog
// CHECK-CBAR: int bar
@@ -28,10 +28,10 @@ int FOO;
int get(void) {
#ifdef __cplusplus
- // CHECK-CPP: .h.gch{{[/\\]}}cpp.gch
+ // CHECK-CPP: .h.pch{{[/\\]}}cpp.pch
return i;
#else
- // CHECK-C: .h.gch{{[/\\]}}c.gch
+ // CHECK-C: .h.pch{{[/\\]}}c.pch
return j;
#endif
}
diff --git a/clang/test/SemaCXX/warn-unused-local-typedef-serialize.cpp b/clang/test/SemaCXX/warn-unused-local-typedef-serialize.cpp
index aa2c48bb5719d83..9c0f145e4c79559 100644
--- a/clang/test/SemaCXX/warn-unused-local-typedef-serialize.cpp
+++ b/clang/test/SemaCXX/warn-unused-local-typedef-serialize.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang -x c++-header -c -Wunused-local-typedef %s -o %t.gch -Werror
+// RUN: %clang -x c++-header -c -Wunused-local-typedef %s -o %t.pch -Werror
// RUN: %clang -DBE_THE_SOURCE -c -Wunused-local-typedef -include %t %s -o /dev/null 2>&1 | FileCheck %s
// RUN: %clang -DBE_THE_SOURCE -c -Wunused-local-typedef -include %t %s -o /dev/null 2>&1 | FileCheck %s
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Xcode is actively using this feature: the .pch
extension is used for headers that are to be precompiled, the .pch.gch
extension is used for the actual precompiled header, and Clang is expected to expand the given -include X.pch
argument into -include-pch X.pch.gch
.
We're okay with changing the build system to explicitly pass -include-pch X.pch.gch
to the compiler, but I think it would be more prudent for Clang to emit a deprecation warning for now and only remove this feature (land this patch) after the next upstream release is cut.
Sounds good. Switched to a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! LGTM.
`-include a.h` probes `a.h.pch` and `a.h.gch`, if not found, falls back to `a.h`. `.pch` is the preferred extension name. Probing .gch is supposed to provide compatibility with build systems that do ``` clang -x c-header a.h -o out/a.h.gch clang -include out/a.h -c a.c # out/a.h.gch is present while out/a.h is absent ``` (not sure what projects actually do this with Clang) But it can often get in the way [^0][^1][^2] when GCC and Clang are mixed as the file format is incompatible with GCC's. Let's deprecate .gch probing. Some tests using `-include` are switched to `.pch`. `test/PCH/pch-dir.c` shows the -Wdeprecated warning. [^0]: https://discourse.llvm.org/t/how-to-have-clang-ignore-gch-directories/51835 [^1]: https://bugreports.qt.io/browse/QTCREATORBUG-22427 [^2]: https://gitlab.kitware.com/cmake/cmake/-/issues/22081
`-include a.h` probes `a.h.pch` and `a.h.gch`, if not found, falls back to `a.h`. `.pch` is the preferred extension name. Probing .gch is supposed to provide compatibility with build systems that do ``` clang -x c-header a.h -o out/a.h.gch clang -include out/a.h -c a.c # out/a.h.gch is present while out/a.h is absent ``` (not sure what projects actually do this with Clang) But it can often get in the way [^0][^1][^2] when GCC and Clang are mixed as the file format is incompatible with GCC's. Let's deprecate .gch probing. Some tests using `-include` are switched to `.pch`. `test/PCH/pch-dir.c` shows the -Wdeprecated warning. [^0]: https://discourse.llvm.org/t/how-to-have-clang-ignore-gch-directories/51835 [^1]: https://bugreports.qt.io/browse/QTCREATORBUG-22427 [^2]: https://gitlab.kitware.com/cmake/cmake/-/issues/22081
Can we add a dedicated Reading the linked bugs, it's not clear that removing this would've helped all these issues all that much and it introduces a bunch of toil. So maybe we don't want to do this at all? But if we do, please put it behind a dedicated warning flag. |
I gave it a flag in 39f36d5
Turns out Chromium (and anyone else using gn) does: https://crbug.com/1486799 In an environment like that, I'm not sure what action users should take when they see this warning: GCC doesn't understand So it seems this feature really is necessary for drop-in compatibility with GCC. |
As an archaeological note, the gch probing was added a long time ago in a2aedc6 with the motivation
|
Clang PCH generation prefers
Having a |
But do we intend to remove it later? That will break the drop-in ability of Clang, and probably a lot of people's builds.
To solve this, couldn't the driver peek at the magic at the start of the file or something like that? |
increases DIAG_SIZE_DRIVER to 400 from 300 `-include a.h` probes `a.h.pch` and `a.h.gch`, if not found, falls back to `a.h`. `.pch` is the preferred extension name. Probing .gch is supposed to provide compatibility with build systems that do ``` clang -x c-header a.h -o out/a.h.gch clang -include out/a.h -c a.c # out/a.h.gch is present while out/a.h is absent ``` (not sure what projects actually do this with Clang) But it can often get in the way [^0][^1][^2] when GCC and Clang are mixed as the file format is incompatible with GCC's. Let's deprecate .gch probing. Some tests using `-include` are switched to `.pch`. `test/PCH/pch-dir.c` shows the -Wdeprecated warning. [^0]: https://discourse.llvm.org/t/how-to-have-clang-ignore-gch-directories/51835 [^1]: https://bugreports.qt.io/browse/QTCREATORBUG-22427 [^2]: https://gitlab.kitware.com/cmake/cmake/-/issues/22081 Change-Id: I55408399eb0b194fe2be33e66ef2c84a945f077a
This is feasible but not elegant, and likely unnecessary. I have tried many keywords to figure out Many modern build systems (Bazel, Buck) require the full set of output files. |
The .gch probing has been part of Clang since 2009, and it matches GCC's behavior, so of course there are going to be users depending on it (Hyrum's law etc.). We don't have to look far for those users: Jan reported that Xcode relies on it, and I have reported that Chromium does as well. I think it's safe to assume that there are many more. Because of that, I feel strongly that we should keep this behavior. It may be inelegant, but breaking our users is much worse. Maybe one day Clang will define a new elegant driver interface without concerns about GCC or backwards compatibility, but that's not today. If we want to solve the issues you linked to, checking the file magic seems like a more practical approach. cc @llvm/clang-vendors in case there are more opinions. |
I am also rather uncomfortable with this behavioral change. There are a lot of build systems in use out there. My preference would be to continue to probe for a .gch file, but also validate that it is a (compatible) Clang PCH file before trying to use it. |
I'd appreciate seeing concrete evidence rather than relying solely on intuition. I've considered the potential disruption of deprecating FWIW https://github.com/Kitware/CMake/blob/92adbb5d8c2a043c6e6c8539e9817a75a813fa1b/Modules/Compiler/Clang.cmake#L108 sets |
XCode and GN are two concrete examples. |
Instead of deprecating the "gch probe" as in f726da1, this makes clang ignore files which are not clang pch files (See discussion on PR llvm#67084). This fixes the issues mentioned in the former patch, with GCC-generated .gch files getting in the way when using clang, while maintaining the probing behavior for builds which rely on that.
I've posted an alternative patch in #69204 which I believe is fixing the issues mentioned in this pr better (users don't have to wait another release), while not breaking builds relying on gch probing. |
…69204) Instead of deprecating the "gch probe" as in f726da1, this makes clang ignore files which are not clang pch files (See discussion on PR #67084). This fixes the issues mentioned in the former patch, with GCC-generated .gch files getting in the way when using clang, while maintaining the probing behavior for builds which rely on that.
-include a.h
probesa.h.pch
anda.h.gch
, if not found, falls back toa.h
..pch
is the preferred extension name. Probing .gch is supposed toprovide compatibility with build systems that do
(not sure what projects actually do this with Clang)
But it can often get in the way 123 when GCC and Clang are mixed as the file
format is incompatible with GCC's. Let's deprecate .gch probing.
Some tests using
-include
are switched to.pch
.test/PCH/pch-dir.c
shows the -Wdeprecated warning.Footnotes
https://discourse.llvm.org/t/how-to-have-clang-ignore-gch-directories/51835 ↩
https://bugreports.qt.io/browse/QTCREATORBUG-22427 ↩
https://gitlab.kitware.com/cmake/cmake/-/issues/22081 ↩