Skip to content

Compiler option sets for Native targets - #6665

Merged
stuhood merged 20 commits into
pantsbuild:masterfrom
CMLivingston:clivingston/bump-conan-182
Nov 2, 2018
Merged

Compiler option sets for Native targets#6665
stuhood merged 20 commits into
pantsbuild:masterfrom
CMLivingston:clivingston/bump-conan-182

Conversation

@CMLivingston

@CMLivingston CMLivingston commented Oct 20, 2018

Copy link
Copy Markdown
Contributor

Problem

Native targets do not have support for compiler option sets.

Solution

Add support for compiler options sets for use in native compile tasks.

Result

Users can specify option set defaults and their corresponding default enabled values in Pants.ini. Native targets support option sets.

@CMLivingston CMLivingston changed the title (WIP) Extra compiler args for cpp_library targets Add 2 extra compiler args for native targets Oct 22, 2018
@stuhood

stuhood commented Oct 23, 2018

Copy link
Copy Markdown
Member

@CMLivingston talked about this offline... I had initially suggested that it would be easier to add compiler_options_sets in a followup change, but I think that I was wrong about that. Sorry @CMLivingston !

@cosmicexplorer : If you agree that it is worthwhile to do compiler_option_sets here, that would be my vote.

@CMLivingston

Copy link
Copy Markdown
Contributor Author

I'll move forward with compiler_option_sets.

@CMLivingston

Copy link
Copy Markdown
Contributor Author

Took a first pass at option sets. @cosmicexplorer I tried to capture what you were talking about as using a mixin for shared default option set keys. Please let me know if this is at all related to what you were describing. More testing to come after I get the green light. Thanks!

@stuhood stuhood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks reasonable, thanks.

