Repository: spack/spack

Issue:
Installation issue: libxsmm
### Steps to reproduce the issue

@hfp

The `libxsmm` doesn't specify a dependency on `binutils`, so a (potentially old) system binutils is used and the build fails:

```
$ as --version
GNU assembler version 2.25.1-22.base.el7
$ spack install libxsmm
Error: no such instruction: ...
```

I'm not an expert here, so is the right thing to do to add a dependency on `binutils`?

### Information on your system

* **Spack:** 0.17.1-663-3cd599d6f6
* **Python:** 3.8.7
* **Platform:** linux-centos7-haswell
* **Concretizer:** clingo

### Additional information

_No response_

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have run `spack maintainers <name-of-the-package>` and **@mentioned** any maintainers
- [X] I have uploaded the build log and environment files
- [X] I have searched the issues of this repo and believe this is not a duplicate


Discussion:
https://github.com/spack/spack/pull/21671#issuecomment-779882282
Actually I'll keep this open for now (though feel free to close if you want to handle the issue differently). My understanding is that we need one of the following to resolve this sort of issue:

- Handle compilers as dependencies, along with things like binutils.
- Add binutils as dependency to packages, if they need a particular version.

I'm no expert here, so there are probably other solutions.
@nilsvu, we also came across similar issue like this or #25696.

Bottom line: Even when you build a custom compiler like modern GCC 11.3, the `libxsmm` package build fails on RHEL 8.5 because it uses `/usr/bin/as` from the system `binutils`. You can install a custom `binutils` package but you must explicitly define it as build dependency for the `libxsmm` package.

That's fine for `libxsmm` but we had a hunch that there is more to it and dug deeper. After around 200+ packages we analysed the build logs and found that most Autoconf based packages (and likely CMake packages etc.) use binaries like `nm`, `ar`, `ranlib`, `strip`, etc. from the **system**, even though we have `binutils` installed. Problem is that most packages do not define `binutils` as build dependency.

Option A: Update each and every Automake, CMake, ... based package to correctly include `binutils` as a build dep. Probably tens of hundreds of packages. Not worth the effort IMHO.

Option B: Modify `gcc` and rename it as `gcc-core`, and then use `gcc` as compiler bundle which depends on `gcc-core` and `binutils`. Breaks a lot of intrinsic magic of Spack.

Option C: Add `binutils` in the `compilers.yaml` as additional module. Clean and elegant but doesn't work because the additional modules are loaded only during build stage while the binaries are detected by `configure` during configure stage.

Option D: Modify/add the `binutils/bin` directory to `$PATH` of the compiler via `compilers.yaml`. Workaround around for C.

Personally I like option C the most because it's upstream-compatible (from our point of view), it's site-configurable, and it's IMHO the most elegant solution to the problem. However, it doesn't work because it only addresses the build stage, not the configure stage.

Any way we can modify the configure stage of Spack to load the modules as well?
So, `lib/spack/spack/compiler.py#L629-L659` implements the `compiler_environment` method which loads the modules but this is apparently not widely used. It would make IMHO to update, e.g., `lib/spack/spack/build_systems/autotools.py#L597-L619` and add the `compiler_environment` context here as well.
> You can install a custom `binutils` package but you must explicitly define it as build dependency for the `libxsmm` package.

Note that for libxsmm you need specifically `binutils+ld+gas`, just `binutils` won't do it: https://github.com/libxsmm/libxsmm/issues/652#issuecomment-1143596808.  I think this should be an  explicit build dependency for `libxsmm` (with the appropriate version required), it's a too common footgun when building this package.

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/libxsmm/package.py b/var/spack/repos/builtin/packages/libxsmm/package.py
--- a/var/spack/repos/builtin/packages/libxsmm/package.py
+++ b/var/spack/repos/builtin/packages/libxsmm/package.py
@@ -77,6 +77,11 @@ class Libxsmm(MakefilePackage):
     )
     depends_on("python", type="build")
 
+    # A recent `as` is needed to compile libxmss until version 1.17
+    # (<https://github.com/spack/spack/issues/28404>), but not afterwards
+    # (<https://github.com/spack/spack/pull/21671#issuecomment-779882282>).
+    depends_on("binutils+ld+gas@2.33:", type="build", when="@:1.17")
+
     @property
     def libs(self):
         result = find_libraries(["libxsmm", "libxsmmf"], root=self.prefix, recursive=True)


Test patch: