in src/python/pants/backend/jvm/tasks/jvm_compile/zinc/zinc_compile.py [0:0]
def compile(self, ctx, args, dependency_classpath, upstream_analysis,
settings, compiler_option_sets, zinc_file_manager,
javac_plugin_map, scalac_plugin_map):
absolute_classpath = (ctx.classes_dir.path,) + tuple(ce.path for ce in dependency_classpath)
if self.get_options().capture_classpath:
self._record_compile_classpath(absolute_classpath, ctx.target, ctx.classes_dir.path)
self._verify_zinc_classpath(absolute_classpath, allow_dist=(self.execution_strategy != self.HERMETIC))
# TODO: Investigate upstream_analysis for hermetic compiles
self._verify_zinc_classpath(upstream_analysis.keys())
def relative_to_exec_root(path):
# TODO: Support workdirs not nested under buildroot by path-rewriting.
return fast_relpath(path, get_buildroot())
classes_dir = ctx.classes_dir.path
analysis_cache = ctx.analysis_file
analysis_cache = relative_to_exec_root(analysis_cache)
classes_dir = relative_to_exec_root(classes_dir)
# TODO: Have these produced correctly, rather than having to relativize them here
relative_classpath = tuple(relative_to_exec_root(c) for c in absolute_classpath)
# list of classpath entries
scalac_classpath_entries = self.scalac_classpath_entries()
scala_path = [classpath_entry.path for classpath_entry in scalac_classpath_entries]
zinc_args = []
zinc_args.extend([
'-log-level', self.get_options().level,
'-analysis-cache', analysis_cache,
'-classpath', ':'.join(relative_classpath),
'-d', classes_dir,
])
if not self.get_options().colors:
zinc_args.append('-no-color')
compiler_bridge_classpath_entry = self._zinc.compile_compiler_bridge(self.context)
zinc_args.extend(['-compiled-bridge-jar', relative_to_exec_root(compiler_bridge_classpath_entry.path)])
zinc_args.extend(['-scala-path', ':'.join(scala_path)])
zinc_args.extend(self._javac_plugin_args(javac_plugin_map))
# Search for scalac plugins on the classpath.
# Note that:
# - We also search in the extra scalac plugin dependencies, if specified.
# - In scala 2.11 and up, the plugin's classpath element can be a dir, but for 2.10 it must be
# a jar. So in-repo plugins will only work with 2.10 if --use-classpath-jars is true.
# - We exclude our own classes_dir/jar_file, because if we're a plugin ourselves, then our
# classes_dir doesn't have scalac-plugin.xml yet, and we don't want that fact to get
# memoized (which in practice will only happen if this plugin uses some other plugin, thus
# triggering the plugin search mechanism, which does the memoizing).
scalac_plugin_search_classpath = (
(set(absolute_classpath) | set(self.scalac_plugin_classpath_elements())) -
{ctx.classes_dir.path, ctx.jar_file.path}
)
zinc_args.extend(self._scalac_plugin_args(scalac_plugin_map, scalac_plugin_search_classpath))
if upstream_analysis:
zinc_args.extend(['-analysis-map',
','.join('{}:{}'.format(
relative_to_exec_root(k),
relative_to_exec_root(v)
) for k, v in upstream_analysis.items())])
zinc_args.extend(args)
zinc_args.extend(self._get_zinc_arguments(settings))
zinc_args.append('-transactional')
compiler_option_sets_args = self.get_merged_args_for_compiler_option_sets(compiler_option_sets)
zinc_args.extend(compiler_option_sets_args)
if not self._clear_invalid_analysis:
zinc_args.append('-no-clear-invalid-analysis')
if not zinc_file_manager:
zinc_args.append('-no-zinc-file-manager')
jvm_options = []
if self.javac_classpath():
# Make the custom javac classpath the first thing on the bootclasspath, to ensure that
# it's the one javax.tools.ToolProvider.getSystemJavaCompiler() loads.
# It will probably be loaded even on the regular classpath: If not found on the bootclasspath,
# getSystemJavaCompiler() constructs a classloader that loads from the JDK's tools.jar.
# That classloader will first delegate to its parent classloader, which will search the
# regular classpath. However it's harder to guarantee that our javac will preceed any others
# on the classpath, so it's safer to prefix it to the bootclasspath.
jvm_options.extend(['-Xbootclasspath/p:{}'.format(':'.join(self.javac_classpath()))])
jvm_options.extend(self._jvm_options)
zinc_args.extend(ctx.sources)
self.log_zinc_file(ctx.analysis_file)
with open(ctx.zinc_args_file, 'w') as fp:
for arg in zinc_args:
# NB: in Python 2, options are stored sometimes as bytes and sometimes as unicode in the OptionValueContainer.
# This is due to how Python 2 natively stores attributes as a map of `str` (aka `bytes`) to their value. So,
# the setattr() and getattr() functions sometimes use bytes.
if PY2:
arg = ensure_text(arg)
fp.write(arg)
fp.write('\n')
return self.execution_strategy_enum.resolve_for_enum_variant({
self.HERMETIC: lambda: self._compile_hermetic(
jvm_options, ctx, classes_dir, zinc_args, compiler_bridge_classpath_entry,
dependency_classpath, scalac_classpath_entries),
self.SUBPROCESS: lambda: self._compile_nonhermetic(jvm_options, zinc_args),
self.NAILGUN: lambda: self._compile_nonhermetic(jvm_options, zinc_args),
})()