-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] use relative paths for builtin headers during module compilation #68023
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-modules ChangesWhen including builtin headers as part of a system module, ensure we use absolute paths to those headers. Otherwise the module will fail to compile when specifying relative resource directories. Full diff: https://github.com/llvm/llvm-project/pull/68023.diff 3 Files Affected:
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp
index e8437572ebf4bf6..75dd76a63063274 100644
--- a/clang/lib/Lex/ModuleMap.cpp
+++ b/clang/lib/Lex/ModuleMap.cpp
@@ -348,6 +348,10 @@ bool ModuleMap::resolveAsBuiltinHeader(
if (!File)
return false;
+ // Ensure the path to the module directory is absolute, otherwise
+ // builtin headers will fail to resolve when using relative resource
+ // directory paths without a -I.
+ llvm::sys::fs::make_absolute(Path);
auto Role = headerKindToRole(Header.Kind);
Module::Header H = {Header.FileName, std::string(Path.str()), *File};
addHeader(Mod, H, Role);
diff --git a/clang/test/Modules/Inputs/builtin-headers/module.modulemap b/clang/test/Modules/Inputs/builtin-headers/module.modulemap
new file mode 100644
index 000000000000000..78a5b730dc6a925
--- /dev/null
+++ b/clang/test/Modules/Inputs/builtin-headers/module.modulemap
@@ -0,0 +1,3 @@
+module ModuleWithBuiltinHeader [system] {
+ header "float.h"
+}
\ No newline at end of file
diff --git a/clang/test/Modules/relative-resource-dir.m b/clang/test/Modules/relative-resource-dir.m
new file mode 100644
index 000000000000000..1d38fe922e71849
--- /dev/null
+++ b/clang/test/Modules/relative-resource-dir.m
@@ -0,0 +1,8 @@
+// RUN: EXPECTED_RESOURCE_DIR=`%clang -print-resource-dir` && \
+// RUN: mkdir -p %t && rm -rf %t/resource-dir && \
+// RUN: cp -R $EXPECTED_RESOURCE_DIR %t/resource-dir
+// RUN: cd %t && %clang -cc1 -x objective-c -fmodules -fmodule-format=obj \
+// RUN: -fimplicit-module-maps -fmodules-cache-path=%t.mcp \
+// RUN: -fbuiltin-headers-in-system-modules -resource-dir resource-dir \
+// RUN: -emit-module %S/Inputs/builtin-headers/module.modulemap \
+// RUN: -fmodule-name=ModuleWithBuiltinHeader -o %t.pcm
|
a44aa3a
to
3617539
Compare
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.
This seems reasonable to me, but I would like @jansvoboda11 to also look at it.
This is now always storing an absolute path into My bigger concern is that we now generate absolute paths into the I'm not sure what the best solution here... Maybe prepending |
Wouldn't this always have been the case? I'll check shortly with a resource dir picked up via toolchain bundle layout.
This is the use case I am trying to support, via -fmodule-file-home-is-cwd and with the resource dir as a subfolder of the cwd. This works currently, but we require adding a -I. to module compilation or modules with builtin headers will not compile successfully. If the resource dir is outside of the cwd then you would have to have an absolute path here anyway, wouldn't you? I guess the alternative would be to set PathRelativeToRootModuleDirectory relative to the resource dir module directory instead, and rely on the resource dir being added to the header search paths to make lookup succeed. This seems confusing too though, as you would expect the PathRelativeToRootModuleDirectory to be the module being compiled, not a different module. |
Could you expand on this? Not sure I get the idea. |
Looks like yes:
This was debugging:
|
Yes. But my understanding was that's not what you're interested in. I thought you're trying to fix the situation where your resource dir is in the CWD, so that's the context I'm assuming. Is that correct?
I was considering your test case, where we'd previously store
But
If you originally compiled the PCM on machine A that has CWD set to
Is that not a concern for your use-case?
I was going to suggest keeping
This would ensure both machines A and B produce identical PCM files. |
Yes.
Oh I see, being a bit slow there.
Ah, didn't consider that, yes that is an issue you are right.
Wouldn't this work without the pragma? Isn't the resource directory always added to the header search paths, so the header should be found correctly if we set PathRelativeToRootModuleDirectory relative to the resource dir for builtin headers? |
Yeah, the driver adds auto Directory = Header.HasBuiltinHeader ? BuiltinIncludeDir : M->Directory; Which effectively mimics what we already do in |
I had a go at this approach this morning, it mostly works but fails for the case where we have a module with a textual header with the same name as a builtin header. When using relative paths for the builtin headers we now prefer the module's textual header instead of the builtin header. This fails the following test case: I believe this is because:
What would you suggest as the best solution here? Do you think its reasonable to always add the builtin header directory to the front of the Includers ahead of the module build directory? |
3617539
to
d824f38
Compare
d824f38
to
9d5ae4b
Compare
How about the updated approach? This will use a different include dir based on if the header is a builtin header name or not, which also solves the issue of having to pass the extra include path to the frontend. |
@jansvoboda11 still good with this change, or is there a less invasive way to get this done? |
Hi, sorry for being unresponsive, I'm out of office until the end of the week. This looks reasonable to me, but I'd like to run a smoke test with the Darwin SDK first. I can get back to you early next week. Sounds good? |
clang/lib/Lex/ModuleMap.cpp
Outdated
auto Directory = M->Directory; | ||
// Search for the header file within the module's home directory | ||
// or the builtin include dir if this is a builtin header. | ||
auto Directory = Header.HasBuiltinHeader ? BuiltinIncludeDir : M->Directory; |
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.
Is this change still needed?
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.
Looks like we don't, no. The header ends up resolved against the resource dir as expected:
<SUBMODULE_BLOCK NumWords=63 BlockCodeSize=5>
<SUBMODULE_METADATA op0=1 op1=0/>
<SUBMODULE_DEFINITION abbrevid=4 op0=1 op1=0 op2=0 op3=18 op4=0 op5=0 op6=1 op7=0 op8=0 op9=0 op10=0 op11=0 op12=0 op13=1/> blob data = 'ModuleWithBuiltinHeader'
<SUBMODULE_HEADER abbrevid=6/> blob data = 'float.h'
<SUBMODULE_TOPHEADER abbrevid=7/> blob data = '/home/llvmbuilddbg.noindex/tools/clang/test/Modules/Output/relative-resource-dir.m.tmp/resource-dir/include/float.h'
</SUBMODULE_BLOCK>
Our downstream test |
9d5ae4b
to
5e3c631
Compare
Thanks for your patience, I should have looked at this sooner. The change to our downstream test looks expected; the -#import "/^tc/lib/clang/18/include/stdbool.h"
+#import "stdbool.h" But the actual resolution of which header is used is identical. I'm happy with this change; @jansvoboda11 were you looking at anything else or is this okay for @rmaz to land? |
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 for confirming, Ben! I don't have other concerns, this should be good to land.
Thanks for the detailed reviews all, will get this rebased and landed. |
5e3c631
to
87bbfac
Compare
When including builtin headers as part of a system module, serialize them relative to the builtin include dir. To handle later lookup add a method to provide the correct base directory. This makes it possible to compile modules including builtin headers with relative resource dirs.
87bbfac
to
cf4ae97
Compare
Summary: Add a swift_toolchain attribute to identify if the toolchain supports relative resource directories in module output. This requires llvm/llvm-project#68023. Reviewed By: milend Differential Revision: D50943679 fbshipit-source-id: c944f3a5e3879dd91605ad9df008b5784bdfcda1
Summary: Add a swift_toolchain attribute to identify if the toolchain supports relative resource directories in module output. This requires llvm/llvm-project#68023. Reviewed By: milend Differential Revision: D50943679 fbshipit-source-id: c944f3a5e3879dd91605ad9df008b5784bdfcda1
Summary: Add a swift_toolchain attribute to identify if the toolchain supports relative resource directories in module output. This requires llvm/llvm-project#68023. Reviewed By: milend Differential Revision: D50943679 fbshipit-source-id: c944f3a5e3879dd91605ad9df008b5784bdfcda1
When including builtin headers as part of a system module, ensure we use absolute paths to those headers. Otherwise the module will fail to compile when specifying relative resource directories.