diff options
author | 2015-06-11 10:00:35 +0000 | |
---|---|---|
committer | 2015-06-11 10:39:54 +0000 | |
commit | 93e5b8223839e28e064812d9d4e7c144dee67f43 (patch) | |
tree | 9763d2e3704b864b7f2f6bb122b13039c2e0a9ac /src | |
parent | 0bf90f7c2102689a2733087b458e8a2b8b7e6f6f (diff) |
Various improvements to Python support in Bazel:
- Make it possible to select the Python2/Python3 binaries to be used on the command line. Ideally, we'd also support hermetic Python runtimes, but no one wants them at the moment, so let's not do speculative work.
- Make the Python stub script compatible with Python3.
- Use the Python3 binary for py_binaries that are built for it.
--
MOS_MIGRATED_REVID=95722749
Diffstat (limited to 'src')
4 files changed, 112 insertions, 3 deletions
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 a95c2dfa37..e7cdabe296 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 @@ -50,6 +50,7 @@ import com.google.devtools.build.lib.bazel.rules.python.BazelPyBinaryRule; import com.google.devtools.build.lib.bazel.rules.python.BazelPyLibraryRule; 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.bazel.rules.sh.BazelShBinaryRule; import com.google.devtools.build.lib.bazel.rules.sh.BazelShLibraryRule; import com.google.devtools.build.lib.bazel.rules.sh.BazelShRuleClasses; @@ -184,6 +185,7 @@ public class BazelRuleClassProvider { CppOptions.class, JavaOptions.class, PythonOptions.class, + BazelPythonConfiguration.Options.class, ObjcCommandLineOptions.class, J2ObjcCommandLineOptions.class ); @@ -310,6 +312,7 @@ public class BazelRuleClassProvider { builder.addConfigurationFragment(new CppConfigurationLoader( Functions.<String>identity())); builder.addConfigurationFragment(new PythonConfigurationLoader(Functions.<String>identity())); + builder.addConfigurationFragment(new BazelPythonConfiguration.Loader()); builder.addConfigurationFragment(new JvmConfigurationLoader(JAVA_CPU_SUPPLIER)); builder.addConfigurationFragment(new JavaConfigurationLoader(JAVA_CPU_SUPPLIER)); builder.addConfigurationFragment(new ObjcConfigurationLoader()); diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonConfiguration.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonConfiguration.java new file mode 100644 index 0000000000..005fc61688 --- /dev/null +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonConfiguration.java @@ -0,0 +1,96 @@ +// Copyright 2015 Google Inc. 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.common.collect.ImmutableSet; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration; +import com.google.devtools.build.lib.analysis.config.BuildConfiguration.Fragment; +import com.google.devtools.build.lib.analysis.config.BuildOptions; +import com.google.devtools.build.lib.analysis.config.ConfigurationEnvironment; +import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory; +import com.google.devtools.build.lib.analysis.config.FragmentOptions; +import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException; +import com.google.devtools.common.options.Option; + +import javax.annotation.Nullable; + +/** + * Bazel-specific Python configuration. + */ +public class BazelPythonConfiguration extends BuildConfiguration.Fragment { + + /** + * Bazel-specific Python configuration options. + */ + public static final class Options extends FragmentOptions { + @Option(name = "python2_path", + defaultValue = "python", + category = "version", + help = "Local path to the Python2 executable.") + public String python2Path; + + @Option(name = "python3_path", + defaultValue = "python3", + category = "version", + help = "Local path to the Python3 executable.") + public String python3Path; + } + + /** + * Loader for the Bazel-specific Python configuration. + */ + public static final class Loader implements ConfigurationFragmentFactory { + @Nullable + @Override + public Fragment create(ConfigurationEnvironment env, BuildOptions buildOptions) + throws InvalidConfigurationException { + return new BazelPythonConfiguration(buildOptions.get(Options.class)); + } + + @Override + public Class<? extends Fragment> creates() { + return BazelPythonConfiguration.class; + } + + @Override + public ImmutableSet<Class<? extends FragmentOptions>> requiredOptions() { + return ImmutableSet.<Class<? extends FragmentOptions>>of(Options.class); + } + } + + private final Options options; + + private BazelPythonConfiguration(Options options) { + this.options = options; + } + + @Override + public String getName() { + return "BazelPython"; + } + + @Override + public String cacheKey() { + return ""; + } + + public String getPython2Path() { + return options.python2Path; + } + + public String getPython3Path() { + return options.python3Path; + } +} diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java index 3b249010c1..e560f6dd20 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/BazelPythonSemantics.java @@ -58,12 +58,22 @@ public class BazelPythonSemantics implements PythonSemantics { public void createExecutable(RuleContext ruleContext, PyCommon common, CcLinkParamsStore ccLinkParamsStore) { String main = common.determineMainExecutableSource(); + BazelPythonConfiguration config = ruleContext.getFragment(BazelPythonConfiguration.class); + String pythonBinary; + + switch (common.getVersion()) { + case PY2: pythonBinary = config.getPython2Path(); break; + case PY3: pythonBinary = config.getPython3Path(); break; + default: throw new IllegalStateException(); + } ruleContext.registerAction(new TemplateExpansionAction( ruleContext.getActionOwner(), common.getExecutable(), STUB_TEMPLATE, - ImmutableList.of(Substitution.of("%main%", main)), + ImmutableList.of( + Substitution.of("%main%", main), + Substitution.of("%python_binary%", pythonBinary)), true)); } diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/stub_template.txt b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/stub_template.txt index 743ffd4d5f..fcedeb3bcc 100644 --- a/src/main/java/com/google/devtools/build/lib/bazel/rules/python/stub_template.txt +++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/python/stub_template.txt @@ -1,5 +1,5 @@ #!/bin/bash -eu -STUBPATH=$(python -c "import os.path; print os.path.realpath('$0');") +STUBPATH=$(%python_binary% -c "import os.path; print(os.path.realpath('$0'));") export PYTHONPATH=$STUBPATH.runfiles -exec python ${PYTHONPATH}/%main% $@ +exec %python_binary% ${PYTHONPATH}/%main% $@ |