Skip to content

Commit

Permalink
F/make (#601)
Browse files Browse the repository at this point in the history
* Add 'make' command

* Updates for spack-manager parsing

* Add a -j arg for most common use case

* Style and docs

* Add first unit-test

* Style
  • Loading branch information
psakievich authored May 1, 2024
1 parent 6901793 commit 6ee835b
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 2 deletions.
10 changes: 8 additions & 2 deletions docs/user_profiles/developers/developer_workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ To see the options for the command we can run it with the `--help` command.

```console
quick-create-dev -h
+ spack-start
*************************************************************
HELP MESSAGE:
quick-create-dev sets up a developer environment
Expand Down Expand Up @@ -143,7 +142,6 @@ git clone --recursive --branch main [email protected]:Exawind/exawind-driver.git ex
git clone --recursive --branch master [email protected]:Exawind/nalu-wind.git
git clone --recursive --branch main [email protected]:Exawind/amr-wind.git
quick-create-dev -s exawind@main amr-wind@main nalu-wind@master
+ spack-start
+ spack manager create-dev-env -s exawind@master amr-wind@main nalu-wind@master
==> Configuring spec exawind@master for development at path exawind
==> Warning: included configuration files should be updated manually [files=include.yaml]
Expand Down Expand Up @@ -181,13 +179,21 @@ If they are newer than the install time then it will trigger an incremental buil
Any changes you make in a dependency will also trigger a rebuild of the upstream software too.
In this environment if you make a change in `amr-wind` it will also trigger a rebuild of the `exawind` package as well.

If you wish to just do a quick incremental build you can use the `spack manager make` command:
```console
spack manager make amr-wind -j=16
```

## Running Tests and Coming Back

To run tests in a one off manner you can use the `spack build-env` command to run commands in a sub-shell with the build environment.
This is further documented [here](https://sandialabs.github.io/spack-manager/user_profiles/developers/snapshot_workflow.html#running).
We also have a function `build-env-dive` which is a beta feature that launches this same subshell in your terminal and dives into it.
It is further documented [here](https://sandialabs.github.io/spack-manager/user_profiles/developers/useful_commands.html#build-env-dive).
Finally, if a `test` target is implementd for your software you can use `spack manager make`
```console
spack manager make --args="test -j16" amr-wind
```

If you wish to come back to an environment later, or in a new shell you can just run
```console
Expand Down
4 changes: 4 additions & 0 deletions docs/user_profiles/developers/snapshot_workflow.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Snapshot Developer Workflow Example

**WARNING:** This documentation is fairly specific to ExaWind and has not been generalized for an arbitrary `Spack-Manager` project.
THe information is still useful. However, you may not translate directly or be able to follow along.


In this tutorial we will look at how to setup a developer workflow using snapshots if they are provided on your machine.

## Setup
Expand Down
2 changes: 2 additions & 0 deletions manager/cmd/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import spack.extensions.manager.manager_cmds.find_machine as find_machine
import spack.extensions.manager.manager_cmds.include as include
import spack.extensions.manager.manager_cmds.location as location
import spack.extensions.manager.manager_cmds.make as make

# import spack.extensions.manager.manager_cmds.pin as pin
# import spack.extensions.manager.manager_cmds.snapshot as snapshot
Expand Down Expand Up @@ -44,6 +45,7 @@ def setup_parser(subparser):
find_machine.add_command(sp, _subcommands)
include.add_command(sp, _subcommands)
location.add_command(sp, _subcommands)
make.add_command(sp, _subcommands)
# pin.add_command(sp, _subcommands)
# snapshot.add_command(sp, _subcommands)

Expand Down
94 changes: 94 additions & 0 deletions manager/manager_cmds/make.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Copyright (c) 2022, National Technology & Engineering Solutions of Sandia,
# LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
# Government retains certain rights in this software.
#
# This software is released under the BSD 3-clause license. See LICENSE file
# for more details.

import os

import llnl.util.tty as tty
from llnl.util.filesystem import working_dir

import spack.build_environment as build_environment
import spack.builder
import spack.cmd
import spack.paths
from spack.util.executable import Executable

"""
This was originally implemented by Tim Fuller @tjfulle
With his permission it is being published in the spack manager
subset of commands
"""
description = "make SPEC directly with `make` or `ninja`"
section = "manager"
level = "short"


def setup_parser(parser):
parser.add_argument(
"spec", metavar="SPEC", nargs="+", help="Spack package to build (must be a develop spec)"
)
build_args = parser.add_mutually_exclusive_group()
build_args.add_argument(
"--args",
"-a",
default="",
required=False,
help="Additional arguments to pass to make as a string i.e. `--args='test -j16'`",
)
build_args.add_argument(
"-j",
type=int,
required=False,
help="number of ranks to build with (specialized implementation of --args)",
)


def make(parser, args):
env = spack.cmd.require_active_env(cmd_name="make")
specs = spack.cmd.parse_specs(args.spec)
if args.j:
extra_make_args = [f"-j{args.j}"]
else:
extra_make_args = args.args.split()
if not specs:
tty.die("You must supply a spec.")
if len(specs) != 1:
tty.die("Too many specs. Supply only one.")
spec = env.matching_spec(specs[0])
if spec is None:
tty.die(f"{specs[0]}: spec not found in environment")
elif not spec.is_develop:
tty.die(f"{specs[0]}: must be a develop spec")
pkg = spec.package
builder = spack.builder.create(pkg)
if hasattr(builder, "build_directory"):
build_directory = os.path.normpath(os.path.join(pkg.stage.path, builder.build_directory))
else:
build_directory = pkg.stage.source_path
try:
build_environment.setup_package(spec.package, False, "build")
except TypeError:
build_environment.setup_package(spec.package, False)

if not os.path.isdir(build_directory):
tty.die(
(
"Build directory does not exist. "
"Please run `spack install` to ensure the build is "
"configured properly"
)
)

with working_dir(build_directory):
make_program = "ninja" if os.path.exists("build.ninja") else "make"
make = Executable(make_program)
make(*extra_make_args)


def add_command(parser, command_dict):
subparser = parser.add_parser("make", help=description)
setup_parser(subparser)
command_dict["make"] = make
26 changes: 26 additions & 0 deletions tests/test_make.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright (c) 2022, National Technology & Engineering Solutions of Sandia,
# LLC (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
# Government retains certain rights in this software.
#
# This software is released under the BSD 3-clause license. See LICENSE file
# for more details.

import pytest

import spack.environment as ev
import spack.extensions
import spack.main

env = spack.main.SpackCommand("env")
manager = spack.main.SpackCommand("manager")
add = spack.main.SpackCommand("add")


@pytest.mark.usefixtures("mutable_mock_env_path_wh_manager", "mock_packages", "mock_fetch")
def test_spackManagerMakeRequiresDevelopSpec():
env("create", "test")
with ev.read("test"):
add("mpich")
with pytest.raises(spack.main.SpackCommandError):
out = manager("make", "mpich")
assert "must be a develop spec" in str(out)

0 comments on commit 6ee835b

Please sign in to comment.