Skip to content

dynamic inheritance for packages that change build system#10411

Closed
becker33 wants to merge 5 commits intodevelopfrom
mfu-cmake
Closed

dynamic inheritance for packages that change build system#10411
becker33 wants to merge 5 commits intodevelopfrom
mfu-cmake

Conversation

@becker33
Copy link
Copy Markdown
Member

Began with @gonsie changing mpifileutils to use cmake.

Implemented DynamicInheritancePackage build system that can dynamically change its phases and attributes to mirror the other build system classes. The classes field is a dictionary of build system classes and anonymous specs describing when they are used.

Package classes are responsible for shadowing any dependencies and variants from the build system classes they intend to inherit from.

mpifileutils provides an example with a package changing from autotools to cmake, including handling the build_type variant from CMakePackage through the flag_handler method for the earlier versions that use autotools.

@tgamblin I think you will find this interesting.

Copy link
Copy Markdown
Member

@adamjstewart adamjstewart left a comment

Choose a reason for hiding this comment

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

Overall, very interesting! I was hoping there would be some kind of way to specify multiple base classes, like:

class Mpifileutils(CMakePackage, AutotoolsPackage):

in terms of syntax, but this is better than nothing.

@adamjstewart adamjstewart requested a review from alalazo January 23, 2019 03:01
Copy link
Copy Markdown
Contributor

@healther healther left a comment

Choose a reason for hiding this comment

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

I very much like this! And actually I think I prefer this implementation, i.e. an explicit list of build types for different versions, rather than trying to abuse multiple inheritances. But I guess that is just a personal opinion.

Some comments, but mainly typos (or suspected ones) that I found. There should be some documentation for DynamicInheritancePackage at least I don't currently completely grasp what the intended behavior and use is in most cases.

Properties are captured using fget and attached to the package class
All others are attached directly.

This will need to be revisited if/when a build system adds a multimethod
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 assumption should probably be guarded by a unit test...


depends_on('[email protected]', when='@0.9:', type='build')

variant('build_type', default='RelWithDebInfo',
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.

Doesn't this variant come from CMakePackage? Why does it need to be created here again?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Packages inheriting from DynamicInheritancePackage will have to shadow the directives from the parent class, since they need access to those before they get a chance to set their inheritance. That's variants, dependencies, and conflicts. If anyone has a brilliant idea let me know, but as of now I don't know of any way to do it other than shadowing those.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Jan 23, 2019

TL;DR I think this PR addresses a need that is present in more than a few packages and has been overlooked so far, but I also have a few strong concerns on the current implementation where all the attributes of different build-systems are merged in a single class.

This can become quite messy and doesn't keep the information pertaining to different build-systems separated from each other. To get this feature right we might need some support from the concretizer and possibly an extension of the spec syntax.

I'll share below a few random thoughts that I noted down in the past on this issue. Hope they can be useful to foster some discussion.


Packages that can be built with different build systems fall into two categories:

  1. Software that changed build-system at a particular point in time (e.g. mpifileutils)
  2. Software that for a non-null time window could be built with two different build systems (e.g. hdf5 or fftw)

In case number 1. we have a 1:1 correspondence from a version number to a build-system. Case number 2. is more problematic as for a given version there can be multiple build-systems. The latter case might not be resolved with a "pick your preferred build-system" approach, as the artifacts of the build might be different for the same version of the software.

For all the examples that I could find right now, the time period in which a package could be built with a given build-system can be mapped to a version range. Nothing prevents though to identify this set with further constraints (like the os or anything - think of a package using one build system on Linux and one on Windows). Not sure though if generalizing this aspect is only of theoretical interest or if there are actual use cases.

If we model packages supporting multiple build-systems under the assumption that for a given version number we have a corresponding build-system (restrictive with respect to the use cases found so far) we can employ the current spec syntax. If we go instead with overlapping build-systems that the user can choose, the spec syntax needs to be extended (e.g. fftw can currently be built with CMake and Autotools, the user needs to be able to specify which one he wants to use).

Different build-systems might mean different variants or even different dependencies for the package. Nonetheless it would be good to keep the information well factored and avoid mixing together variants or attributes that come from different places. A tentative package API could be obtained with decorators (the pseudo-code below is only for illustrative purposes):

class FFTW(MultipleBuildSystems):
    """FFTW is ..."""

    # All the common directives and attributes


@FFTW.when('@:3.1')
class _FFTW(AutotoolsPackage):

    # All the directives and attributes related to the autotools build-system only
    # Here I need to be able to refer to variants in the FFTW main class


@FFTW.when('@3.0:')
class _FFTW(CMakePackage):

    # All the directives and attributes related to the CMake build-system only
    # Here I need to be able to refer to variants in the FFTW main class

The FFTW class should behave, during concretization, as a finite state machine with 2 states:

  • build-system-undefined
  • build-system-selected

When in the build-system-undefined state it should accept any constraint imposed by the concretizer, as the class doesn't know yet its full set of dependencies or variants etc. As soon as the build-system can be selected the constraints that have been imposed so far need to be checked and any inconsistency needs to be reported. This will probably need some support from the concretizer.

At install time the underlying spec is already concretized, and the behavior of the class is well-defined, so that should not pose any problem.

@becker33 becker33 force-pushed the mfu-cmake branch 2 times, most recently from 8001540 to 29c78f7 Compare January 24, 2019 00:31
@tgamblin tgamblin self-requested a review January 24, 2019 09:30
@gonsie gonsie mentioned this pull request Feb 21, 2019
@AndrewGaspar
Copy link
Copy Markdown
Contributor

Just want to leave some input that this would be useful for a few packages that transitioned from merely header-only to support a CMake style package system (supporting find_package).

alalazo added a commit to alalazo/spack that referenced this pull request Mar 10, 2020
closes spack#10411
closes spack#12941

This commit introduces a new repository where to move
deprecated recipes e.g. for packages that changed build
system. This will allow to benefit from base classes
specialized for each build-system while still providing
support for both recipes. Mpifileutils used as an example.
@alalazo
Copy link
Copy Markdown
Member

alalazo commented Mar 10, 2020

Just want to mention a simpler approach for the same issue in #15420 meant for comparison with other proposals.

@alalazo
Copy link
Copy Markdown
Member

alalazo commented Sep 16, 2021

@becker33 I'm closing this PR and I added a link to it in spack/seps#3

@alalazo alalazo closed this Sep 16, 2021
@adamjstewart adamjstewart deleted the mfu-cmake branch September 16, 2021 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants