Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add testproject with C/C++ interdependent targets, fix native backend…
… design mistake (#6628) ### Problem *This probably blocks #6486 and #6492.* As @CMLivingston and I realized sometime this week (to my *immense* dismay), we had no tests of native library targets depending on each other. When making these examples, I realized two things: 1. `--strict-deps` doesn't really make sense as two separate options for C and C++ targets which can depend on each other. 2. The implementation of `--strict-deps` in the native backend ("caching" native target interdependencies in a product from the compiler tasks) was absurd and unnecessary. I think I vaguely recall that the fact that `LinkSharedLibraries` previously did not have a subsystem dependency on the `CCompileSettings` or `CppCompileSettings` subsystems may have led to a subtle caching bug in the link task when options in those subsystems were modified, but I don't remember all the details right now. Regardless, that bug would have been fixed with this PR -- see the below: ### Solution - Move dependency calculation into a single `NativeBuildSettings` subsystem which is consumed by compile and link tasks, and use it to calculate the dependencies in both tasks. - Drop the very unnecessary `NativeTargetDependencies` product. - Move a ton of logic into `NativeTask` that really should have been there instead of `NativeCompile`, but couldn't because of the hacked together dependency calculation. - Add a testproject with C and C++ targets depending on each other, and an integration test showing the above all works. ### Result We have a working example of C and C++ targets depending on each other, resulting in idiomatic enough C and C++, which also work extremely effectively in a `python_dist()` target.
- Loading branch information
1 parent
103c0a6
commit f5120a2
Showing
25 changed files
with
433 additions
and
175 deletions.
There are no files selected for viewing
32 changes: 32 additions & 0 deletions
32
src/python/pants/backend/native/subsystems/native_build_settings.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# coding=utf-8 | ||
# Copyright 2018 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import absolute_import, division, print_function, unicode_literals | ||
|
||
from pants.backend.native.subsystems.utils.mirrored_target_option_mixin import \ | ||
MirroredTargetOptionMixin | ||
from pants.subsystem.subsystem import Subsystem | ||
|
||
|
||
class NativeBuildSettings(Subsystem, MirroredTargetOptionMixin): | ||
"""Any settings relevant to a compiler and/or linker invocation.""" | ||
options_scope = 'native-build-settings' | ||
|
||
mirrored_option_to_kwarg_map = { | ||
'strict_deps': 'strict_deps', | ||
} | ||
|
||
@classmethod | ||
def register_options(cls, register): | ||
super(NativeBuildSettings, cls).register_options(register) | ||
|
||
# TODO: rename this so it's clear it is not the same option as JVM strict deps! | ||
register('--strict-deps', type=bool, default=True, fingerprint=True, advanced=True, | ||
help="Whether to include only dependencies directly declared in the BUILD file " | ||
"for C and C++ targets by default. If this is False, all transitive dependencies " | ||
"are used when compiling and linking native code. C and C++ targets may override " | ||
"this behavior with the strict_deps keyword argument as well.") | ||
|
||
def get_strict_deps_value_for_target(self, target): | ||
return self.get_target_mirrored_option('strict_deps', target) |
41 changes: 41 additions & 0 deletions
41
src/python/pants/backend/native/subsystems/native_build_step_settings_base.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# coding=utf-8 | ||
# Copyright 2018 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import absolute_import, division, print_function, unicode_literals | ||
|
||
from pants.backend.native.subsystems.utils.mirrored_target_option_mixin import \ | ||
MirroredTargetOptionMixin | ||
from pants.subsystem.subsystem import Subsystem | ||
|
||
|
||
class NativeBuildStepSettingsBase(Subsystem, MirroredTargetOptionMixin): | ||
|
||
mirrored_option_to_kwarg_map = { | ||
'fatal_warnings': 'fatal_warnings', | ||
} | ||
|
||
@classmethod | ||
def register_options(cls, register): | ||
super(NativeBuildStepSettingsBase, cls).register_options(register) | ||
|
||
# TODO: implement compiler_option_sets as an interface to platform/host-specific optimization | ||
# flags! | ||
register('--fatal-warnings', type=bool, default=True, fingerprint=True, advanced=True, | ||
help='The default for the "fatal_warnings" argument for targets of this language.') | ||
|
||
def get_fatal_warnings_value_for_target(self, target): | ||
return self.get_target_mirrored_option('fatal_warnings', target) | ||
|
||
|
||
class CCompileSettings(NativeBuildStepSettingsBase): | ||
options_scope = 'c-compile-settings' | ||
|
||
|
||
class CppCompileSettings(NativeBuildStepSettingsBase): | ||
options_scope = 'cpp-compile-settings' | ||
|
||
|
||
# TODO: add a fatal_warnings kwarg to NativeArtifact and make a LinkSharedLibrariesSettings subclass | ||
# of NativeBuildStepSettingsBase here! The method should work even though NativeArtifact is not a | ||
# Target. |
37 changes: 0 additions & 37 deletions
37
src/python/pants/backend/native/subsystems/native_compile_settings.py
This file was deleted.
Oops, something went wrong.
35 changes: 35 additions & 0 deletions
35
src/python/pants/backend/native/subsystems/utils/mirrored_target_option_mixin.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
# coding=utf-8 | ||
# Copyright 2018 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import absolute_import, division, print_function, unicode_literals | ||
|
||
from builtins import object | ||
|
||
from pants.util.meta import classproperty | ||
|
||
|
||
# TODO: consider coalescing existing methods of mirroring options between a target and a subsystem | ||
# -- see pants.backend.jvm.subsystems.dependency_context.DependencyContext#defaulted_property()! | ||
class MirroredTargetOptionMixin(object): | ||
"""Get option values which may be set in this subsystem or in a Target's keyword argument.""" | ||
|
||
@classproperty | ||
def mirrored_option_to_kwarg_map(cls): | ||
"""Subclasses should override and return a dict of (subsystem option name) -> (target kwarg). | ||
This classproperty should return a dict mapping this subsystem's options attribute name (with | ||
underscores) to the corresponding target's keyword argument name. | ||
""" | ||
raise NotImplementedError() | ||
|
||
def get_target_mirrored_option(self, option_name, target): | ||
field_name = self.mirrored_option_to_kwarg_map[option_name] | ||
return self._get_subsystem_target_mirrored_field_value(option_name, field_name, target) | ||
|
||
def _get_subsystem_target_mirrored_field_value(self, option_name, field_name, target): | ||
"""Get the attribute `field_name` from `target` if set, else from this subsystem's options.""" | ||
tgt_setting = getattr(target, field_name) | ||
if tgt_setting is None: | ||
return getattr(self.get_options(), option_name) | ||
return tgt_setting |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.