diff --git a/BUILD b/BUILD index 87fac64996f0e9..e45f130c511f3e 100644 --- a/BUILD +++ b/BUILD @@ -98,6 +98,7 @@ genrule( "//third_party:rules_jvm_external_6.0.patch", "//third_party/protobuf:BUILD", "//third_party/protobuf:remove_rules_rust.patch", + "//third_party/protobuf:add_python_loads.patch", ], outs = ["MODULE.bazel.lock.dist"], cmd = " && ".join([ diff --git a/MODULE.bazel b/MODULE.bazel index e47059de52b445..8a0a683b0434b1 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -43,7 +43,7 @@ archive_override( # Temporarily patch out rules_rust stuff from protobuf. Not just because we don't need it, # but also because it introduces huge dependency bloat: rules_rust -> aspect_rules_js -> # aspect_rules_lint -> rules_buf. - patches = ["//third_party/protobuf:remove_rules_rust.patch"], + patches = ["//third_party/protobuf:remove_rules_rust.patch", "//third_party/protobuf:add_python_loads.patch"], strip_prefix = "protobuf-3b62052186d39775090fb074adcba078ea622f54", urls = ["https://github.com/protocolbuffers/protobuf/archive/3b62052186d39775090fb074adcba078ea622f54.zip"], ) diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 04f24cf4bb8ced..08eea9335390b3 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -138,6 +138,7 @@ "https://bcr.bazel.build/modules/rules_java/6.0.0/MODULE.bazel": "8a43b7df601a7ec1af61d79345c17b31ea1fedc6711fd4abfd013ea612978e39", "https://bcr.bazel.build/modules/rules_java/6.4.0/MODULE.bazel": "e986a9fe25aeaa84ac17ca093ef13a4637f6107375f64667a15999f77db6c8f6", "https://bcr.bazel.build/modules/rules_java/6.5.2/MODULE.bazel": "1d440d262d0e08453fa0c4d8f699ba81609ed0e9a9a0f02cd10b3e7942e61e31", + "https://bcr.bazel.build/modules/rules_java/7.11.1/MODULE.bazel": "b4782e019dd0b0151bd49fd8929136fd4441f527eb208fbd991b77e480b7236e", "https://bcr.bazel.build/modules/rules_java/7.12.1/MODULE.bazel": "0a2ebb53b48a6eb092aef24b36db23294d4d3ebf96bff02b0ccc962bdc70717d", "https://bcr.bazel.build/modules/rules_java/7.12.1/source.json": "2ab5ceabe9d87a773fa44e4cce42c950e34ff6d2f5164e7413088542fa4f1f3e", "https://bcr.bazel.build/modules/rules_java/7.2.0/MODULE.bazel": "06c0334c9be61e6cef2c8c84a7800cef502063269a5af25ceb100b192453d4ab", diff --git a/src/BUILD b/src/BUILD index b0697bcede5b99..def2c943659893 100644 --- a/src/BUILD +++ b/src/BUILD @@ -144,7 +144,7 @@ rule_size_test( # WARNING: Only adjust the number in `expect` if you are intentionally # adding or removing embedded tools. Know that the more embedded tools there # are in Bazel, the bigger the binary becomes and the slower Bazel starts. - expect = 421, + expect = 445, margin = 5, # percentage ) @@ -604,7 +604,6 @@ filegroup( "@rules_java//:WORKSPACE", "@rules_license//:WORKSPACE", "@rules_pkg//:WORKSPACE", - "@rules_proto//proto:defs", "@rules_python//:WORKSPACE", "@rules_testing//:LICENSE", ] + select({ diff --git a/src/MODULE.tools b/src/MODULE.tools index dc99e9f752bee9..fa6c7d1957d974 100644 --- a/src/MODULE.tools +++ b/src/MODULE.tools @@ -5,7 +5,6 @@ module(name = "bazel_tools") bazel_dep(name = "rules_license", version = "0.0.7") -bazel_dep(name = "rules_proto", version = "6.0.2") bazel_dep(name = "buildozer", version = "7.1.2") bazel_dep(name = "platforms", version = "0.0.10") diff --git a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java index 28d1e0ca804097..e882b9183a1d41 100644 --- a/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java +++ b/src/main/java/com/google/devtools/build/docgen/BuildEncyclopediaProcessor.java @@ -137,7 +137,9 @@ private List filterRuleFamilies( List ruleFamilies = new ArrayList<>(ruleFamilyNames.size()); for (String name : ruleFamilyNames) { ListMultimap ruleTypeMap = ruleMapping.get(name); - ruleFamilies.add(new RuleFamily(ruleTypeMap, name, familySummary.get(name).toString())); + ruleFamilies.add( + new RuleFamily( + ruleTypeMap, name, familySummary.getOrDefault(name, new StringBuilder()).toString())); } return ruleFamilies; } diff --git a/src/main/java/com/google/devtools/build/lib/actions/BUILD b/src/main/java/com/google/devtools/build/lib/actions/BUILD index 36496c1a6490ad..2b5cce94374c53 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/BUILD +++ b/src/main/java/com/google/devtools/build/lib/actions/BUILD @@ -557,6 +557,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/worker:worker_key", "//src/main/java/com/google/devtools/build/lib/worker:worker_pool", "//src/main/java/com/google/devtools/build/lib/worker:worker_process_status", + "//src/main/protobuf:failure_details_java_proto", "//third_party:auto_value", "//third_party:error_prone_annotations", "//third_party:flogger", diff --git a/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java b/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java index f9b7b0f507495f..92dcc06df0a153 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java +++ b/src/main/java/com/google/devtools/build/lib/actions/FilesetOutputSymlink.java @@ -152,7 +152,6 @@ public static FilesetOutputSymlink createAlreadyRelativized( HasDigest metadata, boolean isRelativeToExecRoot, @Nullable PathFragment enclosingTreeArtifactExecPath) { - checkArgument(!name.isEmpty(), "Empty symlink name pointing to %s", target); checkArgument(!target.isEmpty(), "Empty symlink target for %s", name); return new AutoValue_FilesetOutputSymlink( name, target, metadata, isRelativeToExecRoot, enclosingTreeArtifactExecPath); diff --git a/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java b/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java index 43e8a0542e6124..61e6fd527b3d39 100644 --- a/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java +++ b/src/main/java/com/google/devtools/build/lib/actions/ResourceManager.java @@ -26,6 +26,7 @@ import com.google.devtools.build.lib.profiler.AutoProfiler; import com.google.devtools.build.lib.profiler.Profiler; import com.google.devtools.build.lib.profiler.ProfilerTask; +import com.google.devtools.build.lib.server.FailureDetails; import com.google.devtools.build.lib.worker.Worker; import com.google.devtools.build.lib.worker.WorkerKey; import com.google.devtools.build.lib.worker.WorkerPool; @@ -38,7 +39,6 @@ import java.util.Iterator; import java.util.LinkedList; import java.util.Map; -import java.util.NoSuchElementException; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executors; @@ -368,7 +368,7 @@ record ResourceRequest( */ public ResourceHandle acquireResources( ActionExecutionMetadata owner, ResourceSet resources, ResourcePriority priority) - throws InterruptedException, IOException { + throws InterruptedException, IOException, ExecException { Preconditions.checkNotNull( resources, "acquireResources called with resources == NULL during %s", owner); Preconditions.checkState( @@ -376,6 +376,8 @@ public ResourceHandle acquireResources( ResourceLatch resourceLatch = null; + // Validate requested resources exist before creating a request. + assertResourcesTracked(resources); ResourceRequest request = new ResourceRequest(owner, resources, priority, requestIdGenerator.getAndIncrement()); @@ -590,12 +592,24 @@ private synchronized void processWaitingRequests(Deque requests) } /** Throws an exception if requested extra resource isn't being tracked */ - private void assertResourcesTracked(ResourceSet resources) throws NoSuchElementException { + private void assertResourcesTracked(ResourceSet resources) throws ExecException { for (Map.Entry resource : resources.getResources().entrySet()) { String key = resource.getKey(); if (!availableResources.getResources().containsKey(key)) { - throw new NoSuchElementException( - "Resource " + key + " is not tracked in this resource set."); + StringBuilder message = new StringBuilder(); + message.append("Resource "); + message.append(key); + message.append(" is not being tracked by the resource manager."); + message.append(" Available resources are: "); + message.append(String.join(", ", availableResources.getResources().keySet())); + throw new UserExecException( + FailureDetails.FailureDetail.newBuilder() + .setMessage(message.toString()) + .setLocalExecution( + FailureDetails.LocalExecution.newBuilder() + .setCode(FailureDetails.LocalExecution.Code.UNTRACKED_RESOURCE) + .build()) + .build()); } } } @@ -625,10 +639,6 @@ synchronized boolean areResourcesAvailable(ResourceSet resources) { return false; } - // We test for tracking of extra resources whenever acquired and throw an - // exception before acquiring any untracked resource. - assertResourcesTracked(resources); - if (usedResources.isEmpty() && usedLocalTestCount == 0) { return true; } diff --git a/src/main/java/com/google/devtools/build/lib/analysis/constraints/EnvironmentRule.java b/src/main/java/com/google/devtools/build/lib/analysis/constraints/EnvironmentRule.java index 2d51c4f9729caf..1aef0c16a8c938 100644 --- a/src/main/java/com/google/devtools/build/lib/analysis/constraints/EnvironmentRule.java +++ b/src/main/java/com/google/devtools/build/lib/analysis/constraints/EnvironmentRule.java @@ -23,6 +23,7 @@ import com.google.devtools.build.lib.analysis.config.transitions.NoConfigTransition; import com.google.devtools.build.lib.packages.BuildType; import com.google.devtools.build.lib.packages.RuleClass; +import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; import com.google.devtools.build.lib.packages.RuleClass.ToolchainResolutionMode; import com.google.devtools.build.lib.packages.Types; import com.google.devtools.build.lib.util.FileTypeSet; @@ -72,6 +73,9 @@ public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) public Metadata getMetadata() { return RuleDefinition.Metadata.builder() .name(ConstraintConstants.ENVIRONMENT_RULE) + // Not allowed in symbolic macros: lazy expansion of symbolic macros could hide environment + // targets from environment groups. + .type(RuleClassType.BUILD_ONLY) .ancestors(BaseRuleClasses.NativeBuildRule.class) .factoryClass(Environment.class) .build(); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/BUILD index 44329d05ef88b7..f8356c97339e58 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/BUILD @@ -140,6 +140,7 @@ java_library( "//src/main/java/com/google/devtools/build/lib/util:abrupt_exit_exception", "//src/main/java/com/google/devtools/build/lib/util:detailed_exit_code", "//src/main/java/com/google/devtools/build/lib/vfs", + "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", "//src/main/protobuf:failure_details_java_proto", "//third_party:guava", "//third_party:jsr305", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java b/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java index d19819c9327cb0..3f8faf797b0f06 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/SpawnLogModule.java @@ -38,6 +38,7 @@ import com.google.devtools.build.lib.util.AbruptExitException; import com.google.devtools.build.lib.util.DetailedExitCode; import com.google.devtools.build.lib.vfs.Path; +import com.google.devtools.build.lib.vfs.PathFragment; import java.io.IOException; import javax.annotation.Nullable; @@ -94,11 +95,10 @@ private void initOutputs(CommandEnvironment env) throws IOException { return; } - Path workingDirectory = env.getWorkingDirectory(); Path outputBase = env.getOutputBase(); if (executionOptions.executionLogCompactFile != null) { - outputPath = workingDirectory.getRelative(executionOptions.executionLogCompactFile); + outputPath = getAbsolutePath(executionOptions.executionLogCompactFile, env); try { spawnLogContext = @@ -121,10 +121,10 @@ private void initOutputs(CommandEnvironment env) throws IOException { if (executionOptions.executionLogBinaryFile != null) { encoding = Encoding.BINARY; - outputPath = workingDirectory.getRelative(executionOptions.executionLogBinaryFile); + outputPath = getAbsolutePath(executionOptions.executionLogBinaryFile, env); } else if (executionOptions.executionLogJsonFile != null) { encoding = Encoding.JSON; - outputPath = workingDirectory.getRelative(executionOptions.executionLogJsonFile); + outputPath = getAbsolutePath(executionOptions.executionLogJsonFile, env); } // Use a well-known temporary path to avoid accumulation of potentially large files in /tmp @@ -144,6 +144,25 @@ private void initOutputs(CommandEnvironment env) throws IOException { } } + /** + * If the given path is absolute path, leave it as it is. If the given path is a relative path, it + * is relative to the current working directory. If the given path starts with '%workspace%, it is + * relative to the workspace root, which is the output of `bazel info workspace`. + * + * @return Absolute Path + */ + private Path getAbsolutePath(PathFragment path, CommandEnvironment env) { + String pathString = path.getPathString(); + if (env.getWorkspace() != null) { + pathString = pathString.replace("%workspace%", env.getWorkspace().getPathString()); + } + if (!PathFragment.isAbsolute(pathString)) { + return env.getWorkingDirectory().getRelative(pathString); + } + + return env.getRuntime().getFileSystem().getPath(pathString); + } + @Override public void registerActionContexts( ModuleActionContextRegistry.Builder registryBuilder, diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BUILD b/src/main/java/com/google/devtools/build/lib/bazel/rules/BUILD index 2de3e1b7b2c743..d4aab29185c010 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BUILD +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BUILD @@ -149,7 +149,6 @@ gen_workspace_stanza( "rules_cc", # For auto-load cc rules symbols "rules_python", # For auto-load python rules symbols "rules_license", # for license attestations - "rules_proto", ], use_maybe = 1, visibility = ["//:__pkg__"], diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java index 6bad3d50233927..0032bb506a6eb3 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java @@ -22,7 +22,6 @@ import com.google.common.collect.ImmutableSet; import com.google.devtools.build.lib.actions.ActionEnvironment; import com.google.devtools.build.lib.analysis.BaseRuleClasses; -import com.google.devtools.build.lib.analysis.BaseRuleClasses.EmptyRule; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider; import com.google.devtools.build.lib.analysis.ConfiguredRuleClassProvider.RuleSet; import com.google.devtools.build.lib.analysis.PackageSpecificationProvider; @@ -36,10 +35,7 @@ import com.google.devtools.build.lib.analysis.config.RequiresOptions; import com.google.devtools.build.lib.bazel.BazelConfiguration; import com.google.devtools.build.lib.bazel.repository.LocalConfigPlatformRule; -import com.google.devtools.build.lib.bazel.rules.python.BazelPyBinaryRule; import com.google.devtools.build.lib.bazel.rules.python.BazelPyBuiltins; -import com.google.devtools.build.lib.bazel.rules.python.BazelPyRuleClasses; -import com.google.devtools.build.lib.bazel.rules.python.BazelPyTestRule; import com.google.devtools.build.lib.bazel.rules.python.BazelPythonConfiguration; import com.google.devtools.build.lib.cmdline.RepositoryName; import com.google.devtools.build.lib.packages.PackageCallable; @@ -53,7 +49,6 @@ import com.google.devtools.build.lib.rules.platform.PlatformRules; import com.google.devtools.build.lib.rules.proto.BazelProtoCommon; import com.google.devtools.build.lib.rules.proto.ProtoConfiguration; -import com.google.devtools.build.lib.rules.python.PyRuntimeRule; import com.google.devtools.build.lib.rules.python.PythonConfiguration; import com.google.devtools.build.lib.rules.repository.CoreWorkspaceRules; import com.google.devtools.build.lib.rules.repository.NewLocalRepositoryRule; @@ -316,13 +311,6 @@ public void init(ConfiguredRuleClassProvider.Builder builder) { builder.addConfigurationFragment(PythonConfiguration.class); builder.addConfigurationFragment(BazelPythonConfiguration.class); - builder.addRuleDefinition(new BazelPyRuleClasses.PyBaseRule()); - builder.addRuleDefinition(new BazelPyRuleClasses.PyBinaryBaseRule()); - builder.addRuleDefinition(new EmptyRule("py_library") {}); - builder.addRuleDefinition(new BazelPyBinaryRule()); - builder.addRuleDefinition(new BazelPyTestRule()); - builder.addRuleDefinition(new PyRuntimeRule()); - // This symbol is overridden by exports.bzl builder.addBzlToplevel( "py_internal", @@ -333,7 +321,8 @@ public void init(ConfiguredRuleClassProvider.Builder builder) { try { builder.addWorkspaceFileSuffix( - ResourceFileLoader.loadResource(BazelPyBinaryRule.class, "python.WORKSPACE")); + ResourceFileLoader.loadResource( + BazelPythonConfiguration.class, "python.WORKSPACE")); } catch (IOException e) { throw new IllegalStateException(e); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java index ad9a8e750ebc3d..b670daabd1a50e 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRulesModule.java @@ -380,6 +380,15 @@ public static final class BazelBuildGraveyardOptions extends BuildGraveyardOptio + " https://blog.bazel.build/2023/11/15/android-platforms.html for details and" + " migration directions"; + @Option( + name = "android_sdk", + defaultValue = "", + documentationCategory = OptionDocumentationCategory.UNDOCUMENTED, + effectTags = {OptionEffectTag.UNKNOWN}, + help = "No-op", + deprecationWarning = ANDROID_FLAG_DEPRECATION) + public String sdk; + @Option( name = "android_cpu", defaultValue = "", diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/ObjcRules.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/ObjcRules.java index e56f9c3f54a351..d693949e2ea80f 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/ObjcRules.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/ObjcRules.java @@ -38,7 +38,6 @@ public void init(ConfiguredRuleClassProvider.Builder builder) { builder.addConfigurationFragment(AppleConfiguration.class); // j2objc shouldn't be here! builder.addConfigurationFragment(J2ObjcConfiguration.class); - builder.addRuleDefinition(new EmptyRule("j2objc_library") {}); builder.addRuleDefinition(new EmptyRule("objc_import") {}); builder.addRuleDefinition(new EmptyRule("objc_library") {}); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyBinaryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyBinaryRule.java deleted file mode 100644 index 2ff8fae0b70236..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyBinaryRule.java +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.bazel.rules.python; - - -import com.google.devtools.build.lib.analysis.BaseRuleClasses; -import com.google.devtools.build.lib.analysis.RuleDefinition; -import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; -import com.google.devtools.build.lib.bazel.rules.python.BazelPyRuleClasses.PyBinaryBaseRule; -import com.google.devtools.build.lib.packages.RuleClass; - -/** - * Rule definition for the {@code py_binary} rule. - */ -public final class BazelPyBinaryRule implements RuleDefinition { - @Override - public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { - /* -
If main is unspecified, this should be the same as the name - of the source file that is the main entry point of the application, - minus the extension. For example, if your entry point is called - main.py, then your name should be main. - */ - return builder - .build(); - } - - @Override - public Metadata getMetadata() { - return RuleDefinition.Metadata.builder() - .name("py_binary") - .ancestors(PyBinaryBaseRule.class, BaseRuleClasses.BinaryBaseRule.class) - .factoryClass(BaseRuleClasses.EmptyRuleConfiguredTargetFactory.class) - .build(); - } -} - -/* - -

- A py_binary is an executable Python program consisting - of a collection of .py source files (possibly belonging - to other py_library rules), a *.runfiles - directory tree containing all the code and data needed by the - program at run-time, and a stub script that starts up the program with - the correct initial environment and data. -

- -

Examples

- -
-py_binary(
-    name = "foo",
-    srcs = ["foo.py"],
-    data = [":transform"],  # a cc_binary which we invoke at run time
-    deps = [
-        ":foolib",  # a py_library
-    ],
-)
-
- -

If you want to run a py_binary from within another binary or - test (for example, running a python binary to set up some mock resource from - within a java_test) then the correct approach is to make the other binary or - test depend on the py_binary in its data section. The other - binary can then locate the py_binary relative to the source - directory. -

- -
-py_binary(
-    name = "test_main",
-    srcs = ["test_main.py"],
-    deps = [":testing"],
-)
-
-java_library(
-    name = "testing",
-    srcs = glob(["*.java"]),
-    data = [":test_main"]
-)
-
-*/ diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyLibraryRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyLibraryRule.java deleted file mode 100644 index 832f6df39e021a..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyLibraryRule.java +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.bazel.rules.python; - -import static com.google.devtools.build.lib.packages.Attribute.attr; -import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; - -import com.google.devtools.build.lib.analysis.BaseRuleClasses; -import com.google.devtools.build.lib.analysis.RuleDefinition; -import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; -import com.google.devtools.build.lib.bazel.rules.python.BazelPyRuleClasses.PyBaseRule; -import com.google.devtools.build.lib.packages.RuleClass; -import com.google.devtools.build.lib.rules.python.PyRuleClasses; -import com.google.devtools.build.lib.rules.python.PythonConfiguration; - -/** - * Rule definition for the {@code py_library} rule. - */ -public final class BazelPyLibraryRule implements RuleDefinition { - @Override - public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { - return builder - .requiresConfigurationFragments(PythonConfiguration.class) - - /* - The list of source (.py) files that are processed to create the target. - This includes all your checked-in code and any generated source files. - */ - .add( - attr("srcs", LABEL_LIST) - .direct_compile_time_input() - .allowedFileTypes(PyRuleClasses.PYTHON_SOURCE)) - .build(); - } - - @Override - public Metadata getMetadata() { - return RuleDefinition.Metadata.builder() - .name("py_library") - .ancestors(PyBaseRule.class) - .factoryClass(BaseRuleClasses.EmptyRuleConfiguredTargetFactory.class) - .build(); - } -} - -/* - -*/ diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java deleted file mode 100644 index 4bd2f54bc609fc..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyRuleClasses.java +++ /dev/null @@ -1,229 +0,0 @@ -// Copyright 2014 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.bazel.rules.python; - -import static com.google.devtools.build.lib.packages.Attribute.attr; -import static com.google.devtools.build.lib.packages.BuildType.LABEL; -import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; -import static com.google.devtools.build.lib.packages.BuildType.TRISTATE; -import static com.google.devtools.build.lib.packages.Type.STRING; -import static com.google.devtools.build.lib.packages.Types.STRING_LIST; - -import com.google.common.collect.ImmutableList; -import com.google.devtools.build.lib.analysis.BaseRuleClasses; -import com.google.devtools.build.lib.analysis.RuleDefinition; -import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; -import com.google.devtools.build.lib.analysis.config.ToolchainTypeRequirement; -import com.google.devtools.build.lib.bazel.rules.cpp.BazelCppRuleClasses.CcToolchainRequiringRule; -import com.google.devtools.build.lib.packages.Attribute.AllowedValueSet; -import com.google.devtools.build.lib.packages.Attribute.LabelLateBoundDefault; -import com.google.devtools.build.lib.packages.RuleClass; -import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; -import com.google.devtools.build.lib.packages.TriState; -import com.google.devtools.build.lib.rules.python.PyCommon; -import com.google.devtools.build.lib.rules.python.PyRuleClasses; -import com.google.devtools.build.lib.rules.python.PythonVersion; - -/** - * Bazel-specific rule definitions for Python rules. - */ -public final class BazelPyRuleClasses { - - private BazelPyRuleClasses() {} - - public static final LabelLateBoundDefault PY_INTERPRETER = - LabelLateBoundDefault.fromTargetConfiguration( - BazelPythonConfiguration.class, - null, - (rule, attributes, bazelPythonConfig) -> bazelPythonConfig.getPythonTop()); - - /** - * Base class for Python rule definitions. - */ - public static final class PyBaseRule implements RuleDefinition { - @Override - public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { - return builder - /* - The list of other libraries to be linked in to the binary target. - See general comments about deps at - - Typical attributes defined by most build rules. - These are generally - py_library rules. - */ - .override(builder.copy("deps")) - /* - List of import directories to be added to the PYTHONPATH. -

- Subject to "Make variable" substitution. These import - directories will be added for this rule and all rules that depend on it (note: not the - rules this rule depends on. Each directory will be added to PYTHONPATH by - py_binary rules that depend on this rule. -

-

- Absolute paths (paths that start with /) and paths that references a path - above the execution root are not allowed and will result in an error. -

- */ - .add(attr("imports", STRING_LIST).value(ImmutableList.of())) - /* - This attribute declares the target's srcs to be compatible with either Python - 2, Python 3, or both. To actually set the Python runtime version, use the - python_version attribute of an - executable Python rule (py_binary or py_test). - -

Allowed values are: "PY2AND3", "PY2", and "PY3". - The values "PY2ONLY" and "PY3ONLY" are also allowed for historic - reasons, but they are essentially the same as "PY2" and "PY3" - and should be avoided. - -

Note that only the executable rules (py_binary and py_library - ) actually verify the current Python version against the value of this attribute. - (This is a feature; since py_library does not change the current Python - version, if it did the validation, it'd be impossible to build both PY2ONLY - and PY3ONLY libraries in the same invocation.) Furthermore, if there is a - version mismatch, the error is only reported in the execution phase. In particular, the - error will not appear in a bazel build --nobuild invocation.) - -

To get diagnostic information about which dependencies introduce version requirements, - you can run the find_requirements aspect on your target: -

-          bazel build <your target> \
-              --aspects=@rules_python//python:defs.bzl%find_requirements \
-              --output_groups=pyversioninfo
-          
- This will build a file with the suffix -pyversioninfo.txt giving information - about why your target requires one Python version or another. Note that it works even if - the given target failed to build due to a version conflict. - */ - .add( - attr("srcs_version", STRING) - .value(PythonVersion.DEFAULT_SRCS_VALUE.toString()) - .allowedValues(new AllowedValueSet(PythonVersion.SRCS_STRINGS))) - .build(); - } - - @Override - public Metadata getMetadata() { - return RuleDefinition.Metadata.builder() - .name("$base_py") - .type(RuleClassType.ABSTRACT) - .ancestors(BaseRuleClasses.NativeActionCreatingRule.class) - .build(); - } - } - - /** - * Base class for Python rule definitions that produce binaries. - */ - public static final class PyBinaryBaseRule implements RuleDefinition { - @Override - public RuleClass build(RuleClass.Builder builder, final RuleDefinitionEnvironment env) { - return builder - /* - The name of the source file that is the main entry point of the application. - This file must also be listed in srcs. If left unspecified, - name is used instead (see above). If name does not - match any filename in srcs, main must be specified. - */ - .add(attr("main", LABEL).allowedFileTypes(PyRuleClasses.PYTHON_SOURCE)) - /* - Whether to build this target (and its transitive deps) for Python 2 or Python - 3. Valid values are "PY2" and "PY3" (the default). - -

The Python version is always reset (possibly by default) to whatever version is - specified by this attribute, regardless of the version specified on the command line or by - other higher targets that depend on this one. - -

If you want to select() on the current Python version, you can inspect the - value of @rules_python//python:python_version. See - here - for more information. - -

Bug warning: This attribute sets the version for which Bazel builds your target, - but due to #4815, the - resulting stub script may still invoke the wrong interpreter version at runtime. See - this - workaround, which involves defining a py_runtime target that points to - either Python version as needed, and activating this py_runtime by setting - --python_top. - */ - .add( - attr(PyCommon.PYTHON_VERSION_ATTRIBUTE, STRING) - .value(PythonVersion._INTERNAL_SENTINEL.toString()) - .allowedValues(PyRuleClasses.TARGET_PYTHON_ATTR_VALUE_SET) - .nonconfigurable( - "read by PyRuleClasses.PYTHON_VERSION_TRANSITION, which doesn't have access" - + " to the configuration")) - /* - The list of source (.py) files that are processed to create the target. - This includes all your checked-in code and any generated source files. Library targets - belong in deps instead, while other binary files needed at runtime belong in - data. - */ - .add( - attr("srcs", LABEL_LIST) - .mandatory() - .allowedFileTypes(PyRuleClasses.PYTHON_SOURCE) - .direct_compile_time_input()) - /* - Whether to implicitly create empty __init__.py files in the runfiles tree. - These are created in every directory containing Python source code or - shared libraries, and every parent directory of those directories, excluding the repo root - directory. The default, auto, means true unless - --incompatible_default_to_explicit_init_py is used. If false, the user is - responsible for creating (possibly empty) __init__.py files and adding them to the - srcs of Python targets as required. - */ - .add(attr("legacy_create_init", TRISTATE).value(TriState.AUTO)) - /* - Whether to encode build information into the binary. Possible values: -

    -
  • - stamp = 1: Always stamp the build information into the binary, even in - --nostamp builds. This - setting should be avoided, since it potentially kills remote caching for the - binary and any downstream actions that depend on it. -
  • -
  • - stamp = 0: Always replace build information by constant values. This - gives good build result caching. -
  • -
  • - stamp = -1: Embedding of build information is controlled by the - --[no]stamp flag. -
  • -
-

Stamped binaries are not rebuilt unless their dependencies change.

- */ - .add(attr("stamp", TRISTATE).value(TriState.AUTO)) - .addToolchainTypes( - ToolchainTypeRequirement.builder(env.getToolsLabel("//tools/python:toolchain_type")) - .mandatory(true) - .build()) - .build(); - } - - @Override - public Metadata getMetadata() { - return RuleDefinition.Metadata.builder() - .name("$base_py_binary") - .type(RuleClassType.ABSTRACT) - .ancestors(PyBaseRule.class, CcToolchainRequiringRule.class) - .build(); - } - } -} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyTestRule.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyTestRule.java deleted file mode 100644 index eedc0d928d5651..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyTestRule.java +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.bazel.rules.python; - -import static com.google.devtools.build.lib.packages.Attribute.attr; -import static com.google.devtools.build.lib.packages.BuildType.TRISTATE; -import static com.google.devtools.build.lib.packages.Type.BOOLEAN; - -import com.google.devtools.build.lib.analysis.BaseRuleClasses; -import com.google.devtools.build.lib.analysis.RuleDefinition; -import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; -import com.google.devtools.build.lib.bazel.rules.python.BazelPyRuleClasses.PyBinaryBaseRule; -import com.google.devtools.build.lib.packages.RuleClass; -import com.google.devtools.build.lib.packages.RuleClass.Builder.RuleClassType; -import com.google.devtools.build.lib.packages.TriState; -import com.google.devtools.build.lib.rules.python.PythonConfiguration; - -/** - * Rule definition for the py_test rule. - */ -public final class BazelPyTestRule implements RuleDefinition { - @Override - public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { - return builder - .requiresConfigurationFragments(PythonConfiguration.class, BazelPythonConfiguration.class) - .override( - attr("testonly", BOOLEAN) - .value(true) - .nonconfigurable("policy decision: should be consistent across configurations")) - /* - See the section on py_binary() arguments, except - that the stamp argument is set to 0 by default for tests. - */ - .override(attr("stamp", TRISTATE).value(TriState.NO)) - .build(); - } - - @Override - public Metadata getMetadata() { - return RuleDefinition.Metadata.builder() - .name("py_test") - .type(RuleClassType.TEST) - .ancestors(PyBinaryBaseRule.class, BaseRuleClasses.TestBaseRule.class) - .factoryClass(BaseRuleClasses.EmptyRuleConfiguredTargetFactory.class) - .build(); - } -} - -/* - -

-A py_test() rule compiles a test. A test is a binary wrapper - around some test code.

- -

Examples

- -

-

-py_test(
-    name = "runtest_test",
-    srcs = ["runtest_test.py"],
-    deps = [
-        "//path/to/a/py/library",
-    ],
-)
-
- -

It's also possible to specify a main module:

- -
-py_test(
-    name = "runtest_test",
-    srcs = [
-        "runtest_main.py",
-        "runtest_lib.py",
-    ],
-    main = "runtest_main.py",
-)
-
- -*/ diff --git a/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java b/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java index 74bf20311440c7..1d3dff479737fa 100644 --- a/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java +++ b/src/main/java/com/google/devtools/build/lib/exec/StandaloneTestStrategy.java @@ -21,7 +21,6 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMultimap; import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Maps; import com.google.common.io.ByteStreams; import com.google.devtools.build.lib.actions.ActionExecutionContext; import com.google.devtools.build.lib.actions.ActionInput; @@ -460,28 +459,19 @@ private static Spawn createXmlGeneratingSpawn( envBuilder.put("TEST_SHARD_INDEX", "0"); envBuilder.put("TEST_TOTAL_SHARDS", "0"); } - Map executionInfo = - Maps.newHashMapWithExpectedSize(action.getExecutionInfo().size() + 1); - executionInfo.putAll(action.getExecutionInfo()); - if (result.exitCode() != 0) { - // If the test is failed, the spawn shouldn't use remote cache since the test.xml file is - // renamed immediately after the spawn execution. If there is another test attempt, the async - // upload will fail because it cannot read the file at original position. - executionInfo.put(ExecutionRequirements.NO_REMOTE_CACHE, ""); - } return new SimpleSpawn( action, args, envBuilder.buildOrThrow(), // Pass the execution info of the action which is identical to the supported tags set on the // test target. In particular, this does not set the test timeout on the spawn. - ImmutableMap.copyOf(executionInfo), + action.getExecutionInfo(), ImmutableMap.of(), - /*inputs=*/ NestedSetBuilder.create( + /* inputs= */ NestedSetBuilder.create( Order.STABLE_ORDER, action.getTestXmlGeneratorScript(), action.getTestLog()), - /*tools=*/ NestedSetBuilder.emptySet(Order.STABLE_ORDER), - /*outputs=*/ ImmutableSet.of(ActionInputHelper.fromPath(action.getXmlOutputPath())), - /*mandatoryOutputs=*/ null, + /* tools= */ NestedSetBuilder.emptySet(Order.STABLE_ORDER), + /* outputs= */ ImmutableSet.of(ActionInputHelper.fromPath(action.getXmlOutputPath())), + /* mandatoryOutputs= */ null, SpawnAction.DEFAULT_RESOURCE_SET); } diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java index 89174c2edb457c..2079659ba97ca7 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClass.java @@ -362,9 +362,10 @@ public void checkAttributes(Map attributes) { }, /** - * Normal rules are instantiable by BUILD files. Their names must therefore obey the rules for - * identifiers in the BUILD language. In addition, {@link TargetUtils#isTestRuleName} must - * return false for the name. + * Normal rules are instantiable by BUILD files, possibly via a macro (symbolic or legacy), in + * which case the rule's symbol is namespaced under {@code native}. Normal rule names must + * therefore obey the rules for identifiers in the BUILD language. In addition, {@link + * TargetUtils#isTestRuleName} must return false for the name. */ NORMAL { @Override @@ -393,6 +394,22 @@ public void checkAttributes(Map attributes) { } }, + /** + * Normal rules with the additional restriction that they can only be instantiated by BUILD + * files or legacy macros - but not symbolic macros. + */ + BUILD_ONLY { + @Override + public void checkName(String name) { + NORMAL.checkName(name); + } + + @Override + public void checkAttributes(Map attributes) { + NORMAL.checkAttributes(attributes); + } + }, + /** * Workspace rules can only be instantiated from a WORKSPACE file. Their names obey the rule * for identifiers. diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java index 07de534cc2aaba..3aa6c4addb4945 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java +++ b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java @@ -323,7 +323,8 @@ public static ImmutableMap buildRuleFunctions( for (String ruleClassName : ruleClassMap.keySet()) { RuleClass cl = ruleClassMap.get(ruleClassName); if (cl.getRuleClassType() == RuleClassType.NORMAL - || cl.getRuleClassType() == RuleClassType.TEST) { + || cl.getRuleClassType() == RuleClassType.TEST + || cl.getRuleClassType() == RuleClassType.BUILD_ONLY) { result.put(ruleClassName, new BuiltinRuleFunction(cl)); } } @@ -347,7 +348,10 @@ public NoneType call(StarlarkThread thread, Tuple args, Dict kwa throw Starlark.errorf("unexpected positional arguments"); } try { - Package.Builder pkgBuilder = Package.Builder.fromOrFail(thread, "rules"); + Package.Builder pkgBuilder = + ruleClass.getRuleClassType() != RuleClassType.BUILD_ONLY + ? Package.Builder.fromOrFail(thread, "rules") + : Package.Builder.fromOrFailAllowBuildOnly(thread, ruleClass.getName() + " rule"); RuleFactory.createAndAddRule( pkgBuilder, ruleClass, diff --git a/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java b/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java index e50d5c5cc8d6ff..1b1b2e0b41fe3d 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java +++ b/src/main/java/com/google/devtools/build/lib/packages/semantics/BuildLanguageOptions.java @@ -15,6 +15,8 @@ package com.google.devtools.build.lib.packages.semantics; +import static com.google.common.collect.ImmutableList.toImmutableList; + import com.google.common.collect.ImmutableList; import com.google.common.collect.Interner; import com.google.devtools.build.lib.concurrent.BlazeInterners; @@ -1038,7 +1040,11 @@ public StarlarkSemantics toStarlarkSemantics() { FlagConstants.DEFAULT_INCOMPATIBLE_AUTOLOAD_EXTERNALLY.isEmpty() ? ImmutableList.of() : ImmutableList.copyOf( - FlagConstants.DEFAULT_INCOMPATIBLE_AUTOLOAD_EXTERNALLY.split(","))); + FlagConstants.DEFAULT_INCOMPATIBLE_AUTOLOAD_EXTERNALLY.split(",")) + .stream() + .distinct() + .sorted() + .collect(toImmutableList())); public static final StarlarkSemantics.Key> REPOSITORIES_WITHOUT_AUTOLOAD = new StarlarkSemantics.Key<>("repositories_without_autoloads", ImmutableList.of()); public static final StarlarkSemantics.Key> EXPERIMENTAL_BUILTINS_INJECTION_OVERRIDE = diff --git a/src/main/java/com/google/devtools/build/lib/packages/semantics/FlagConstants.java b/src/main/java/com/google/devtools/build/lib/packages/semantics/FlagConstants.java index 40461ac384167c..ba365d3140fc93 100644 --- a/src/main/java/com/google/devtools/build/lib/packages/semantics/FlagConstants.java +++ b/src/main/java/com/google/devtools/build/lib/packages/semantics/FlagConstants.java @@ -21,7 +21,7 @@ class FlagConstants { private FlagConstants() {} - public static final String DEFAULT_INCOMPATIBLE_AUTOLOAD_EXTERNALLY = "+@rules_python"; + public static final String DEFAULT_INCOMPATIBLE_AUTOLOAD_EXTERNALLY = "+@rules_python,+@rules_java"; public static final String DEFAULT_INCOMPATIBLE_PACKAGE_GROUP_HAS_PUBLIC_SYNTAX = "true"; public static final String DEFAULT_INCOMPATIBLE_FIX_PACKAGE_GROUP_REPOROOT_SYNTAX = "true"; diff --git a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java index 4c8fea500e7b5e..bb56ee12c591d1 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java +++ b/src/main/java/com/google/devtools/build/lib/rules/android/AndroidConfiguration.java @@ -235,22 +235,6 @@ public static class Options extends FragmentOptions { + "'off' means that all libraries will be linked in mostly static mode.") public DynamicMode dynamicMode; - // Label of filegroup combining all Android tools used as implicit dependencies of - // android_* rules - // TODO(blaze-configurability): Mark this as deprecated in favor of --android_platforms. - @Option( - name = "android_sdk", - defaultValue = "null", - converter = LabelConverter.class, - documentationCategory = OptionDocumentationCategory.TOOLCHAIN, - effectTags = { - OptionEffectTag.CHANGES_INPUTS, - OptionEffectTag.LOADING_AND_ANALYSIS, - OptionEffectTag.LOSES_INCREMENTAL_STATE, - }, - help = "Specifies Android SDK/platform that is used to build Android applications.") - public Label sdk; - // TODO(bazel-team): Maybe merge this with --android_cpu above. // TODO(blaze-configurability): Mark this as deprecated in favor of --android_platforms. @Option( diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java index 97f3ece8536118..f1cb9dc44056bd 100644 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java @@ -271,6 +271,8 @@ public CcCompilationContext getCcCompilationContext() { private final LinkedHashMap compilationUnitSources = new LinkedHashMap<>(); private final LinkedHashMap moduleInterfaceSources = new LinkedHashMap<>(); private ImmutableList copts = ImmutableList.of(); + private ImmutableList conlyopts = ImmutableList.of(); + private ImmutableList cxxopts = ImmutableList.of(); private CoptsFilter coptsFilter = CoptsFilter.alwaysPasses(); private final Set defines = new LinkedHashSet<>(); private final Set localDefines = new LinkedHashSet<>(); @@ -615,6 +617,18 @@ public void setCoptsFilter(CoptsFilter coptsFilter) { this.coptsFilter = Preconditions.checkNotNull(coptsFilter); } + @CanIgnoreReturnValue + public CcCompilationHelper setConlyopts(ImmutableList copts) { + this.conlyopts = Preconditions.checkNotNull(copts); + return this; + } + + @CanIgnoreReturnValue + public CcCompilationHelper setCxxopts(ImmutableList copts) { + this.cxxopts = Preconditions.checkNotNull(copts); + return this; + } + /** * Adds the given defines to the compiler command line of this target as well as its dependent * targets. @@ -1270,9 +1284,21 @@ public static ImmutableList getCoptsFromOptions( private ImmutableList getCopts(Artifact sourceFile, Label sourceLabel) { ImmutableList.Builder coptsList = ImmutableList.builder(); - coptsList.addAll( - getCoptsFromOptions(cppConfiguration, semantics, sourceFile.getExecPathString())); + String sourceFilename = sourceFile.getExecPathString(); + coptsList.addAll(getCoptsFromOptions(cppConfiguration, semantics, sourceFilename)); coptsList.addAll(copts); + + if (CppFileTypes.C_SOURCE.matches(sourceFilename)) { + coptsList.addAll(conlyopts); + } + + if (CppFileTypes.CPP_SOURCE.matches(sourceFilename) + || CppFileTypes.CPP_HEADER.matches(sourceFilename) + || CppFileTypes.CPP_MODULE_MAP.matches(sourceFilename) + || CppFileTypes.CLIF_INPUT_PROTO.matches(sourceFilename)) { + coptsList.addAll(cxxopts); + } + if (sourceFile != null && sourceLabel != null) { coptsList.addAll(collectPerFileCopts(sourceFile, sourceLabel)); } diff --git a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java index b56c713203904c..ca3ef1601351f4 100755 --- a/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java +++ b/src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java @@ -2049,6 +2049,8 @@ public Tuple compile( String includePrefix, String stripIncludePrefix, Sequence userCompileFlags, // expected + Sequence conlyFlags, // expected + Sequence cxxFlags, // expected Sequence ccCompilationContexts, // expected Object implementationCcCompilationContextsObject, String name, @@ -2216,6 +2218,8 @@ public Tuple compile( .setCopts( ImmutableList.copyOf( Sequence.cast(userCompileFlags, String.class, "user_compile_flags"))) + .setConlyopts(ImmutableList.copyOf(Sequence.cast(conlyFlags, String.class, "conly_flags"))) + .setCxxopts(ImmutableList.copyOf(Sequence.cast(cxxFlags, String.class, "cxx_flags"))) .addAdditionalCompilationInputs( Sequence.cast(additionalInputs, Artifact.class, "additional_inputs")) .addAdditionalInputs(nonCompilationAdditionalInputs) diff --git a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeRule.java b/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeRule.java deleted file mode 100644 index 84cf37836bd614..00000000000000 --- a/src/main/java/com/google/devtools/build/lib/rules/python/PyRuntimeRule.java +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.rules.python; - -import static com.google.devtools.build.lib.packages.Attribute.attr; -import static com.google.devtools.build.lib.packages.BuildType.LABEL; -import static com.google.devtools.build.lib.packages.BuildType.LABEL_LIST; -import static com.google.devtools.build.lib.packages.BuildType.LICENSE; -import static com.google.devtools.build.lib.packages.Type.STRING; - -import com.google.devtools.build.lib.analysis.BaseRuleClasses; -import com.google.devtools.build.lib.analysis.RuleDefinition; -import com.google.devtools.build.lib.analysis.RuleDefinitionEnvironment; -import com.google.devtools.build.lib.packages.RuleClass; -import com.google.devtools.build.lib.util.FileTypeSet; - -/** Fake rule definition for {@code py_runtime} for generated doc purposes. */ -public final class PyRuntimeRule implements RuleDefinition { - - @Override - public RuleClass build(RuleClass.Builder builder, RuleDefinitionEnvironment env) { - return builder - - // For --incompatible_py3_is_default. - .requiresConfigurationFragments(PythonConfiguration.class) - - /* - For an in-build runtime, this is the set of files comprising this runtime. These files will - be added to the runfiles of Python binaries that use this runtime. For a platform runtime - this attribute must not be set. - */ - .add(attr("files", LABEL_LIST).allowedFileTypes(FileTypeSet.ANY_FILE)) - - /* - For an in-build runtime, this is the target to invoke as the interpreter. For a platform - runtime this attribute must not be set. - */ - .add(attr("interpreter", LABEL).allowedFileTypes(FileTypeSet.ANY_FILE).singleArtifact()) - - /* - For a platform runtime, this is the absolute path of a Python interpreter on the target - platform. For an in-build runtime this attribute must not be set. - */ - .add(attr("interpreter_path", STRING)) - - /* - This is a target to use for collecting code coverage information from py_binary - and py_test targets. - -

If set, the target must either produce a single file or be and executable target. - The path to the single file, or the executable if the target is executable, - determines the entry point for the python coverage tool. The target and its - runfiles will be added to the runfiles when coverage is enabled.

- -

The entry point for the tool must be loadable by a python interpreter (e.g. a - .py or .pyc file). It must accept the command line arguments - of coverage.py, at least including - the run and lcov subcommands. - */ - .add(attr("coverage_tool", LABEL).allowedFileTypes(FileTypeSet.NO_FILE)) - - /* - Whether this runtime is for Python major version 2 or 3. Valid values are "PY2" - and "PY3". - -

The default value is controlled by the --incompatible_py3_is_default flag. - However, in the future this attribute will be mandatory and have no default value. - */ - .add( - attr("python_version", STRING) - .value(PythonVersion._INTERNAL_SENTINEL.toString()) - .allowedValues(PyRuleClasses.TARGET_PYTHON_ATTR_VALUE_SET)) - - /* - "Shebang" expression prepended to the bootstrapping Python script - used when executing py_binary targets. - -

See issue 8685 for - motivation. - -

Does not apply to Windows. - */ - .add(attr("stub_shebang", STRING).value(PyRuntimeInfo.DEFAULT_STUB_SHEBANG)) - - /* - Previously referred to as the "Python stub script", this is the - entrypoint to every Python executable target. - */ - .add( - attr("bootstrap_template", LABEL) - .value(env.getToolsLabel(PyRuntimeInfo.DEFAULT_BOOTSTRAP_TEMPLATE)) - .allowedFileTypes(FileTypeSet.ANY_FILE) - .singleArtifact()) - .add(attr("output_licenses", LICENSE)) - .build(); - } - - @Override - public Metadata getMetadata() { - return Metadata.builder() - .name("py_runtime") - .ancestors(BaseRuleClasses.NativeBuildRule.class) - .factoryClass(BaseRuleClasses.EmptyRuleConfiguredTargetFactory.class) - .build(); - } -} -/* - -

Represents a Python runtime used to execute Python code. - -

A py_runtime target can represent either a platform runtime or an -in-build runtime. A platform runtime accesses a system-installed interpreter at a known -path, whereas an in-build runtime points to an executable target that acts as the interpreter. In -both cases, an "interpreter" means any executable binary or wrapper script that is capable of -running a Python script passed on the command line, following the same conventions as the standard -CPython interpreter. - -

A platform runtime is by its nature non-hermetic. It imposes a requirement on the target platform -to have an interpreter located at a specific path. An in-build runtime may or may not be hermetic, -depending on whether it points to a checked-in interpreter or a wrapper script that accesses the -system interpreter. - -

Example:

- -
-py_runtime(
-    name = "python-2.7.12",
-    files = glob(["python-2.7.12/**"]),
-    interpreter = "python-2.7.12/bin/python",
-)
-
-py_runtime(
-    name = "python-3.6.0",
-    interpreter_path = "/opt/pyenv/versions/3.6.0/bin/python",
-)
-
- -*/ diff --git a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcModuleApi.java b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcModuleApi.java index db81e5588a8910..0867415556f026 100755 --- a/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcModuleApi.java +++ b/src/main/java/com/google/devtools/build/lib/starlarkbuildapi/cpp/CcModuleApi.java @@ -233,6 +233,18 @@ default void compilerFlagExists() {} positional = false, named = true, defaultValue = "[]"), + @Param( + name = "conly_flags", + doc = "Additional list of compilation options for C compiles.", + positional = false, + named = true, + defaultValue = "[]"), + @Param( + name = "cxx_flags", + doc = "Additional list of compilation options for C++ compiles.", + positional = false, + named = true, + defaultValue = "[]"), @Param( name = "compilation_contexts", doc = "Headers from dependencies used for compilation.", @@ -395,6 +407,8 @@ Tuple compile( String includePrefix, String stripIncludePrefix, Sequence userCompileFlags, // expected + Sequence conlyFlags, // expected + Sequence cxxFlags, // expected Sequence ccCompilationContexts, // expected Object implementationCcCompilationContextsObject, String name, diff --git a/src/main/protobuf/failure_details.proto b/src/main/protobuf/failure_details.proto index c73e8940605e90..7659066ddb11a9 100644 --- a/src/main/protobuf/failure_details.proto +++ b/src/main/protobuf/failure_details.proto @@ -750,6 +750,7 @@ message LocalExecution { enum Code { LOCAL_EXECUTION_UNKNOWN = 0 [(metadata) = { exit_code: 37 }]; LOCKFREE_OUTPUT_PREREQ_UNMET = 1 [(metadata) = { exit_code: 2 }]; + UNTRACKED_RESOURCE = 2 [(metadata) = { exit_code: 1 }]; } Code code = 1; diff --git a/src/main/starlark/builtins_bzl/bazel/exports.bzl b/src/main/starlark/builtins_bzl/bazel/exports.bzl index 96198058fae806..68ba159b49c10b 100644 --- a/src/main/starlark/builtins_bzl/bazel/exports.bzl +++ b/src/main/starlark/builtins_bzl/bazel/exports.bzl @@ -21,7 +21,6 @@ load("@_builtins//:common/java/java_plugin.bzl", "java_plugin") load("@_builtins//:common/java/proto/java_proto_library.bzl", "java_proto_library") load("@_builtins//:common/proto/proto_library.bzl", "proto_library") load("@_builtins//:common/python/py_internal.bzl", "py_internal") -load("@_builtins//:common/python/py_runtime_macro.bzl", "py_runtime") # still used in @bazel_tools load(":bazel/java/bazel_java_binary.bzl", "java_test") load(":bazel/java/bazel_java_binary_wrapper.bzl", "java_binary") load(":bazel/sh/sh_library.bzl", "sh_library") @@ -52,7 +51,6 @@ exported_rules = { "java_package_configuration": java_package_configuration, "java_runtime": java_runtime, "java_toolchain": java_toolchain, - "py_runtime": py_runtime, "sh_library": sh_library, } exported_to_java = {} diff --git a/src/main/starlark/builtins_bzl/common/cc/attrs.bzl b/src/main/starlark/builtins_bzl/common/cc/attrs.bzl index f02ab98356b08f..808c5d44d6c24b 100644 --- a/src/main/starlark/builtins_bzl/common/cc/attrs.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/attrs.bzl @@ -163,7 +163,7 @@ is prepended with -D and added to the compile command line for this but not to its dependents. """), "copts": attr.string_list(doc = """ -Add these options to the C++ compilation command. +Add these options to the C/C++ compilation command. Subject to "Make variable" substitution and Bourne shell tokenization.

@@ -178,6 +178,16 @@ Subject to "Make variable" substitution and no_copts_tokenization, Bourne shell tokenization applies only to strings that consist of a single "Make" variable.

+"""), + "conlyopts": attr.string_list(doc = """ +Add these options to the C compilation command. +Subject to "Make variable" substitution and +Bourne shell tokenization. +"""), + "cxxopts": attr.string_list(doc = """ +Add these options to the C++ compilation command. +Subject to "Make variable" substitution and +Bourne shell tokenization. """), "hdrs_check": attr.string( doc = "Deprecated, no-op.", diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_binary.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_binary.bzl index 40b637694db45b..8203180c2a1ff8 100644 --- a/src/main/starlark/builtins_bzl/common/cc/cc_binary.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_binary.bzl @@ -502,7 +502,9 @@ def cc_binary_impl(ctx, additional_linkopts, force_linkstatic = False): actions = ctx.actions, feature_configuration = feature_configuration, cc_toolchain = cc_toolchain, - user_compile_flags = runtimes_copts + cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions), + user_compile_flags = runtimes_copts + cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "copts"), + conly_flags = cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "conlyopts"), + cxx_flags = cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "cxxopts"), defines = cc_helper.defines(ctx, additional_make_variable_substitutions), local_defines = cc_helper.local_defines(ctx, additional_make_variable_substitutions) + cc_helper.get_local_defines_for_runfiles_lookup(ctx, ctx.attr.deps), system_includes = cc_helper.system_include_dirs(ctx, additional_make_variable_substitutions), diff --git a/src/main/starlark/builtins_bzl/common/cc/cc_common.bzl b/src/main/starlark/builtins_bzl/common/cc/cc_common.bzl index 0a578b88163802..f516506add9605 100644 --- a/src/main/starlark/builtins_bzl/common/cc/cc_common.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_common.bzl @@ -675,6 +675,8 @@ def _compile( include_prefix = "", strip_include_prefix = "", user_compile_flags = [], + conly_flags = [], + cxx_flags = [], compilation_contexts = [], implementation_compilation_contexts = _UNBOUND, disallow_pic_outputs = False, @@ -760,6 +762,8 @@ def _compile( include_prefix = include_prefix, strip_include_prefix = strip_include_prefix, user_compile_flags = user_compile_flags, + conly_flags = conly_flags, + cxx_flags = cxx_flags, compilation_contexts = compilation_contexts, implementation_compilation_contexts = implementation_compilation_contexts, disallow_pic_outputs = disallow_pic_outputs, 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 92b6864f05fc32..5292b08cbfd9e9 100644 --- a/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_helper.bzl @@ -924,10 +924,10 @@ def _expand_make_variables_for_copts(ctx, tokenization, unexpanded_tokens, addit tokens.append(_expand(ctx, token, additional_make_variable_substitutions, targets = targets)) return tokens -def _get_copts(ctx, feature_configuration, additional_make_variable_substitutions): - if not hasattr(ctx.attr, "copts"): - fail("could not find rule attribute named: 'copts'") - attribute_copts = ctx.attr.copts +def _get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "copts"): + if not hasattr(ctx.attr, attr): + fail("could not find rule attribute named: '{}'".format(attr)) + attribute_copts = getattr(ctx.attr, attr) tokenization = not (cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "no_copts_tokenization") or "no_copts_tokenization" in ctx.features) expanded_attribute_copts = _expand_make_variables_for_copts(ctx, tokenization, attribute_copts, additional_make_variable_substitutions) return expanded_attribute_copts 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 5a68c89be5d18f..a62767520d45cb 100755 --- a/src/main/starlark/builtins_bzl/common/cc/cc_library.bzl +++ b/src/main/starlark/builtins_bzl/common/cc/cc_library.bzl @@ -58,7 +58,9 @@ def _cc_library_impl(ctx): name = ctx.label.name, cc_toolchain = cc_toolchain, feature_configuration = feature_configuration, - user_compile_flags = runtimes_copts + cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions), + user_compile_flags = runtimes_copts + cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "copts"), + conly_flags = cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "conlyopts"), + cxx_flags = cc_helper.get_copts(ctx, feature_configuration, additional_make_variable_substitutions, attr = "cxxopts"), defines = cc_helper.defines(ctx, additional_make_variable_substitutions), local_defines = cc_helper.local_defines(ctx, additional_make_variable_substitutions) + cc_helper.get_local_defines_for_runfiles_lookup(ctx, ctx.attr.deps + ctx.attr.implementation_deps), system_includes = cc_helper.system_include_dirs(ctx, additional_make_variable_substitutions), diff --git a/src/main/starlark/builtins_bzl/common/exports.bzl b/src/main/starlark/builtins_bzl/common/exports.bzl index 7d88030ce35899..c2b175cf412d6f 100755 --- a/src/main/starlark/builtins_bzl/common/exports.bzl +++ b/src/main/starlark/builtins_bzl/common/exports.bzl @@ -27,7 +27,6 @@ load("@_builtins//:common/cc/cc_toolchain.bzl", "cc_toolchain") load("@_builtins//:common/cc/cc_toolchain_alias.bzl", "cc_toolchain_alias") load("@_builtins//:common/cc/experimental_cc_static_library.bzl", "cc_static_library") load("@_builtins//:common/java/proto/java_lite_proto_library.bzl", "java_lite_proto_library") -load("@_builtins//:common/objc/j2objc_library.bzl", "j2objc_library") load("@_builtins//:common/objc/objc_import.bzl", "objc_import") load("@_builtins//:common/objc/objc_library.bzl", "objc_library") load("@_builtins//:common/proto/proto_common.bzl", "proto_common_do_not_use") @@ -77,7 +76,6 @@ exported_rules = { "java_lite_proto_library": java_lite_proto_library, "objc_import": objc_import, "objc_library": objc_library, - "j2objc_library": j2objc_library, "cc_shared_library": cc_shared_library, "cc_static_library": cc_static_library, "cc_binary": cc_binary, diff --git a/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl b/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl index 46e2323d8e2779..aac4c9652a6735 100644 --- a/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl +++ b/src/main/starlark/builtins_bzl/common/java/proto/java_proto_library.bzl @@ -213,7 +213,6 @@ rules to generate Java code for. """, ), "licenses": attr.license() if hasattr(attr, "license") else attr.string_list(), - "distribs": attr.string_list(), } | toolchains.if_legacy_toolchain({ "_aspect_java_proto_toolchain": attr.label( default = configuration_field(fragment = "proto", name = "proto_toolchain_for_java"), diff --git a/src/main/starlark/builtins_bzl/common/objc/j2objc_aspect.bzl b/src/main/starlark/builtins_bzl/common/objc/j2objc_aspect.bzl deleted file mode 100644 index ecccff038d7b0a..00000000000000 --- a/src/main/starlark/builtins_bzl/common/objc/j2objc_aspect.bzl +++ /dev/null @@ -1,594 +0,0 @@ -# Copyright 2023 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Definition of j2objc_aspect. -""" - -load(":common/cc/cc_common.bzl", "cc_common") -load(":common/cc/cc_helper.bzl", "cc_helper") -load(":common/cc/cc_info.bzl", "CcInfo") -load(":common/cc/semantics.bzl", cc_semantics = "semantics") -load(":common/java/java_info.bzl", "JavaInfo") -load(":common/java/java_semantics.bzl", java_semantics = "semantics") -load(":common/objc/apple_common.bzl", "apple_common") -load(":common/objc/compilation_artifacts_info.bzl", "CompilationArtifactsInfo") -load(":common/objc/compilation_support.bzl", "compilation_support") -load(":common/objc/intermediate_artifacts.bzl", "j2objc_create_intermediate_artifacts") -load(":common/objc/objc_common.bzl", "objc_common") -load(":common/objc/objc_compilation_context_info.bzl", "create_cc_compilation_context") -load(":common/objc/providers.bzl", "J2ObjcMappingFileInfo") -load(":common/paths.bzl", "paths") -load( - ":common/proto/proto_common.bzl", - "ProtoLangToolchainInfo", - proto_common = "proto_common_do_not_use", -) -load(":common/proto/proto_info.bzl", "ProtoInfo") - -def _j2objc_source_header_search_paths(genfiles_dir_path, bin_dir_path, objc_file_path, proto_sources): - for source_to_translate in proto_sources: - if not source_to_translate.is_source: - genfiles_root_header_search_path = paths.get_relative(objc_file_path, genfiles_dir_path) - bin_root_header_search_path = paths.get_relative(objc_file_path, bin_dir_path) - return [objc_file_path, genfiles_root_header_search_path, bin_root_header_search_path] - return [objc_file_path] - -def _proto_j2objc_source(ctx, proto_info, proto_sources, objc_file_path): - return struct( - target = ctx.label, - objc_srcs = [] if not proto_sources else proto_common.declare_generated_files(ctx.actions, proto_info, ".j2objc.pb.m"), - objc_hdrs = [] if not proto_sources else proto_common.declare_generated_files(ctx.actions, proto_info, ".j2objc.pb.h"), - objc_file_path = objc_file_path, - source_type = "PROTO", - header_search_paths = _j2objc_source_header_search_paths( - ctx.genfiles_dir.path, - ctx.bin_dir.path, - objc_file_path, - proto_sources, - ), - compile_with_arc = False, - ) - -def _get_output_objc_files(actions, srcs, objc_file_root_relative_path, suffix): - objc_sources = [] - for src in srcs: - src_path = src.path.removesuffix("." + src.extension) - objc_source_path = paths.get_relative(objc_file_root_relative_path, src_path) + suffix - objc_sources.append(actions.declare_file(objc_source_path)) - return objc_sources - -def _get_header_base(experimental_shorter_header_path): - return "_ios" if experimental_shorter_header_path else "_j2objc" - -def _get_source_tree_artifact_rel_path(label_name): - return "_j2objc/src_jar_files/" + label_name + "/source_files" - -def _get_header_tree_artifact_rel_path(ctx): - header_base = _get_header_base(ctx.fragments.j2objc.experimental_shorter_header_path()) - return header_base + "/src_jar_files/" + ctx.label.name + "/header_files" - -def _java_j2objc_source(ctx, java_source_files, java_source_jars): - header_base = _get_header_base(ctx.fragments.j2objc.experimental_shorter_header_path()) - objc_file_root_relative_path = header_base + "/" + ctx.label.name - objc_file_root_exec_path = paths.get_relative(ctx.bin_dir.path, ctx.label.package + "/" + objc_file_root_relative_path) - - objc_srcs = _get_output_objc_files( - ctx.actions, - java_source_files, - objc_file_root_relative_path, - ".m", - ) - objc_hdrs = _get_output_objc_files( - ctx.actions, - java_source_files, - objc_file_root_relative_path, - ".h", - ) - header_search_paths = _j2objc_source_header_search_paths( - ctx.genfiles_dir.path, - ctx.bin_dir.path, - objc_file_root_exec_path, - java_source_files, - ) - - if java_source_jars: - source_tree_artifact_rel_path = _get_source_tree_artifact_rel_path(ctx.label.name) - objc_srcs.append(ctx.actions.declare_directory(source_tree_artifact_rel_path)) - header_tree_artifact_rel_path = _get_header_tree_artifact_rel_path(ctx) - translated_header = ctx.actions.declare_directory(header_tree_artifact_rel_path) - objc_hdrs.append(translated_header) - header_search_paths.append(translated_header.path) - - return struct( - target = ctx.label, - objc_srcs = objc_srcs, - objc_hdrs = objc_hdrs, - objc_file_path = objc_file_root_exec_path, - source_type = "JAVA", - header_search_paths = header_search_paths, - compile_with_arc = "-use-arc" in ctx.fragments.j2objc.translation_flags, - ) - -def _create_j2objc_proto_compile_actions( - proto_info, - proto_lang_toolchain_info, - ctx, - filtered_proto_sources_non_empty, - j2objc_source, - objc_file_path): - output_header_mapping_files = [] - output_class_mapping_files = [] - if filtered_proto_sources_non_empty: - output_header_mapping_files = proto_common.declare_generated_files(ctx.actions, proto_info, ".j2objc.mapping") - output_class_mapping_files = proto_common.declare_generated_files(ctx.actions, proto_info, ".clsmap.properties") - - outputs = j2objc_source.objc_srcs + j2objc_source.objc_hdrs + output_header_mapping_files + output_class_mapping_files - - proto_common.compile( - actions = ctx.actions, - proto_info = proto_info, - proto_lang_toolchain_info = proto_lang_toolchain_info, - generated_files = outputs, - plugin_output = objc_file_path, - ) - - return J2ObjcMappingFileInfo( - header_mapping_files = depset(direct = output_header_mapping_files), - class_mapping_files = depset(direct = output_class_mapping_files), - dependency_mapping_files = depset([]), - archive_source_mapping_files = depset([]), - ) - -def _empty_j2objc_mapping_file_info(): - return J2ObjcMappingFileInfo( - header_mapping_files = depset([]), - class_mapping_files = depset([]), - dependency_mapping_files = depset([]), - archive_source_mapping_files = depset([]), - ) - -def _proto(target, ctx): - proto_lang_toolchain_info = ctx.attr._j2objc_proto_toolchain[ProtoLangToolchainInfo] - filtered_proto_sources, _ = proto_common.experimental_filter_sources(target[ProtoInfo], proto_lang_toolchain_info) - objc_file_path = cc_helper.proto_output_root( - proto_root = target[ProtoInfo].proto_source_root, - bin_dir_path = ctx.bin_dir.path, - ) - j2objc_source = _proto_j2objc_source(ctx, target[ProtoInfo], filtered_proto_sources, objc_file_path) - - direct_j2objc_mapping_file_provider = None - if len(j2objc_source.objc_srcs) == 0: - direct_j2objc_mapping_file_provider = _empty_j2objc_mapping_file_info() - else: - direct_j2objc_mapping_file_provider = _create_j2objc_proto_compile_actions( - proto_info = target[ProtoInfo], - proto_lang_toolchain_info = proto_lang_toolchain_info, - ctx = ctx, - filtered_proto_sources_non_empty = len(filtered_proto_sources) > 0, - j2objc_source = j2objc_source, - objc_file_path = objc_file_path, - ) - - return _build_aspect( - target = target, - ctx = ctx, - j2objc_source = j2objc_source, - direct_j2objc_mapping_file_provider = direct_j2objc_mapping_file_provider, - dep_attributes = ["deps"], - proto_toolchain_runtime = [proto_lang_toolchain_info.runtime], - ) - -def _dep_j2objc_mapping_file_provider(ctx): - transitive_header_mapping_files = [] - transitive_class_mapping_files = [] - transitive_dependency_mapping_files = [] - transitive_archive_source_mapping_files = [] - - deps = getattr(ctx.rule.attr, "deps", []) + getattr(ctx.rule.attr, "runtime_deps", []) + getattr(ctx.rule.attr, "exports", []) - providers = [dep[J2ObjcMappingFileInfo] for dep in deps if J2ObjcMappingFileInfo in dep] - for provider in providers: - transitive_header_mapping_files.append(provider.header_mapping_files) - transitive_class_mapping_files.append(provider.class_mapping_files) - transitive_dependency_mapping_files.append(provider.dependency_mapping_files) - transitive_archive_source_mapping_files.append(provider.archive_source_mapping_files) - - return J2ObjcMappingFileInfo( - header_mapping_files = depset([], transitive = transitive_header_mapping_files), - class_mapping_files = depset([], transitive = transitive_class_mapping_files), - dependency_mapping_files = depset([], transitive = transitive_dependency_mapping_files), - archive_source_mapping_files = depset([], transitive = transitive_archive_source_mapping_files), - ) - -def _exported_j2objc_mapping_file_provider(target, ctx, direct_j2objc_mapping_file_provider): - dep_j2objc_mapping_file_provider = _dep_j2objc_mapping_file_provider(ctx) - - transitive_header_mapping_files = [] - transitive_class_mapping_files = [] - transitive_dependency_mapping_files = [] - transitive_archive_source_mapping_files = [] - - transitive_header_mapping_files.append(direct_j2objc_mapping_file_provider.header_mapping_files) - transitive_class_mapping_files.append(direct_j2objc_mapping_file_provider.class_mapping_files) - transitive_dependency_mapping_files.append(direct_j2objc_mapping_file_provider.dependency_mapping_files) - transitive_archive_source_mapping_files.append(direct_j2objc_mapping_file_provider.archive_source_mapping_files) - - experimental_j2objc_header_map = ctx.fragments.j2objc.experimental_j2objc_header_map() - if ProtoInfo in target or len(transitive_header_mapping_files) == 0 or experimental_j2objc_header_map: - transitive_header_mapping_files.append(dep_j2objc_mapping_file_provider.header_mapping_files) - transitive_class_mapping_files.append(dep_j2objc_mapping_file_provider.class_mapping_files) - transitive_dependency_mapping_files.append(dep_j2objc_mapping_file_provider.dependency_mapping_files) - transitive_archive_source_mapping_files.append(dep_j2objc_mapping_file_provider.archive_source_mapping_files) - - return J2ObjcMappingFileInfo( - header_mapping_files = depset([], transitive = transitive_header_mapping_files), - class_mapping_files = depset([], transitive = transitive_class_mapping_files), - dependency_mapping_files = depset([], transitive = transitive_dependency_mapping_files), - archive_source_mapping_files = depset([], transitive = transitive_archive_source_mapping_files), - ) - -def _get_file_path_with_suffix(objc_srcs, suffix): - for src in objc_srcs: - if src.path.endswith(suffix): - return src.path - fail("File with %s suffix must exist inside objc_sources.", suffix) - -def _create_j2objc_transpilation_action( - ctx, - java_source_files, - java_source_jars, - dep_j2objc_mapping_file_provider, - transitive_compile_time_jars, - j2objc_source): - java_runtime = ctx.toolchains[java_semantics.JAVA_TOOLCHAIN_TYPE].java.java_runtime - - args = ctx.actions.args() - args.use_param_file(param_file_arg = "@%s", use_always = True) - args.set_param_file_format("multiline") - - args.add("--java", java_runtime.java_executable_exec_path) - - j2objc_deploy_jar = ctx.file._j2objc - args.add("--j2objc", j2objc_deploy_jar) - - args.add("--main_class", "com.google.devtools.j2objc.J2ObjC") - - objc_file_path = j2objc_source.objc_file_path - args.add("--objc_file_path", objc_file_path) - - output_dep_mapping_file = ctx.actions.declare_file(ctx.label.name + ".dependency_mapping.j2objc") - args.add("--output_dependency_mapping_file", output_dep_mapping_file) - - if java_source_jars: - args.add_joined("--src_jars", java_source_jars, join_with = ",") - args.add("--output_gen_source_dir", _get_file_path_with_suffix(j2objc_source.objc_srcs, "source_files")) - args.add("--output_gen_header_dir", _get_file_path_with_suffix(j2objc_source.objc_hdrs, "header_files")) - - args.add_all(ctx.fragments.j2objc.translation_flags) - - header_mapping_files = dep_j2objc_mapping_file_provider.header_mapping_files - if header_mapping_files: - args.add_joined("--header-mapping", header_mapping_files, join_with = ",") - - experimental_j2objc_header_map = ctx.fragments.j2objc.experimental_j2objc_header_map() - output_header_mapping_file = ctx.actions.declare_file(ctx.label.name + ".mapping.j2objc") - if not experimental_j2objc_header_map: - args.add("--output-header-mapping", output_header_mapping_file) - - deps_class_mapping_files = dep_j2objc_mapping_file_provider.class_mapping_files - if deps_class_mapping_files: - args.add_joined("--mapping", deps_class_mapping_files, join_with = ",") - - archive_source_mapping_file = ctx.actions.declare_file(ctx.label.name + ".archive_source_mapping.j2objc") - args.add("--output_archive_source_mapping_file", archive_source_mapping_file) - - compiled_library = j2objc_create_intermediate_artifacts(ctx = ctx).archive() - args.add("--compiled_archive_file_path", compiled_library) - - boothclasspath_jar = ctx.file._jre_emul_jar - args.add("-Xbootclasspath:" + boothclasspath_jar.path) - - module_files = ctx.attr._jre_emul_module.files.to_list() - for file in module_files: - if file.basename == "release": - args.add("--system", file.dirname) - break - - dead_code_report = ctx.file._dead_code_report - if dead_code_report: - args.add("--dead-code-report", dead_code_report) - - args.add("-d", objc_file_path) - - if transitive_compile_time_jars: - args.add_joined("-classpath", transitive_compile_time_jars.to_list(), join_with = ":") - - args.add_all(java_source_files) - - direct_files = [j2objc_deploy_jar, boothclasspath_jar] - if dead_code_report != None: - direct_files.append(dead_code_report) - if not experimental_j2objc_header_map: - direct_files.append(output_header_mapping_file) - - ctx.actions.run( - mnemonic = "TranspilingJ2objc", - executable = ctx.executable._j2objc_wrapper, - arguments = [args], - inputs = depset( - direct_files + module_files + java_source_files + java_source_jars, - transitive = [ - transitive_compile_time_jars, - java_runtime.files, - header_mapping_files, - deps_class_mapping_files, - ], - ), - outputs = j2objc_source.objc_srcs + j2objc_source.objc_hdrs + - [output_dep_mapping_file, archive_source_mapping_file], - toolchain = None, - ) - - if experimental_j2objc_header_map: - args_header_map = ctx.actions.args() - if java_source_files: - args_header_map.add_joined("--source_files", java_source_files, join_with = ",") - if java_source_jars: - args_header_map.add_joined("--source_jars", java_source_jars, join_with = ",") - args_header_map.add("--output_mapping_file", output_header_mapping_file) - - ctx.actions.run( - mnemonic = "GenerateJ2objcHeaderMap", - executable = ctx.executable._j2objc_header_map, - arguments = [args_header_map], - inputs = java_source_files + java_source_jars, - outputs = [output_header_mapping_file], - toolchain = None, - ) - - return J2ObjcMappingFileInfo( - header_mapping_files = depset([output_header_mapping_file]), - class_mapping_files = depset([]), - dependency_mapping_files = depset([output_dep_mapping_file]), - archive_source_mapping_files = depset([archive_source_mapping_file]), - ) - -def _java(target, ctx): - java_info = target[JavaInfo] - transitive_compile_time_jars = java_info.transitive_compile_time_jars - generated_source_jars = [ - output.generated_source_jar - for output in java_info.java_outputs - if output.generated_source_jar != None - ] - - java_source_files = [] - java_source_jars = [] - if hasattr(ctx.rule.attr, "srcs"): - for src in ctx.rule.files.srcs: - src_path = src.path - if src_path.endswith(".srcjar"): - java_source_jars.append(src) - if src_path.endswith(".java"): - java_source_files.append(src) - - src_jar_target = getattr(ctx.rule.attr, "srcjar", None) - if src_jar_target: - java_source_jars.extend(ctx.rule.files.srcjar) - if generated_source_jars: - java_source_jars.extend(generated_source_jars) - - j2objc_source = _java_j2objc_source(ctx, java_source_files, java_source_jars) - - dep_j2objc_mapping_file_provider = _dep_j2objc_mapping_file_provider(ctx) - - if len(j2objc_source.objc_srcs) == 0: - direct_j2objc_mapping_file_provider = _empty_j2objc_mapping_file_info() - else: - direct_j2objc_mapping_file_provider = _create_j2objc_transpilation_action( - ctx, - java_source_files, - java_source_jars, - dep_j2objc_mapping_file_provider, - transitive_compile_time_jars, - j2objc_source, - ) - return _build_aspect( - target = target, - ctx = ctx, - j2objc_source = j2objc_source, - direct_j2objc_mapping_file_provider = direct_j2objc_mapping_file_provider, - dep_attributes = ["_jre_lib", "deps", "exports", "runtime_deps"], - proto_toolchain_runtime = [], - ) - -def _common( - ctx, - intermediate_artifacts, - transpiled_sources, - transpiled_headers, - header_search_paths, - dependent_attributes, - other_deps, - compile_with_arc): - compilation_artifacts = None - has_module_map = False - if transpiled_sources or transpiled_headers: - if compile_with_arc: - compilation_artifacts = CompilationArtifactsInfo( - srcs = transpiled_sources, - non_arc_srcs = [], - hdrs = transpiled_headers, - intermediate_artifacts = intermediate_artifacts, - ) - else: - compilation_artifacts = CompilationArtifactsInfo( - srcs = [], - non_arc_srcs = transpiled_sources, - hdrs = transpiled_headers, - intermediate_artifacts = intermediate_artifacts, - ) - has_module_map = True - - deps = [] - for dep_attr in dependent_attributes: - if dep_attr == "_jre_lib": - deps.append(ctx.attr._jre_lib) - elif hasattr(ctx.rule.attr, dep_attr): - deps.extend(getattr(ctx.rule.attr, dep_attr)) - - ( - objc_provider, - objc_compilation_context, - objc_linking_context, - ) = objc_common.create_context_and_provider( - ctx = ctx, - compilation_artifacts = compilation_artifacts, - has_module_map = has_module_map, - deps = deps + other_deps, - intermediate_artifacts = intermediate_artifacts, - includes = header_search_paths, - compilation_attributes = None, - implementation_deps = [], - attr_linkopts = [], - is_aspect = True, - ) - - return struct( - compilation_artifacts = compilation_artifacts, - objc_provider = objc_provider, - objc_compilation_context = objc_compilation_context, - objc_linking_context = objc_linking_context, - ) - -def _build_aspect( - target, - ctx, - j2objc_source, - direct_j2objc_mapping_file_provider, - dep_attributes, - proto_toolchain_runtime): - intermediate_artifacts = j2objc_create_intermediate_artifacts(ctx = ctx) - if j2objc_source.objc_srcs: - common = _common( - ctx = ctx, - intermediate_artifacts = intermediate_artifacts, - transpiled_sources = j2objc_source.objc_srcs, - transpiled_headers = j2objc_source.objc_hdrs, - header_search_paths = j2objc_source.header_search_paths, - dependent_attributes = dep_attributes, - other_deps = proto_toolchain_runtime, - compile_with_arc = j2objc_source.compile_with_arc, - ) - - cc_toolchain = cc_helper.find_cpp_toolchain(ctx) - - if j2objc_source.compile_with_arc: - extra_compile_args = ["-fno-strict-overflow", "-fobjc-arc-exceptions"] - else: - extra_compile_args = ["-fno-strict-overflow", "-fobjc-weak"] - - compilation_result = compilation_support.register_compile_and_archive_actions_for_j2objc( - ctx = ctx, - toolchain = cc_toolchain, - intermediate_artifacts = intermediate_artifacts, - compilation_artifacts = common.compilation_artifacts, - objc_compilation_context = common.objc_compilation_context, - cc_linking_contexts = common.objc_linking_context.cc_linking_contexts, - extra_compile_args = extra_compile_args, - ) - cc_compilation_context = compilation_result[0] - cc_linking_context = compilation_result[1] - else: - common = _common( - ctx = ctx, - intermediate_artifacts = intermediate_artifacts, - transpiled_sources = [], - transpiled_headers = [], - header_search_paths = [], - dependent_attributes = dep_attributes, - other_deps = proto_toolchain_runtime, - compile_with_arc = j2objc_source.compile_with_arc, - ) - - cc_compilation_context = create_cc_compilation_context(common.objc_compilation_context) - cc_linking_context = cc_common.merge_linking_contexts( - linking_contexts = common.objc_linking_context.cc_linking_contexts, - ) - - return [ - _exported_j2objc_mapping_file_provider(target, ctx, direct_j2objc_mapping_file_provider), - common.objc_provider, - CcInfo( - compilation_context = cc_compilation_context, - linking_context = cc_linking_context, - ), - ] - -def _j2objc_aspect_impl(target, ctx): - if ProtoInfo in target: - return _proto(target, ctx) - return _java(target, ctx) - -j2objc_aspect = aspect( - implementation = _j2objc_aspect_impl, - attr_aspects = ["deps", "exports", "runtime_deps"], - attrs = { - "_use_auto_exec_groups": attr.bool(default = True), - "_j2objc": attr.label( - cfg = "exec", - allow_single_file = True, - default = "@" + cc_semantics.get_repo() + "//tools/j2objc:j2objc_deploy.jar", - ), - "_j2objc_wrapper": attr.label( - cfg = "exec", - executable = True, - default = "@" + cc_semantics.get_repo() + "//tools/j2objc:j2objc_wrapper_binary", - ), - "_j2objc_header_map": attr.label( - cfg = "exec", - executable = True, - default = "@" + cc_semantics.get_repo() + "//tools/j2objc:j2objc_header_map_binary", - ), - "_jre_emul_jar": attr.label( - cfg = "exec", - allow_single_file = True, - default = Label("@" + cc_semantics.get_repo() + "//third_party/java/j2objc:jre_emul.jar"), - ), - "_jre_emul_module": attr.label( - cfg = "exec", - allow_files = True, - default = Label("@" + cc_semantics.get_repo() + "//third_party/java/j2objc:jre_emul_module"), - ), - "_dead_code_report": attr.label( - allow_single_file = True, - cfg = "exec", - default = configuration_field( - name = "dead_code_report", - fragment = "j2objc", - ), - ), - "_jre_lib": attr.label( - allow_files = True, - default = Label("@" + cc_semantics.get_repo() + "//third_party/java/j2objc:jre_core_lib"), - ), - "_j2objc_proto_toolchain": attr.label( - default = configuration_field(fragment = "proto", name = "proto_toolchain_for_j2objc"), - ), - }, - required_providers = [[JavaInfo], [ProtoInfo]], - provides = [apple_common.Objc, CcInfo], - toolchains = [java_semantics.JAVA_TOOLCHAIN_TYPE] + cc_helper.use_cpp_toolchain() + cc_semantics.get_runtimes_toolchain(), - fragments = ["apple", "cpp", "j2objc", "objc", "proto"], -) diff --git a/src/main/starlark/builtins_bzl/common/objc/j2objc_library.bzl b/src/main/starlark/builtins_bzl/common/objc/j2objc_library.bzl deleted file mode 100644 index a7fd4ac0bc24bc..00000000000000 --- a/src/main/starlark/builtins_bzl/common/objc/j2objc_library.bzl +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright 2023 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -Definition of j2objc_library rule. -""" - -load(":common/cc/cc_common.bzl", "cc_common") -load(":common/cc/cc_helper.bzl", "cc_helper") -load(":common/cc/cc_info.bzl", "CcInfo") -load(":common/cc/semantics.bzl", "semantics") -load(":common/objc/compilation_support.bzl", "compilation_support") -load(":common/objc/j2objc_aspect.bzl", "j2objc_aspect") -load(":common/objc/objc_compilation_context_info.bzl", "create_cc_compilation_context") -load(":common/objc/providers.bzl", "J2ObjcEntryClassInfo", "J2ObjcMappingFileInfo") -load(":common/objc/semantics.bzl", objc_semantics = "semantics") - -_MIGRATION_TAG = "__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__" - -def _jre_deps_aspect_impl(_, ctx): - if "j2objc_jre_lib" not in ctx.rule.attr.tags: - fail("in jre_deps attribute of j2objc_library rule: objc_library rule '%s' is misplaced here (Only J2ObjC JRE libraries are allowed)" % - str(ctx.label).removeprefix("@")) - return [] - -jre_deps_aspect = aspect( - implementation = _jre_deps_aspect_impl, -) - -def _check_entry_classes(ctx): - entry_classes = ctx.attr.entry_classes - remove_dead_code = ctx.fragments.j2objc.remove_dead_code() - if remove_dead_code and not entry_classes: - fail("Entry classes must be specified when flag --compilation_mode=opt is on in order to perform J2ObjC dead code stripping.") - -def _entry_class_provider(entry_classes, deps): - transitive_entry_classes = [dep[J2ObjcEntryClassInfo].entry_classes for dep in deps if J2ObjcEntryClassInfo in dep] - return J2ObjcEntryClassInfo(entry_classes = depset(entry_classes, transitive = transitive_entry_classes)) - -def _mapping_file_provider(deps): - infos = [dep[J2ObjcMappingFileInfo] for dep in deps if J2ObjcMappingFileInfo in dep] - transitive_header_mapping_files = [info.header_mapping_files for info in infos] - transitive_class_mapping_files = [info.class_mapping_files for info in infos] - transitive_dependency_mapping_files = [info.dependency_mapping_files for info in infos] - transitive_archive_source_mapping_files = [info.archive_source_mapping_files for info in infos] - - return J2ObjcMappingFileInfo( - header_mapping_files = depset([], transitive = transitive_header_mapping_files), - class_mapping_files = depset([], transitive = transitive_class_mapping_files), - dependency_mapping_files = depset([], transitive = transitive_dependency_mapping_files), - archive_source_mapping_files = depset([], transitive = transitive_archive_source_mapping_files), - ) - -def j2objc_library_lockdown(ctx): - if not ctx.fragments.j2objc.j2objc_library_migration(): - return - if _MIGRATION_TAG not in ctx.attr.tags: - fail("j2objc_library is locked. Please do not use this rule since it will be deleted in the future.") - -def _j2objc_library_impl(ctx): - j2objc_library_lockdown(ctx) - - _check_entry_classes(ctx) - - common_variables = compilation_support.build_common_variables( - ctx = ctx, - toolchain = None, - deps = ctx.attr.deps + ctx.attr.jre_deps, - empty_compilation_artifacts = True, - direct_cc_compilation_contexts = [dep[CcInfo].compilation_context for dep in ctx.attr.deps if CcInfo in dep], - ) - - cc_compilation_context = create_cc_compilation_context(common_variables.objc_compilation_context) - return [ - _entry_class_provider(ctx.attr.entry_classes, ctx.attr.deps), - _mapping_file_provider(ctx.attr.deps), - common_variables.objc_provider, - CcInfo( - compilation_context = cc_compilation_context, - linking_context = cc_common.merge_linking_contexts(linking_contexts = common_variables.objc_linking_context.cc_linking_contexts), - ), - ] - -j2objc_library = rule( - _j2objc_library_impl, - doc = """ -

This rule uses J2ObjC to translate Java source -files to Objective-C, which then can be used used as dependencies of objc_library and objc_binary -rules. Detailed information about J2ObjC itself can be found at the -J2ObjC site -

-

Custom J2ObjC transpilation flags can be specified using the build flag ---j2objc_translation_flags in the command line. -

-

Please note that the translated files included in a j2objc_library target will be -compiled using the default compilation configuration, the same configuration as for the sources of -an objc_library rule with no compilation options specified in attributes. -

-

Plus, generated code is de-duplicated at target level, not source level. If you have two -different Java targets that include the same Java source files, you may see a duplicate symbol error -at link time. The correct way to resolve this issue is to move the shared Java source files into a -separate common target that can be depended upon. -

- """, - attrs = { - "deps": attr.label_list( - allow_rules = ["j2objc_library", "java_library", "java_import", "java_proto_library"], - aspects = [j2objc_aspect], - doc = """ -A list of j2objc_library, java_library, -java_import and java_proto_library targets that contain -Java files to be transpiled to Objective-C. -

All java_library and java_import targets that can be reached -transitively through exports, deps and runtime_deps -will be translated and compiled, including files generated by Java annotation processing. -There is no support for code>java_import targets with no srcjar -specified. -

-

The J2ObjC translation works differently depending on the type of source Java source -files included in the transitive closure. For each .java source files included in -srcs of java_library, a corresponding .h and .m source file -will be generated. For each source jar included in srcs of -java_library or srcjar of java_import, a -corresponding .h and .m source file will be generated with all the code for that jar. -

-

Users can import the J2ObjC-generated header files in their code. The import paths for -these files are the root-relative path of the original Java artifacts. For example, -//some/package/foo.java has an import path of some/package/foo.h -and //some/package/bar.srcjar has some/package/bar.h -

-If proto_library rules are in the transitive closure of this rule, J2ObjC protos will also -be generated, compiled and linked-in at the binary level. For proto -//some/proto/foo.proto, users can reference the generated code using import -path some/proto/foo.j2objc.pb.h. -

""", - ), - "entry_classes": attr.string_list(doc = """ -The list of Java classes whose translated ObjC counterparts will be referenced directly -by user ObjC code. This attribute is required if flag --j2objc_dead_code_removal - is on. The Java classes should be specified in their canonical names as defined by -the Java -Language Specification. -When flag --j2objc_dead_code_removal is specified, the list of entry classes -will be collected transitively and used as entry points to perform dead code analysis. -Unused classes will then be removed from the final ObjC app bundle."""), - "jre_deps": attr.label_list( - allow_rules = ["objc_library"], - aspects = [jre_deps_aspect], - doc = """ -The list of additional JRE emulation libraries required by all Java code translated by this -j2objc_library rule. Only core JRE functionality is linked by default.""", - ), - }, - cfg = objc_semantics.apple_crosstool_transition, - fragments = ["apple", "cpp", "j2objc", "objc"] + semantics.additional_fragments(), - toolchains = cc_helper.use_cpp_toolchain(), - provides = [CcInfo, J2ObjcEntryClassInfo, J2ObjcMappingFileInfo], -) diff --git a/src/main/starlark/builtins_bzl/common/python/py_runtime_macro.bzl b/src/main/starlark/builtins_bzl/common/python/py_runtime_macro.bzl deleted file mode 100644 index 6b27bccfcc1feb..00000000000000 --- a/src/main/starlark/builtins_bzl/common/python/py_runtime_macro.bzl +++ /dev/null @@ -1,22 +0,0 @@ -# Copyright 2022 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Macro to wrap the py_runtime rule.""" - -load(":common/python/py_runtime_rule.bzl", py_runtime_rule = "py_runtime") - -# NOTE: The function name is purposefully selected to match the underlying -# rule name so that e.g. 'generator_function' shows as the same name so -# that it is less confusing to users. -def py_runtime(**kwargs): - py_runtime_rule(**kwargs) diff --git a/src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl b/src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl deleted file mode 100644 index 97e2793cb7787e..00000000000000 --- a/src/main/starlark/builtins_bzl/common/python/py_runtime_rule.bzl +++ /dev/null @@ -1,214 +0,0 @@ -# Copyright 2022 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -"""Implementation of py_runtime rule.""" - -load(":common/paths.bzl", "paths") -load(":common/python/attributes.bzl", "NATIVE_RULES_ALLOWLIST_ATTRS") -load(":common/python/common.bzl", "check_native_allowed") -load(":common/python/providers.bzl", "DEFAULT_BOOTSTRAP_TEMPLATE", "DEFAULT_STUB_SHEBANG", _PyRuntimeInfo = "PyRuntimeInfo") - -_py_builtins = _builtins.internal.py_builtins - -def _py_runtime_impl(ctx): - check_native_allowed(ctx) - interpreter_path = ctx.attr.interpreter_path or None # Convert empty string to None - interpreter = ctx.file.interpreter - if (interpreter_path and interpreter) or (not interpreter_path and not interpreter): - fail("exactly one of the 'interpreter' or 'interpreter_path' attributes must be specified") - - runtime_files = depset(transitive = [ - t[DefaultInfo].files - for t in ctx.attr.files - ]) - - hermetic = bool(interpreter) - if not hermetic: - if runtime_files: - fail("if 'interpreter_path' is given then 'files' must be empty") - if not paths.is_absolute(interpreter_path): - fail("interpreter_path must be an absolute path") - - if ctx.attr.coverage_tool: - coverage_di = ctx.attr.coverage_tool[DefaultInfo] - - if _py_builtins.is_singleton_depset(coverage_di.files): - coverage_tool = coverage_di.files.to_list()[0] - elif coverage_di.files_to_run and coverage_di.files_to_run.executable: - coverage_tool = coverage_di.files_to_run.executable - else: - fail("coverage_tool must be an executable target or must produce exactly one file.") - - coverage_files = depset(transitive = [ - coverage_di.files, - coverage_di.default_runfiles.files, - ]) - else: - coverage_tool = None - coverage_files = None - - python_version = ctx.attr.python_version - if python_version == "_INTERNAL_SENTINEL": - if ctx.fragments.py.use_toolchains: - fail( - "When using Python toolchains, this attribute must be set explicitly to either 'PY2' " + - "or 'PY3'. See https://github.com/bazelbuild/bazel/issues/7899 for more " + - "information. You can temporarily avoid this error by reverting to the legacy " + - "Python runtime mechanism (`--incompatible_use_python_toolchains=false`).", - ) - else: - python_version = ctx.fragments.py.default_python_version - - # TODO: Uncomment this after --incompatible_python_disable_py2 defaults to true - # if ctx.fragments.py.disable_py2 and python_version == "PY2": - # fail("Using Python 2 is not supported and disabled; see " + - # "https://github.com/bazelbuild/bazel/issues/15684") - - return [ - _PyRuntimeInfo( - interpreter_path = interpreter_path or None, - interpreter = interpreter, - files = runtime_files if hermetic else None, - coverage_tool = coverage_tool, - coverage_files = coverage_files, - python_version = python_version, - stub_shebang = ctx.attr.stub_shebang, - bootstrap_template = ctx.file.bootstrap_template, - ), - DefaultInfo( - files = runtime_files, - runfiles = ctx.runfiles(), - ), - ] - -# Bind to the name "py_runtime" to preserve the kind/rule_class it shows up -# as elsewhere. -py_runtime = rule( - implementation = _py_runtime_impl, - doc = """ -Represents a Python runtime used to execute Python code. - -A `py_runtime` target can represent either a *platform runtime* or an *in-build -runtime*. A platform runtime accesses a system-installed interpreter at a known -path, whereas an in-build runtime points to an executable target that acts as -the interpreter. In both cases, an "interpreter" means any executable binary or -wrapper script that is capable of running a Python script passed on the command -line, following the same conventions as the standard CPython interpreter. - -A platform runtime is by its nature non-hermetic. It imposes a requirement on -the target platform to have an interpreter located at a specific path. An -in-build runtime may or may not be hermetic, depending on whether it points to -a checked-in interpreter or a wrapper script that accesses the system -interpreter. - -# Example - -``` -py_runtime( - name = "python-2.7.12", - files = glob(["python-2.7.12/**"]), - interpreter = "python-2.7.12/bin/python", -) - -py_runtime( - name = "python-3.6.0", - interpreter_path = "/opt/pyenv/versions/3.6.0/bin/python", -) -``` -""", - fragments = ["py"], - attrs = NATIVE_RULES_ALLOWLIST_ATTRS | { - "files": attr.label_list( - allow_files = True, - doc = """ -For an in-build runtime, this is the set of files comprising this runtime. -These files will be added to the runfiles of Python binaries that use this -runtime. For a platform runtime this attribute must not be set. -""", - ), - "interpreter": attr.label( - allow_single_file = True, - doc = """ -For an in-build runtime, this is the target to invoke as the interpreter. For a -platform runtime this attribute must not be set. -""", - ), - "interpreter_path": attr.string(doc = """ -For a platform runtime, this is the absolute path of a Python interpreter on -the target platform. For an in-build runtime this attribute must not be set. -"""), - "coverage_tool": attr.label( - allow_files = False, - doc = """ -This is a target to use for collecting code coverage information from `py_binary` -and `py_test` targets. - -If set, the target must either produce a single file or be an executable target. -The path to the single file, or the executable if the target is executable, -determines the entry point for the python coverage tool. The target and its -runfiles will be added to the runfiles when coverage is enabled. - -The entry point for the tool must be loadable by a Python interpreter (e.g. a -`.py` or `.pyc` file). It must accept the command line arguments -of coverage.py (https://coverage.readthedocs.io), at least including -the `run` and `lcov` subcommands. -""", - ), - "python_version": attr.string( - default = "_INTERNAL_SENTINEL", - values = ["PY2", "PY3", "_INTERNAL_SENTINEL"], - doc = """ -Whether this runtime is for Python major version 2 or 3. Valid values are `"PY2"` -and `"PY3"`. - -The default value is controlled by the `--incompatible_py3_is_default` flag. -However, in the future this attribute will be mandatory and have no default -value. - """, - ), - "stub_shebang": attr.string( - default = DEFAULT_STUB_SHEBANG, - doc = """ -"Shebang" expression prepended to the bootstrapping Python stub script -used when executing `py_binary` targets. - -See https://github.com/bazelbuild/bazel/issues/8685 for -motivation. - -Does not apply to Windows. -""", - ), - "bootstrap_template": attr.label( - allow_single_file = True, - default = DEFAULT_BOOTSTRAP_TEMPLATE, - doc = """ -The bootstrap script template file to use. Should have %python_binary%, -%workspace_name%, %main%, and %imports%. - -This template, after expansion, becomes the executable file used to start the -process, so it is responsible for initial bootstrapping actions such as finding -the Python interpreter, runfiles, and constructing an environment to run the -intended Python application. - -While this attribute is currently optional, it will become required when the -Python rules are moved out of Bazel itself. - -The exact variable names expanded is an unstable API and is subject to change. -The API will become more stable when the Python rules are moved out of Bazel -itself. - -See @bazel_tools//tools/python:python_bootstrap_template.txt for more variables. -""", - ), - }, -) diff --git a/src/main/starlark/builtins_bzl/common/python/semantics.bzl b/src/main/starlark/builtins_bzl/common/python/semantics.bzl index 487ff303ef9f33..d05b877798702a 100644 --- a/src/main/starlark/builtins_bzl/common/python/semantics.bzl +++ b/src/main/starlark/builtins_bzl/common/python/semantics.bzl @@ -13,8 +13,6 @@ # limitations under the License. """Contains constants that vary between Bazel and Google-internal""" -IMPORTS_ATTR_SUPPORTED = True - TOOLS_REPO = "bazel_tools" PLATFORMS_LOCATION = "@platforms/" @@ -22,13 +20,5 @@ SRCS_ATTR_ALLOW_FILES = [".py", ".py3"] DEPS_ATTR_ALLOW_RULES = None -PY_RUNTIME_ATTR_NAME = "_py_interpreter" - -BUILD_DATA_SYMLINK_PATH = None - -IS_BAZEL = True - NATIVE_RULES_MIGRATION_HELP_URL = "https://github.com/bazelbuild/bazel/issues/17773" NATIVE_RULES_MIGRATION_FIX_CMD = "add_python_loads" - -ALLOWED_MAIN_EXTENSIONS = [".py"] diff --git a/src/main/starlark/docgen/objc.bzl b/src/main/starlark/docgen/objc.bzl index 38253cddc82621..9749d4ab54945c 100644 --- a/src/main/starlark/docgen/objc.bzl +++ b/src/main/starlark/docgen/objc.bzl @@ -21,7 +21,6 @@ binary_rules = struct( library_rules = struct( objc_library = native.objc_library, objc_import = native.objc_import, - j2objc_library = native.j2objc_library, ) test_rules = struct( diff --git a/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java b/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java index 0d2db28283f27e..6d825239798863 100644 --- a/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java +++ b/src/test/java/com/google/devtools/build/lib/actions/ResourceManagerTest.java @@ -95,17 +95,17 @@ public void configureResourceManager() throws Exception { } private ResourceHandle acquire(double ram, double cpu, int tests, ResourcePriority priority) - throws InterruptedException, IOException { + throws InterruptedException, IOException, ExecException { return manager.acquireResources(resourceOwner, ResourceSet.create(ram, cpu, tests), priority); } private ResourceHandle acquire(double ram, double cpu, int tests) - throws InterruptedException, IOException { + throws InterruptedException, IOException, ExecException { return acquire(ram, cpu, tests, ResourcePriority.LOCAL); } private ResourceHandle acquire(double ram, double cpu, int tests, String mnemonic) - throws InterruptedException, IOException { + throws InterruptedException, IOException, ExecException { return manager.acquireResources( resourceOwner, @@ -123,7 +123,7 @@ private ResourceHandle acquire( ImmutableMap extraResources, int tests, ResourcePriority priority) - throws InterruptedException, IOException, NoSuchElementException { + throws InterruptedException, IOException, NoSuchElementException, ExecException { ImmutableMap.Builder resources = ImmutableMap.builder(); resources.putAll(extraResources).put(ResourceSet.MEMORY, ram).put(ResourceSet.CPU, cpu); return manager.acquireResources( @@ -133,7 +133,7 @@ private ResourceHandle acquire( @CanIgnoreReturnValue private ResourceHandle acquire( double ram, double cpu, ImmutableMap extraResources, int tests) - throws InterruptedException, IOException, NoSuchElementException { + throws InterruptedException, IOException, NoSuchElementException, ExecException { return acquire(ram, cpu, extraResources, tests, ResourcePriority.LOCAL); } @@ -665,7 +665,7 @@ public void testNonexistingResource() throws Exception { new TestThread( () -> assertThrows( - NoSuchElementException.class, + UserExecException.class, () -> acquire(0, 0, ImmutableMap.of("nonexisting", 1.0), 0))); thread1.start(); thread1.joinAndAssertState(1000); @@ -688,7 +688,7 @@ public void testAcquireWithWorker_acquireAndRelease() throws Exception { } @Test - public void testInvalidateAndClose() throws IOException, InterruptedException { + public void testInvalidateAndClose() throws IOException, InterruptedException, ExecException { ResourceHandle handle; verify(workerStatus, times(0)).maybeUpdateStatus(any()); diff --git a/src/test/java/com/google/devtools/build/lib/analysis/SymbolicMacroTest.java b/src/test/java/com/google/devtools/build/lib/analysis/SymbolicMacroTest.java index 18dc31877aefa3..2ce82243dc566b 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/SymbolicMacroTest.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/SymbolicMacroTest.java @@ -685,6 +685,11 @@ public void macroCannotCallExistingRules() throws Exception { doCannotCallApiTest("existing_rules()", "native.existing_rules()"); } + @Test + public void macroCannotCallEnvironmentRuleFunction() throws Exception { + doCannotCallApiTest("environment rule", "native.environment(name = 'foo')"); + } + // There are other symbols that must not be called from within symbolic macros, but we don't test // them because they can't be obtained from a symbolic macro implementation anyway, since they are // not under `native` (at least, for BUILD-loaded .bzl files) and because symbolic macros can't diff --git a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java index 0f5a0f40ff34f6..9458fabe367b9c 100644 --- a/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java +++ b/src/test/java/com/google/devtools/build/lib/analysis/mock/BazelAnalysisMock.java @@ -172,7 +172,6 @@ public void setupMockClient(MockToolsConfig config, List workspaceConten "rules_java_workspace", "rules_python_workspace", "protobuf_workspace", - "third_party/bazel_rules/rules_proto", "build_bazel_apple_support", "local_config_xcode_workspace", "third_party/bazel_rules/rules_cc"); @@ -662,9 +661,6 @@ function rlocation() { config.create("embedded_tools/objcproto/empty.cc"); config.create("embedded_tools/objcproto/well_known_type.proto"); - config.create("third_party/bazel_rules/rules_proto/WORKSPACE"); - config.create("third_party/bazel_rules/rules_proto/MODULE.bazel", "module(name='rules_proto')"); - // Copies bazel_skylib from real @bazel_skylib (needed by rules_python) PathFragment path = PathFragment.create(runfiles.rlocation("bazel_skylib/lib/paths.bzl")); config.copyDirectory( @@ -841,7 +837,6 @@ public ImmutableMap getBuiltinModules(BlazeDirector .put("rules_python_internal", "rules_python_internal_workspace") .put("bazel_skylib", "bazel_skylib_workspace") .put("protobuf", "protobuf_workspace") - .put("rules_proto", "third_party/bazel_rules/rules_proto") .put("build_bazel_apple_support", "build_bazel_apple_support") .put("local_config_xcode", "local_config_xcode_workspace") .put("rules_cc", "third_party/bazel_rules/rules_cc") diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyBinaryConfiguredTargetTest.java b/src/test/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyBinaryConfiguredTargetTest.java index b778e35c6be070..0629e05a71500f 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyBinaryConfiguredTargetTest.java +++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/python/BazelPyBinaryConfiguredTargetTest.java @@ -37,9 +37,6 @@ @RunWith(JUnit4.class) public class BazelPyBinaryConfiguredTargetTest extends BuildViewTestCase { - private static final String TOOLCHAIN_BZL = - TestConstants.TOOLS_REPOSITORY + "//tools/python:toolchain.bzl"; - private static final String TOOLCHAIN_TYPE = TestConstants.TOOLS_REPOSITORY + "//tools/python:toolchain_type"; @@ -194,7 +191,8 @@ public void pythonTopTakesPrecedenceOverPythonPath() throws Exception { private void defineToolchains() throws Exception { scratch.file( "toolchains/BUILD", - "load('" + TOOLCHAIN_BZL + "', 'py_runtime_pair')", + getPyLoad("py_runtime"), + getPyLoad("py_runtime_pair"), "py_runtime(", " name = 'py3_runtime',", " interpreter_path = '/system/python3',", diff --git a/src/test/java/com/google/devtools/build/lib/blackbox/framework/BUILD b/src/test/java/com/google/devtools/build/lib/blackbox/framework/BUILD index d860a82e67e39c..0b78774c979167 100644 --- a/src/test/java/com/google/devtools/build/lib/blackbox/framework/BUILD +++ b/src/test/java/com/google/devtools/build/lib/blackbox/framework/BUILD @@ -45,7 +45,6 @@ gen_workspace_stanza( preamble = "load('@bazel_tools//tools/build_defs/repo:http.bzl', 'http_archive')", repos = [ "rules_cc", - "rules_proto", "rules_python", ], visibility = ["//visibility:private"], diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java b/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java index 572a5711bf26b5..49d2f22ce2ca13 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java +++ b/src/test/java/com/google/devtools/build/lib/packages/util/BazelMockPythonSupport.java @@ -14,6 +14,7 @@ package com.google.devtools.build.lib.packages.util; +import static com.google.devtools.build.lib.rules.python.PythonTestUtils.getPyLoad; import static java.lang.Integer.MAX_VALUE; import com.google.devtools.build.lib.analysis.Runfiles; @@ -46,8 +47,9 @@ public void setup(MockToolsConfig config) throws IOException { config.create( TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/python/BUILD", "package(default_visibility=['//visibility:public'])", + getPyLoad("py_runtime"), + getPyLoad("py_runtime_pair"), "load(':python_version.bzl', 'define_python_version_flag')", - "load('//tools/python:toolchain.bzl', 'py_runtime_pair')", "define_python_version_flag(", " name = 'python_version',", ")", @@ -77,7 +79,7 @@ public void setup(MockToolsConfig config) throws IOException { " toolchain = ':default_py_runtime_pair',", " toolchain_type = ':toolchain_type',", ")", - "exports_files(['precompile.py'])"); + "exports_files(['precompile.py', 'python_bootstrap_template.txt'])"); // Copies and mock rules_python from real @rules_python com.google.devtools.build.runfiles.Runfiles runfiles = @@ -94,9 +96,11 @@ public void setup(MockToolsConfig config) throws IOException { config.overwrite("rules_python_workspace/MODULE.bazel", "module(name = 'rules_python')"); config.overwrite( "rules_python_workspace/python/private/BUILD", + "load('@bazel_skylib//rules:common_settings.bzl', 'bool_setting')", "filegroup(name = 'stage2_bootstrap_template', srcs = ['stage2_bootstrap_template.py'])", "filegroup(name = 'zip_main_template', srcs = ['zip_main_template.py'])", - "filegroup(name = 'bootstrap_template', srcs = ['python_bootstrap_template.txt'])"); + "filegroup(name = 'bootstrap_template', srcs = ['python_bootstrap_template.txt'])", + "bool_setting(name = 'visible_for_testing', build_setting_default = False)"); config.overwrite("rules_python_workspace/python/private/common/BUILD"); config.overwrite( "rules_python_workspace/python/config_settings/BUILD", @@ -107,7 +111,7 @@ public void setup(MockToolsConfig config) throws IOException { "string_flag(name = 'precompile_source_retention', build_setting_default = 'auto')", "string_flag(name = 'bootstrap_impl', build_setting_default = 'system_python')", "string_flag(name = 'precompile_add_to_runfiles', build_setting_default = 'always')"); - + config.overwrite("rules_python_workspace/python/private/python_bootstrap_template.txt"); config.overwrite("rules_python_workspace/tools/build_defs/python/private/BUILD"); config.overwrite("rules_python_workspace/tools/launcher/BUILD", "filegroup(name = 'launcher')"); diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/MockJ2ObjcSupport.java b/src/test/java/com/google/devtools/build/lib/packages/util/MockJ2ObjcSupport.java deleted file mode 100644 index f5e0dc4c452bed..00000000000000 --- a/src/test/java/com/google/devtools/build/lib/packages/util/MockJ2ObjcSupport.java +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.packages.util; - -import static com.google.devtools.build.lib.rules.python.PythonTestUtils.getPyLoad; - -import com.google.devtools.build.lib.testutil.TestConstants; -import java.io.IOException; - -/** Creates mock BUILD files required for J2Objc. */ -public final class MockJ2ObjcSupport { - /** Setup the support for building with J2ObjC. */ - public static void setup(MockToolsConfig config) throws IOException { - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/jre_emul.jar"); - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/mod/release"); - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/mod/lib/mods"); - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/jre.h"); - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/jre.m"); - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/runtime.h"); - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/runtime.m"); - config.create( - TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/proto_plugin_binary"); - config.create( - TestConstants.TOOLS_REPOSITORY_SCRATCH + "third_party/java/j2objc/BUILD", - "package(default_visibility=['//visibility:public'])", - "licenses(['notice'])", - "", - "exports_files(['jre_emul.jar'])", - "", - "filegroup(", - " name = 'jre_emul_module',", - " srcs = ['mod/release', 'mod/lib/mods'])", - "", - "objc_library(", - " name = 'jre_emul_lib',", - " hdrs = ['jre_emul.h'],", - " srcs = ['jre_emul.m'],", - " deps = [':jre_core_lib', ':jre_io_lib'],", - " tags = ['j2objc_jre_lib'])", - "", - "objc_library(", - " name = 'jre_core_lib',", - " hdrs = ['jre_core.h'],", - " srcs = ['jre_core.m'],", - " tags = ['j2objc_jre_lib'])", - "", - "objc_library(", - " name = 'jre_io_lib',", - " hdrs = ['jre_io.h'],", - " srcs = ['jre_io.m'],", - " deps = [':jre_core_lib'],", - " tags = ['j2objc_jre_lib'])", - "", - "objc_library(", - " name = 'proto_runtime',", - " hdrs = ['runtime.h'],", - " srcs = ['runtime.m'])", - "", - "filegroup(", - " name = 'proto_plugin',", - " srcs = ['proto_plugin_binary'])"); - - config.create( - TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/BUILD", - TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, - getPyLoad("py_binary"), - "package(default_visibility=['//visibility:public'])", - "licenses(['notice'])", - "py_binary(", - " name = 'j2objc_wrapper_binary',", - " srcs = ['j2objc_wrapper_binary.py'],", - ")", - "py_binary(", - " name = 'j2objc_header_map_binary',", - " srcs = ['j2objc_header_map_binary.py'],", - ")", - "proto_lang_toolchain(", - " name = 'j2objc_proto_toolchain',", - " blacklisted_protos = [':j2objc_proto_blacklist'],", - " command_line = '--PLUGIN_j2objc_out=file_dir_mapping,generate_class_mappings:$(OUT)',", - " plugin_format_flag = '--plugin=protoc-gen-PLUGIN_j2objc=%s', ", - " visibility = ['//visibility:public'],", - " plugin = '//third_party/java/j2objc:proto_plugin',", - " runtime = '//third_party/java/j2objc:proto_runtime',", - " progress_message = 'Generating j2objc proto_library %{label}',", - ")", - "exports_files([", - " 'j2objc_deploy.jar',", - "])", - "proto_library(", - " name = 'j2objc_proto_blacklist',", - " deps = [", - " '" + TestConstants.TOOLS_REPOSITORY + "//tools/j2objc/proto:blacklisted'", - " ])"); - - config.create( - TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/proto/BUILD", - TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, - "package(default_visibility=['//visibility:public'])", - "proto_library(name = 'blacklisted',", - " srcs = ['blacklisted.proto'])"); - - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/proto/blacklisted.proto"); - - if (config.isRealFileSystem()) { - config.linkTool(TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/j2objc_deploy.jar"); - config.linkTool( - TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/j2objc_wrapper_binary"); - config.linkTool( - TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/j2objc_header_map_binary"); - } else { - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/j2objc_deploy.jar"); - config.create(TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/j2objc_wrapper_binary"); - config.create( - TestConstants.TOOLS_REPOSITORY_SCRATCH + "tools/j2objc/j2objc_header_map_binary"); - } - } -} diff --git a/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java b/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java index 74d970daa2b9b8..e0dc9d11f5a3c4 100644 --- a/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java +++ b/src/test/java/com/google/devtools/build/lib/query2/testutil/AbstractQueryTest.java @@ -1757,11 +1757,6 @@ protected void useReducedSetOfRules() throws Exception { helper.writeFile( "/workspace/build_bazel_apple_support/MODULE.bazel", "module(name='build_bazel_apple_support')"); - helper.writeFile("/workspace/third_party/bazel_rules/rules_proto/BUILD"); - helper.writeFile("/workspace/third_party/bazel_rules/rules_proto/WORKSPACE"); - helper.writeFile( - "/workspace/third_party/bazel_rules/rules_proto/MODULE.bazel", - "module(name='rules_proto')"); helper.writeFile("/workspace/third_party/bazel_rules/rules_cc/BUILD"); helper.writeFile("/workspace/third_party/bazel_rules/rules_cc/WORKSPACE"); helper.writeFile( diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java index 241902a3c12afd..28c701109e6af7 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CompileBuildVariablesTest.java @@ -103,6 +103,48 @@ public void testPresenceOfUserCompileFlags() throws Exception { assertThat(copts).contains("-foo"); } + @Test + public void testPresenceOfConlyFlags() throws Exception { + useConfiguration( + "--conlyopt=-foo", "--cxxopt=-not-passed", "--per_file_copt=//x:bin@-per-file"); + + scratch.file( + "x/BUILD", + "cc_binary(name = 'bin', srcs = ['bin.c'], copts = ['-bar'], conlyopts = ['-baz'], cxxopts" + + " = ['-not-passed'])"); + scratch.file("x/bin.c"); + + CcToolchainVariables variables = getCompileBuildVariables("//x:bin", "bin"); + + ImmutableList copts = + CcToolchainVariables.toStringList( + variables, CompileBuildVariables.USER_COMPILE_FLAGS.getVariableName(), PathMapper.NOOP); + assertThat(copts) + .containsExactlyElementsIn(ImmutableList.of("-foo", "-bar", "-baz", "-per-file")) + .inOrder(); + } + + @Test + public void testCxxFlagsOrder() throws Exception { + useConfiguration( + "--cxxopt=-foo", "--conlyopt=-not-passed", "--per_file_copt=//x:bin@-per-file"); + + scratch.file( + "x/BUILD", + "cc_binary(name = 'bin', srcs = ['bin.cc'], copts = ['-bar'], cxxopts = ['-baz'], conlyopts" + + " = ['-not-passed'])"); + scratch.file("x/bin.cc"); + + CcToolchainVariables variables = getCompileBuildVariables("//x:bin", "bin"); + + ImmutableList copts = + CcToolchainVariables.toStringList( + variables, CompileBuildVariables.USER_COMPILE_FLAGS.getVariableName(), PathMapper.NOOP); + assertThat(copts) + .containsExactlyElementsIn(ImmutableList.of("-foo", "-bar", "-baz", "-per-file")) + .inOrder(); + } + @Test public void testPerFileCoptsAreInUserCompileFlags() throws Exception { scratch.file("x/BUILD", "cc_binary(name = 'bin', srcs = ['bin.cc'])"); diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/BUILD b/src/test/java/com/google/devtools/build/lib/rules/objc/BUILD index 19762bf4b632f9..9f88551c086b4c 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/BUILD +++ b/src/test/java/com/google/devtools/build/lib/rules/objc/BUILD @@ -13,65 +13,9 @@ filegroup( visibility = ["//src:__subpackages__"], ) -java_test( - name = "BazelJ2ObjcLibraryTest", - tags = ["no_windows"], - runtime_deps = [":BazelJ2ObjcLibraryTest_lib"], -) - -java_library( - name = "BazelJ2ObjcLibraryTest_lib", - srcs = ["BazelJ2ObjcLibraryTest.java"], - deps = [ - ":J2ObjcLibraryTest", - "//src/main/java/com/google/devtools/build/lib/actions", - "//src/main/java/com/google/devtools/build/lib/actions:artifacts", - "//src/main/java/com/google/devtools/build/lib/actions:thread_state_receiver", - "//src/main/java/com/google/devtools/build/lib/analysis:actions/parameter_file_write_action", - "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster", - "//src/main/java/com/google/devtools/build/lib/analysis:configured_target", - "//src/main/java/com/google/devtools/build/lib/cmdline", - "//src/main/java/com/google/devtools/build/lib/collect/nestedset", - "//src/main/java/com/google/devtools/build/lib/packages", - "//src/main/java/com/google/devtools/build/lib/rules/cpp", - "//src/main/java/com/google/devtools/build/lib/skyframe:bzl_load_value", - "//src/main/java/com/google/devtools/build/lib/vfs", - "//src/main/java/com/google/devtools/build/lib/vfs:pathfragment", - "//src/test/java/com/google/devtools/build/lib/actions/util", - "//src/test/java/com/google/devtools/build/lib/packages:testutil", - "//src/test/java/com/google/devtools/build/lib/rules/python:PythonTestUtils", - "//src/test/java/com/google/devtools/build/lib/testutil:TestConstants", - "//third_party:guava", - "//third_party:jsr305", - "//third_party:junit4", - "//third_party:truth", - ], -) - -java_library( - name = "J2ObjcLibraryTest", - srcs = ["J2ObjcLibraryTest.java"], - deps = [ - ":ObjcRulesTests_lib", - "//src/main/java/com/google/devtools/build/lib/actions:artifact_expander", - "//src/main/java/com/google/devtools/build/lib/actions:artifacts", - "//src/main/java/com/google/devtools/build/lib/analysis:configured_target", - "//src/test/java/com/google/devtools/build/lib/packages:testutil", - "//src/test/java/com/google/devtools/build/lib/testutil:TestConstants", - "//third_party:guava", - "//third_party:junit4", - ], -) - java_library( name = "ObjcRulesTests_lib", - srcs = glob( - ["*.java"], - exclude = [ - "J2ObjcLibraryTest.java", - "BazelJ2ObjcLibraryTest.java", - ], - ), + srcs = glob(["*.java"]), deps = [ "//src/main/java/com/google/devtools/build/lib/actions", "//src/main/java/com/google/devtools/build/lib/actions:action_lookup_data", diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java deleted file mode 100644 index 52d1d00aa73d7e..00000000000000 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/BazelJ2ObjcLibraryTest.java +++ /dev/null @@ -1,1453 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.rules.objc; - -import static com.google.common.truth.Truth.assertThat; -import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.baseArtifactNames; -import static com.google.devtools.build.lib.actions.util.ActionsTestUtil.getFirstArtifactEndingWith; -import static com.google.devtools.build.lib.rules.python.PythonTestUtils.getPyLoad; -import static com.google.devtools.build.lib.skyframe.BzlLoadValue.keyForBuiltins; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import com.google.devtools.build.lib.actions.Action; -import com.google.devtools.build.lib.actions.ActionAnalysisMetadata; -import com.google.devtools.build.lib.actions.ActionExecutionContext; -import com.google.devtools.build.lib.actions.ActionExecutionContext.LostInputsCheck; -import com.google.devtools.build.lib.actions.ActionExecutionException; -import com.google.devtools.build.lib.actions.ActionInputPrefetcher; -import com.google.devtools.build.lib.actions.Artifact; -import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; -import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; -import com.google.devtools.build.lib.actions.CommandAction; -import com.google.devtools.build.lib.actions.CommandLineLimits; -import com.google.devtools.build.lib.actions.CommandLines.ExpandedCommandLines; -import com.google.devtools.build.lib.actions.DiscoveredModulesPruner; -import com.google.devtools.build.lib.actions.PathMapper; -import com.google.devtools.build.lib.actions.ThreadStateReceiver; -import com.google.devtools.build.lib.actions.util.ActionsTestUtil; -import com.google.devtools.build.lib.analysis.ConfiguredTarget; -import com.google.devtools.build.lib.analysis.actions.ParameterFileWriteAction; -import com.google.devtools.build.lib.analysis.actions.SpawnAction; -import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget; -import com.google.devtools.build.lib.cmdline.Label; -import com.google.devtools.build.lib.cmdline.RepositoryName; -import com.google.devtools.build.lib.collect.nestedset.Depset; -import com.google.devtools.build.lib.packages.Provider; -import com.google.devtools.build.lib.packages.StarlarkInfo; -import com.google.devtools.build.lib.packages.StarlarkProvider; -import com.google.devtools.build.lib.packages.StructImpl; -import com.google.devtools.build.lib.packages.util.MockObjcSupport; -import com.google.devtools.build.lib.rules.cpp.CcCompilationContext; -import com.google.devtools.build.lib.rules.cpp.CcInfo; -import com.google.devtools.build.lib.rules.cpp.CcLinkingContext; -import com.google.devtools.build.lib.rules.cpp.CppCompileAction; -import com.google.devtools.build.lib.rules.cpp.CppCompileActionTemplate; -import com.google.devtools.build.lib.rules.cpp.CppModuleMapAction; -import com.google.devtools.build.lib.rules.cpp.CppRuleClasses; -import com.google.devtools.build.lib.rules.cpp.UmbrellaHeaderAction; -import com.google.devtools.build.lib.testutil.TestConstants; -import com.google.devtools.build.lib.vfs.PathFragment; -import com.google.devtools.build.lib.vfs.SyscallCache; -import java.io.ByteArrayOutputStream; -import java.util.Optional; -import java.util.regex.Pattern; -import javax.annotation.Nullable; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Unit test for Java source file translation into ObjC in java_library and translated - * file compilation and linking in {@link ObjcBinary} and {@link J2ObjcLibrary}. - */ -@RunWith(JUnit4.class) -public class BazelJ2ObjcLibraryTest extends J2ObjcLibraryTest { - - private static final Provider.Key starlarkJ2objcMappingFileProviderKey = - new StarlarkProvider.Key( - keyForBuiltins(Label.parseCanonicalUnchecked("@_builtins//:common/objc/providers.bzl")), - "J2ObjcMappingFileInfo"); - - private StructImpl getJ2ObjcMappingFileInfoFromTarget(ConfiguredTarget configuredTarget) - throws Exception { - return (StructImpl) configuredTarget.get(starlarkJ2objcMappingFileProviderKey); - } - - private ImmutableList getArtifacts(StructImpl j2ObjcMappingFileInfo, String attribute) - throws Exception { - Depset filesDepset = (Depset) j2ObjcMappingFileInfo.getValue(attribute); - return filesDepset.toList(Artifact.class); - } - - @Test - public void testJ2ObjCInformationExportedFromJ2ObjcLibrary() throws Exception { - ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget( - "//java/com/google/dummy/test:transpile"); - - CcLinkingContext ccLinkingContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .containsExactly("libjre_core_lib.a", "libtest_j2objc.lo"); - - CcCompilationContext ccCompilationContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(baseArtifactNames(ccCompilationContext.getDeclaredIncludeSrcs())) - .containsExactly("jre_core.h", "test.h"); - - String execPath = getRuleContext(j2objcLibraryTarget).getBinFragment() + "/"; - assertThat( - Iterables.transform( - ccCompilationContext.getIncludeDirs(), PathFragment::getSafePathString)) - .containsExactly(execPath + "java/com/google/dummy/test/_j2objc/test"); - } - - @Test - public void testJ2ObjCAspectDisablesParseHeaders() throws Exception { - MockObjcSupport.setupCcToolchainConfig( - mockToolsConfig, MockObjcSupport.darwinX86_64().withFeatures(CppRuleClasses.PARSE_HEADERS)); - useConfiguration("--features=parse_headers", "--process_headers_in_dependencies"); - - ConfiguredTarget j2objcAspectTarget = - getJ2ObjCAspectConfiguredTarget("//java/com/google/dummy/test:test"); - CcCompilationContext ccCompilationContext = - j2objcAspectTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - - assertThat(baseArtifactNames(ccCompilationContext.getHeaderTokens().toList())) - .doesNotContain("test.h.processed"); - } - - @Test - public void testJ2ObjCInformationExportedWithGeneratedJavaSources() throws Exception { - scratch.file("java/com/google/test/in.txt"); - scratch.file( - "java/com/google/test/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - genrule( - name = "dummy_gen", - srcs = ["in.txt"], - outs = ["test.java"], - cmd = "dummy", - ) - - java_library( - name = "test", - srcs = [":test.java"], - ) - - j2objc_library( - name = "transpile", - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - deps = ["test"], - ) - """); - - ConfiguredTarget target = getConfiguredTarget("//java/com/google/test:transpile"); - - CcLinkingContext ccLinkingContext = target.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .containsExactly("libjre_core_lib.a", "libtest_j2objc.lo"); - - CcCompilationContext ccCompilationContext = - target.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(baseArtifactNames(ccCompilationContext.getDeclaredIncludeSrcs())) - .containsExactly("jre_core.h", "test.h"); - - String execPath = getRuleContext(target).getBinFragment() + "/"; - String genfilesFragment = getRuleContext(target).getGenfilesFragment().toString(); - assertThat( - Iterables.transform( - ccCompilationContext.getIncludeDirs(), PathFragment::getSafePathString)) - .containsExactly( - execPath + "java/com/google/test/_j2objc/test/" + genfilesFragment, - execPath + "java/com/google/test/_j2objc/test"); - } - - @Test - public void testJ2ObjcProtoRuntimeLibraryAndHeadersExported() throws Exception { - scratch.file("java/com/google/dummy/test/proto/test.java"); - scratch.file("java/com/google/dummy/test/proto/test.proto"); - scratch.file( - "java/com/google/dummy/test/proto/BUILD", - TestConstants.LOAD_PROTO_LIBRARY, - "package(default_visibility=['//visibility:public'])", - "proto_library(", - " name = 'test_proto',", - " srcs = ['test.proto'],", - ")", - "java_proto_library(", - " name = 'test_java_proto',", - " deps = [':test_proto'],", - ")", - "java_library(", - " name = 'test',", - " srcs = ['test.java'],", - " deps = [':test_java_proto']", - ")", - "j2objc_library(", - " name = 'transpile',", - " deps = ['test'],", - " tags = ['__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__'],", - ")"); - - ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget( - "//java/com/google/dummy/test/proto:transpile"); - - CcLinkingContext ccLinkingContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .containsExactly( - "libjre_core_lib.a", - "libproto_runtime.a", - "libtest_j2objc.lo", - "libtest_proto_j2objc.lo"); - - CcCompilationContext ccCompilationContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(baseArtifactNames(ccCompilationContext.getDeclaredIncludeSrcs())) - .containsExactly("jre_core.h", "runtime.h", "test.j2objc.pb.h", "test.h"); - } - - @Test - public void testJ2ObjcHeaderMapExportedInJavaLibrary() throws Exception { - scratch.file( - "java/com/google/transpile/BUILD", - """ - java_library( - name = "dummy", - srcs = ["dummy.java"], - ) - """); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//java/com/google/transpile:dummy"); - StructImpl j2ObjcMappingFileInfo = getJ2ObjcMappingFileInfoFromTarget(target); - ImmutableList headerMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "header_mapping_files"); - - assertThat(headerMappingFilesList.get(0).getRootRelativePath().toString()) - .isEqualTo("java/com/google/transpile/dummy.mapping.j2objc"); - } - - @Test - public void testDepsJ2ObjcHeaderMapExportedInJavaLibraryWithNoSourceFile() throws Exception { - scratch.file( - "java/com/google/transpile/BUILD", - """ - java_library( - name = "dummy", - exports = ["//java/com/google/dep"], - ) - """); - scratch.file( - "java/com/google/dep/BUILD", - """ - java_library( - name = "dep", - srcs = ["dummy.java"], - ) - """); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//java/com/google/transpile:dummy"); - StructImpl j2ObjcMappingFileInfo = getJ2ObjcMappingFileInfoFromTarget(target); - ImmutableList headerMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "header_mapping_files"); - - assertThat(headerMappingFilesList.get(0).getRootRelativePath().toString()) - .isEqualTo("java/com/google/dep/dep.mapping.j2objc"); - } - - @Test - public void testJ2ObjcProtoClassMappingFilesExportedInJavaLibrary() throws Exception { - scratch.file("java/com/google/dummy/test/proto/test.java"); - scratch.file("java/com/google/dummy/test/proto/test.proto"); - scratch.file( - "java/com/google/dummy/test/proto/BUILD", - TestConstants.LOAD_PROTO_LIBRARY, - "package(default_visibility=['//visibility:public'])", - "proto_library(", - " name = 'test_proto',", - " srcs = ['test.proto'],", - ")", - "java_proto_library(", - " name = 'test_java_proto',", - " deps = [':test_proto'],", - ")", - "java_library(", - " name = 'test',", - " srcs = ['test.java'],", - " deps = [':test_java_proto']", - ")"); - useConfiguration( - "--proto_toolchain_for_java=//tools/proto/toolchains:java", - "--platforms=" + MockObjcSupport.DARWIN_X86_64, - "--apple_platform_type=macos", - "--experimental_platform_in_output_dir"); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget( - "//java/com/google/dummy/test/proto:test"); - StructImpl j2ObjcMappingFileInfo = getJ2ObjcMappingFileInfoFromTarget(target); - ImmutableList classMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "class_mapping_files"); - - assertThat(classMappingFilesList.get(0).getExecPathString()) - .containsMatch( - "/darwin_x86_64-fastbuild/bin/java/com/google/dummy/test/proto/test.clsmap.properties"); - } - - @Test - public void testJavaProtoLibraryWithProtoLibrary() throws Exception { - scratch.file( - "x/BUILD", - TestConstants.LOAD_PROTO_LIBRARY, - "proto_library(", - " name = 'test_proto',", - " srcs = ['test.proto'],", - ")", - "java_proto_library(", - " name = 'test_java_proto',", - " deps = [':test_proto'],", - ")", - "java_library(", - " name = 'test',", - " srcs = ['test.java'],", - " deps = [':test_java_proto']", - ")"); - useConfiguration( - "--proto_toolchain_for_java=//tools/proto/toolchains:java", - "--platforms=" + MockObjcSupport.DARWIN_X86_64, - "--apple_platform_type=macos", - "--experimental_platform_in_output_dir"); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//x:test"); - StructImpl j2ObjcMappingFileInfo = getJ2ObjcMappingFileInfoFromTarget(target); - ImmutableList classMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "class_mapping_files"); - assertThat(classMappingFilesList.get(0).getExecPathString()) - .containsMatch("/darwin_x86_64-fastbuild/bin/x/test.clsmap.properties"); - - StarlarkInfo objcProvider = getObjcInfo(target); - CcCompilationContext ccCompilationContext = - target.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(ccCompilationContext.getDeclaredIncludeSrcs().toList().toString()) - .containsMatch("/darwin_x86_64-fastbuild/bin]x/test.j2objc.pb.h"); - assertThat(getSource(objcProvider).toString()) - .containsMatch("/darwin_x86_64-fastbuild/bin]x/test.j2objc.pb.m,"); - } - - @Test - public void testJavaProtoLibraryWithProtoLibrary_external() throws Exception { - scratch.file("/bla/MODULE.bazel", "module(name='bla')"); - // Create the rule '@bla//foo:test_proto'. - scratch.file( - "/bla/foo/BUILD", - TestConstants.LOAD_PROTO_LIBRARY, - "package(default_visibility=['//visibility:public'])", - "proto_library(", - " name = 'test_proto',", - " srcs = ['test.proto'],", - ")", - "java_proto_library(", - " name = 'test_java_proto',", - " deps = [':test_proto'])", - ""); - - scratch.appendFile( - "MODULE.bazel", - "bazel_dep(name='bla')", - "local_path_override(module_name = 'bla', path = '/bla/')"); - invalidatePackages(); // A dash of magic to re-evaluate the WORKSPACE file. - - scratch.file( - "x/BUILD", - """ - java_library( - name = "test", - srcs = ["test.java"], - deps = ["@bla//foo:test_java_proto"], - ) - """); - useConfiguration( - "--proto_toolchain_for_java=//tools/proto/toolchains:java", - "--platforms=" + MockObjcSupport.DARWIN_X86_64, - "--apple_platform_type=macos", - "--experimental_platform_in_output_dir"); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//x:test"); - - StructImpl j2ObjcMappingFileInfo = getJ2ObjcMappingFileInfoFromTarget(target); - ImmutableList classMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "class_mapping_files"); - - assertThat(classMappingFilesList.get(0).getExecPathString()) - .containsMatch("/darwin_x86_64-fastbuild/bin/external/bla\\+/foo/test.clsmap.properties"); - - StarlarkInfo objcProvider = getObjcInfo(target); - CcCompilationContext ccCompilationContext = - target.get(CcInfo.PROVIDER).getCcCompilationContext(); - - assertThat(ccCompilationContext.getDeclaredIncludeSrcs().toList().toString()) - .containsMatch("/darwin_x86_64-fastbuild/bin]external/bla\\+/foo/test.j2objc.pb.h"); - assertThat(getSource(objcProvider).toString()) - .containsMatch("/darwin_x86_64-fastbuild/bin]external/bla\\+/foo/test.j2objc.pb.m"); - assertThat(ccCompilationContext.getIncludeDirs()) - .contains( - getConfiguration(target) - .getGenfilesFragment(RepositoryName.create("bla+")) - .getRelative("external/bla+")); - } - - @Test - public void testJ2ObjcInfoExportedInJavaImport() throws Exception { - scratch.file( - "java/com/google/transpile/BUILD", - """ - java_import( - name = "dummy", - jars = ["dummy.jar"], - srcjar = "dummy.srcjar", - ) - """); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//java/com/google/transpile:dummy"); - StructImpl j2ObjcMappingFileInfo = getJ2ObjcMappingFileInfoFromTarget(target); - ImmutableList headerMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "header_mapping_files"); - ImmutableList classMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "class_mapping_files"); - - assertThat(headerMappingFilesList.get(0).getRootRelativePath().toString()) - .isEqualTo("java/com/google/transpile/dummy.mapping.j2objc"); - assertThat(classMappingFilesList).isEmpty(); - } - - protected Artifact getBinArtifact(String outputName, RuleConfiguredTarget target) { - for (ActionAnalysisMetadata action : target.getActions()) { - Optional artifact = - action.getOutputs().stream().filter(artifactNamed(outputName)).findFirst(); - if (artifact.isPresent()) { - return artifact.get(); - } - } - return null; - } - - protected void checkObjcArchiveAndLinkActions( - String archiveFileName, String objFileName, Iterable compilationInputExecPaths) - throws Exception { - CommandAction linkAction = - (CommandAction) - getGeneratingAction( - getBinArtifact( - "app/app_bin", (RuleConfiguredTarget) getConfiguredTarget("//app:app"))); - - checkObjcCompileActions( - getFirstArtifactEndingWith(linkAction.getInputs(), archiveFileName), - objFileName, compilationInputExecPaths); - } - - @Test - public void testMissingEntryClassesError() throws Exception { - useConfiguration("--j2objc_dead_code_removal"); - checkError( - "java/com/google/dummy", - "transpile", - "Entry classes must be specified when flag --compilation_mode=opt is on in order to perform" - + " J2ObjC dead code stripping.", - "j2objc_library(", - " name = 'transpile',", - " deps = ['//java/com/google/dummy/test:test'],", - " tags = ['__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__'],", - ")"); - } - - @Test - public void testNoJ2ObjcDeadCodeRemovalActionWithoutOptFlag() throws Exception { - useConfiguration("--noj2objc_dead_code_removal"); - addSimpleJ2ObjcLibraryWithEntryClasses(); - addAppleBinaryStarlarkRule(scratch); - addSimpleBinaryTarget("//java/com/google/app/test:transpile"); - - Artifact expectedPrunedSource = getBinArtifact( - "_j2objc_pruned/app/java/com/google/app/test/_j2objc/test/" - + "java/com/google/app/test/test_pruned.m", getConfiguredTarget("//app:app")); - assertThat(getGeneratingAction(expectedPrunedSource)).isNull(); - } - - @Test - public void testExplicitJreDeps() throws Exception { - ConfiguredTarget j2objcLibraryTarget = getConfiguredTarget( - "//java/com/google/dummy/test:transpile"); - - CcLinkingContext ccLinkingContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .containsExactly("libjre_core_lib.a", "libtest_j2objc.lo"); - - CcCompilationContext ccCompilationContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(baseArtifactNames(ccCompilationContext.getDeclaredIncludeSrcs())) - .containsExactly("jre_core.h", "test.h"); - } - - @Test - public void testTagInJreDeps() throws Exception { - scratch.file( - "app/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - objc_library( - name = "no_tag_dep", - ) - - j2objc_library( - name = "test", - jre_deps = ["no_tag_dep"], - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - ) - """); - reporter.removeHandler(failFastHandler); - - getConfiguredTarget("//app:test"); - - assertContainsEvent( - Pattern.compile( - ".* objc_library rule \\'@//app:no_tag_dep\\' is misplaced here \\(Only J2ObjC JRE" - + " libraries are allowed\\)")); - } - - @Test - public void testTranspilationActionTreeArtifactOutputsFromSourceJar() throws Exception { - useConfiguration("--ios_minimum_os=1.0"); - scratch.file("java/com/google/transpile/dummy.java"); - scratch.file("java/com/google/transpile/dummyjar.srcjar"); - scratch.file( - "java/com/google/transpile/BUILD", - """ - java_library( - name = "dummy", - srcs = [ - "dummy.java", - "dummyjar.srcjar", - ], - ) - """); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//java/com/google/transpile:dummy"); - StarlarkInfo provider = getObjcInfo(target); - CcCompilationContext ccCompilationContext = - target.get(CcInfo.PROVIDER).getCcCompilationContext(); - Artifact srcJarSources = getFirstArtifactEndingWith(getSource(provider), "source_files"); - Artifact srcJarHeaders = - getFirstArtifactEndingWith(ccCompilationContext.getDeclaredIncludeSrcs(), "header_files"); - assertThat(srcJarSources.getRootRelativePathString()) - .isEqualTo("java/com/google/transpile/_j2objc/src_jar_files/dummy/source_files"); - assertThat(srcJarHeaders.getRootRelativePathString()) - .isEqualTo("java/com/google/transpile/_j2objc/src_jar_files/dummy/header_files"); - assertThat(srcJarSources.isTreeArtifact()).isTrue(); - assertThat(srcJarHeaders.isTreeArtifact()).isTrue(); - } - - @Test - public void testGeneratedTreeArtifactFromGenJar() throws Exception { - useConfiguration("--ios_minimum_os=1.0"); - addSimpleJ2ObjcLibraryWithJavaPlugin(); - ConfiguredTarget j2objcLibraryTarget = - getConfiguredTarget("//java/com/google/app/test:transpile"); - StarlarkInfo provider = getObjcInfo(j2objcLibraryTarget); - CcCompilationContext ccCompilationContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - Artifact headers = - getFirstArtifactEndingWith(ccCompilationContext.getDeclaredIncludeSrcs(), "header_files"); - Artifact sources = getFirstArtifactEndingWith(getSource(provider), "source_files"); - assertThat(headers.isTreeArtifact()).isTrue(); - assertThat(sources.isTreeArtifact()).isTrue(); - - SpawnAction j2objcAction = (SpawnAction) getGeneratingAction(headers); - assertThat(j2objcAction.getOutputs()).containsAtLeast(headers, sources); - - assertContainsSublist( - ImmutableList.copyOf(paramFileArgsForAction(j2objcAction)), - ImmutableList.of( - "--output_gen_source_dir", - sources.getExecPathString(), - "--output_gen_header_dir", - headers.getExecPathString())); - } - - @Test - public void testJ2ObjcHeaderMappingAction() throws Exception { - scratch.file( - "java/com/google/transpile/BUILD", - """ - java_library( - name = "lib1", - srcs = [ - "jar.srcjar", - "libOne.java", - ], - deps = [":lib2"], - ) - - java_library( - name = "lib2", - srcs = ["libTwo.java"], - ) - """); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget( - "//java/com/google/transpile:lib1"); - StructImpl j2ObjcMappingFileInfo = getJ2ObjcMappingFileInfoFromTarget(target); - ImmutableList headerMappingFilesList = - getArtifacts(j2ObjcMappingFileInfo, "header_mapping_files"); - assertThat(baseArtifactNames(headerMappingFilesList)) - .containsExactly("lib1.mapping.j2objc", "lib2.mapping.j2objc"); - - Artifact mappingFile = - getFirstArtifactEndingWith(headerMappingFilesList, "lib1.mapping.j2objc"); - SpawnAction headerMappingAction = (SpawnAction) getGeneratingAction(mappingFile); - String execPath = getRuleContext(target).getBinFragment() + "/"; - assertThat(baseArtifactNames(headerMappingAction.getInputs())) - .containsAtLeast("libOne.java", "jar.srcjar"); - assertThat(headerMappingAction.getArguments().get(0)) - .contains("tools/j2objc/j2objc_header_map_binary"); - assertThat(headerMappingAction.getArguments().get(1)).isEqualTo("--source_files"); - assertThat(headerMappingAction.getArguments().get(2)) - .isEqualTo("java/com/google/transpile/libOne.java"); - assertThat(headerMappingAction.getArguments().get(3)).isEqualTo("--source_jars"); - assertThat(headerMappingAction.getArguments().get(4)) - .isEqualTo("java/com/google/transpile/jar.srcjar"); - assertThat(headerMappingAction.getArguments().get(5)).isEqualTo("--output_mapping_file"); - assertThat(headerMappingAction.getArguments().get(6)) - .isEqualTo(execPath + "java/com/google/transpile/lib1.mapping.j2objc"); - } - - protected void checkObjcCompileActions( - Artifact archiveFile, String objFileName, Iterable compilationInputExecPaths) - throws Exception { - CommandAction compileAction = getObjcCompileAction(archiveFile, objFileName); - assertThat(baseArtifactNames(compileAction.getPossibleInputsForTesting())) - .containsAtLeastElementsIn(compilationInputExecPaths); - } - - protected CommandAction getObjcCompileAction(Artifact archiveFile, String objFileName) - throws Exception { - CommandAction archiveAction = (CommandAction) getGeneratingAction(archiveFile); - CommandAction compileAction = - (CommandAction) - getGeneratingAction(getFirstArtifactEndingWith(archiveAction.getInputs(), objFileName)); - return compileAction; - } - - protected void addSimpleBinaryTarget(String j2objcLibraryTargetDep) throws Exception { - scratch.file("app/app.m"); - scratch.file("app/Info.plist"); - scratch.file( - "app/BUILD", - "load('//test_starlark:apple_binary_starlark.bzl', 'apple_binary_starlark')", - "package(default_visibility=['//visibility:public'])", - "objc_library(", - " name = 'lib',", - " deps = ['" + j2objcLibraryTargetDep + "'])", - "", - "apple_binary_starlark(", - " name = 'app',", - " platform_type = 'ios',", - " deps = [':main_lib'],", - ")", - "objc_library(", - " name = 'main_lib',", - " srcs = ['app.m'],", - " deps = [':lib'],", - ")"); - } - - protected void addSimpleJ2ObjcLibraryWithEntryClasses() throws Exception { - scratch.file("java/com/google/app/test/test.java"); - scratch.file( - "java/com/google/app/test/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - java_library( - name = "test", - srcs = ["test.java"], - ) - - j2objc_library( - name = "transpile", - entry_classes = ["com.google.app.test.test"], - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - deps = ["test"], - ) - """); - } - - protected void addSimpleJ2ObjcLibraryWithJavaPlugin() throws Exception { - scratch.file("java/com/google/app/test/test.java"); - scratch.file("java/com/google/app/test/plugin.java"); - scratch.file( - "java/com/google/app/test/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - java_library( - name = "test", - srcs = ["test.java"], - plugins = [":plugin"], - ) - - java_plugin( - name = "plugin", - srcs = ["plugin.java"], - processor_class = "com.google.process.stuff", - ) - - j2objc_library( - name = "transpile", - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - deps = [":test"], - ) - """); - } - - protected Artifact j2objcArchive(String j2objcLibraryTarget, String javaTargetName) - throws Exception { - ConfiguredTarget target = getConfiguredTarget(j2objcLibraryTarget); - CcLinkingContext ccLinkingContext = target.get(CcInfo.PROVIDER).getCcLinkingContext(); - String archiveName = String.format("lib%s_j2objc.lo", javaTargetName); - return getFirstArtifactEndingWith( - ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries(), archiveName); - } - - @Test - public void testJ2ObjcInformationExportedFromObjcLibrary() throws Exception { - scratch.file("app/lib.m"); - scratch.file( - "app/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - objc_library( - name = "lib", - srcs = ["lib.m"], - deps = ["//java/com/google/dummy/test:transpile"], - ) - """); - - ConfiguredTarget objcTarget = getConfiguredTarget("//app:lib"); - - CcLinkingContext ccLinkingContext = objcTarget.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .containsExactly("libjre_core_lib.a", "libtest_j2objc.lo", "liblib.a"); - - CcCompilationContext ccCompilationContext = - objcTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(baseArtifactNames(ccCompilationContext.getDeclaredIncludeSrcs())) - .containsExactly("jre_core.h", "test.h"); - - String execPath = getRuleContext(objcTarget).getBinFragment() + "/"; - assertThat( - Iterables.transform( - ccCompilationContext.getIncludeDirs(), PathFragment::getSafePathString)) - .containsExactly(execPath + "java/com/google/dummy/test/_j2objc/test"); - } - - @Test - public void testJ2ObjcInfoExportedInObjcLibraryFromRuntimeDeps() throws Exception { - scratch.file("app/lib.m"); - scratch.file( - "app/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - java_library( - name = "dummyOne", - srcs = ["dummyOne.java"], - ) - - java_library( - name = "dummyTwo", - srcs = ["dummyTwo.java"], - runtime_deps = [":dummyOne"], - ) - - j2objc_library( - name = "transpile", - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - deps = [":dummyTwo"], - ) - - objc_library( - name = "lib", - srcs = ["lib.m"], - deps = ["//app:transpile"], - ) - """); - - ConfiguredTarget objcTarget = getConfiguredTarget("//app:lib"); - - CcLinkingContext ccLinkingContext = objcTarget.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .containsExactly( - "libjre_core_lib.a", "libdummyOne_j2objc.lo", "libdummyTwo_j2objc.lo", "liblib.a"); - - CcCompilationContext ccCompilationContext = - objcTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(baseArtifactNames(ccCompilationContext.getDeclaredIncludeSrcs())) - .containsExactly("jre_core.h", "dummyOne.h", "dummyTwo.h"); - - String execPath = getRuleContext(objcTarget).getBinFragment() + "/"; - assertThat( - Iterables.transform( - ccCompilationContext.getIncludeDirs(), PathFragment::getSafePathString)) - .containsExactly(execPath + "app/_j2objc/dummyOne", execPath + "app/_j2objc/dummyTwo"); - } - - @Nullable - private ParameterFileWriteAction paramFileWriteActionForLinkAction(Action action) { - for (Artifact input : action.getInputs().toList()) { - if (!(input instanceof SpecialArtifact)) { - if (input.getFilename().endsWith("linker.objlist")) { - Action generatingAction = getGeneratingAction(input); - if (generatingAction instanceof ParameterFileWriteAction parameterFileWriteAction) { - return parameterFileWriteAction; - } - } - } - } - return null; - } - - @Test - public void testJ2ObjcAppearsInLinkArgs() throws Exception { - scratch.file( - "java/c/y/BUILD", - """ - java_library( - name = "ylib", - srcs = ["lib.java"], - ) - """); - addAppleBinaryStarlarkRule(scratch); - scratch.file( - "x/BUILD", - "load('//test_starlark:apple_binary_starlark.bzl', 'apple_binary_starlark')", - "j2objc_library(", - " name = 'j2',", - " deps = [ '//java/c/y:ylib' ],", - " tags = ['__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__'],", - " jre_deps = [ '" - + TestConstants.TOOLS_REPOSITORY - + "//third_party/java/j2objc:jre_io_lib' ],", - ")", - "apple_binary_starlark(", - " name = 'test',", - " platform_type = 'ios',", - " deps = [':main_lib'],", - ")", - "objc_library(", - " name = 'main_lib',", - " srcs = ['test.m'],", - " deps = [':j2'],", - ")"); - - CommandAction linkAction = linkAction("//x:test"); - ConfiguredTarget target = getConfiguredTarget("//x:test"); - String binDir = removeConfigFragment(getRuleContext(target).getBinFragment().toString()); - ParameterFileWriteAction paramAction = paramFileWriteActionForLinkAction(linkAction); - Iterable paramFileArgs = paramAction.getCommandLine().arguments(); - assertThat(removeConfigFragment(ImmutableList.copyOf(linkAction.getArguments()))) - .contains("-force_load " + binDir + "/java/c/y/libylib_j2objc.lo"); - assertThat(removeConfigFragment(ImmutableList.copyOf(paramFileArgs))) - .containsAtLeast( - // All jre libraries mus appear after java libraries in the link order. - binDir - + "/" - + TestConstants.TOOLS_REPOSITORY_PATH_PREFIX - + "third_party/java/j2objc/libjre_io_lib.a", - binDir - + "/" - + TestConstants.TOOLS_REPOSITORY_PATH_PREFIX - + "third_party/java/j2objc/libjre_core_lib.a") - .inOrder(); - } - - @Test - public void testArchiveLinkActionWithTreeArtifactFromGenJar() throws Exception { - useConfiguration("--ios_minimum_os=1.0"); - addSimpleJ2ObjcLibraryWithJavaPlugin(); - Artifact archive = j2objcArchive("//java/com/google/app/test:transpile", "test"); - SpawnAction archiveAction = (SpawnAction) getGeneratingAction(archive); - Artifact objectFilesFromGenJar = - getFirstArtifactEndingWith(archiveAction.getInputs(), "source_files"); - Artifact normalObjectFile = getFirstArtifactEndingWith(archiveAction.getInputs(), "test.o"); - - // Test that the archive commandline contains the individual object files inside - // the object file tree artifact. - ExpandedCommandLines expandedCommandLines = - archiveAction - .getCommandLines() - .expand( - DUMMY_ARTIFACT_EXPANDER, - archiveAction.getPrimaryOutput().getExecPath(), - PathMapper.NOOP, - CommandLineLimits.UNLIMITED); - - assertThat(expandedCommandLines.arguments()) - .containsAtLeast( - objectFilesFromGenJar.getExecPathString() + "/children1", - objectFilesFromGenJar.getExecPathString() + "/children2", - normalObjectFile.getExecPathString()); - } - - @Test - public void testJ2ObjCCustomModuleMap() throws Exception { - scratch.file("java/com/google/transpile/dummy.java"); - scratch.file( - "java/com/google/transpile/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - java_library( - name = "dummy", - srcs = ["dummy.java"], - ) - """); - - ConfiguredTarget target = getJ2ObjCAspectConfiguredTarget("//java/com/google/transpile:dummy"); - - StarlarkInfo provider = getObjcInfo(target); - Artifact moduleMap = - getFirstArtifactEndingWith(getModuleMap(provider), "dummy.modulemaps/module.modulemap"); - - Artifact umbrellaHeader = - getFirstArtifactEndingWith(getUmbrellaHeader(provider), "dummy.modulemaps/umbrella.h"); - - CppModuleMapAction moduleMapAction = (CppModuleMapAction) getGeneratingAction(moduleMap); - UmbrellaHeaderAction umbrellaHeaderAction = - (UmbrellaHeaderAction) getGeneratingAction(umbrellaHeader); - - ActionExecutionContext dummyActionExecutionContext = - new ActionExecutionContext( - /* executor= */ null, - /* inputMetadataProvider= */ null, - ActionInputPrefetcher.NONE, - actionKeyContext, - /* outputMetadataStore= */ null, - /* rewindingEnabled= */ false, - LostInputsCheck.NONE, - /* fileOutErr= */ null, - /* eventHandler= */ null, - /* clientEnv= */ ImmutableMap.of(), - /* topLevelFilesets= */ ImmutableMap.of(), - DUMMY_ARTIFACT_EXPANDER, - /* actionFileSystem= */ null, - /* skyframeDepsResult= */ null, - DiscoveredModulesPruner.DEFAULT, - SyscallCache.NO_CACHE, - ThreadStateReceiver.NULL_INSTANCE); - ByteArrayOutputStream moduleMapStream = new ByteArrayOutputStream(); - ByteArrayOutputStream umbrellaHeaderStream = new ByteArrayOutputStream(); - moduleMapAction.newDeterministicWriter(dummyActionExecutionContext) - .writeOutputFile(moduleMapStream); - umbrellaHeaderAction.newDeterministicWriter(dummyActionExecutionContext) - .writeOutputFile(umbrellaHeaderStream); - String moduleMapContent = moduleMapStream.toString(); - String umbrellaHeaderContent = umbrellaHeaderStream.toString(); - - assertThat(moduleMapContent).contains("umbrella header \"umbrella.h\""); - assertThat(umbrellaHeaderContent).contains("/dummy.h"); - assertThat(umbrellaHeaderContent).contains("#include"); - } - - @Test - public void testModuleMapFromGenJarTreeArtifact() throws Exception { - useConfiguration("--ios_minimum_os=1.0"); - addSimpleJ2ObjcLibraryWithJavaPlugin(); - ConfiguredTarget j2objcLibraryTarget = - getConfiguredTarget("//java/com/google/app/test:transpile"); - StarlarkInfo provider = getObjcInfo(j2objcLibraryTarget); - CcCompilationContext ccCompilationContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - Artifact moduleMap = - getFirstArtifactEndingWith(getModuleMap(provider), "test.modulemaps/module.modulemap"); - Artifact umbrellaHeader = - getFirstArtifactEndingWith(getUmbrellaHeader(provider), "test.modulemaps/umbrella.h"); - - CppModuleMapAction moduleMapAction = (CppModuleMapAction) getGeneratingAction(moduleMap); - UmbrellaHeaderAction umbrellaHeaderAction = - (UmbrellaHeaderAction) getGeneratingAction(umbrellaHeader); - Artifact headers = - getFirstArtifactEndingWith(ccCompilationContext.getDeclaredIncludeSrcs(), "header_files"); - - // Test that the module map action contains the header tree artifact as both the public header - // and part of the action inputs. - assertThat(moduleMapAction.getPublicHeaders()).contains(headers); - assertThat(moduleMapAction.getInputs().toList()).contains(headers); - - ActionExecutionContext dummyActionExecutionContext = - new ActionExecutionContext( - /* executor= */ null, - /* inputMetadataProvider= */ null, - ActionInputPrefetcher.NONE, - actionKeyContext, - /* outputMetadataStore= */ null, - /* rewindingEnabled= */ false, - LostInputsCheck.NONE, - /* fileOutErr= */ null, - /* eventHandler= */ null, - /* clientEnv= */ ImmutableMap.of(), - /* topLevelFilesets= */ ImmutableMap.of(), - DUMMY_ARTIFACT_EXPANDER, - /* actionFileSystem= */ null, - /* skyframeDepsResult= */ null, - DiscoveredModulesPruner.DEFAULT, - SyscallCache.NO_CACHE, - ThreadStateReceiver.NULL_INSTANCE); - - ByteArrayOutputStream moduleMapStream = new ByteArrayOutputStream(); - ByteArrayOutputStream umbrellaHeaderStream = new ByteArrayOutputStream(); - moduleMapAction - .newDeterministicWriter(dummyActionExecutionContext) - .writeOutputFile(moduleMapStream); - umbrellaHeaderAction - .newDeterministicWriter(dummyActionExecutionContext) - .writeOutputFile(umbrellaHeaderStream); - String moduleMapContent = moduleMapStream.toString(); - String umbrellaHeaderContent = umbrellaHeaderStream.toString(); - - // Test that the module map content contains the individual headers inside the header tree - // artifact. - assertThat(moduleMapContent).contains("umbrella header \"umbrella.h\""); - assertThat(umbrellaHeaderContent).contains(headers.getExecPathString() + "/children1"); - assertThat(umbrellaHeaderContent).contains(headers.getExecPathString() + "/children2"); - } - - @Test - public void testObjcCompileAction() throws Exception { - Artifact archive = j2objcArchive("//java/com/google/dummy/test:transpile", "test"); - CommandAction compileAction = getObjcCompileAction(archive, "test.o"); - assertThat(baseArtifactNames(compileAction.getPossibleInputsForTesting())) - .containsAtLeast("jre_core.h", "test.h", "test.m"); - assertThat(compileAction.getArguments()) - .containsAtLeast("-fno-objc-arc", "-fno-strict-overflow", "-fobjc-weak"); - } - - @Test - public void testObjcCompileArcAction() throws Exception { - useConfiguration("--j2objc_translation_flags=-use-arc"); - Artifact archive = j2objcArchive("//java/com/google/dummy/test:transpile", "test"); - CommandAction compileAction = getObjcCompileAction(archive, "test.o"); - assertThat(baseArtifactNames(compileAction.getPossibleInputsForTesting())) - .containsAtLeast("jre_core.h", "test.h", "test.m"); - assertThat(compileAction.getArguments()) - .containsAtLeast("-fobjc-arc", "-fobjc-arc-exceptions", "-fno-strict-overflow"); - } - - @Test - public void testJ2ObjcSourcesCompilationAndLinking() throws Exception { - addAppleBinaryStarlarkRule(scratch); - addSimpleBinaryTarget("//java/com/google/dummy/test:transpile"); - - checkObjcArchiveAndLinkActions( - "libtest_j2objc.lo", - "test.o", - ImmutableList.of("jre_core.h", "test.h", "test.m")); - } - - @Test - public void testNestedJ2ObjcLibraryDeps() throws Exception { - scratch.file("java/com/google/dummy/dummy.java"); - scratch.file( - "java/com/google/dummy/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - java_library( - name = "dummy", - srcs = ["dummy.java"], - ) - - j2objc_library( - name = "transpile", - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - deps = [ - ":dummy", - "//java/com/google/dummy/test:transpile", - ], - ) - """); - addAppleBinaryStarlarkRule(scratch); - addSimpleBinaryTarget("//java/com/google/dummy:transpile"); - - checkObjcArchiveAndLinkActions( - "libtest_j2objc.lo", - "test.o", - ImmutableList.of("jre_core.h", "test.h", "test.m")); - - checkObjcArchiveAndLinkActions( - "libdummy_j2objc.lo", - "dummy.o", - ImmutableList.of("jre_core.h", "dummy.h", "dummy.m")); - } - - // Tests that a j2objc library can acquire java library information from a Starlark rule target. - @Test - public void testJ2ObjcLibraryDepThroughStarlarkRule() throws Exception { - scratch.file("examples/inner.java"); - scratch.file("examples/outer.java"); - scratch.file( - "examples/fake_rule.bzl", - """ - def _fake_rule_impl(ctx): - myProvider = ctx.attr.deps[0][JavaInfo] - return myProvider - - fake_rule = rule( - implementation = _fake_rule_impl, - attrs = {"deps": attr.label_list()}, - provides = [JavaInfo], - ) - """); - scratch.file( - "examples/BUILD", - """ - load("//examples:fake_rule.bzl", "fake_rule") - - package(default_visibility = ["//visibility:public"]) - - java_library( - name = "inner", - srcs = ["inner.java"], - ) - - fake_rule( - name = "propagator", - deps = [":inner"], - ) - - java_library( - name = "outer", - srcs = ["outer.java"], - deps = [":propagator"], - ) - - j2objc_library( - name = "transpile", - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - deps = [ - ":outer", - ], - ) - - objc_library( - name = "lib", - srcs = ["lib.m"], - deps = [":transpile"], - ) - """); - - ConfiguredTarget objcTarget = getConfiguredTarget("//examples:lib"); - - // The only way that //examples:lib can see inner's archive is through the Starlark rule. - CcLinkingContext ccLinkingContext = objcTarget.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .contains("libinner_j2objc.lo"); - } - - @Test - public void testJ2ObjcTranspiledHeaderInCompilationAction() throws Exception { - scratch.file("app/lib.m"); - scratch.file( - "app/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - objc_library( - name = "lib", - srcs = ["lib.m"], - deps = ["//java/com/google/dummy/test:transpile"], - ) - """); - - checkObjcCompileActions( - getBinArtifact("liblib.a", getConfiguredTarget("//app:lib")), - "lib.o", - ImmutableList.of("test.h")); - } - - @Test - public void testProtoToolchainForJ2ObjcFlag() throws Exception { - useConfiguration( - "--proto_toolchain_for_java=//tools/proto/toolchains:java", - "--proto_toolchain_for_j2objc=//tools/j2objc:alt_j2objc_proto_toolchain"); - - scratch.file("tools/j2objc/proto_plugin_binary"); - scratch.file("tools/j2objc/alt_proto_runtime.h"); - scratch.file("tools/j2objc/alt_proto_runtime.m"); - scratch.file("tools/j2objc/proto_to_exclude.proto"); - - scratch.overwriteFile( - "tools/j2objc/BUILD", - TestConstants.LOAD_PROTO_LIBRARY, - TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, - "package(default_visibility=['//visibility:public'])", - "exports_files(['j2objc_deploy.jar'])", - getPyLoad("py_binary"), - "py_binary(", - " name = 'j2objc_wrapper_binary',", - " srcs = ['j2objc_wrapper_binary.py'],", - ")", - "proto_library(", - " name = 'excluded_protos',", - " srcs = ['proto_to_exclude.proto'],", - ")", - "py_binary(", - " name = 'j2objc_header_map_binary',", - " srcs = ['j2objc_header_map_binary.py'],", - ")", - "proto_lang_toolchain(", - " name = 'alt_j2objc_proto_toolchain',", - " command_line = '--PLUGIN_j2objc_out=file_dir_mapping,generate_class_mappings:$(OUT)',", - " plugin_format_flag = '--plugin=protoc-gen-PLUGIN_j2objc=%s', ", - " plugin = ':alt_proto_plugin',", - " runtime = ':alt_proto_runtime',", - " blacklisted_protos = [':excluded_protos'],", - ")", - "proto_library(", - " name = 'excluded_proto_library',", - " srcs = ['proto_to_exclude.proto'],", - ")", - "objc_library(", - " name = 'alt_proto_runtime',", - " hdrs = ['alt_proto_runtime.h'],", - " srcs = ['alt_proto_runtime.m'],", - ")", - "filegroup(", - " name = 'alt_proto_plugin',", - " srcs = ['proto_plugin_binary']", - ")"); - - scratch.file("java/com/google/dummy/test/proto/test.java"); - scratch.file("java/com/google/dummy/test/proto/test.proto"); - scratch.file( - "java/com/google/dummy/test/proto/BUILD", - TestConstants.LOAD_PROTO_LIBRARY, - "package(default_visibility=['//visibility:public'])", - "proto_library(", - " name = 'test_proto',", - " srcs = ['test.proto'],", - " deps = ['//tools/j2objc:excluded_proto_library'],", - ")", - "java_proto_library(", - " name = 'test_java_proto',", - " deps = [':test_proto'],", - ")", - "java_library(", - " name = 'test',", - " srcs = ['test.java'],", - " deps = [':test_java_proto'])", - "", - "j2objc_library(", - " name = 'transpile',", - " tags = ['__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__'],", - " deps = ['test'])"); - - ConfiguredTarget j2objcLibraryTarget = - getConfiguredTarget("//java/com/google/dummy/test/proto:transpile"); - - CcLinkingContext ccLinkingContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcLinkingContext(); - assertThat(baseArtifactNames(ccLinkingContext.getStaticModeParamsForDynamicLibraryLibraries())) - .containsExactly( - "libjre_core_lib.a", - "libalt_proto_runtime.a", - "libtest_j2objc.lo", - "libtest_proto_j2objc.lo"); - - CcCompilationContext ccCompilationContext = - j2objcLibraryTarget.get(CcInfo.PROVIDER).getCcCompilationContext(); - assertThat(baseArtifactNames(ccCompilationContext.getDeclaredIncludeSrcs())) - .containsExactly("jre_core.h", "alt_proto_runtime.h", "test.j2objc.pb.h", "test.h"); - } - - @Test - public void testJ2ObjcDeadCodeRemovalActionWithOptFlag() throws Exception { - useConfiguration("--j2objc_dead_code_removal"); - addSimpleJ2ObjcLibraryWithEntryClasses(); - addAppleBinaryStarlarkRule(scratch); - addSimpleBinaryTarget("//java/com/google/app/test:transpile"); - - RuleConfiguredTarget appTarget = (RuleConfiguredTarget) getConfiguredTarget("//app:app"); - Artifact prunedArchive = - getBinArtifact( - "app/_j2objc_pruned/app/java/com/google/app/test/libtest_j2objc_pruned.lo", appTarget); - Action action = getGeneratingAction(prunedArchive); - ConfiguredTarget javaTarget = getConfiguredTarget("//java/com/google/app/test:test"); - Artifact inputArchive = getBinArtifact("libtest_j2objc.lo", javaTarget); - Artifact headerMappingFile = getBinArtifact("test.mapping.j2objc", javaTarget); - Artifact dependencyMappingFile = getBinArtifact("test.dependency_mapping.j2objc", javaTarget); - Artifact archiveSourceMappingFile = - getBinArtifact("test.archive_source_mapping.j2objc", javaTarget); - String execPath = removeConfigFragment(getRuleContext(javaTarget).getBinFragment() + "/"); - - assertContainsSublist( - removeConfigFragment(ImmutableList.copyOf(paramFileArgsForAction(action))), - ImmutableList.of( - "--input_archive", - removeConfigFragment(inputArchive.getExecPathString()), - "--output_archive", - removeConfigFragment(prunedArchive.getExecPathString()), - "--dummy_archive", - execPath - + TestConstants.TOOLS_REPOSITORY_PATH_PREFIX - + "tools/objc/dummy/libdummy_lib.a", - "--dependency_mapping_files", - removeConfigFragment(dependencyMappingFile.getExecPathString()), - "--header_mapping_files", - removeConfigFragment(headerMappingFile.getExecPathString()), - "--archive_source_mapping_files", - removeConfigFragment(archiveSourceMappingFile.getExecPathString()), - "--entry_classes", - "com.google.app.test.test")); - - SpawnAction deadCodeRemovalAction = (SpawnAction) getGeneratingAction(prunedArchive); - assertThat(deadCodeRemovalAction.getArguments().get(0)) - .contains("tools/objc/j2objc_dead_code_pruner_binary"); - assertThat(deadCodeRemovalAction.getOutputs()).containsExactly(prunedArchive); - } - - /** Returns the actions created by the action template corresponding to given artifact. */ - protected ImmutableList getActionsForInputsOfGeneratingActionTemplate( - Artifact artifact, TreeFileArtifact treeFileArtifact) throws ActionExecutionException { - CppCompileActionTemplate template = - (CppCompileActionTemplate) getActionGraph().getGeneratingAction(artifact); - return template.generateActionsForInputArtifacts( - ImmutableSet.of(treeFileArtifact), ActionsTestUtil.NULL_TEMPLATE_EXPANSION_ARTIFACT_OWNER); - } - - @Test - public void testCompileActionTemplateFromGenJar() throws Exception { - useConfiguration( - "--apple_platform_type=ios", - "--ios_minimum_os=1.0", - "--platforms=" + MockObjcSupport.IOS_X86_64, - "--experimental_platform_in_output_dir"); - addSimpleJ2ObjcLibraryWithJavaPlugin(); - Artifact archive = j2objcArchive("//java/com/google/app/test:transpile", "test"); - CommandAction archiveAction = (CommandAction) getGeneratingAction(archive); - Artifact objectFilesFromGenJar = - getFirstArtifactEndingWith(archiveAction.getInputs(), "source_files"); - - assertThat(objectFilesFromGenJar.isTreeArtifact()).isTrue(); - assertThat(objectFilesFromGenJar.getRootRelativePathString()) - .isEqualTo("java/com/google/app/test/_objs/test/non_arc/source_files"); - - ActionAnalysisMetadata actionTemplate = - getActionGraph().getGeneratingAction(objectFilesFromGenJar); - Artifact sourceFilesFromGenJar = - getFirstArtifactEndingWith(actionTemplate.getInputs(), "source_files"); - assertThat(sourceFilesFromGenJar.getRootRelativePathString()) - .isEqualTo("java/com/google/app/test/_j2objc/src_jar_files/test/source_files"); - // We can't easily access the header artifact through the middleman artifact, so use its - // expected path directly. - String headerFilesFromGenJar = - "java/com/google/app/test/_j2objc/src_jar_files/test/header_files"; - - // The files contained inside the tree artifacts are not known until execution time. - // Therefore we need to fake some files inside them to test the action template in this - // analysis-time test. - TreeFileArtifact oneSourceFileFromGenJar = - TreeFileArtifact.createTreeOutput((SpecialArtifact) sourceFilesFromGenJar, "children1.m"); - TreeFileArtifact oneObjFileFromGenJar = - TreeFileArtifact.createTreeOutput((SpecialArtifact) objectFilesFromGenJar, "children1.o"); - Iterable compileActions = - getActionsForInputsOfGeneratingActionTemplate( - objectFilesFromGenJar, oneSourceFileFromGenJar); - CommandAction compileAction = Iterables.getOnlyElement(compileActions); - ConfiguredTarget j2objcLibraryTarget = - getConfiguredTarget("//java/com/google/dummy/test:transpile"); - String genfilesFragment = getRuleContext(j2objcLibraryTarget).getGenfilesFragment().toString(); - String binFragment = getRuleContext(j2objcLibraryTarget).getBinFragment().toString(); - - String commandLine = Joiner.on(" ").join(compileAction.getArguments()); - ImmutableList expectedArgs = - new ImmutableList.Builder() - .add("-fexceptions") - .add("-fasm-blocks") - .add("-fobjc-abi-version=2") - .add("-fobjc-legacy-dispatch") - .add("-DOS_IOS") - .add("-arch", "x86_64") - .add("-isysroot") - .add("__BAZEL_XCODE_SDKROOT__") - .add("-O0") - .add("-DDEBUG=1") - .add("-iquote") - .add(".") - .add("-iquote") - .add(genfilesFragment) - .add("-I") - .add(binFragment + "/java/com/google/app/test/_j2objc/test") - .add("-I") - .add(headerFilesFromGenJar) - .add("-fno-strict-overflow") - .add("-fno-objc-arc") - .add("-c") - .add(oneSourceFileFromGenJar.getExecPathString()) - .add("-o") - .add(oneObjFileFromGenJar.getExecPathString()) - .build(); - for (String expectedArg : expectedArgs) { - assertThat(commandLine).contains(expectedArg); - } - } - - @Test - public void j2objcLibrary_noPropperTag_lockdownError() throws Exception { - useConfiguration("--incompatible_j2objc_library_migration"); - scratch.file("test/BUILD", "j2objc_library(name = 'test')"); - reporter.removeHandler(failFastHandler); - - getConfiguredTarget("//test"); - - assertContainsEvent( - "j2objc_library is locked. Please do not use this rule since it will be deleted in the" - + " future."); - } - - @Test - public void j2objcLibrary_withPropperTag_noError() throws Exception { - useConfiguration("--incompatible_j2objc_library_migration"); - scratch.file( - "test/BUILD", - """ - j2objc_library( - name = "test", - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - ) - """); - - getConfiguredTarget("//test"); - - assertNoEvents(); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java b/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java deleted file mode 100644 index decfdfaad002ea..00000000000000 --- a/src/test/java/com/google/devtools/build/lib/rules/objc/J2ObjcLibraryTest.java +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2017 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package com.google.devtools.build.lib.rules.objc; - -import com.google.common.collect.ImmutableSortedSet; -import com.google.devtools.build.lib.actions.Artifact.SpecialArtifact; -import com.google.devtools.build.lib.actions.Artifact.TreeFileArtifact; -import com.google.devtools.build.lib.actions.ArtifactExpander; -import com.google.devtools.build.lib.analysis.ConfiguredTarget; -import com.google.devtools.build.lib.packages.util.MockJ2ObjcSupport; -import com.google.devtools.build.lib.packages.util.MockObjcSupport; -import com.google.devtools.build.lib.packages.util.MockProtoSupport; -import com.google.devtools.build.lib.testutil.TestConstants; -import org.junit.Before; - -/** Setup for unit tests for j2objc transpilation. */ -public class J2ObjcLibraryTest extends ObjcRuleTestCase { - - static final ArtifactExpander DUMMY_ARTIFACT_EXPANDER = - treeArtifact -> { - SpecialArtifact parent = (SpecialArtifact) treeArtifact; - return ImmutableSortedSet.of( - TreeFileArtifact.createTreeOutput(parent, "children1"), - TreeFileArtifact.createTreeOutput(parent, "children2")); - }; - - /** - * Creates and injects a j2objc_library target that depends upon the given label, then returns the - * ConfiguredTarget for the label with the aspects added. - */ - protected ConfiguredTarget getJ2ObjCAspectConfiguredTarget(String label) throws Exception { - // Blaze exposes no interface to summon aspects ex nihilo. - // To get an aspect, you must create a dependent target that requires the aspect. - scratch.file( - "java/com/google/dummy/aspect/BUILD", - "j2objc_library(", - " name = 'transpile',", - " tags = ['__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__'],", - " deps = ['" + label + "'],", - ")"); - - ConfiguredTarget configuredTarget = - getConfiguredTarget("//java/com/google/dummy/aspect:transpile"); - return getDirectPrerequisite(configuredTarget, label); - } - - @Before - public final void setup() throws Exception { - scratch.file("java/com/google/dummy/test/test.java"); - scratch.file( - "java/com/google/dummy/test/BUILD", - """ - package(default_visibility = ["//visibility:public"]) - - java_library( - name = "test", - srcs = ["test.java"], - ) - - j2objc_library( - name = "transpile", - tags = ["__J2OBJC_LIBRARY_MIGRATION_DO_NOT_USE_WILL_BREAK__"], - deps = ["test"], - ) - """); - MockJ2ObjcSupport.setup(mockToolsConfig); - MockProtoSupport.setup(mockToolsConfig); - - useConfiguration( - "--proto_toolchain_for_java=//tools/proto/toolchains:java", - "--platforms=" + MockObjcSupport.DARWIN_X86_64, - "--experimental_platform_in_output_dir"); - - setBuildLanguageOptions("--incompatible_disable_objc_library_transition"); - - mockToolsConfig.append( - "tools/proto/toolchains/BUILD", - TestConstants.LOAD_PROTO_LANG_TOOLCHAIN, - "package(default_visibility=['//visibility:public'])", - "proto_lang_toolchain(name = 'java', command_line = 'dont_care:$(OUT)')", - "proto_lang_toolchain(name='java_stubby1_immutable', command_line = 'dont_care:$(OUT)')", - "proto_lang_toolchain(name='java_stubby3_immutable', command_line = 'dont_care:$(OUT)')", - "proto_lang_toolchain(name='java_stubby_compatible13_immutable', " - + "command_line = 'dont_care')"); - - invalidatePackages(); - } -} diff --git a/src/test/java/com/google/devtools/build/lib/rules/python/PythonTestUtils.java b/src/test/java/com/google/devtools/build/lib/rules/python/PythonTestUtils.java index 6aa9d21c2653d7..65d8cbd8e0e873 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/python/PythonTestUtils.java +++ b/src/test/java/com/google/devtools/build/lib/rules/python/PythonTestUtils.java @@ -52,13 +52,7 @@ public static void assumesDefaultIsPY3() { public static String getPyLoad(String symbolName) { if (RULES_PYTHON_PACKAGE_ROOT.isEmpty()) { - if (symbolName.equals("py_runtime_pair")) { - return String.format( - "load('%s//tools/python:toolchain.bzl', 'py_runtime_pair')", - TestConstants.TOOLS_REPOSITORY); - } else { - return ""; - } + return ""; } String bzlFilename; switch (symbolName) { diff --git a/src/test/java/com/google/devtools/build/lib/rules/python/PythonToolchainTest.java b/src/test/java/com/google/devtools/build/lib/rules/python/PythonToolchainTest.java index ebedf362901d93..cbb4891215e7cb 100644 --- a/src/test/java/com/google/devtools/build/lib/rules/python/PythonToolchainTest.java +++ b/src/test/java/com/google/devtools/build/lib/rules/python/PythonToolchainTest.java @@ -35,8 +35,6 @@ @RunWith(JUnit4.class) public class PythonToolchainTest extends BuildViewTestCase { - private static final String TOOLCHAIN_BZL = - TestConstants.TOOLS_REPOSITORY + "//tools/python:toolchain.bzl"; private static final String TOOLCHAIN_TYPE = TestConstants.TOOLS_REPOSITORY + "//tools/python:toolchain_type"; @@ -78,7 +76,7 @@ public void userDefinedConsumerUsingToolchainResolution() throws Exception { scratch.file( "pkg/BUILD", getPyLoad("py_runtime"), - "load('" + TOOLCHAIN_BZL + "', 'py_runtime_pair')", + getPyLoad("py_runtime_pair"), "load(':rules.bzl', 'myrule')", "py_runtime(", " name = 'my_py3_runtime',", @@ -110,7 +108,7 @@ public void userDefinedConsumerUsingToolchainResolution() throws Exception { public void okToOmitRuntimes() throws Exception { scratch.file( "pkg/BUILD", - "load('" + TOOLCHAIN_BZL + "', 'py_runtime_pair')", + getPyLoad("py_runtime_pair"), "py_runtime_pair(", " name = 'my_py_runtime_pair',", ")"); @@ -125,7 +123,7 @@ public void missingProviderInToolchainAttribute() throws Exception { reporter.removeHandler(failFastHandler); scratch.file( "pkg/BUILD", - "load('" + TOOLCHAIN_BZL + "', 'py_runtime_pair')", + getPyLoad("py_runtime_pair"), "sh_binary(", " name = 'not_a_runtime',", " srcs = ['not_a_runtime.sh'],", diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD index cab8c4e3c09683..4c0769a97c4825 100644 --- a/src/test/java/com/google/devtools/build/lib/skyframe/BUILD +++ b/src/test/java/com/google/devtools/build/lib/skyframe/BUILD @@ -927,6 +927,7 @@ java_test( name = "StarlarkBuiltinsFunctionTest", timeout = "short", srcs = ["StarlarkBuiltinsFunctionTest.java"], + shard_count = 5, deps = [ ":testutil", "//src/main/java/com/google/devtools/build/lib/analysis:analysis_cluster", diff --git a/src/test/shell/bazel/BUILD b/src/test/shell/bazel/BUILD index c5e8f897fffadc..c20d60e16d266d 100644 --- a/src/test/shell/bazel/BUILD +++ b/src/test/shell/bazel/BUILD @@ -32,6 +32,7 @@ filegroup( ":test-deps-wo-bazel", "//src:bazel", "//src/test/shell:bin/bazel", + "//third_party/protobuf:add_python_loads.patch", "//third_party/protobuf:remove_rules_rust.patch", ], visibility = [ diff --git a/src/test/shell/bazel/bazel_execlog_test.sh b/src/test/shell/bazel/bazel_execlog_test.sh index ff435795abca82..660fb1639d2293 100755 --- a/src/test/shell/bazel/bazel_execlog_test.sh +++ b/src/test/shell/bazel/bazel_execlog_test.sh @@ -183,6 +183,26 @@ EOF grep "listedOutputs" output.json || fail "log does not contain listed outputs" } +function test_nested_directory() { + mkdir d + cat > d/BUILD <<'EOF' +genrule( + name = "action", + outs = ["out.txt"], + cmd = "echo hello > $(location out.txt)", + tags = ["no-remote-cache"], +) +EOF + + cd d + bazel build //d:action --execution_log_json_file=%workspace%/output.json 2>&1 >> $TEST_log || fail "could not build" + [[ -e ../output.json ]] || fail "no json log produced" + bazel build //d:action --execution_log_binary_file=%workspace%/output.binary 2>&1 >> $TEST_log || fail "could not build" + [[ -e ../output.binary ]] || fail "no binary log produced" + bazel build //d:action --execution_log_compact_file=%workspace%/output.compact 2>&1 >> $TEST_log || fail "could not build" + [[ -e ../output.compact ]] || fail "no compact log produced" +} + function test_no_remote_cache() { cat > BUILD <<'EOF' genrule( diff --git a/src/test/shell/bazel/bazel_tools_test.sh b/src/test/shell/bazel/bazel_tools_test.sh index 6e180618beabef..2fda71798a4b36 100755 --- a/src/test/shell/bazel/bazel_tools_test.sh +++ b/src/test/shell/bazel/bazel_tools_test.sh @@ -19,12 +19,6 @@ CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${CURRENT_DIR}/../integration_test_setup.sh" \ || { echo "integration_test_setup.sh not found!" >&2; exit 1; } -function test_build_objc_tools() { - # TODO(cparsons): Test building tools/objc/... - bazel build @bazel_tools//tools/objc:j2objc_dead_code_pruner_binary.py \ - || fail "should build tools/objc/j2objc_dead_code_pruner_binary.py" -} - # Test that verifies @bazel_tools//tools:bzl_srcs contains all .bzl source # files underneath @bazel_tools//tools function test_bzl_srcs() { diff --git a/src/test/shell/bazel/python_version_test.sh b/src/test/shell/bazel/python_version_test.sh index 748d065f2ffc95..e1ce747ef0465d 100755 --- a/src/test/shell/bazel/python_version_test.sh +++ b/src/test/shell/bazel/python_version_test.sh @@ -147,6 +147,11 @@ EOF # The specific issue #5104 was caused by file permissions being lost when # unzipping runfiles, which led to an unexecutable runtime. function test_build_python_zip_works_with_workspace_runtime() { + cat > MODULE.bazel << EOF +module(name="pyzip") +bazel_dep(name = "rules_python", version = "0.19.0") +EOF + mkdir -p test # The runfiles interpreter is either a sh script or bat script depending on @@ -158,7 +163,8 @@ function test_build_python_zip_works_with_workspace_runtime() { fi cat > test/BUILD << EOF -load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair") +load("@rules_python//python:py_runtime.bzl", "py_runtime") +load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair") py_binary( name = "pybin", diff --git a/src/test/shell/bazel/runfiles_test.sh b/src/test/shell/bazel/runfiles_test.sh index a29e2caef24fa2..2f4b07698c00e4 100755 --- a/src/test/shell/bazel/runfiles_test.sh +++ b/src/test/shell/bazel/runfiles_test.sh @@ -22,7 +22,8 @@ CURRENT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "${CURRENT_DIR}/../integration_test_setup.sh" \ || { echo "integration_test_setup.sh not found!" >&2; exit 1; } -function test_runfiles_without_bzlmod() { +# TODO - ilist@: reenable when java_tools depends on protobuf +function disable_test_runfiles_without_bzlmod() { name="blorp_malorp" echo "workspace(name = '$name')" > WORKSPACE mkdir foo diff --git a/src/test/shell/integration/BUILD b/src/test/shell/integration/BUILD index ba573378872e65..4342824b8c4e6a 100644 --- a/src/test/shell/integration/BUILD +++ b/src/test/shell/integration/BUILD @@ -37,10 +37,9 @@ filegroup( ) gen_workspace_stanza( - name = "rules_proto_stanza", - out = "rules_proto_stanza.txt", + name = "protobuf_stanza", + out = "protobuf_stanza.txt", repos = [ - "rules_proto", "rules_python", ], ) @@ -374,12 +373,12 @@ sh_test( name = "modify_execution_info_test", srcs = ["modify_execution_info_test.sh"], data = [ - ":rules_proto_stanza.txt", + ":protobuf_stanza.txt", ":test-deps", "//third_party/zlib", "@bazel_tools//tools/bash/runfiles", ], - tags = ["requires-network"], # Allow this test to access internet to fetch rules_proto dependencies. + tags = ["requires-network"], # Allow this test to access internet to fetch protobuf dependencies. ) sh_test( diff --git a/src/test/shell/integration/aspect_test.sh b/src/test/shell/integration/aspect_test.sh index 1d2782b104b595..7da68e0b86190a 100755 --- a/src/test/shell/integration/aspect_test.sh +++ b/src/test/shell/integration/aspect_test.sh @@ -55,11 +55,6 @@ else declare -r EXE_EXT="" fi -# Tests in this file do not actually start a Python interpreter, but plug in a -# fake stub executable to serve as the "interpreter". - -use_fake_python_runtimes_for_testsuite - #### TESTS ############################################################# # Tests that a cycle reached via a command-line aspect does not crash. diff --git a/src/test/shell/testenv.sh b/src/test/shell/testenv.sh index 61240536d31c1c..5d3585c0f1b368 100755 --- a/src/test/shell/testenv.sh +++ b/src/test/shell/testenv.sh @@ -501,7 +501,7 @@ function maybe_setup_python_windows_tools() { mkdir -p tools/python/windows cat > tools/python/windows/BUILD << EOF -load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair") +load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair") package(default_visibility = ["//visibility:public"]) @@ -597,6 +597,7 @@ function add_protobuf() { mkdir -p third_party/protobuf touch third_party/protobuf/BUILD cp "$(rlocation io_bazel/third_party/protobuf/remove_rules_rust.patch)" third_party/protobuf/remove_rules_rust.patch + cp "$(rlocation io_bazel/third_party/protobuf/add_python_loads.patch)" third_party/protobuf/add_python_loads.patch cat >> "$1" < aspect_rules_js -> # aspect_rules_lint -> rules_buf. - patches = ["//third_party/protobuf:remove_rules_rust.patch"], + patches = ["//third_party/protobuf:remove_rules_rust.patch", "//third_party/protobuf:add_python_loads.patch"], strip_prefix = "protobuf-3b62052186d39775090fb074adcba078ea622f54", urls = ["https://github.com/protocolbuffers/protobuf/archive/3b62052186d39775090fb074adcba078ea622f54.zip"], ) @@ -807,7 +808,8 @@ function use_fake_python_runtimes_for_testsuite() { mkdir -p tools/python cat > tools/python/BUILD << EOF -load("@bazel_tools//tools/python:toolchain.bzl", "py_runtime_pair") +load("@rules_python//python:py_runtime.bzl", "py_runtime") +load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair") package(default_visibility=["//visibility:public"]) diff --git a/src/tools/one_version/one_version_main.cc b/src/tools/one_version/one_version_main.cc index 577df968134f09..c22ed45980906e 100644 --- a/src/tools/one_version/one_version_main.cc +++ b/src/tools/one_version/one_version_main.cc @@ -45,8 +45,6 @@ int main(int argc, char *argv[]) { if (tokens.MatchAndSet("--output", &output_file) || tokens.MatchAndSet("--succeed_on_found_violations", &succeed_on_found_violations) || - // TODO(b/366268295): remove once the flag is no longer used - tokens.MatchAndSet("--whitelist", &allowlist_file) || tokens.MatchAndSet("--allowlist", &allowlist_file) || tokens.MatchAndSet("--inputs", &inputs)) { } else { diff --git a/third_party/grpc/bazel/generate_cc.bzl b/third_party/grpc/bazel/generate_cc.bzl index d829097ba0be5b..f0df77c5e7e2d1 100644 --- a/third_party/grpc/bazel/generate_cc.bzl +++ b/third_party/grpc/bazel/generate_cc.bzl @@ -17,7 +17,7 @@ This is an internal rule used by cc_grpc_library, and shouldn't be used directly. """ -load("@rules_proto//proto:defs.bzl", "ProtoInfo") +load("@protobuf//bazel/common:proto_info.bzl", "ProtoInfo") load( ":protobuf.bzl", "get_include_directory", diff --git a/third_party/grpc/bazel/protobuf.bzl b/third_party/grpc/bazel/protobuf.bzl index 38b33ff0ff8c32..382f82565fc558 100644 --- a/third_party/grpc/bazel/protobuf.bzl +++ b/third_party/grpc/bazel/protobuf.bzl @@ -13,7 +13,7 @@ # limitations under the License. """Utility functions for generating protobuf code.""" -load("@rules_proto//proto:defs.bzl", "ProtoInfo") +load("@protobuf//bazel/common:proto_info.bzl", "ProtoInfo") _PROTO_EXTENSION = ".proto" _VIRTUAL_IMPORTS = "/_virtual_imports/" diff --git a/third_party/pprof/BUILD b/third_party/pprof/BUILD index f3484be717f5fe..95ea7167fb0ec0 100644 --- a/third_party/pprof/BUILD +++ b/third_party/pprof/BUILD @@ -1,6 +1,6 @@ -load("@rules_java//java:defs.bzl", "java_proto_library") +load("@protobuf//bazel:java_proto_library.bzl", "java_proto_library") +load("@protobuf//bazel:proto_library.bzl", "proto_library") load("@rules_license//rules:license.bzl", "license") -load("@rules_proto//proto:defs.bzl", "proto_library") package( default_applicable_licenses = [":license"], diff --git a/third_party/protobuf/BUILD b/third_party/protobuf/BUILD index 3989ec20bdffcd..152db8b79dd62e 100644 --- a/third_party/protobuf/BUILD +++ b/third_party/protobuf/BUILD @@ -9,6 +9,7 @@ filegroup( exports_files([ "BUILD", "remove_rules_rust.patch", + "add_python_loads.patch", ]) alias( diff --git a/third_party/protobuf/add_python_loads.patch b/third_party/protobuf/add_python_loads.patch new file mode 100644 index 00000000000000..329fbc3b174f32 --- /dev/null +++ b/third_party/protobuf/add_python_loads.patch @@ -0,0 +1,59 @@ +diff --git a/python/internal.bzl b/python/internal.bzl +index 8f99becec..8c667e1ae 100644 +--- a/python/internal.bzl ++++ b/python/internal.bzl +@@ -1,6 +1,7 @@ + """ + Internal helpers for building the Python protobuf runtime. + """ ++load("@rules_python//python:py_test.bzl", "py_test") + + def _remove_cross_repo_path(path): + components = path.split("/") +@@ -123,7 +124,7 @@ def internal_py_test(deps = [], **kwargs): + deps: any additional dependencies of the test. + **kwargs: arguments forwarded to py_test. + """ +- native.py_test( ++ py_test( + imports = ["."], + deps = deps + ["//python:python_test_lib"], + target_compatible_with = select({ +diff --git a/python/pb_unit_tests/pyproto_test_wrapper.bzl b/python/pb_unit_tests/pyproto_test_wrapper.bzl +index b5f474d3d..1e2b5daa2 100644 +--- a/python/pb_unit_tests/pyproto_test_wrapper.bzl ++++ b/python/pb_unit_tests/pyproto_test_wrapper.bzl +@@ -1,8 +1,10 @@ + """Wrapper for another py_test to run with upb, possibly with a set of expected failures.""" + ++load("@rules_python//python:py_test.bzl", "py_test") ++ + def pyproto_test_wrapper(name, deps = []): + src = name + "_wrapper.py" +- native.py_test( ++ py_test( + name = name, + srcs = [src], + legacy_create_init = False, +diff --git a/upb/cmake/build_defs.bzl b/upb/cmake/build_defs.bzl +index 325189c7f..c7a7a4558 100644 +--- a/upb/cmake/build_defs.bzl ++++ b/upb/cmake/build_defs.bzl +@@ -7,6 +7,8 @@ + + """Bazel support functions related to CMake support.""" + ++load("@rules_python//python:py_test.bzl", "py_test") ++ + def staleness_test(name, outs, generated_pattern, target_files = None, tags = [], **kwargs): + """Tests that checked-in file(s) match the contents of generated file(s). + +@@ -46,7 +48,7 @@ def staleness_test(name, outs, generated_pattern, target_files = None, tags = [] + "sed -i.bak -e 's|INSERT_FILE_LIST_HERE|" + "\\\n ".join(file_list) + "|' $@", + ) + +- native.py_test( ++ py_test( + name = name, + srcs = [script_name], + data = existing_outs + [generated_pattern % file for file in outs], diff --git a/third_party/remoteapis/MODULE.bazel b/third_party/remoteapis/MODULE.bazel index e973c0a405976b..548e8497ee87b5 100644 --- a/third_party/remoteapis/MODULE.bazel +++ b/third_party/remoteapis/MODULE.bazel @@ -7,7 +7,6 @@ module( ) bazel_dep(name = "rules_java", version = "4.0.0") -bazel_dep(name = "rules_proto", version = "4.0.0") bazel_dep(name = "protobuf", version = "3.19.0") bazel_dep(name = "googleapis", version = "0.0.0-20240819-fe8ba054a") bazel_dep(name = "bazel", version = "", repo_name = "io_bazel") diff --git a/tools/BUILD b/tools/BUILD index 676f4803ba9032..1a735ca914444a 100644 --- a/tools/BUILD +++ b/tools/BUILD @@ -21,7 +21,6 @@ filegroup( "//tools/def_parser:srcs", "//tools/distributions:srcs", "//tools/genrule:srcs", - "//tools/j2objc:srcs", "//tools/java:srcs", "//tools/jdk:srcs", "//tools/launcher:srcs", @@ -57,7 +56,6 @@ filegroup( "//tools/cpp:embedded_tools", "//tools/def_parser:srcs", "//tools/genrule:srcs", - "//tools/j2objc:srcs", "//tools/java:embedded_tools", "//tools/java:java_stub_template.txt", "//tools/jdk:package-srcs", diff --git a/tools/j2objc/BUILD b/tools/j2objc/BUILD deleted file mode 100644 index 4c5ffe97cbc0a6..00000000000000 --- a/tools/j2objc/BUILD +++ /dev/null @@ -1,6 +0,0 @@ -package(default_visibility = ["//visibility:public"]) - -filegroup( - name = "srcs", - srcs = glob(["**"]), -) diff --git a/tools/j2objc/BUILD.tools b/tools/j2objc/BUILD.tools deleted file mode 100644 index b66c36d02cf599..00000000000000 --- a/tools/j2objc/BUILD.tools +++ /dev/null @@ -1,35 +0,0 @@ -load("@rules_java//java:defs.bzl", "java_binary") -load("@protobuf//bazel/toolchains:proto_lang_toolchain.bzl", "proto_lang_toolchain") - -package(default_visibility = ["//visibility:public"]) - -exports_files(glob(["**"])) - -java_binary( - name = "j2objc", - main_class = "com.google.devtools.j2objc.J2ObjC", - runtime_deps = ["@bazel_j2objc//:j2objc"], -) - -py_binary( - name = "j2objc_wrapper_binary", - srcs = ["j2objc_wrapper_binary.py"], - python_version = "PY3", -) - -py_binary( - name = "j2objc_header_map_binary", - srcs = ["j2objc_header_map_binary.py"], - python_version = "PY3", -) - -proto_lang_toolchain( - name = "j2objc_proto_toolchain", - blacklisted_protos = [], - command_line = "--PLUGIN_j2objc_out=file_dir_mapping,generate_class_mappings:$(OUT)", - plugin = "//third_party/java/j2objc:proto_plugin", - plugin_format_flag = "--plugin=protoc-gen-PLUGIN_j2objc=%s", - progress_message = "Generating j2objc proto_library %{label}", - runtime = "//third_party/java/j2objc:proto_runtime", - visibility = ["//visibility:public"], -) diff --git a/tools/j2objc/j2objc_header_map_binary.py b/tools/j2objc/j2objc_header_map_binary.py deleted file mode 100755 index ecdf1a5dc6118b..00000000000000 --- a/tools/j2objc/j2objc_header_map_binary.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/python3 - -# Copyright 2017 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""A script to generate Java class to ObjC header mapping for J2ObjC. - -This script generates a text file containing mapping between top-level Java -classes to associated ObjC headers, generated by J2ObjC. - -The mapping file is used by dependent J2ObjC transpilation actions to locate -the correct header import paths for dependent Java classes. - -Inside the script, we read the Java source files and source jars of a single -Java rule, and parse out the package names from the package statements, using -regular expression matching. - -Note that we cannot guarantee 100% correctness by using just regular expression, -but it should be good enough. This allows us to avoid doing any further complex -parsing of the source files and keep the script light-weight without other -dependencies. In the future, we can consider implementing a simple Java lexer -here that correctly parses the package statements out of Java files. -""" - -import argparse -import os -import re -import zipfile - -_PACKAGE_RE = re.compile(r'(package)\s+([\w\.]+);') - - -def _get_file_map_entry(java_file_path, java_file): - """Returns the top-level Java class and header file path tuple. - - Args: - java_file_path: The file path of the source Java file. - java_file: The actual file of the source java file. - Returns: - A tuple containing top-level Java class and associated header file path. Or - None if no package statement exists in the source file. - """ - for line in java_file: - stripped_line = line.strip() - stripped_line_str = stripped_line - if isinstance(stripped_line, bytes): - stripped_line_str = stripped_line.decode('utf-8', 'strict') - elif not isinstance(stripped_line, (str, bytes)): - raise TypeError("not expecting type '%s'" % type(stripped_line_str)) - package_statement = _PACKAGE_RE.search(stripped_line_str) - - # We identified a potential package statement. - if package_statement: - preceding_characters = stripped_line[0:package_statement.start(1)] - # We have preceding characters before the package statement. We need to - # look further into them. - if preceding_characters: - # Skip comment line. - if preceding_characters.startswith('//'): - continue - - # Preceding characters also must end with a space, represent an end - # of comment, or end of a statement. - # Otherwise, we skip the current line. - if not (preceding_characters[len(preceding_characters) - 1].isspace() or - preceding_characters.endswith(';') or - preceding_characters.endswith('*/')): - continue - package_name = package_statement.group(2) - class_name = os.path.splitext(os.path.basename(java_file_path))[0] - header_file = os.path.splitext(java_file_path)[0] + '.h' - return (package_name + '.' + class_name, header_file) - return None - - -def main(): - parser = argparse.ArgumentParser(fromfile_prefix_chars='@') - parser.add_argument( - '--source_files', - required=False, - help='The source files') - parser.add_argument( - '--source_jars', - required=False, - help='The source jars.') - parser.add_argument( - '--output_mapping_file', - required=False, - help='The output mapping file') - - args, _ = parser.parse_known_args() - class_to_header_map = dict() - - # Process the source files. - if args.source_files: - source_files = args.source_files.split(',') - for source_file in source_files: - with open(source_file, 'r') as f: - entry = _get_file_map_entry(source_file, f) - if entry: - class_to_header_map[entry[0]] = entry[1] - - # Process the source jars. - if args.source_jars: - source_jars = args.source_jars.split(',') - for source_jar in source_jars: - with zipfile.ZipFile(source_jar, 'r') as jar: - for jar_entry in jar.namelist(): - if jar_entry.endswith('.java'): - with jar.open(jar_entry) as jar_entry_file: - entry = _get_file_map_entry(jar_entry, jar_entry_file) - if entry: - class_to_header_map[entry[0]] = entry[1] - - # Generate the output header mapping file. - if args.output_mapping_file: - with open(args.output_mapping_file, 'w') as output_mapping_file: - for class_name in sorted(class_to_header_map): - header_path = class_to_header_map[class_name] - output_mapping_file.write(class_name + '=' + header_path + '\n') - -if __name__ == '__main__': - main() diff --git a/tools/j2objc/j2objc_wrapper_binary.py b/tools/j2objc/j2objc_wrapper_binary.py deleted file mode 100755 index e6f4c75dbd5c12..00000000000000 --- a/tools/j2objc/j2objc_wrapper_binary.py +++ /dev/null @@ -1,538 +0,0 @@ -#!/usr/bin/python3 - -# Copyright 2015 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""A wrapper script for J2ObjC transpiler. - -This script wraps around J2ObjC transpiler to also output a dependency mapping -file by scanning the import and include directives of the J2ObjC-translated -files. -""" - -import argparse -import errno -import multiprocessing -import os -import queue -import re -import shutil -import subprocess -import tempfile -import threading -import zipfile - -_INCLUDE_RE = re.compile('#(include|import) "([^"]+)"') -_CONST_DATE_TIME = [1980, 1, 1, 0, 0, 0] -_ADD_EXPORTS = [ - '--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED', - '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED', - '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED', - '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED', - '--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED', -] - - -def RunJ2ObjC(java, jvm_flags, j2objc, main_class, output_file_path, - j2objc_args, source_paths, files_to_translate): - """Runs J2ObjC transpiler to translate Java source files to ObjC. - - Args: - java: The path of the Java executable. - jvm_flags: A comma-separated list of flags to pass to JVM. - j2objc: The deploy jar of J2ObjC. - main_class: The J2ObjC main class to invoke. - output_file_path: The output file directory. - j2objc_args: A list of args to pass to J2ObjC transpiler. - source_paths: A list of directories that contain sources to translate. - files_to_translate: A list of relative paths (relative to source_paths) that - point to sources to translate. - Returns: - None. - """ - j2objc_args.extend(['-sourcepath', ':'.join(source_paths)]) - j2objc_args.extend(['-d', output_file_path]) - j2objc_args.extend(files_to_translate) - param_file_content = ' '.join(j2objc_args).encode('utf-8') - fd = None - param_filename = None - try: - fd, param_filename = tempfile.mkstemp(text=True) - os.write(fd, param_file_content) - finally: - if fd: - os.close(fd) - try: - j2objc_cmd = [java] - j2objc_cmd.extend([f_ for f_ in jvm_flags.split(',') if f_]) - j2objc_cmd.extend(_ADD_EXPORTS) - j2objc_cmd.extend(['-cp', j2objc, main_class]) - j2objc_cmd.append('@%s' % param_filename) - subprocess.check_call(j2objc_cmd, stderr=subprocess.STDOUT) - finally: - if param_filename: - os.remove(param_filename) - - -def WriteDepMappingFile(objc_files, - objc_file_root, - output_dependency_mapping_file, - file_open=open): - """Scans J2ObjC-translated files and outputs a dependency mapping file. - - The mapping file contains mappings between translated source files and their - imported source files scanned from the import and include directives. - - Args: - objc_files: A list of ObjC files translated by J2ObjC. - objc_file_root: The file path which represents a directory where the - generated ObjC files reside. - output_dependency_mapping_file: The path of the dependency mapping file to - write to. - file_open: Reference to the builtin open function so it may be - overridden for testing. - Raises: - RuntimeError: If spawned threads throw errors during processing. - Returns: - None. - """ - dep_mapping = dict() - input_file_queue = queue.Queue() - output_dep_mapping_queue = queue.Queue() - error_message_queue = queue.Queue() - for objc_file in objc_files: - input_file_queue.put(os.path.join(objc_file_root, objc_file)) - - for _ in range(multiprocessing.cpu_count()): - t = threading.Thread(target=_ReadDepMapping, args=(input_file_queue, - output_dep_mapping_queue, - error_message_queue, - objc_file_root, - file_open)) - t.start() - - input_file_queue.join() - - if not error_message_queue.empty(): - error_messages = list(error_message_queue.queue) - raise RuntimeError('\n'.join(error_messages)) - - while not output_dep_mapping_queue.empty(): - entry_file, deps = output_dep_mapping_queue.get() - dep_mapping[entry_file] = deps - - with file_open(output_dependency_mapping_file, 'w') as f: - for entry in sorted(dep_mapping): - for dep in dep_mapping[entry]: - f.write(entry + ':' + dep + '\n') - - -def _ReadDepMapping(input_file_queue, output_dep_mapping_queue, - error_message_queue, output_root, file_open=open): - while True: - try: - input_file = input_file_queue.get_nowait() - except queue.Empty: - # No more work left in the queue. - return - - try: - deps = set() - input_file_name = os.path.splitext(input_file)[0] - entry = os.path.relpath(input_file_name, output_root) - for file_ext in ['.m', '.h']: - with file_open(input_file_name + file_ext, 'r') as f: - for line in f: - include = _INCLUDE_RE.match(line) - if include: - include_path = include.group(2) - dep = os.path.splitext(include_path)[0] - if dep != entry: - deps.add(dep) - - output_dep_mapping_queue.put((entry, sorted(deps))) - except Exception as e: # pylint: disable=broad-except - error_message_queue.put(str(e)) - finally: - # We need to mark the task done to prevent blocking the main process - # indefinitely. - input_file_queue.task_done() - - -def WriteArchiveSourceMappingFile(compiled_archive_file_path, - output_archive_source_mapping_file, - objc_files, - file_open=open): - """Writes a mapping file between archive file to associated ObjC source files. - - Args: - compiled_archive_file_path: The path of the archive file. - output_archive_source_mapping_file: A path of the mapping file to write to. - objc_files: A list of ObjC files translated by J2ObjC. - file_open: Reference to the builtin open function so it may be - overridden for testing. - Returns: - None. - """ - with file_open(output_archive_source_mapping_file, 'w') as f: - for objc_file in objc_files: - f.write(compiled_archive_file_path + ':' + objc_file + '\n') - - -def _ParseArgs(j2objc_args): - """Separate arguments passed to J2ObjC into source files and J2ObjC flags. - - Args: - j2objc_args: A list of args to pass to J2ObjC transpiler. - Returns: - A tuple containing source files and J2ObjC flags - """ - source_files = [] - flags = [] - is_next_flag_value = False - for j2objc_arg in j2objc_args: - if j2objc_arg.startswith('-'): - flags.append(j2objc_arg) - is_next_flag_value = True - elif is_next_flag_value: - flags.append(j2objc_arg) - is_next_flag_value = False - else: - source_files.append(j2objc_arg) - return (source_files, flags) - - -def _J2ObjcOutputObjcFiles(java_files): - """Returns the relative paths of the associated output ObjC source files. - - Args: - java_files: The list of Java files to translate. - Returns: - A list of associated output ObjC source files. - """ - return [os.path.splitext(java_file)[0] + '.m' for java_file in java_files] - - -def UnzipSourceJarSources(source_jars): - """Unzips the source jars containing Java source files. - - Args: - source_jars: The list of input Java source jars. - Returns: - A tuple of the temporary output root and a list of root-relative paths of - unzipped Java files - """ - srcjar_java_files = [] - if source_jars: - tmp_input_root = tempfile.mkdtemp() - for source_jar in source_jars: - zip_ref = zipfile.ZipFile(source_jar, 'r') - zip_entries = [] - - for file_entry in zip_ref.namelist(): - # We only care about Java source files. - if file_entry.endswith('.java'): - zip_entries.append(file_entry) - - zip_ref.extractall(tmp_input_root, zip_entries) - zip_ref.close() - srcjar_java_files.extend(zip_entries) - - return (tmp_input_root, srcjar_java_files) - else: - return None - - -def RenameGenJarObjcFileRootInFileContent(tmp_objc_file_root, - j2objc_source_paths, - gen_src_jar, genjar_objc_files, - execute=subprocess.check_call): - """Renames references to temporary root inside ObjC sources from gen srcjar. - - Args: - tmp_objc_file_root: The temporary output root containing ObjC sources. - j2objc_source_paths: The source paths used by J2ObjC. - gen_src_jar: The path of the gen srcjar. - genjar_objc_files: The list of ObjC sources translated from the gen srcjar. - execute: The function used to execute shell commands. - Returns: - None. - """ - if genjar_objc_files: - abs_genjar_objc_source_files = [ - os.path.join(tmp_objc_file_root, genjar_objc_f) - for genjar_objc_f in genjar_objc_files - ] - abs_genjar_objc_header_files = [ - os.path.join(tmp_objc_file_root, - os.path.splitext(genjar_objc_f)[0] + '.h') - for genjar_objc_f in genjar_objc_files - ] - - # We execute a command to change all references of the temporary Java root - # where we unzipped the gen srcjar sources, to the actual gen srcjar that - # contains the original Java sources. - cmd = [ - 'sed', - '-i', - '-e', - 's|%s/|%s::|g' % (j2objc_source_paths[1], gen_src_jar) - ] - cmd.extend(abs_genjar_objc_source_files) - cmd.extend(abs_genjar_objc_header_files) - execute(cmd, stderr=subprocess.STDOUT) - - -def MoveObjcFileToFinalOutputRoot(objc_files, - tmp_objc_file_root, - final_objc_file_root, - suffix, - os_module=os, - shutil_module=shutil): - """Moves ObjC files from temporary location to the final output location. - - Args: - objc_files: The list of objc files to move. - tmp_objc_file_root: The temporary output root containing ObjC sources. - final_objc_file_root: The final output root. - suffix: The suffix of the files to move. - os_module: The os python module. - shutil_module: The shutil python module. - Returns: - None. - """ - for objc_file in objc_files: - file_with_suffix = os_module.path.splitext(objc_file)[0] + suffix - dest_path = os_module.path.join( - final_objc_file_root, file_with_suffix) - dest_path_dir = os_module.path.dirname(dest_path) - - if not os_module.path.isdir(dest_path_dir): - try: - os_module.makedirs(dest_path_dir) - except OSError as e: - if e.errno != errno.EEXIST or not os_module.path.isdir(dest_path_dir): - raise - - shutil_module.move( - os_module.path.join(tmp_objc_file_root, file_with_suffix), - dest_path) - - -def PostJ2ObjcFileProcessing(normal_objc_files, genjar_objc_files, - tmp_objc_file_root, final_objc_file_root, - j2objc_source_paths, gen_src_jar, - output_gen_source_dir, output_gen_header_dir): - """Performs cleanups on ObjC files and moves them to final output location. - - Args: - normal_objc_files: The list of objc files translated from normal Java files. - genjar_objc_files: The list of ObjC sources translated from the gen srcjar. - tmp_objc_file_root: The temporary output root containing ObjC sources. - final_objc_file_root: The final output root. - j2objc_source_paths: The source paths used by J2ObjC. - gen_src_jar: The path of the gen srcjar. - output_gen_source_dir: The final output directory of ObjC source files - translated from gen srcjar. Maybe null. - output_gen_header_dir: The final output directory of ObjC header files - translated from gen srcjar. Maybe null. - Returns: - None. - """ - RenameGenJarObjcFileRootInFileContent(tmp_objc_file_root, - j2objc_source_paths, - gen_src_jar, - genjar_objc_files) - MoveObjcFileToFinalOutputRoot(normal_objc_files, - tmp_objc_file_root, - final_objc_file_root, - '.m') - MoveObjcFileToFinalOutputRoot(normal_objc_files, - tmp_objc_file_root, - final_objc_file_root, - '.h') - - if output_gen_source_dir: - MoveObjcFileToFinalOutputRoot( - genjar_objc_files, - tmp_objc_file_root, - output_gen_source_dir, - '.m') - - if output_gen_header_dir: - MoveObjcFileToFinalOutputRoot( - genjar_objc_files, - tmp_objc_file_root, - output_gen_header_dir, - '.h') - - -def GenerateJ2objcMappingFiles(normal_objc_files, - genjar_objc_files, - tmp_objc_file_root, - output_dependency_mapping_file, - output_archive_source_mapping_file, - compiled_archive_file_path): - """Generates J2ObjC mapping files. - - Args: - normal_objc_files: The list of objc files translated from normal Java files. - genjar_objc_files: The list of ObjC sources translated from the gen srcjar. - tmp_objc_file_root: The temporary output root containing ObjC sources. - output_dependency_mapping_file: The path of the dependency mapping file to - write to. - output_archive_source_mapping_file: A path of the mapping file to write to. - compiled_archive_file_path: The path of the archive file. - Returns: - None. - """ - WriteDepMappingFile(normal_objc_files + genjar_objc_files, - tmp_objc_file_root, - output_dependency_mapping_file) - - if output_archive_source_mapping_file: - WriteArchiveSourceMappingFile(compiled_archive_file_path, - output_archive_source_mapping_file, - normal_objc_files + genjar_objc_files) - - -def main(): - parser = argparse.ArgumentParser(fromfile_prefix_chars='@') - parser.add_argument( - '--java', - required=True, - help='The path to the Java executable.') - parser.add_argument( - '--jvm_flags', - default='-Xss4m,-XX:+UseParallelGC', - help='A comma-separated list of flags to pass to the JVM.') - parser.add_argument( - '--j2objc', - required=True, - help='The path to the J2ObjC deploy jar.') - parser.add_argument( - '--main_class', - required=True, - help='The main class of the J2ObjC deploy jar to execute.') - # TODO(rduan): Remove, no longer needed. - parser.add_argument( - '--translated_source_files', - required=False, - help=('A comma-separated list of file paths where J2ObjC will write the ' - 'translated files to.')) - parser.add_argument( - '--output_dependency_mapping_file', - required=True, - help='The file path of the dependency mapping file to write to.') - parser.add_argument( - '--objc_file_path', '-d', - required=True, - help=('The file path which represents a directory where the generated ' - 'ObjC files reside.')) - parser.add_argument( - '--output_archive_source_mapping_file', - help='The file path of the mapping file containing mappings between the ' - 'translated source files and the to-be-generated archive file ' - 'compiled from those source files. --compile_archive_file_path must ' - 'be specified if this option is specified.') - parser.add_argument( - '--compiled_archive_file_path', - required=False, - help=('The archive file path that will be produced by ObjC compile action' - ' later')) - # TODO(rduan): Remove this flag once it is fully replaced by flag --src_jars. - parser.add_argument( - '--gen_src_jar', - required=False, - help='The jar containing Java sources generated by annotation processor.') - parser.add_argument( - '--src_jars', - required=False, - help='The list of Java source jars containing Java sources to translate.') - parser.add_argument( - '--output_gen_source_dir', - required=False, - help='The output directory of ObjC source files translated from the gen' - ' srcjar') - parser.add_argument( - '--output_gen_header_dir', - required=False, - help='The output directory of ObjC header files translated from the gen' - ' srcjar') - - args, pass_through_args = parser.parse_known_args() - normal_java_files, j2objc_flags = _ParseArgs(pass_through_args) - srcjar_java_files = [] - j2objc_source_paths = [os.getcwd()] - - # Unzip the source jars, so J2ObjC can translate the contained sources. - # Also add the temporary directory containing the unzipped sources as a source - # path for J2ObjC, so it can find these sources. - source_jars = [] - if args.gen_src_jar: - source_jars.append(args.gen_src_jar) - if args.src_jars: - source_jars.extend(args.src_jars.split(',')) - - srcjar_source_tuple = UnzipSourceJarSources(source_jars) - if srcjar_source_tuple: - j2objc_source_paths.append(srcjar_source_tuple[0]) - srcjar_java_files = srcjar_source_tuple[1] - - # Run J2ObjC over the normal input Java files and unzipped gen jar Java files. - # The output is stored in a temporary directory. - tmp_objc_file_root = tempfile.mkdtemp() - - # If we do not generate the header mapping from J2ObjC, we still - # need to specify --output-header-mapping, as it signals to J2ObjC that we - # are using source paths as import paths, not package paths. - # TODO(rduan): Make another flag in J2ObjC to specify using source paths. - if '--output-header-mapping' not in j2objc_flags: - j2objc_flags.extend(['--output-header-mapping', '/dev/null']) - - RunJ2ObjC(args.java, - args.jvm_flags, - args.j2objc, - args.main_class, - tmp_objc_file_root, - j2objc_flags, - j2objc_source_paths, - normal_java_files + srcjar_java_files) - - # Calculate the relative paths of generated objc files. - normal_objc_files = _J2ObjcOutputObjcFiles(normal_java_files) - genjar_objc_files = _J2ObjcOutputObjcFiles(srcjar_java_files) - - # Generate J2ObjC mapping files needed for distributed builds. - GenerateJ2objcMappingFiles(normal_objc_files, - genjar_objc_files, - tmp_objc_file_root, - args.output_dependency_mapping_file, - args.output_archive_source_mapping_file, - args.compiled_archive_file_path) - - # Post J2ObjC-run processing, involving file editing, zipping and moving - # files to their final output locations. - PostJ2ObjcFileProcessing( - normal_objc_files, - genjar_objc_files, - tmp_objc_file_root, - args.objc_file_path, - j2objc_source_paths, - args.gen_src_jar, - args.output_gen_source_dir, - args.output_gen_header_dir) - -if __name__ == '__main__': - main() diff --git a/tools/objc/BUILD b/tools/objc/BUILD index 56767ccef08691..479155b669b856 100644 --- a/tools/objc/BUILD +++ b/tools/objc/BUILD @@ -27,11 +27,6 @@ xcode_config( name = "host_xcodes", ) -py_binary( - name = "j2objc_dead_code_pruner_binary", - srcs = ["j2objc_dead_code_pruner_binary.py"], -) - objc_library( name = "dummy_lib", srcs = [ diff --git a/tools/python/BUILD.tools b/tools/python/BUILD.tools index 416ff6e122a384..489722fcfbff24 100644 --- a/tools/python/BUILD.tools +++ b/tools/python/BUILD.tools @@ -11,11 +11,7 @@ ################################################################################ load(":python_version.bzl", "define_python_version_flag") -load(":toolchain.bzl", "define_autodetecting_toolchain") - -# Please do not use write_file.bzl outside of this package. -# See https://groups.google.com/d/msg/bazel-dev/I8IvJyoyo-s/AttqDcnOCgAJ -load(":write_file.bzl", "write_file") +load(":define_autodetecting_toolchain.bzl", "define_autodetecting_toolchain") package(default_visibility = ["//visibility:public"]) @@ -30,7 +26,6 @@ exports_files([ "toolchain.bzl", "utils.bzl", "private/py_test_alias.bzl", - # write_file.bzl fortunately doesn't need to be exposed because it's only # used in this BUILD file. ]) diff --git a/tools/python/define_autodetecting_toolchain.bzl b/tools/python/define_autodetecting_toolchain.bzl new file mode 100644 index 00000000000000..fa3afb7085ecb4 --- /dev/null +++ b/tools/python/define_autodetecting_toolchain.bzl @@ -0,0 +1,129 @@ +# Copyright 2019 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Definitions related to the Python toolchain.""" + +load("@rules_python//python:py_runtime.bzl", "py_runtime") +load("@rules_python//python:py_runtime_pair.bzl", "py_runtime_pair") +load(":utils.bzl", "expand_pyversion_template") + +# TODO(#7844): Add support for a windows (.bat) version of the autodetecting +# toolchain, based on the "py" wrapper (e.g. "py -2" and "py -3"). Use select() +# in the template attr of the _generate_*wrapper targets. + +def define_autodetecting_toolchain( + name, + pywrapper_template, + windows_config_setting): + """Defines the autodetecting Python toolchain. + + This includes both strict and non-strict variants. + + For use only by @bazel_tools//tools/python:BUILD; see the documentation + comment there. + + Args: + name: The name of the toolchain to introduce. Must have value + "autodetecting_toolchain". This param is present only to make the + BUILD file more readable. + pywrapper_template: The label of the pywrapper_template.txt file. + windows_config_setting: The label of a config_setting that matches when + the platform is windows, in which case the toolchain is configured + in a way that triggers a workaround for #7844. + """ + if native.package_name() != "tools/python": + fail("define_autodetecting_toolchain() is private to " + + "@bazel_tools//tools/python") + if name != "autodetecting_toolchain": + fail("Python autodetecting toolchain must be named " + + "'autodetecting_toolchain'") + + expand_pyversion_template( + name = "_generate_wrappers", + template = pywrapper_template, + out2 = ":py2wrapper.sh", + out3 = ":py3wrapper.sh", + out2_nonstrict = ":py2wrapper_nonstrict.sh", + out3_nonstrict = ":py3wrapper_nonstrict.sh", + visibility = ["//visibility:private"], + ) + + # Note that the pywrapper script is a .sh file, not a sh_binary target. If + # we needed to make it a proper shell target, e.g. because it needed to + # access runfiles and needed to depend on the runfiles library, then we'd + # have to use a workaround to allow it to be depended on by py_runtime. See + # https://github.com/bazelbuild/bazel/issues/4286#issuecomment-475661317. + + py_runtime( + name = "_autodetecting_py3_runtime", + interpreter = ":py3wrapper.sh", + python_version = "PY3", + stub_shebang = "#!/usr/bin/env python3", + visibility = ["//visibility:private"], + ) + + py_runtime( + name = "_autodetecting_py3_runtime_nonstrict", + interpreter = ":py3wrapper_nonstrict.sh", + python_version = "PY3", + stub_shebang = "#!/usr/bin/env python3", + visibility = ["//visibility:private"], + ) + + # This is a dummy runtime whose interpreter_path triggers the native rule + # logic to use the legacy behavior on Windows. + # TODO(#7844): Remove this target. + py_runtime( + name = "_magic_sentinel_runtime", + interpreter_path = "/_magic_pyruntime_sentinel_do_not_use", + python_version = "PY3", + visibility = ["//visibility:private"], + ) + + py_runtime_pair( + name = "_autodetecting_py_runtime_pair", + py3_runtime = select({ + # If we're on windows, inject the sentinel to tell native rule logic + # that we attempted to use the autodetecting toolchain and need to + # switch back to legacy behavior. + # TODO(#7844): Remove this hack. + windows_config_setting: ":_magic_sentinel_runtime", + "//conditions:default": ":_autodetecting_py3_runtime", + }), + visibility = ["//visibility:public"], + ) + + py_runtime_pair( + name = "_autodetecting_py_runtime_pair_nonstrict", + py3_runtime = select({ + # Same hack as above. + # TODO(#7844): Remove this hack. + windows_config_setting: ":_magic_sentinel_runtime", + "//conditions:default": ":_autodetecting_py3_runtime_nonstrict", + }), + visibility = ["//visibility:public"], + ) + + native.toolchain( + name = name, + toolchain = ":_autodetecting_py_runtime_pair", + toolchain_type = ":toolchain_type", + visibility = ["//visibility:public"], + ) + + native.toolchain( + name = name + "_nonstrict", + toolchain = ":_autodetecting_py_runtime_pair_nonstrict", + toolchain_type = ":toolchain_type", + visibility = ["//visibility:public"], + ) diff --git a/tools/python/toolchain.bzl b/tools/python/toolchain.bzl index eb5f63f0b563e7..c58577d76cb30d 100644 --- a/tools/python/toolchain.bzl +++ b/tools/python/toolchain.bzl @@ -11,242 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. +"""Deprecated py_runtime_pair, here because it's loaded from rules_python""" -"""Definitions related to the Python toolchain.""" - -load(":utils.bzl", "expand_pyversion_template") - -# TODO: move py_runtime_pair into rules_python (and the rest of @bazel_tools//python) -# py_runtime should be loaded from rules_python, but this creates a circular dep, because py_runtime_pair is imported there. -py_runtime = native.py_runtime - -def _py_runtime_pair_impl(ctx): - if ctx.attr.py2_runtime != None: - py2_runtime = ctx.attr.py2_runtime[PyRuntimeInfo] - if py2_runtime.python_version != "PY2": - fail("The Python runtime in the 'py2_runtime' attribute did not have " + - "version 'PY2'") - else: - py2_runtime = None - - if ctx.attr.py3_runtime != None: - py3_runtime = ctx.attr.py3_runtime[PyRuntimeInfo] - if py3_runtime.python_version != "PY3": - fail("The Python runtime in the 'py3_runtime' attribute did not have " + - "version 'PY3'") - else: - py3_runtime = None - - # TODO: Uncomment this after --incompatible_python_disable_py2 defaults to true - # if _is_py2_disabled(ctx) and py2_runtime != None: - # fail("Using Python 2 is not supported and disabled; see " + - # "https://github.com/bazelbuild/bazel/issues/15684") - - return [platform_common.ToolchainInfo( - py2_runtime = py2_runtime, - py3_runtime = py3_runtime, - )] - -def _is_py2_disabled(ctx): - # In Google, this file isn't bundled with Bazel, so we have to conditionally - # check for this flag. - # TODO: Remove this once a build with the flag is released in Google - if not hasattr(ctx.fragments.py, "disable_py"): - return False - return ctx.fragments.py.disable_py2 - -py_runtime_pair = rule( - implementation = _py_runtime_pair_impl, - attrs = { - # The two runtimes are used by the py_binary at runtime, and so need to - # be built for the target platform. - "py2_runtime": attr.label( - providers = [PyRuntimeInfo], - cfg = "target", - doc = """\ -The runtime to use for Python 2 targets. Must have `python_version` set to -`PY2`. -""", - ), - "py3_runtime": attr.label( - providers = [PyRuntimeInfo], - cfg = "target", - doc = """\ -The runtime to use for Python 3 targets. Must have `python_version` set to -`PY3`. -""", - ), - }, - fragments = ["py"], - doc = """\ -A toolchain rule for Python. - -This wraps up to two Python runtimes, one for Python 2 and one for Python 3. -The rule consuming this toolchain will choose which runtime is appropriate. -Either runtime may be omitted, in which case the resulting toolchain will be -unusable for building Python code using that version. - -Usually the wrapped runtimes are declared using the `py_runtime` rule, but any -rule returning a `PyRuntimeInfo` provider may be used. - -This rule returns a `platform_common.ToolchainInfo` provider with the following -schema: - -```python -platform_common.ToolchainInfo( - py2_runtime = , - py3_runtime = , -) -``` - -Example usage: - -```python -# In your BUILD file... - -load("@rules_python//python:defs.bzl", "py_runtime_pair") - -py_runtime( - name = "my_py2_runtime", - interpreter_path = "/system/python2", - python_version = "PY2", -) - -py_runtime( - name = "my_py3_runtime", - interpreter_path = "/system/python3", - python_version = "PY3", -) - -py_runtime_pair( - name = "my_py_runtime_pair", - py2_runtime = ":my_py2_runtime", - py3_runtime = ":my_py3_runtime", -) - -toolchain( - name = "my_toolchain", - target_compatible_with = <...>, - toolchain = ":my_py_runtime_pair", - toolchain_type = "@rules_python//python:toolchain_type", -) -``` - -```python -# In your WORKSPACE... - -register_toolchains("//my_pkg:my_toolchain") -``` -""", -) - -# TODO(#7844): Add support for a windows (.bat) version of the autodetecting -# toolchain, based on the "py" wrapper (e.g. "py -2" and "py -3"). Use select() -# in the template attr of the _generate_*wrapper targets. - -def define_autodetecting_toolchain( - name, - pywrapper_template, - windows_config_setting): - """Defines the autodetecting Python toolchain. - - This includes both strict and non-strict variants. - - For use only by @bazel_tools//tools/python:BUILD; see the documentation - comment there. - - Args: - name: The name of the toolchain to introduce. Must have value - "autodetecting_toolchain". This param is present only to make the - BUILD file more readable. - pywrapper_template: The label of the pywrapper_template.txt file. - windows_config_setting: The label of a config_setting that matches when - the platform is windows, in which case the toolchain is configured - in a way that triggers a workaround for #7844. - """ - if native.package_name() != "tools/python": - fail("define_autodetecting_toolchain() is private to " + - "@bazel_tools//tools/python") - if name != "autodetecting_toolchain": - fail("Python autodetecting toolchain must be named " + - "'autodetecting_toolchain'") - - expand_pyversion_template( - name = "_generate_wrappers", - template = pywrapper_template, - out2 = ":py2wrapper.sh", - out3 = ":py3wrapper.sh", - out2_nonstrict = ":py2wrapper_nonstrict.sh", - out3_nonstrict = ":py3wrapper_nonstrict.sh", - visibility = ["//visibility:private"], - ) - - # Note that the pywrapper script is a .sh file, not a sh_binary target. If - # we needed to make it a proper shell target, e.g. because it needed to - # access runfiles and needed to depend on the runfiles library, then we'd - # have to use a workaround to allow it to be depended on by py_runtime. See - # https://github.com/bazelbuild/bazel/issues/4286#issuecomment-475661317. - - py_runtime( - name = "_autodetecting_py3_runtime", - interpreter = ":py3wrapper.sh", - python_version = "PY3", - stub_shebang = "#!/usr/bin/env python3", - visibility = ["//visibility:private"], - ) - - py_runtime( - name = "_autodetecting_py3_runtime_nonstrict", - interpreter = ":py3wrapper_nonstrict.sh", - python_version = "PY3", - stub_shebang = "#!/usr/bin/env python3", - visibility = ["//visibility:private"], - ) - - # This is a dummy runtime whose interpreter_path triggers the native rule - # logic to use the legacy behavior on Windows. - # TODO(#7844): Remove this target. - py_runtime( - name = "_magic_sentinel_runtime", - interpreter_path = "/_magic_pyruntime_sentinel_do_not_use", - python_version = "PY3", - visibility = ["//visibility:private"], - ) - - py_runtime_pair( - name = "_autodetecting_py_runtime_pair", - py3_runtime = select({ - # If we're on windows, inject the sentinel to tell native rule logic - # that we attempted to use the autodetecting toolchain and need to - # switch back to legacy behavior. - # TODO(#7844): Remove this hack. - windows_config_setting: ":_magic_sentinel_runtime", - "//conditions:default": ":_autodetecting_py3_runtime", - }), - visibility = ["//visibility:public"], - ) - - py_runtime_pair( - name = "_autodetecting_py_runtime_pair_nonstrict", - py3_runtime = select({ - # Same hack as above. - # TODO(#7844): Remove this hack. - windows_config_setting: ":_magic_sentinel_runtime", - "//conditions:default": ":_autodetecting_py3_runtime_nonstrict", - }), - visibility = ["//visibility:public"], - ) - - native.toolchain( - name = name, - toolchain = ":_autodetecting_py_runtime_pair", - toolchain_type = ":toolchain_type", - visibility = ["//visibility:public"], - ) - - native.toolchain( - name = name + "_nonstrict", - toolchain = ":_autodetecting_py_runtime_pair_nonstrict", - toolchain_type = ":toolchain_type", - visibility = ["//visibility:public"], - ) +def py_runtime_pair(**_kwargs): # buildifier: disable=unused-variable + fail("@bazel_tools//toolchain.bzl py_runtime_pair is deprecated. Use version from rules_python") diff --git a/tools/python/write_file.bzl b/tools/python/write_file.bzl deleted file mode 100644 index 45ec1b6effa6fa..00000000000000 --- a/tools/python/write_file.bzl +++ /dev/null @@ -1,95 +0,0 @@ -# Copyright 2019 The Bazel Authors. All rights reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""write_file() rule from bazel-skylib 0.8.0. - -This file is a copy of rules/private/write_file_private.bzl [1] with some edits: - - this DocString is different - - the rule's 'out' attribute does not create a label, so it is select()-able - -IMPORTANT: please do not use this rule outside of this package. -Related discussion here [2]. - - -[1] https://github.com/bazelbuild/bazel-skylib/blob/3721d32c14d3639ff94320c780a60a6e658fb033/rules/private/write_file_private.bzl - -[2] https://groups.google.com/d/msg/bazel-dev/I8IvJyoyo-s/AttqDcnOCgAJ -""" - -def _common_impl(ctx, is_executable): - # ctx.actions.write creates a FileWriteAction which uses UTF-8 encoding. - out = ctx.actions.declare_file(ctx.attr.out) - ctx.actions.write( - output = out, - content = "\n".join(ctx.attr.content) if ctx.attr.content else "", - is_executable = is_executable, - ) - files = depset(direct = [out]) - runfiles = ctx.runfiles(files = [out]) - if is_executable: - return [DefaultInfo(files = files, runfiles = runfiles, executable = out)] - else: - return [DefaultInfo(files = files, runfiles = runfiles)] - -def _impl(ctx): - return _common_impl(ctx, False) - -def _ximpl(ctx): - return _common_impl(ctx, True) - -_ATTRS = { - "content": attr.string_list(mandatory = False, allow_empty = True), - "out": attr.string(mandatory = True), -} - -_write_file = rule( - implementation = _impl, - provides = [DefaultInfo], - attrs = _ATTRS, -) - -_write_xfile = rule( - implementation = _ximpl, - executable = True, - provides = [DefaultInfo], - attrs = _ATTRS, -) - -def write_file(name, out, content = [], is_executable = False, **kwargs): - """Creates a UTF-8 encoded text file. - - Args: - name: Name of the rule. - out: Path of the output file, relative to this package. - content: A list of strings. Lines of text, the contents of the file. - Newlines are added automatically after every line except the last one. - is_executable: A boolean. Whether to make the output file executable. When - True, the rule's output can be executed using `bazel run` and can be - in the srcs of binary and test rules that require executable sources. - **kwargs: further keyword arguments, e.g. `visibility` - """ - if is_executable: - _write_xfile( - name = name, - content = content, - out = out, - **kwargs - ) - else: - _write_file( - name = name, - content = content, - out = out, - **kwargs - ) diff --git a/workspace_deps.bzl b/workspace_deps.bzl index 77a8f2be9cd4dd..d628179ee5785b 100644 --- a/workspace_deps.bzl +++ b/workspace_deps.bzl @@ -29,13 +29,6 @@ WORKSPACE_REPOS = { "sha256": "dfbadbb37a79eb9e1cc1e156ecb8f817edf3899b28bc02410a6c1eb88b1a6862", "urls": ["https://github.com/bazelbuild/rules_java/releases/download/7.12.1/rules_java-7.12.1.tar.gz"], }, - # Used in src/test/java/com/google/devtools/build/lib/blackbox/framework/blackbox.WORKSAPCE - "rules_proto": { - "archive": "5.3.0-21.7.tar.gz", - "sha256": "dc3fb206a2cb3441b485eb1e423165b231235a1ea9b031b4433cf7bc1fa460dd", - "strip_prefix": "rules_proto-5.3.0-21.7", - "urls": ["https://github.com/bazelbuild/rules_proto/archive/refs/tags/5.3.0-21.7.tar.gz"], - }, "bazel_skylib": { "archive": "bazel-skylib-1.6.1.tar.gz", "sha256": "9f38886a40548c6e96c106b752f242130ee11aaa068a56ba7e56f4511f33e4f2",