Repository: spack/spack

Issue:
Error in Perl build system for package perl-net-ssleay
### Steps to reproduce

```
With spack develop:
commit ee0d3a3be2800a28e9e73b0bc800a6dc0a83b41f (HEAD -> develop, origin/develop, origin/HEAD)
Date:   Thu Nov 23 11:30:39 2023 +0100

$ spack env create dev1
$ spack -e dev1 add perl-net-ssleay
$ spack -e dev1 concretize
$ spack -e dev1 install
```

Also tested with v0.19, v0.20 - While the text is slightly different for 0.19, I think it's the same error for each.
This is a fairly central Perl package.

While this might be a package issue, I think this is actually an issue in the Perl build system.
It seems that the build system does not pick up on object attributes that the package sets.

### Error message

```console
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/zlib-1.2.13-hxk7v2wptynargcg6nixsbno2b5duwj2
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/berkeley-db-18.1.40-u6erx4pbjtjeic4dwdcrc4h3ftybzi43
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/bzip2-1.0.8-7hgypxjzwmmzisakfk6l4dfqhwejy7w5
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/ncurses-6.3-dt5vd5yvfhvota52zx2nooz7yacwiifo
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/openssl-1.1.1s-un7y5qp4yewqfzq3y7eo4ki52qnqfzte
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/readline-8.1.2-fnseamjwm7sa4usj6eal2twjvkjnebrl
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/gdbm-1.23-4mjw2o6dxveiio3tssbd26sokyhifruq
[+] /home/arnie/spack/opt/spack/linux-ubuntu22.04-icelake/gcc-11.3.0/perl-5.36.0-734mtg4ajafuppgqzppwjmsqrrlyam5i
==> Installing perl-net-ssleay-1.85-h22ilxwqtxlux2ocycsu3uxh7jbhhmac [9/9]
==> No binary for perl-net-ssleay-1.85-h22ilxwqtxlux2ocycsu3uxh7jbhhmac found: installing from source
==> Using cached archive: /home/arnie/spack/var/spack/cache/_source-cache/archive/9d/9d8188b9fb1cae3bd791979c20554925d5e94a138d00414f1a6814549927b0c8.tar.gz
==> No patches needed for perl-net-ssleay
==> perl-net-ssleay: Executing phase: 'configure'
==> Error: AttributeError: 'Adapter' object has no attribute 'build_method'

The 'perl-net-ssleay' package cannot find an attribute while trying to build from sources. This might be due to a change in Spack's package format to support multiple build-systems for a single package. You can fix this by updating the build recipe, and you can also report the issue as a bug. More information at https://spack.readthedocs.io/en/latest/packaging_guide.html#installation-procedure

/home/arnie/spack/lib/spack/spack/build_systems/perl.py:103, in fix_shebang:
        101    @spack.builder.run_after("configure")
        102    def fix_shebang(self):
  >>    103        if self.build_method == "Build.PL":
        104            pattern = "#!{0}".format(self.spec["perl"].command.path)
        105            repl = "#!/usr/bin/env perl"
        106            filter_file(pattern, repl, "Build", backup=False)

See build log for details:
  /tmp/arnie/spack-stage/spack-stage-perl-net-ssleay-1.85-h22ilxwqtxlux2ocycsu3uxh7jbhhmac/spack-build-out.txt
```

### Information on your system

* **Spack:** 0.22.0.dev0 (ee0d3a3be2800a28e9e73b0bc800a6dc0a83b41f)
* **Python:** 3.10.6
* **Platform:** linux-ubuntu22.04-icelake
* **Concretizer:** clingo

### General information

- [X] I have run `spack debug report` and reported the version of Spack/Python/Platform
- [X] I have searched the issues of this repo and believe this is not a duplicate
- [X] I have run the failing commands in debug mode and reported the output


Discussion:
Should be fixed by #41396

Resolving patch:
diff --git a/lib/spack/spack/build_systems/perl.py b/lib/spack/spack/build_systems/perl.py
--- a/lib/spack/spack/build_systems/perl.py
+++ b/lib/spack/spack/build_systems/perl.py
@@ -10,13 +10,12 @@
 import spack.builder
 import spack.package_base
 from spack.directives import build_system, extends
-from spack.package_base import PackageBase
 from spack.util.executable import Executable
 
 from ._checks import BaseBuilder, execute_build_time_tests
 
 
-class PerlPackage(PackageBase):
+class PerlPackage(spack.package_base.PackageBase):
     """Specialized class for packages that are built using Perl."""
 
     #: This attribute is used in UI queries that need to know the build
@@ -61,6 +60,30 @@ class PerlBuilder(BaseBuilder):
     #: Callback names for build-time test
     build_time_test_callbacks = ["check"]
 
+    @property
+    def build_method(self):
+        """Searches the package for either a Makefile.PL or Build.PL.
+
+        Raises:
+            RuntimeError: if neither Makefile.PL nor Build.PL exist
+        """
+        if os.path.isfile("Makefile.PL"):
+            build_method = "Makefile.PL"
+        elif os.path.isfile("Build.PL"):
+            build_method = "Build.PL"
+        else:
+            raise RuntimeError("Unknown build_method for perl package")
+        return build_method
+
+    @property
+    def build_executable(self):
+        """Returns the executable method to build the perl package"""
+        if self.build_method == "Makefile.PL":
+            build_executable = inspect.getmodule(self.pkg).make
+        elif self.build_method == "Build.PL":
+            build_executable = Executable(os.path.join(self.pkg.stage.source_path, "Build"))
+        return build_executable
+
     def configure_args(self):
         """List of arguments passed to :py:meth:`~.PerlBuilder.configure`.
 
@@ -73,19 +96,7 @@ def configure(self, pkg, spec, prefix):
         """Run Makefile.PL or Build.PL with arguments consisting of
         an appropriate installation base directory followed by the
         list returned by :py:meth:`~.PerlBuilder.configure_args`.
-
-        Raises:
-            RuntimeError: if neither Makefile.PL nor Build.PL exist
         """
-        if os.path.isfile("Makefile.PL"):
-            self.build_method = "Makefile.PL"
-            self.build_executable = inspect.getmodule(self.pkg).make
-        elif os.path.isfile("Build.PL"):
-            self.build_method = "Build.PL"
-            self.build_executable = Executable(os.path.join(self.pkg.stage.source_path, "Build"))
-        else:
-            raise RuntimeError("Unknown build_method for perl package")
-
         if self.build_method == "Makefile.PL":
             options = ["Makefile.PL", "INSTALL_BASE={0}".format(prefix)]
         elif self.build_method == "Build.PL":


Test patch: