summaryrefslogtreecommitdiff
path: root/lib/spack/spack/build_systems/cargo.py
blob: 0aa31b48555a979a3947eb580e9e2a6c7c7aa48e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# Copyright 2013-2024 Lawrence Livermore National Security, LLC and other
# Spack Project Developers. See the top-level COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)

import inspect

import llnl.util.filesystem as fs

import spack.builder
import spack.package_base
from spack.directives import build_system, depends_on
from spack.multimethod import when

from ._checks import BaseBuilder, execute_install_time_tests


class CargoPackage(spack.package_base.PackageBase):
    """Specialized class for packages built using a Makefiles."""

    #: This attribute is used in UI queries that need to know the build
    #: system base class
    build_system_class = "CargoPackage"

    build_system("cargo")

    with when("build_system=cargo"):
        depends_on("rust", type="build")


@spack.builder.builder("cargo")
class CargoBuilder(BaseBuilder):
    """The Cargo builder encodes the most common way of building software with
    a rust Cargo.toml file. It has two phases that can be overridden, if need be:

            1. :py:meth:`~.CargoBuilder.build`
            2. :py:meth:`~.CargoBuilder.install`

    For a finer tuning you may override:

        +-----------------------------------------------+----------------------+
        | **Method**                                    | **Purpose**          |
        +===============================================+======================+
        | :py:meth:`~.CargoBuilder.build_args`          | Specify arguments    |
        |                                               | to ``cargo install`` |
        +-----------------------------------------------+----------------------+
        | :py:meth:`~.CargoBuilder.check_args`          | Specify arguments    |
        |                                               | to ``cargo test``    |
        +-----------------------------------------------+----------------------+
    """

    phases = ("build", "install")

    #: Callback names for install-time test
    install_time_test_callbacks = ["check"]

    @property
    def build_directory(self):
        """Return the directory containing the main Cargo.toml."""
        return self.pkg.stage.source_path

    @property
    def build_args(self):
        """Arguments for ``cargo build``."""
        return []

    @property
    def check_args(self):
        """Argument for ``cargo test`` during check phase"""
        return []

    def build(self, pkg, spec, prefix):
        """Runs ``cargo install`` in the source directory"""
        with fs.working_dir(self.build_directory):
            inspect.getmodule(pkg).cargo(
                "install", "--root", "out", "--path", ".", *self.build_args
            )

    def install(self, pkg, spec, prefix):
        """Copy build files into package prefix."""
        with fs.working_dir(self.build_directory):
            fs.install_tree("out", prefix)

    spack.builder.run_after("install")(execute_install_time_tests)

    def check(self):
        """Run "cargo test"."""
        with fs.working_dir(self.build_directory):
            inspect.getmodule(self.pkg).cargo("test", *self.check_args)