-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[clang-cl] Accept cl
-style output arguments (/Fo
, -Fo
) for --precompile
#121046
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
base: main
Are you sure you want to change the base?
Conversation
d8108f0
to
350a517
Compare
@llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Sharadh Rajaraman (sharadhr) ChangesFull diff: https://github.com/llvm/llvm-project/pull/121046.diff 1 Files Affected:
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index ecae475f75da00..b47e0443d6e9db 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -5442,7 +5442,7 @@ InputInfoList Driver::BuildJobsForAction(
InputInfoList Result = BuildJobsForActionNoCache(
C, A, TC, BoundArch, AtTopLevel, MultipleArchs, LinkingOutput,
CachedResults, TargetDeviceOffloadKind);
- CachedResults[ActionTC] = Result;
+ CachedResults[ActionTC] = Result;
return Result;
}
@@ -5890,7 +5890,7 @@ const char *Driver::GetNamedOutputPath(Compilation &C, const JobAction &JA,
llvm::PrettyStackTraceString CrashInfo("Computing output path");
// Output to a user requested destination?
if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
- if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o))
+ if (Arg *FinalOutput = C.getArgs().getLastArg(options::OPT_o, options::OPT__SLASH_Fo, options::OPT__SLASH_Fo_COLON))
return C.addResultFile(FinalOutput->getValue(), &JA);
}
|
350a517
to
e1708db
Compare
The tests are failing and it looks relevent. |
Why is this submitted against the release/19.x branch? Is this a backport? If so, please indicate which commit it backports. |
e1708db
to
bc9b68d
Compare
Not a backport but a new commit. I have now re-submitted it against |
It is better to fix the test failures (or announce they are not relevant with your pr) |
7487d82
to
ff22639
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
a839072
to
1f40c12
Compare
I'm not sure how to fix the |
Sorry, I can't test and take a deeper look on windows. From https://discourse.llvm.org/t/driver-volunteer-wanted-for-modules-support-in-driver-for-mac-ubuntu-and-windows/83768/13, I think you can CC people there or calling again there. |
Thanks, the code seems correct, but can this be tested? cc @zmodem for clang-cl driver changes |
d030b5a
to
b6bda7b
Compare
Ready for review; all relevant tests passing. |
I think @rnk was saying you should add a test for this. |
Fair point. Added a test. Additionally the CMake repository contains a bigger battery of tests that also all pass with this PR. |
A quick bump. I'd like to get this reviewed hopefully in time for the Clang 20.x release. I think having it in 19.x is a lost battle, it's a bit too late for that. |
clang/lib/Driver/Driver.cpp
Outdated
Arg *FinalOutput = nullptr; | ||
if (IsCLNonPCH && HasAnyOutputArg) { | ||
FinalOutput = C.getArgs().getLastArg( | ||
options::OPT_o, options::OPT__SLASH_Fo, options::OPT__SLASH_Fo_COLON); | ||
} else if (IsCLNonPCH) { | ||
FinalOutput = C.getArgs().getLastArg(options::OPT__SLASH_Fo, | ||
options::OPT__SLASH_Fo_COLON); | ||
} else { | ||
FinalOutput = C.getArgs().getLastArg(options::OPT_o); | ||
} |
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.
I'm having trouble following the logic here. Can you add a comment explaining what's going on? I.e. when is -o
and/or /Fo
supposed to be considered?
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.
I've updated the OP message with the reasoning for this PR.
This logic in particular is to resolve lit
test cases that failed when /Yp
was passed to clang-cl.exe
, i.e. PCHs were generated. I believe this is because /Yp
uses /Fo
for the PCH output, and therefore this invocation needs to use /o
(or -o
). This PR originally just wrapped lines 6111 and 6112 around an if (IsCLMode()) { ... }
, which failed many PCH test cases.
HasAnyOutputArg
was written specifically to resolve llvm-project\clang\test\ClangScanDeps\target-filename.cpp
failing; more particularly, the clangcl.o
test cases. Admittedly it feels like a weird hack and I'm open to suggestions.
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.
I do hope there's some scope for a response, as I'm not sure how to proceed.
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.
You can ping the reviewer @zmodem . The suggested style is no more ping in a week.
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.
The logic has to be clear to any reader. "It makes the lit tests pass" is not a good explanation.
I think you need to figure out how these flags are supposed to work together, and then translate that into code.
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.
Given the comment below, I believe it is incorrect to pass both -fmodule-output
and the combination of --precompile
and -o
(or -Fo
); this is a CMake bug. I therefore think we can simplify this logic.
Additionally, --precompile
+ -o
and -fmodule-output
then need to be marked as mutually-exclusive command-line options.
@@ -14,3 +14,11 @@ | ||
|
||
//--- test.pcm | ||
// CPP20WARNING-NOT: clang-cl: warning: argument unused during compilation: '/std:c++20' [-Wunused-command-line-argument] | ||
|
||
// test whether the following outputs %Hello.bmi | ||
// RUN: %clang_cl /std:c++20 --precompile -x c++-module -fmodule-output=%t/Hello.bmi -Fo"%t/Hello.bmi" -c %t/Hello.cppm -### 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.
This is just one invocation, but the logic in GetNamedOutputPath() seems to cover many cases.
Also, is it -fmodule-output
or /Fo
that sets the output filename (or both?)
(Nit: you'll want to put --
before %t/Hello.cppm
, otherwise it may be interpreted as a command-line option e.g. if the path starts with /Users
.)
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 is just one invocation, but the logic in GetNamedOutputPath() seems to cover many cases.
Agreed; once again; open to suggestions for more test cases.
Also, is it -fmodule-output or /Fo that sets the output filename (or both?)
From the Clang user guide, it appears both are required, and CMake in particular uses the 'one-phase compilation' method.
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.
From the doc:
To generate a BMI for an importable module unit, use either the --precompile or -fmodule-output command line options.
Your test uses both, with the same filename passed to two different flags. This seems wrong to me.
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.
Coming back after a long while...
Both arguments were provided to exercise CMake's command-line invocation which given this information might be incorrect.
@ChuanqiXu9 are you able to provide more information?
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.
Sorry for ignoring this. --precompile
will be meaningless if it is followed by a -c
. So the command line in cmake's thread actually use -fmodule-output
.
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.
Please don't worry too much about what CMake's command-line invocations linked above are doing. CMake doesn't yet support modules with clang-cl
, and is waiting on the work here. The command lines I posted over there are showing what unmerged changes to CMake are doing in its test suite as part of analyzing why not everything is working. This PR should focus on the functionality in clang-cl
and its test should focus on the documented and intended usage. Once this is merged then CMake can be taught to do the right thing.
cl
-style output arguments (/Fo
, -Fo
) for --fmodule-output
cl
-style output arguments (/Fo
, -Fo
) for --precompile
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.
@zmodem given how important this it, I hope we can make this for clang21. Thanks!
91cf98b
to
8653855
Compare
8653855
to
d2e56db
Compare
I'm just a reviewer here, and I still find the patch very confusing. And taking a step back, the whole point of clang-cl is to provide a cl.exe compatible interface to clang. I presume cl.exe does not use |
That was discussed on Discourse. If/when |
Sorry, I don't remember seeing that discussion, and I'm probably missing lots of modules context. As a counter argument, clang-cl uses More importantly, it feels like we're being very unintentional about the interface design here. Why should clang-cl's If the idea is to punt on the design, maybe the solution is just to use regular clang flags for this? |
Not asking for an approval. It is just a ping : )
|
although I don't use MSVC. I think '/Fo' is basically '-o'. Its semantic is to specify the path to the output file. And with '--precompile' the output file is BMI. And with '-c', the output is obj files. And with '-emit-llvm', the output is llvm ir. So I feel it is fine. But of course, all of these are my thoughts and imagination. I am never a clang-cl user ever. So if now clang-cl can accept '-o', I don't mind to use that if @mathstuf agrees on this. Since most end users won't write this in my mind. The build system are the major users here. |
No,
It works in general in clang-cl. I guess we'd have to double check if it works in the modules use case. And |
Is
See this thread: https://discourse.llvm.org/t/clang-cl-exe-support-for-c-modules/72257 |
But if we want to generate BMI only instead of obj files, we should use |
Good point. I think trying to hack
As mentioned above, the Clang C++ Standard Modules document suggests using
But CMake seems to prefer the latter. Additionally, in the CMake MR, it was determined that |
From @zmodem's comment above, MSVC documentation, and Clang-cl documentation, I believe it is now incorrect to use It might be better to use |
I believe the issue can be distilled further. On the
This command does not:
This command also does not:
And the only lines where the driver behaviour appears to diverge, is the // Output to a user requested destination?
if (AtTopLevel && !isa<DsymutilJobAction>(JA) && !isa<VerifyJobAction>(JA)) {
...
} |
This PR resolves this issue, which can be summarised as such. Given the following
foo.cxx
:Running the following outputs
foo.pcm
, but doesn’t outputfoo.bmi
as requested by-Fo
:However, running the following outputs
foo.bmi
as requested:This behaviour is then used by
clang-scan-deps
to output the dependency scanning JSON. In the former case since no.bmi
is output, the corresponding value of theprimary-output
key here is"-"
.This invocation is used by CMake to run
clang-scan-deps
and build the dependency tree.