Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract a zinc subsystem to allow for more entrypoints #4720

Merged
merged 2 commits into from
Jul 5, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/python/pants/backend/jvm/subsystems/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,15 @@ python_library(
]
)

python_library(
name = 'zinc',
sources = ['zinc.py'],
dependencies = [
':jvm_tool_mixin',
'src/python/pants/subsystem',
]
)

python_library(
name = 'zinc_language_mixin',
sources = ['zinc_language_mixin.py'],
Expand Down
75 changes: 75 additions & 0 deletions src/python/pants/backend/jvm/subsystems/zinc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# coding=utf-8
# Copyright 2017 Pants project contributors (see CONTRIBUTORS.md).
# Licensed under the Apache License, Version 2.0 (see LICENSE).

from __future__ import (absolute_import, division, generators, nested_scopes, print_function,
unicode_literals, with_statement)

from pants.backend.jvm.subsystems.jvm_tool_mixin import JvmToolMixin
from pants.backend.jvm.subsystems.shader import Shader
from pants.java.jar.jar_dependency import JarDependency
from pants.subsystem.subsystem import Subsystem


class Zinc(Subsystem, JvmToolMixin):
"""Configuration for Pants' zinc wrapper tool."""

options_scope = 'zinc'

ZINC_COMPILE_MAIN = 'org.pantsbuild.zinc.Main'

@classmethod
def register_options(cls, register):
super(Zinc, cls).register_options(register)
Zinc.register_options_for(cls, register)

@staticmethod
def register_options_for(jvm_tool_mixin_cls, register, **kwargs):
"""Register options for the zinc tool in the context of the given JvmToolMixin.

TODO: Move into the classmethod after zinc registration has been removed
from `zinc_compile` in `1.6.0.dev0`.
"""
cls = jvm_tool_mixin_cls

def sbt_jar(name, **kwargs):
return JarDependency(org='org.scala-sbt', name=name, rev='1.0.0-X5', **kwargs)

shader_rules = [
# The compiler-interface and compiler-bridge tool jars carry xsbt and
# xsbti interfaces that are used across the shaded tool jar boundary so
# we preserve these root packages wholesale along with the core scala
# APIs.
Shader.exclude_package('scala', recursive=True),
Shader.exclude_package('xsbt', recursive=True),
Shader.exclude_package('xsbti', recursive=True),
]

cls.register_jvm_tool(register,
'zinc',
classpath=[
JarDependency('org.pantsbuild', 'zinc_2.10', '0.0.5'),
],
main=Zinc.ZINC_COMPILE_MAIN,
custom_rules=shader_rules,
**kwargs)

cls.register_jvm_tool(register,
'compiler-bridge',
classpath=[
sbt_jar(name='compiler-bridge_2.10',
classifier='sources',
intransitive=True)
],
**kwargs)
cls.register_jvm_tool(register,
'compiler-interface',
classpath=[
sbt_jar(name='compiler-interface')
],
# NB: We force a noop-jarjar'ing of the interface, since it is now broken
# up into multiple jars, but zinc does not yet support a sequence of jars
# for the interface.
main='no.such.main.Main',
custom_rules=shader_rules,
**kwargs)
1 change: 1 addition & 0 deletions src/python/pants/backend/jvm/tasks/jvm_compile/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ python_library(
'src/python/pants/backend/jvm/subsystems:java',
'src/python/pants/backend/jvm/subsystems:scala_platform',
'src/python/pants/backend/jvm/subsystems:shader',
'src/python/pants/backend/jvm/subsystems:zinc',
'src/python/pants/backend/jvm/targets:java',
'src/python/pants/backend/jvm/targets:scala',
'src/python/pants/backend/jvm/zinc',
Expand Down
86 changes: 36 additions & 50 deletions src/python/pants/backend/jvm/tasks/jvm_compile/zinc/zinc_compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from pants.backend.jvm.subsystems.java import Java
from pants.backend.jvm.subsystems.jvm_platform import JvmPlatform
from pants.backend.jvm.subsystems.scala_platform import ScalaPlatform
from pants.backend.jvm.subsystems.shader import Shader
from pants.backend.jvm.subsystems.zinc import Zinc
from pants.backend.jvm.targets.annotation_processor import AnnotationProcessor
from pants.backend.jvm.targets.javac_plugin import JavacPlugin
from pants.backend.jvm.targets.jvm_target import JvmTarget
Expand All @@ -31,7 +31,6 @@
from pants.base.hash_utils import hash_file
from pants.base.workunit import WorkUnitLabel
from pants.java.distribution.distribution import DistributionLocator
from pants.java.jar.jar_dependency import JarDependency
from pants.util.contextutil import open_zip
from pants.util.dirutil import safe_open
from pants.util.memo import memoized_method, memoized_property
Expand All @@ -53,8 +52,6 @@
class BaseZincCompile(JvmCompile):
"""An abstract base class for zinc compilation tasks."""

_ZINC_MAIN = 'org.pantsbuild.zinc.Main'

_supports_concurrent_execution = True

_name = 'zinc'
Expand Down Expand Up @@ -181,44 +178,13 @@ def register_options(cls, register):
'This is unset by default, because it is generally a good precaution to cache '
'only clean/cold builds.')

def sbt_jar(name, **kwargs):
return JarDependency(org='org.scala-sbt', name=name, rev='1.0.0-X5', **kwargs)

shader_rules = [
# The compiler-interface and compiler-bridge tool jars carry xsbt and
# xsbti interfaces that are used across the shaded tool jar boundary so
# we preserve these root packages wholesale along with the core scala
# APIs.
Shader.exclude_package('scala', recursive=True),
Shader.exclude_package('xsbt', recursive=True),
Shader.exclude_package('xsbti', recursive=True),
]

cls.register_jvm_tool(register,
'zinc',
classpath=[
JarDependency('org.pantsbuild', 'zinc_2.10', '0.0.5'),
],
main=cls._ZINC_MAIN,
custom_rules=shader_rules)

cls.register_jvm_tool(register,
'compiler-bridge',
classpath=[
sbt_jar(name='compiler-bridge_2.10',
classifier='sources',
intransitive=True)
])
cls.register_jvm_tool(register,
'compiler-interface',
classpath=[
sbt_jar(name='compiler-interface')
],
# NB: We force a noop-jarjar'ing of the interface, since it is now broken
# up into multiple jars, but zinc does not yet support a sequence of jars
# for the interface.
main='no.such.main.Main',
custom_rules=shader_rules)
Zinc.register_options_for(cls, register,
removal_version='1.6.0.dev0',
removal_hint='Zinc tools should be registered via the `zinc` scope.')

@classmethod
def subsystem_dependencies(cls):
return super(BaseZincCompile, cls).subsystem_dependencies() + (Zinc,)

@classmethod
def prepare(cls, options, round_manager):
Expand All @@ -239,6 +205,28 @@ def cache_incremental(self):
"""Optionally write the results of incremental compiles to the cache."""
return self.get_options().incremental_caching

@memoized_property
def _zinc_tools(self):
"""Get the instance of the JvmToolMixin to use for zinc.

TODO: Remove and use Zinc.global_instance() directly once the old tool location is removed
in `1.6.0.dev0`.
"""
# If any tools were explicitly specified on self, use them... else, use the Zinc subsystem.
explicit_keys = set(self.get_options().get_explicit_keys())
explicit_on_self = explicit_keys & set(['zinc', 'compiler-bridge', 'compiler-interface'])
return self if explicit_on_self else Zinc.global_instance()

def _zinc_tool_classpath(self, toolname):
return self._zinc_tools.tool_classpath_from_products(self.context.products,
toolname,
scope=self.options_scope)

def _zinc_tool_jar(self, toolname):
return self._zinc_tools.tool_jar_from_products(self.context.products,
toolname,
scope=self.options_scope)

def __init__(self, *args, **kwargs):
super(BaseZincCompile, self).__init__(*args, **kwargs)
self.set_distribution(jdk=True)
Expand All @@ -260,9 +248,6 @@ def create_analysis_tools(self):
return AnalysisTools(self.dist.real_home, ZincAnalysisParser(), ZincAnalysis,
get_buildroot(), self.get_options().pants_workdir)

def zinc_classpath(self):
return self.tool_classpath('zinc')

def javac_classpath(self):
# Note that if this classpath is empty then Zinc will automatically use the javac from
# the JDK it was invoked with.
Expand Down Expand Up @@ -297,7 +282,8 @@ def _zinc_cache_dir(self):
"""
hasher = sha1()
for tool in ['zinc', 'compiler-interface', 'compiler-bridge']:
hasher.update(os.path.relpath(self.tool_jar(tool), self.get_options().pants_workdir))
hasher.update(os.path.relpath(self._zinc_tool_jar(tool),
self.get_options().pants_workdir))
key = hasher.hexdigest()[:12]
return os.path.join(self.get_options().pants_bootstrapdir, 'zinc', key)

Expand All @@ -320,8 +306,8 @@ def compile(self, args, classpath, sources, classes_output_dir, upstream_analysi
if log_file:
zinc_args.extend(['-capture-log', log_file])

zinc_args.extend(['-compiler-interface', self.tool_jar('compiler-interface')])
zinc_args.extend(['-compiler-bridge', self.tool_jar('compiler-bridge')])
zinc_args.extend(['-compiler-interface', self._zinc_tool_jar('compiler-interface')])
zinc_args.extend(['-compiler-bridge', self._zinc_tool_jar('compiler-bridge')])
zinc_args.extend(['-zinc-cache-dir', self._zinc_cache_dir])
zinc_args.extend(['-scala-path', ':'.join(self.scalac_classpath())])

Expand Down Expand Up @@ -377,8 +363,8 @@ def compile(self, args, classpath, sources, classes_output_dir, upstream_analysi
fp.write(arg)
fp.write(b'\n')

if self.runjava(classpath=self.zinc_classpath(),
main=self._ZINC_MAIN,
if self.runjava(classpath=self._zinc_tool_classpath('zinc'),
main=Zinc.ZINC_COMPILE_MAIN,
jvm_options=jvm_options,
args=zinc_args,
workunit_name=self.name(),
Expand Down