# 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.')
register('--fatal-warnings-enabled-args', advanced=True, type=list, fingerprint=True,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The changes to the fatal-warnings option should not be necessary here: can leave it as is, and then it can be deprecated in a followup.

help='Extra compiler args to use when fatal warnings are disabled.')
register('--compiler-option-sets-enabled-args', advanced=True, type=dict, fingerprint=True,
default={
'fatal_warnings': list(cls.get_fatal_warnings_enabled_args_default()),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that this backend is fairly young, I don't think that you should worry about attempting to preserve backwards compatibility here. So it should be fine to have the default enabled/disabled args just be empty.

'include_dirs',
'sources',
('fatal_warnings', bool),
('ndebug', bool),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will need an update.

include_dirs=include_dirs,
sources=sources_and_headers,
fatal_warnings=self._compile_settings.get_fatal_warnings_value_for_target(target),
compiler_option_sets_options=self._compile_settings.get_merged_compiler_options_for_target(target),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point they will have been flattened, so you can probably just call this field compiler_options.

@CMLivingston

Copy link
Copy Markdown
Contributor Author

@stuhood regarding inheritance of NativeBuildSettings, is there any reason to use subsystem dependencies over direct inheritance here?

@stuhood

stuhood commented Oct 24, 2018

Copy link
Copy Markdown
Member

@stuhood regarding inheritance of NativeBuildSettings, is there any reason to use subsystem dependencies over direct inheritance here?

There are a few things to think about, and I'm not sure I can recommend the appropriate thing here, but I know that @cosmicexplorer can:

Using a Subsystem always means creating a new "namespace". If you scope the subsystem (MySubsystem.scoped(cls)) then the new namespace is scoped above the dependee's scope (my-subsystem-scope.my-dependee-scope). If you use a global subsystem (MySubsystem), then you're just creating a new independent namespace/scope (my-subsystem-scope).

If you use inheritance, then you're just adding the options directly to some existing (Task, maybe/generally?) scope, rather than creating a new one.

@CMLivingston CMLivingston changed the title Add 2 extra compiler args for native targets Compiler option sets for Native targets Oct 24, 2018
@CMLivingston
CMLivingston force-pushed the clivingston/bump-conan-182 branch from 8eba2b6 to 6801834 Compare October 24, 2018 21:18

@stuhood stuhood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

Comment thread src/python/pants/backend/native/subsystems/conan.py Outdated

class NativeBuildStepSettingsBase(Subsystem, MirroredTargetOptionMixin):

options_scope = 'native-build-step-settings-base'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that this class is supposed to be abstract, and then mixed in to a language specific subsystem? If so, it shouldn't need an options_scope to be defined, because the subclass will handle that.

@CMLivingston CMLivingston Oct 24, 2018

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is here to allow for base options set definitions that can be shared between C and CPP (different from default option set keys).

@stuhood stuhood Oct 24, 2018

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. Do we think that that is a blocker? Might be easier to wait to add that flexibility if need be.

Or to go the other way? I know that in a previous revision @cosmicexplorer mentioned that he wasn't sure that the C/C++ language split was carrying its weight: #6628 (review)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...oh, nevermind. I misinterpreted that.

compiler_options = set()

# Set values for enabled options.
if compiler_option_sets:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Below you directly access the compiler_option_sets variable, which implies that it is not None within this method... if that's the case, it should be fine to just have this loop at the top level rather than guarded by the if.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.get_fatal_warnings_value_for_target(target)),
compiler_options=(self._compile_settings
._native_build_step_settings
.get_merged_compiler_options_for_target(target,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like the get_merged_compiler_options_for_target method already includes the enabled/disabled args dicts... are the arguments here a different collection of options? If so, is there a usecase for that? It's sortof confusing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These arguments are to compose the dicts for the subclasses into the calculation. The dicts that are pulled from self.get_options() belong to the base class.

Comment thread src/python/pants/backend/native/subsystems/native_build_step_settings_base.py Outdated
Comment thread src/python/pants/backend/native/tasks/native_compile.py Outdated
@stuhood stuhood added this to the 1.11.x milestone Oct 24, 2018
@CMLivingston

Copy link
Copy Markdown
Contributor Author

ping @stuhood, this is in a good state for review when you can.

@stuhood stuhood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is very close, but there is one big open question. Thanks!

from pants.util.memo import memoized_property


class NativeBuildStepSettings(Subsystem, MirroredTargetOptionMixin):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not completely clear on why this is a different subsystem than NativeBuildSettings.

Rather than adding this subsystem, would it be useful to just define the new options on that subsystem? And if they need to be split for some reason, could you add docstrings to both of them explaining why?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is described in #6486 -- https://github.com/pantsbuild/pants/blob/5e320b721c234cdc6a56e5c762441a87741d85d7/src/python/pants/backend/native/subsystems/native_build_step_settings_base.py. They are named like this because that PR is still in development. The names could maybe be improved -- I don't like calling everything "settings" but want to differentiate it from e.g. the compile tasks.

Comment thread src/python/pants/backend/native/subsystems/native_build_step_settings.py Outdated

@cosmicexplorer cosmicexplorer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would really like the implementation of compiler_option_sets to be shared with the JVM implementation for this to be merged, ideally as a mixin (something similar to e.g. MirroredTargetOptionMixin). Even getting the hang of understanding how to use compiler_option_sets has been described as difficult to me from users consuming the JVM version, and I really don't want to introduce further idiosyncracies.

The reason why I want this is because we'll never have to make any subsystems just to add a compiler option ever again, and because then every other subsystem will have a deep knowledge of which settings to apply in which scenarios, which could potentially make it extremely easy to then implement reliable and granular caching of native artifacts in a way, yet again, that no other build tool can do.

Comment thread src/python/pants/backend/native/tasks/native_compile.py Outdated
Comment thread src/python/pants/backend/native/subsystems/native_build_step_settings.py Outdated
import os


def get_generated_shared_lib(lib_name):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question unrelated to this specific code -- is there a way we can package the ctypes dylibs in a way that allows us to access it like a JVM resource instead of hardcoding the relative path? Not anything to fix in this PR specifically.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure. I think there would need to be coherence between the compile tasks and the resource target handling. However, I think resources just pull in the same dir structure as the path you provide to the resource files themselves (I'm not too familiar with that target type).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made #6711 in case anyone gets any smart ideas.

]
pants_run = self.run_pants(command=command, config={
'native-build-step-settings.cpp-compile-settings': {
'compiler_option_sets_enabled_args': {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me pretty happy to see, we are changing the C/C++ game every step of the way.

Comment thread src/python/pants/backend/native/subsystems/native_build_step_settings.py Outdated
Comment thread src/python/pants/backend/native/subsystems/native_build_step_settings.py Outdated
from pants.util.memo import memoized_property


class NativeBuildStepSettings(Subsystem, MirroredTargetOptionMixin):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The difference is described in #6486 -- https://github.com/pantsbuild/pants/blob/5e320b721c234cdc6a56e5c762441a87741d85d7/src/python/pants/backend/native/subsystems/native_build_step_settings_base.py. They are named like this because that PR is still in development. The names could maybe be improved -- I don't like calling everything "settings" but want to differentiate it from e.g. the compile tasks.

Comment thread src/python/pants/backend/native/subsystems/conan.py Outdated
@CMLivingston

Copy link
Copy Markdown
Contributor Author

This is in a great state for a final pass @stuhood @cosmicexplorer.

@cosmicexplorer cosmicexplorer left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can extract --fatal-warnings-* args more in the future, but I think the notice I left on deprecating the specific options should be enough for this PR. I left a comment on #6710 to finish any cleanup work that might be necessary beyond that so it doesn't block this PR.

Comment thread src/python/pants/backend/native/tasks/native_compile.py Outdated
Comment thread src/python/pants/backend/native/tasks/native_compile.py Outdated
Comment thread src/python/pants/backend/jvm/tasks/jvm_compile/jvm_compile.py
Comment thread src/python/pants/option/compiler_option_sets_mixin.py
Comment thread src/python/pants/option/compiler_option_sets_mixin.py
import os


def get_generated_shared_lib(lib_name):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made #6711 in case anyone gets any smart ideas.

@stuhood stuhood left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Just a naming nit. Thanks for iterating here.


class NativeBuildStepSettings(CompilerOptionSetsMixin, MirroredTargetOptionMixin, Subsystem):

options_scope = 'native-build-step-settings'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still pretty verbose. Putting the words "options" or "settings" in the names of options is probably superfluous.

In this case you're ending up with a subsystem instance scope named native-build-step-settings.c-compile-settings.

@stuhood
stuhood merged commit f8c02be into pantsbuild:master Nov 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants