From ade32e68dc7aa23b5038cd44a4b86cb491818139 Mon Sep 17 00:00:00 2001 From: Googler Date: Wed, 5 Jul 2023 13:12:31 -0700 Subject: [PATCH] Add additional_compiler_inputs attribute for cc_library. Also, ensure that location function expansion works with these inputs as expected. RELNOTES: Additional source inputs can now be specified for compilation in cc_library targets using the additional_compiler_inputs attribute, and these inputs can be used in the $(location) function. Fixes #18766. PiperOrigin-RevId: 545766084 Change-Id: I2d9f195d81a1358c696601873e60d3cad810a150 --- .../bazel/rules/cpp/BazelCcLibraryRule.java | 6 + .../builtins_bzl/common/cc/cc_helper.bzl | 7 +- .../builtins_bzl/common/cc/cc_library.bzl | 5 + .../cpp/CcLibraryConfiguredTargetTest.java | 181 ++++++++++-------- 4 files changed, 114 insertions(+), 85 deletions(-) diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcLibraryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcLibraryRule.java index a8f3b3518e3327..ea4e63e20126e7 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcLibraryRule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcLibraryRule.java @@ -63,6 +63,12 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) attr("implementation_deps", LABEL_LIST) .allowedFileTypes(FileTypeSet.NO_FILE) .mandatoryProviders(CcInfo.PROVIDER.id())) + /* + Any additional files you might want to pass to the compiler command line, such as sanitizer + ignorelists, for example. Files specified here can then be used in copts with the + $(location) function. + */ + .add(attr("additional_compiler_inputs", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)) .advertiseStarlarkProvider(CcInfo.PROVIDER.id()) .build(); } diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl index 094eca5acb0e84..cde737f8a9a88c 100644 --- a/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl @@ -908,16 +908,19 @@ def _expand_single_make_variable(ctx, token, additional_make_variable_substituti def _expand_make_variables_for_copts(ctx, tokenization, unexpanded_tokens, additional_make_variable_substitutions): tokens = [] + targets = [] + for additional_compiler_input in getattr(ctx.attr, "additional_compiler_inputs", []): + targets.append(additional_compiler_input) for token in unexpanded_tokens: if tokenization: - expanded_token = _expand(ctx, token, additional_make_variable_substitutions) + expanded_token = _expand(ctx, token, additional_make_variable_substitutions, targets = targets) _tokenize(tokens, expanded_token) else: exp = _expand_single_make_variable(ctx, token, additional_make_variable_substitutions) if exp != None: _tokenize(tokens, exp) else: - tokens.append(_expand(ctx, token, additional_make_variable_substitutions)) + tokens.append(_expand(ctx, token, additional_make_variable_substitutions, targets = targets)) return tokens def _get_copts(ctx, feature_configuration, additional_make_variable_substitutions): diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_library.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_library.bzl index 581237a257ab14..5e1e2e185cb49c 100755 --- a/src/main/starlark/builtins_bzl/common/cc/cc_library.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_library.bzl @@ -73,6 +73,7 @@ def _cc_library_impl(ctx): textual_hdrs = ctx.files.textual_hdrs, include_prefix = ctx.attr.include_prefix, strip_include_prefix = ctx.attr.strip_include_prefix, + additional_inputs = ctx.files.additional_compiler_inputs, ) precompiled_objects = cc_common.create_compilation_outputs( @@ -592,6 +593,10 @@ attrs = { "win_def_file": attr.label(allow_single_file = [".def"]), # buildifier: disable=attr-license "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(), + "additional_compiler_inputs": attr.label_list( + allow_files = True, + flags = ["ORDER_INDEPENDENT", "DIRECT_COMPILE_TIME_INPUT"], + ), "_stl": semantics.get_stl(), "_grep_includes": attr.label( allow_files = True, diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java index 546befb6575a87..6247c7ee2042e3 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CcLibraryConfiguredTargetTest.java @@ -54,9 +54,7 @@ import org.junit.runner.RunWith; import org.junit.runners.JUnit4; -/** - * "White-box" unit test of cc_library rule. - */ +/** "White-box" unit test of cc_library rule. */ @RunWith(JUnit4.class) public class CcLibraryConfiguredTargetTest extends BuildViewTestCase { private static final PathFragment STL_CPPMAP = PathFragment.create("stl_cc_library.cppmap"); @@ -108,9 +106,10 @@ private CppCompileAction getCppCompileAction(String label) throws Exception { private CppCompileAction getCppCompileAction(ConfiguredTarget target) throws Exception { List compilationSteps = - actionsTestUtil().findTransitivePrerequisitesOf( - ActionsTestUtil.getFirstArtifactEndingWith(getFilesToBuild(target), ".a"), - CppCompileAction.class); + actionsTestUtil() + .findTransitivePrerequisitesOf( + ActionsTestUtil.getFirstArtifactEndingWith(getFilesToBuild(target), ".a"), + CppCompileAction.class); return compilationSteps.get(0); } @@ -150,9 +149,12 @@ public void checkWrongExtensionInArtifactNamePattern( @Test public void testDefinesAndMakeVariables() throws Exception { - ConfiguredTarget l = scratchConfiguredTarget("a", "l", - "cc_library(name='l', srcs=['l.cc'], defines=['V=$(FOO)'], toolchains=[':v'])", - "make_variable_tester(name='v', variables={'FOO': 'BAR'})"); + ConfiguredTarget l = + scratchConfiguredTarget( + "a", + "l", + "cc_library(name='l', srcs=['l.cc'], defines=['V=$(FOO)'], toolchains=[':v'])", + "make_variable_tester(name='v', variables={'FOO': 'BAR'})"); assertThat(l.get(CcInfo.PROVIDER).getCcCompilationContext().getDefines()).contains("V=BAR"); } @@ -504,15 +506,13 @@ public void testWindowsFileNamePatternsCanBeSpecifiedInToolchain() throws Except @Test public void testWrongObjectFileArtifactNamePattern() throws Exception { checkWrongExtensionInArtifactNamePattern( - "object_file", - ArtifactCategory.OBJECT_FILE.getAllowedExtensions()); + "object_file", ArtifactCategory.OBJECT_FILE.getAllowedExtensions()); } @Test public void testWrongStaticLibraryArtifactNamePattern() throws Exception { checkWrongExtensionInArtifactNamePattern( - "static_library", - ArtifactCategory.STATIC_LIBRARY.getAllowedExtensions()); + "static_library", ArtifactCategory.STATIC_LIBRARY.getAllowedExtensions()); } @Test @@ -525,22 +525,19 @@ public void testWrongAlwayslinkStaticLibraryArtifactNamePattern() throws Excepti @Test public void testWrongExecutableArtifactNamePattern() throws Exception { checkWrongExtensionInArtifactNamePattern( - "executable", - ArtifactCategory.EXECUTABLE.getAllowedExtensions()); + "executable", ArtifactCategory.EXECUTABLE.getAllowedExtensions()); } @Test public void testWrongDynamicLibraryArtifactNamePattern() throws Exception { checkWrongExtensionInArtifactNamePattern( - "dynamic_library", - ArtifactCategory.DYNAMIC_LIBRARY.getAllowedExtensions()); + "dynamic_library", ArtifactCategory.DYNAMIC_LIBRARY.getAllowedExtensions()); } @Test public void testWrongInterfaceLibraryArtifactNamePattern() throws Exception { checkWrongExtensionInArtifactNamePattern( - "interface_library", - ArtifactCategory.INTERFACE_LIBRARY.getAllowedExtensions()); + "interface_library", ArtifactCategory.INTERFACE_LIBRARY.getAllowedExtensions()); } @Test @@ -591,11 +588,13 @@ public void testTransitiveArtifactsToAlwaysBuildStatic() throws Exception { mockToolsConfig, CcToolchainConfig.builder().withFeatures(CppRuleClasses.SUPPORTS_PIC)); useConfiguration("--cpu=k8"); - ConfiguredTarget x = scratchConfiguredTarget( - "foo", "x", - "cc_library(name = 'x', srcs = ['x.cc'], deps = [':y'], linkstatic = 1)", - "cc_library(name = 'y', srcs = ['y.cc'], deps = [':z'])", - "cc_library(name = 'z', srcs = ['z.cc'])"); + ConfiguredTarget x = + scratchConfiguredTarget( + "foo", + "x", + "cc_library(name = 'x', srcs = ['x.cc'], deps = [':y'], linkstatic = 1)", + "cc_library(name = 'y', srcs = ['y.cc'], deps = [':z'])", + "cc_library(name = 'z', srcs = ['z.cc'])"); assertThat(artifactsToStrings(getOutputGroup(x, OutputGroupInfo.HIDDEN_TOP_LEVEL))) .containsExactly( "bin foo/_objs/x/x.pic.o", "bin foo/_objs/y/y.pic.o", "bin foo/_objs/z/z.pic.o"); @@ -653,13 +652,15 @@ public void testDisablingHeaderModulesWhenDependingOnModuleBuildTransitively() t mockToolsConfig, CcToolchainConfig.builder().withFeatures(MockCcSupport.HEADER_MODULES_FEATURES)); useConfiguration(); - scratch.file("module/BUILD", + scratch.file( + "module/BUILD", "package(features = ['header_modules'])", "cc_library(", " name = 'module',", " srcs = ['a.cc', 'a.h'],", ")"); - scratch.file("nomodule/BUILD", + scratch.file( + "nomodule/BUILD", "package(features = ['-header_modules'])", "cc_library(", " name = 'nomodule',", @@ -690,9 +691,7 @@ private static Iterable getHeaderModules(NestedSet input) { input.toList(), (artifact) -> CppFileTypes.CPP_MODULE.matches(artifact.getExecPath())); } - /** - * Returns the flags in {@code input} that reference a header module. - */ + /** Returns the flags in {@code input} that reference a header module. */ private Iterable getHeaderModuleFlags(Iterable input) { List names = new ArrayList<>(); for (String flag : input) { @@ -726,16 +725,16 @@ public void testCompileHeaderModules() throws Exception { ConfiguredTarget moduleB = getConfiguredTarget("//module:b"); Artifact bModuleArtifact = getBinArtifact("_objs/b/b.pic.pcm", moduleB); CppCompileAction bModuleAction = (CppCompileAction) getGeneratingAction(bModuleArtifact); - assertThat(bModuleAction.getIncludeScannerSources()).containsExactly( - getSourceArtifact("module/b.h"), getSourceArtifact("module/t.h")); + assertThat(bModuleAction.getIncludeScannerSources()) + .containsExactly(getSourceArtifact("module/b.h"), getSourceArtifact("module/t.h")); assertThat(bModuleAction.getInputs().toList()) .contains(getGenfilesArtifact("b.cppmap", moduleB)); ConfiguredTarget moduleA = getConfiguredTarget("//module:a"); Artifact aObjectArtifact = getBinArtifact("_objs/a/a.pic.o", moduleA); CppCompileAction aObjectAction = (CppCompileAction) getGeneratingAction(aObjectArtifact); - assertThat(aObjectAction.getIncludeScannerSources()).containsExactly( - getSourceArtifact("module/a.cc")); + assertThat(aObjectAction.getIncludeScannerSources()) + .containsExactly(getSourceArtifact("module/a.cc")); assertThat(aObjectAction.getCcCompilationContext().getTransitiveModules(true).toList()) .contains(getBinArtifact("_objs/b/b.pic.pcm", moduleB)); assertThat(aObjectAction.getInputs().toList()) @@ -788,7 +787,8 @@ public void testContainingSourcesWithSameBaseName() throws Exception { } private void setupPackagesForModuleTests(boolean useHeaderModules) throws Exception { - scratch.file("module/BUILD", + scratch.file( + "module/BUILD", "package(features = ['header_modules'])", "cc_library(", " name = 'b',", @@ -805,9 +805,11 @@ private void setupPackagesForModuleTests(boolean useHeaderModules) throws Except " srcs = ['j.h', 'j.cc'],", " deps = ['//nomodule:c', '//nomodule:i'],", ")"); - scratch.file("nomodule/BUILD", + scratch.file( + "nomodule/BUILD", "package(features = ['-header_modules'" - + (useHeaderModules ? ", 'use_header_modules'" : "") + "])", + + (useHeaderModules ? ", 'use_header_modules'" : "") + + "])", "cc_library(", " name = 'y',", " srcs = ['y.h'],", @@ -852,7 +854,7 @@ private void setupPackagesForModuleTests(boolean useHeaderModules) throws Except " srcs = ['i.h', 'i.cc'],", " deps = [':h'],", ")"); - } + } @Test public void testCompileHeaderModulesTransitively() throws Exception { @@ -876,8 +878,8 @@ public void testCompileHeaderModulesTransitively() throws Exception { .containsExactly( getGenfilesArtifact("f.cppmap", nomoduleF), getGenfilesArtifact("e.cppmap", nomoduleE)); assertThat(getHeaderModules(fObjectAction.getInputs())).isEmpty(); - assertThat(fObjectAction.getIncludeScannerSources()).containsExactly( - getSourceArtifact("nomodule/f.cc")); + assertThat(fObjectAction.getIncludeScannerSources()) + .containsExactly(getSourceArtifact("nomodule/f.cc")); assertThat(getHeaderModuleFlags(fObjectAction.getCompilerOptions())).isEmpty(); // The //nomodule:c target will get the header module for //module:b, which is a direct @@ -893,10 +895,10 @@ public void testCompileHeaderModulesTransitively() throws Exception { assertThat(getHeaderModules(cObjectAction.getInputs())).isEmpty(); // All headers of transitive dependencies that are built as modules are needed as entry points // for include scanning. - assertThat(cObjectAction.getIncludeScannerSources()).containsExactly( - getSourceArtifact("nomodule/c.cc")); - assertThat(cObjectAction.getMainIncludeScannerSource()).isEqualTo( - getSourceArtifact("nomodule/c.cc")); + assertThat(cObjectAction.getIncludeScannerSources()) + .containsExactly(getSourceArtifact("nomodule/c.cc")); + assertThat(cObjectAction.getMainIncludeScannerSource()) + .isEqualTo(getSourceArtifact("nomodule/c.cc")); assertThat(getHeaderModuleFlags(cObjectAction.getCompilerOptions())).isEmpty(); // The //nomodule:d target depends on //module:b via one indirection (//nomodule:c). @@ -909,12 +911,13 @@ public void testCompileHeaderModulesTransitively() throws Exception { getBinArtifact("_objs/d/d.pic.o", getConfiguredTarget("//nomodule:d")); CppCompileAction dObjectAction = (CppCompileAction) getGeneratingAction(dObjectArtifact); // Module map 'c.cppmap' is needed because it is a direct dependency. - assertThat(getNonSystemModuleMaps(dObjectAction.getInputs())).containsExactly( - getGenfilesArtifact("c.cppmap", "//nomodule:c"), - getGenfilesArtifact("d.cppmap", "//nomodule:d")); + assertThat(getNonSystemModuleMaps(dObjectAction.getInputs())) + .containsExactly( + getGenfilesArtifact("c.cppmap", "//nomodule:c"), + getGenfilesArtifact("d.cppmap", "//nomodule:d")); assertThat(getHeaderModules(dObjectAction.getInputs())).isEmpty(); - assertThat(dObjectAction.getIncludeScannerSources()).containsExactly( - getSourceArtifact("nomodule/d.cc")); + assertThat(dObjectAction.getIncludeScannerSources()) + .containsExactly(getSourceArtifact("nomodule/d.cc")); assertThat(getHeaderModuleFlags(dObjectAction.getCompilerOptions())).isEmpty(); // The //module:j target depends on //module:g via //nomodule:h and on //module:b via @@ -926,10 +929,10 @@ public void testCompileHeaderModulesTransitively() throws Exception { .containsExactly( getBinArtifact("_objs/b/b.pic.pcm", getConfiguredTarget("//module:b")), getBinArtifact("_objs/g/g.pic.pcm", getConfiguredTarget("//module:g"))); - assertThat(jObjectAction.getIncludeScannerSources()).containsExactly( - getSourceArtifact("module/j.cc")); - assertThat(jObjectAction.getMainIncludeScannerSource()).isEqualTo( - getSourceArtifact("module/j.cc")); + assertThat(jObjectAction.getIncludeScannerSources()) + .containsExactly(getSourceArtifact("module/j.cc")); + assertThat(jObjectAction.getMainIncludeScannerSource()) + .isEqualTo(getSourceArtifact("module/j.cc")); assertThat(getHeaderModules(jObjectAction.getCcCompilationContext().getTransitiveModules(true))) .containsExactly( getBinArtifact("_objs/b/b.pic.pcm", getConfiguredTarget("//module:b")), @@ -982,11 +985,8 @@ public void testCompileUsingHeaderModulesTransitively() throws Exception { } private void writeSimpleCcLibrary() throws Exception { - scratch.file("module/BUILD", - "cc_library(", - " name = 'map',", - " srcs = ['a.cc', 'a.h'],", - ")"); + scratch.file( + "module/BUILD", "cc_library(", " name = 'map',", " srcs = ['a.cc', 'a.h'],", ")"); } @Test @@ -1005,7 +1005,9 @@ public void testToolchainWithoutPicForNoPicCompilation() throws Exception { CppActionNames.CPP_LINK_STATIC_LIBRARY, CppActionNames.STRIP)); useConfiguration("--features=-supports_pic"); - scratchConfiguredTarget("a", "a", + scratchConfiguredTarget( + "a", + "a", "cc_binary(name='a', srcs=['a.cc'], deps=[':b'])", "cc_library(name='b', srcs=['b.cc'])"); } @@ -1040,8 +1042,7 @@ public void testCppModuleMap() throws Exception { CppModuleMapAction action = getCppModuleMapAction("//module:map"); assertThat(ActionsTestUtil.baseArtifactNames(action.getDependencyArtifacts())) .contains("crosstool.cppmap"); - assertThat(artifactsToStrings(action.getPrivateHeaders())) - .containsExactly("src module/a.h"); + assertThat(artifactsToStrings(action.getPrivateHeaders())).containsExactly("src module/a.h"); assertThat(action.getPublicHeaders()).isEmpty(); } @@ -1051,9 +1052,12 @@ public void testCppModuleMap() throws Exception { */ @Test public void testFilesToBuildWithPrecompiledStaticLibrary() throws Exception { - ConfiguredTarget hello = scratchConfiguredTarget("precompiled", "library", - "cc_library(name = 'library', ", - " srcs = ['missing.a'])"); + ConfiguredTarget hello = + scratchConfiguredTarget( + "precompiled", + "library", + "cc_library(name = 'library', ", + " srcs = ['missing.a'])"); assertThat(artifactsToStrings(getFilesToBuild(hello))) .doesNotContain("src precompiled/missing.a"); } @@ -1224,7 +1228,8 @@ private CppCompileAction getGeneratingCompileAction( @Test public void testIncludePathOrder() throws Exception { useConfiguration("--incompatible_merge_genfiles_directory=false"); - scratch.file("foo/BUILD", + scratch.file( + "foo/BUILD", "cc_library(", " name = 'bar',", " includes = ['bar'],", @@ -1260,7 +1265,8 @@ public void testIncludePathOrder() throws Exception { @Test public void testDefinesOrder() throws Exception { - scratch.file("foo/BUILD", + scratch.file( + "foo/BUILD", "cc_library(", " name = 'bar',", " defines = ['BAR'],", @@ -1303,7 +1309,9 @@ public void testLocalDefinesNotPassedTransitively() throws Exception { // Regression test - setting "-shared" caused an exception when computing the link command. @Test public void testLinkOptsNotPassedToStaticLink() throws Exception { - scratchConfiguredTarget("foo", "foo", + scratchConfiguredTarget( + "foo", + "foo", "cc_library(", " name = 'foo',", " srcs = ['foo.cc'],", @@ -1352,10 +1360,7 @@ public void testCompilationModeFeatures() throws Exception { @Test public void testIncludePathsOutsideExecutionRoot() throws Exception { - scratchRule( - "root", - "a", - "cc_library(name='a', srcs=['a.cc'], copts=['-Id/../../somewhere'])"); + scratchRule("root", "a", "cc_library(name='a', srcs=['a.cc'], copts=['-Id/../../somewhere'])"); CppCompileAction compileAction = getCppCompileAction("//root:a"); try { compileAction.verifyActionIncludePaths(compileAction.getSystemIncludeDirs(), false); @@ -1369,10 +1374,7 @@ public void testIncludePathsOutsideExecutionRoot() throws Exception { @Test public void testAbsoluteIncludePathsOutsideExecutionRoot() throws Exception { - scratchRule( - "root", - "a", - "cc_library(name='a', srcs=['a.cc'], copts=['-I/somewhere'])"); + scratchRule("root", "a", "cc_library(name='a', srcs=['a.cc'], copts=['-I/somewhere'])"); CppCompileAction compileAction = getCppCompileAction("//root:a"); try { compileAction.verifyActionIncludePaths(compileAction.getSystemIncludeDirs(), false); @@ -1386,10 +1388,7 @@ public void testAbsoluteIncludePathsOutsideExecutionRoot() throws Exception { @Test public void testSystemIncludePathsOutsideExecutionRoot() throws Exception { - scratchRule( - "root", - "a", - "cc_library(name='a', srcs=['a.cc'], copts=['-isystem../system'])"); + scratchRule("root", "a", "cc_library(name='a', srcs=['a.cc'], copts=['-isystem../system'])"); CppCompileAction compileAction = getCppCompileAction("//root:a"); try { compileAction.verifyActionIncludePaths(compileAction.getSystemIncludeDirs(), false); @@ -1403,10 +1402,7 @@ public void testSystemIncludePathsOutsideExecutionRoot() throws Exception { @Test public void testAbsoluteSystemIncludePathsOutsideExecutionRoot() throws Exception { - scratchRule( - "root", - "a", - "cc_library(name='a', srcs=['a.cc'], copts=['-isystem/system'])"); + scratchRule("root", "a", "cc_library(name='a', srcs=['a.cc'], copts=['-isystem/system'])"); CppCompileAction compileAction = getCppCompileAction("//root:a"); try { compileAction.verifyActionIncludePaths(compileAction.getSystemIncludeDirs(), false); @@ -1557,7 +1553,6 @@ public void forbidBuildingAndWrappingSameLibraryIdentifier() throws Exception { "cc_library(name = 'foo', srcs = ['foo.cc', 'libfoo.lo'])"); } - @Test public void testProcessedHeadersWithPicSharedLibsAndNoPicBinaries() throws Exception { AnalysisMock.get() @@ -2408,4 +2403,24 @@ public void testDataDepRunfilesArePropagated() throws Exception { lib.get(DefaultInfo.PROVIDER).getDefaultRunfiles().getAllArtifacts())) .containsExactly("src foo/file.txt"); } + + @Test + public void testAdditionalCompilerInputsArePassedToCompile() throws Exception { + AnalysisMock.get().ccSupport().setupCcToolchainConfig(mockToolsConfig); + scratch.file( + "foo/BUILD", + "cc_library(", + " name = 'foo',", + " srcs = ['hello.cc'],", + " copts = ['$(location compiler_input.txt)'],", + " additional_compiler_inputs = ['compiler_input.txt'],", + ")"); + scratch.file("foo/compiler_input.txt", "hello world!"); + + ConfiguredTarget lib = getConfiguredTarget("//foo:foo"); + Artifact artifact = getBinArtifact("_objs/foo/hello.o", lib); + CppCompileAction action = (CppCompileAction) getGeneratingAction(artifact); + assertThat(action.getInputs().toList()).contains(getSourceArtifact("foo/compiler_input.txt")); + assertThat(action.getArguments()).contains("foo/compiler_input.txt"); + } }