This is an archive of the discontinued LLVM Phabricator instance.

[clang][driver] Fix compilation database dump with multiple architectures
ClosedPublic

Authored by jansvoboda11 on Mar 18 2022, 4:52 AM.

Details

Summary

Command lines with multiple -arch arguments expand into multiple entries in the compilation database. However, the file writes are not appending, meaning subsequent writes end up overwriting the previous ones, resulting in garbled output.

This patch fixes that by always appending to the file.

rdar://90165004

Diff Detail

Event Timeline

jansvoboda11 created this revision.Mar 18 2022, 4:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 18 2022, 4:52 AM
jansvoboda11 requested review of this revision.Mar 18 2022, 4:52 AM
Herald added a project: Restricted Project. · View Herald TranscriptMar 18 2022, 4:52 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
dexonsmith added inline comments.Mar 18 2022, 12:01 PM
clang/test/Driver/compilation_database_multiarch.c
2

Usually driver tests don't depend on the -cc1 working. The -cc1 depends on the backends. You'd need to check that the relevant targets have been built and linked in. It'd be better to keep this isolated to the driver?

Is there a way to get the driver to dump the compilation database only (without actually running the actions)?

E.g., will -### still emit the compilation database? Looks like not:

// If this is a dry run, do not create the compilation database file.
if (C.getArgs().hasArg(options::OPT__HASH_HASH_HASH))
  return;

But maybe there's some other way to avoid running the actions. Or, we can add something like -MJ-only <cdb>, which acts like -MJ <cdb> and then exits before running the actions.

5–6

I guess this is off topic, but this is the wrong output. Would be good to fix this — maybe first to avoid adding a test for the wrong behaviour. Running on macOS 12, I would expect:

% clang -arch x86_64 -arch arm64 /dev/null -x c -###

to emit

".../path/to/clang" "-cc1" "-triple" "x86_64-apple-macosx12.0.0" ...
".../path/to/clang" "-cc1" "-triple" "arm64-apple-macosx12.0.0" ...

and that's what I get from the clang that comes with Xcode. But I reproduced the incorrect output you're checking for here with the clang at llvm.org.

Is there something we forgot to upstream? @arphaman, do you know?

dexonsmith added inline comments.Mar 18 2022, 12:04 PM
clang/test/Driver/compilation_database_multiarch.c
5–6

Heh, typo in my reproducer above, which I fixed when I ran it to check but forgot to copy back into Phabricator. Correctly-spelled -### command is:

% clang -arch x86_64 -arch arm64 -x c /dev/null -c -###

Specify the apple-darwin target

jansvoboda11 added inline comments.Mar 18 2022, 12:21 PM
clang/test/Driver/compilation_database_multiarch.c
2

If we manage to only run the driver (without invoking the -cc1s), would the question of built targets go away?

Flang has a frontend option -init-only. Maybe we could add something similar to that to Clang's driver? (-driver-only) Creating a specialized -MJ-only seems too specific IMO.

Avoid buggy driver behavior

dexonsmith added inline comments.Mar 18 2022, 1:20 PM
clang/test/Driver/compilation_database_multiarch.c
5–6

Avoid buggy driver behavior

I just remembered the "correct" way to specify a platform without an SDK if you're using -arch: -mmacosx-version-min=12.0.0. That's probably better for this test than using a half-ignored -target.

dexonsmith added inline comments.Mar 18 2022, 1:28 PM
clang/test/Driver/compilation_database_multiarch.c
2

Sure, -driver-only makes sense to me:

  • Run driver, including side effects.
  • Don't run actions.

It'd be worth testing that it works correctly with -v. My intuition is that -driver-only -v should do the same thing as -###, except that -### suppresses driver outputs that come before running the actions.

Introduce -driver-only to avoid running -cc1s.

dexonsmith accepted this revision.Mar 21 2022, 11:20 AM

The "Fix compilation database dump" changes LGTM, assuming you split out -driver-only and land it separately ahead of the rest of this.

Introduce -driver-only to avoid running -cc1s.

-driver-only looks mostly great, but should really be committed (and tested) separately.

I added a comment inline about -v / CCPrintOptions.

For the testing, I suggest:

  • Add driver-only.c, where you can test a normal compilation (unrelated to -MJ).
    • If you implement -v, you can check its output.
    • Add a RUN: not %clang -driver-only in some case where it should fail.
  • If you implement CCPrintOptions with -v, update clang/test/Driver/cc-print-options.c with an additional RUN line.
  • Update clang/test/Driver/gen-cdb-fragment.c to use -driver-only and remove REQUIRES: x86-registered-target.
clang/lib/Driver/Driver.cpp
1600–1607 ↗(On Diff #416846)

I think if OPT_v then OPT_driver_only should call C.getJobs().Print() somehow... ideally, using the logic that's at the top of Compilation::ExecuteCommand(), also implementing the analogous CCPrintOptions, but that looks potentially awkward... you maybe want to call ExecuteJobs below with a flag that says "don't execute" or something.

Happy for those things to come in a follow-up though; just leave behind FIXME(s) if so.

1609–1611 ↗(On Diff #416846)

-driver-only should return 1 in this case. Please add a test for this as well.

This revision is now accepted and ready to land.Mar 21 2022, 11:20 AM

Extract -fdriver-only into separate patch, ensure output file is consistent.

Hi, it seems on AIX the target and arch options are ignored, so we don't get the expected output for this test. Any ideas about the course of action we should take?
https://lab.llvm.org/buildbot/#/builders/214/builds/1785/steps/6/logs/FAIL__Clang__compilation_database_multiarch_c

Hi, it seems on AIX the target and arch options are ignored, so we don't get the expected output for this test. Any ideas about the course of action we should take?
https://lab.llvm.org/buildbot/#/builders/214/builds/1785/steps/6/logs/FAIL__Clang__compilation_database_multiarch_c

Hey, I disabled the test on non-Darwin hosts in 2de36d0369a5107a3f02aceebb55326adf4ad2cb. Your build bot is back to green.

Should there be an aarch64 guard on the test? There exist downstream Arm compilers that don't support Arm64 and fail. I know other tests explicitly state "REQUIRES: aarch64-registered-target"

Should there be an aarch64 guard on the test? There exist downstream Arm compilers that don't support Arm64 and fail. I know other tests explicitly state "REQUIRES: aarch64-registered-target"

Could you describe your build config? I don't need to enable the Aarch64 or X86 target for this test to pass on macOS.