[clang-tools-extra] [clangd] [C++20] [Modules] Don't reuse prebuilt module files on windows (PR #193426)
Chuanqi Xu via cfe-commits
cfe-commits at lists.llvm.org
Wed Apr 22 00:31:07 PDT 2026
https://github.com/ChuanqiXu9 created https://github.com/llvm/llvm-project/pull/193426
Fix https://github.com/clangd/clangd/issues/2497
Note that this only works for --experimental-modules-support. Otherwise, it is a natural fallback by the design clang based tools.
>From 8ce7a324eb9a3aa9890c466f882b94be94d65774 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <yedeng.yd at linux.alibaba.com>
Date: Wed, 22 Apr 2026 15:25:09 +0800
Subject: [PATCH] [clangd] [C++20] [Modules] Don't reuse prebuilt module files
on windows
Fix https://github.com/clangd/clangd/issues/2497
Note that this only works for --experimental-modules-support. Otherwise,
it is a natural fallback by the design clang based tools.
---
clang-tools-extra/clangd/ModulesBuilder.cpp | 23 +++++++-
.../test/prebuilt_module_file_reuse.test | 58 +++++++++++++++++++
2 files changed, 79 insertions(+), 2 deletions(-)
create mode 100644 clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test
diff --git a/clang-tools-extra/clangd/ModulesBuilder.cpp b/clang-tools-extra/clangd/ModulesBuilder.cpp
index c4a0c54a8fc2f..b7e4ebe314a76 100644
--- a/clang-tools-extra/clangd/ModulesBuilder.cpp
+++ b/clang-tools-extra/clangd/ModulesBuilder.cpp
@@ -29,6 +29,23 @@ llvm::cl::opt<bool> DebugModulesBuilder(
"Remember to remove them later after debugging."),
llvm::cl::init(false));
+// Disable reusing prebuilt module files on windows by default.
+// As clangd may lock these module files on windows to prevent
+// these module files to be updated by buiild system on windows.
+//
+// See https://github.com/clangd/clangd/issues/2497 for details.
+#ifdef _WIN32
+constexpr bool DisablePrebuiltModuleFileReuseDefault = true;
+#else
+constexpr bool DisablePrebuiltModuleFileReuseDefault = false;
+#endif
+
+llvm::cl::opt<bool> DisablePrebuiltModuleFileReuse(
+ "disable-prebuilt-module-file-reuse",
+ llvm::cl::desc("Do not reuse prebuilt module files from existing build "
+ "artifacts."),
+ llvm::cl::init(DisablePrebuiltModuleFileReuseDefault));
+
// Create a path to store module files. Generally it should be:
//
// {TEMP_DIRS}/clangd/module_files/{hashed-file-name}-%%-%%-%%-%%-%%-%%/.
@@ -92,8 +109,7 @@ class FailedPrerequisiteModules : public PrerequisiteModules {
// We shouldn't adjust the compilation commands based on
// FailedPrerequisiteModules.
- void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override {
- }
+ void adjustHeaderSearchOptions(HeaderSearchOptions &Options) const override {}
// FailedPrerequisiteModules can never be reused.
bool
@@ -561,6 +577,9 @@ class ModulesBuilder::ModulesBuilderImpl {
void ModulesBuilder::ModulesBuilderImpl::getPrebuiltModuleFile(
StringRef ModuleName, PathRef ModuleUnitFileName, const ThreadsafeFS &TFS,
ReusablePrerequisiteModules &BuiltModuleFiles) {
+ if (DisablePrebuiltModuleFileReuse)
+ return;
+
auto Cmd = getCDB().getCompileCommand(ModuleUnitFileName);
if (!Cmd)
return;
diff --git a/clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test b/clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test
new file mode 100644
index 0000000000000..bc0d667c77991
--- /dev/null
+++ b/clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test
@@ -0,0 +1,58 @@
+# Check that clangd can optionally avoid reusing prebuilt module files.
+#
+# Windows uses a different default for this flag and has different escaping
+# modes, so keep this test non-Windows for now.
+# UNSUPPORTED: system-windows
+#
+# RUN: rm -fr %t
+# RUN: mkdir -p %t
+# RUN: split-file %s %t
+# RUN: sed -e "s|DIR|%/t|g" %t/compile_commands.json.tmpl > %t/compile_commands.json.tmp
+# RUN: sed -e "s|CLANG_CC|clang|g" %t/compile_commands.json.tmp > %t/compile_commands.json
+# RUN: clang -std=c++20 %t/M.cppm --precompile -o %t/M.pcm
+# RUN: clangd -enable-config=0 -experimental-modules-support -log=verbose \
+# RUN: -compile-commands-dir=%t -check=%t/Use.cpp 2>&1 \
+# RUN: | FileCheck %s --check-prefix=REUSE
+# RUN: clangd -enable-config=0 -experimental-modules-support -log=verbose \
+# RUN: -compile-commands-dir=%t -check=%t/Use.cpp \
+# RUN: --disable-prebuilt-module-file-reuse 2>&1 \
+# RUN: | FileCheck %s --check-prefix=NOREUSE
+
+// REUSE: Built module M to [[PCM:.*clangd.*/module_files/.*/M\.pcm]]
+// REUSE: All checks completed, 0 errors
+
+// NOREUSE-NOT: Reusing prebuilt module file
+// NOREUSE: Built module M to [[BUILT:.*clangd.*/module_files/.*/M\.pcm]]
+// NOREUSE: All checks completed, 0 errors
+
+#--- M.cppm
+export module M;
+export int value() { return 42; }
+
+#--- A.cppm
+export module A;
+import M;
+export int useM() { return value(); }
+
+#--- Use.cpp
+import A;
+int use() { return useM(); }
+
+#--- compile_commands.json.tmpl
+[
+ {
+ "directory": "DIR",
+ "command": "CLANG_CC -std=c++20 DIR/M.cppm --precompile -o DIR/M-from-cdb.pcm",
+ "file": "DIR/M.cppm"
+ },
+ {
+ "directory": "DIR",
+ "command": "CLANG_CC -std=c++20 -fmodule-file=M=DIR/M.pcm DIR/A.cppm --precompile -o DIR/A-from-cdb.pcm",
+ "file": "DIR/A.cppm"
+ },
+ {
+ "directory": "DIR",
+ "command": "CLANG_CC -std=c++20 -fprebuilt-module-path=DIR -c DIR/Use.cpp -o DIR/Use.o",
+ "file": "DIR/Use.cpp"
+ }
+]
More information about the cfe-commits
mailing list