diff options
author | Christopher Di Bella <cjdb@google.com> | 2022-08-09 23:46:12 +0000 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-11-01 17:36:29 +0000 |
commit | 6b285afc5e9caadeb6741efe872981ffdbb3bfe1 (patch) | |
tree | e0fa8650695560aa94b6e39feab53a620fd4161c | |
parent | 29f888ab82314300bae873b564181f001d9f86a1 (diff) | |
download | toolchain-utils-6b285afc5e9caadeb6741efe872981ffdbb3bfe1.tar.gz |
compiler-wrapper: adds an IWYU component
This first patch makes it possible to run IWYU as a part of the build
process. It's not currently possible for us to make changes to packages:
this functionality will appear in a later CL.
BUG=b:237320348
TEST=Tested locally
Change-Id: I00610284143cf478b242b2c0ca1c05e2c8d43de4
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/third_party/toolchain-utils/+/3820351
Reviewed-by: Ryan Beltran <ryanbeltran@chromium.org>
Auto-Submit: Christopher Di Bella <cjdb@google.com>
Commit-Queue: Ryan Beltran <ryanbeltran@chromium.org>
Tested-by: Christopher Di Bella <cjdb@google.com>
7 files changed, 190 insertions, 20 deletions
diff --git a/compiler_wrapper/compiler_wrapper.go b/compiler_wrapper/compiler_wrapper.go index 1386374e..dcaada99 100644 --- a/compiler_wrapper/compiler_wrapper.go +++ b/compiler_wrapper/compiler_wrapper.go @@ -151,6 +151,7 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int } } else { cSrcFile, tidyFlags, tidyMode := processClangTidyFlags(mainBuilder) + cSrcFile, iwyuFlags, iwyuMode := processIWYUFlags(mainBuilder) if mainBuilder.target.compilerType == clangType { err := prepareClangCommand(mainBuilder) if err != nil { @@ -176,6 +177,20 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int return 0, err } } + + if iwyuMode != iwyuModeNone { + if iwyuMode == iwyuModeError { + panic(fmt.Sprintf("Unknown IWYU mode")) + } + + allowCCache = false + clangCmdWithoutRemoteBuildAndCCache := mainBuilder.build() + err := runIWYU(env, clangCmdWithoutRemoteBuildAndCCache, cSrcFile, iwyuFlags) + if err != nil { + return 0, err + } + } + if remoteBuildUsed, err = processRemoteBuildAndCCacheFlags(allowCCache, mainBuilder); err != nil { return 0, err } diff --git a/compiler_wrapper/iwyu_flag.go b/compiler_wrapper/iwyu_flag.go new file mode 100644 index 00000000..c1e6af65 --- /dev/null +++ b/compiler_wrapper/iwyu_flag.go @@ -0,0 +1,155 @@ +// Copyright 2022 The ChromiumOS Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package main + +import ( + "bufio" + "bytes" + "fmt" + "path/filepath" + "strings" +) + +type useIWYUMode int + +const iwyuCrashSubstring = "PLEASE submit a bug report" + +const ( + iwyuModeNone useIWYUMode = iota + iwyuModeAll + iwyuModeError +) + +var srcFileSuffixes = []string{ + ".c", + ".cc", + ".cpp", + ".C", + ".cxx", + ".c++", +} + +func findWithIWYUFlag(args []builderArg) (string, []builderArg) { + for i := range args { + if args[i].value == "--with-iwyu" { + args = append(args[:i], args[i+1:]...) + return "1", args + } + } + return "", args +} + +func processIWYUFlags(builder *commandBuilder) (cSrcFile string, iwyuFlags []string, mode useIWYUMode) { + builder.transformArgs(func(arg builderArg) string { + const prefix = "-iwyu-flag=" + if !strings.HasPrefix(arg.value, prefix) { + return arg.value + } + + iwyuFlags = append(iwyuFlags, arg.value[len(prefix):]) + return "" + }) + + withIWYU, _ := builder.env.getenv("WITH_IWYU") + if withIWYU == "" { + withIWYU, builder.args = findWithIWYUFlag(builder.args) + if withIWYU == "" { + return "", iwyuFlags, iwyuModeNone + } + } + + cSrcFile = "" + lastArg := "" + for _, arg := range builder.args { + if lastArg != "-o" { + for _, suffix := range srcFileSuffixes { + if strings.HasSuffix(arg.value, suffix) { + cSrcFile = arg.value + break + } + } + } + lastArg = arg.value + } + + if cSrcFile == "" { + return "", iwyuFlags, iwyuModeNone + } + + if withIWYU != "1" { + return "", iwyuFlags, iwyuModeError + } + + return cSrcFile, iwyuFlags, iwyuModeAll +} + +func calcIWYUInvocation(env env, clangCmd *command, cSrcFile string, iwyuFlags ...string) (*command, error) { + resourceDir, err := getClangResourceDir(env, clangCmd.Path) + if err != nil { + return nil, err + } + + iwyuPath := filepath.Join(filepath.Dir(clangCmd.Path), "include-what-you-use") + args := append([]string{}, iwyuFlags...) + args = append(args, "-resource-dir="+resourceDir) + args = append(args, clangCmd.Args...) + + for i := 0; i < len(args); i++ { + for j := 0; j < len(srcFileSuffixes); j++ { + if strings.HasSuffix(args[i], srcFileSuffixes[j]) { + args = append(args[:i], args[i+1:]...) + break + } + } + } + args = append(args, cSrcFile) + + return &command{ + Path: iwyuPath, + Args: args, + EnvUpdates: clangCmd.EnvUpdates, + }, nil +} + +func runIWYU(env env, clangCmd *command, cSrcFile string, extraIWYUFlags []string) error { + extraIWYUFlags = append(extraIWYUFlags, "-Xiwyu", "--mapping_file=/usr/share/include-what-you-use/libcxx.imp", "-Xiwyu", "--no_fwd_decls") + iwyuCmd, err := calcIWYUInvocation(env, clangCmd, cSrcFile, extraIWYUFlags...) + if err != nil { + return fmt.Errorf("calculating include-what-you-use invocation: %v", err) + } + + // Note: We pass nil as stdin as we checked before that the compiler + // was invoked with a source file argument. + var stderr bytes.Buffer + stderr_writer := bufio.NewWriter(&stderr) + exitCode, err := wrapSubprocessErrorWithSourceLoc(iwyuCmd, + env.run(iwyuCmd, nil, nil, stderr_writer)) + stderr_ := stderr.String() + fmt.Fprintln(env.stderr(), stderr_) + + if err == nil && exitCode != 0 { + // Note: We continue on purpose when include-what-you-use fails + // to maintain compatibility with the previous wrapper. + fmt.Fprintln(env.stderr(), "include-what-you-use failed") + } + + var path strings.Builder + path.WriteString(strings.TrimSuffix(iwyuCmd.Path, "include-what-you-use")) + path.WriteString("fix_includes.py") + fixIncludesCmd := &command{ + Path: path.String(), + Args: []string{"--nocomment"}, + EnvUpdates: clangCmd.EnvUpdates, + } + + exitCode, err = wrapSubprocessErrorWithSourceLoc(fixIncludesCmd, + env.run(fixIncludesCmd, strings.NewReader(stderr_), env.stdout(), env.stderr())) + if err == nil && exitCode != 0 { + // Note: We continue on purpose when include-what-you-use fails + // to maintain compatibility with the previous wrapper. + fmt.Fprint(env.stderr(), "include-what-you-use failed") + } + return nil +} diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json b/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json index c1cf0507..d0a604ba 100644 --- a/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json +++ b/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json @@ -27,7 +27,7 @@ "path": "/tmp/stable/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "-Qunused-arguments", @@ -117,7 +117,7 @@ "path": "/tmp/stable/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "-Qunused-arguments", @@ -209,7 +209,7 @@ "path": "/tmp/stable/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "-Qunused-arguments", @@ -305,7 +305,7 @@ "path": "/tmp/stable/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "-Qunused-arguments", diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json b/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json index f7438940..bfef2799 100644 --- a/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json +++ b/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json @@ -27,7 +27,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -141,7 +141,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -258,7 +258,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -379,7 +379,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", diff --git a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json index f7438940..bfef2799 100644 --- a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json +++ b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json @@ -27,7 +27,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -141,7 +141,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -258,7 +258,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -379,7 +379,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", diff --git a/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json b/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json index f7438940..bfef2799 100644 --- a/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json +++ b/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json @@ -27,7 +27,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -141,7 +141,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -258,7 +258,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -379,7 +379,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json index 830abee6..3d5078df 100644 --- a/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json +++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json @@ -27,7 +27,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -127,7 +127,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -230,7 +230,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", @@ -337,7 +337,7 @@ "path": "../../usr/bin/clang-tidy", "args": [ "-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*", - "main.cc", + "", "--", "-resource-dir=someResourceDir", "--sysroot=/usr/x86_64-cros-linux-gnu", |