Repository: spack/spack

Issue:
spack fails to build netcdf4-fortan with AOCC
### Steps to reproduce

```console
$ spack install netcdf-fortran%aocc@3.0.0
[+] /home/software/openmpi/aocc30/4.1.0 (external openmpi-4.1.0-fefghc7htlwd2pynnll6oebk5ynx7lao)
[+] /home/testlab/software/spack/opt/spack/linux-centos8-zen3/aocc-3.0.0/zlib-1.2.11-vn23ilbnd5vdzdvfvnuwykei5mhevt4l
[+] /home/testlab/software/spack/opt/spack/linux-centos8-zen3/aocc-3.0.0/libsigsegv-2.12-m2xobswfu7mwcibazdm6o4wyrpvznowr
[+] /home/testlab/software/spack/opt/spack/linux-centos8-zen3/aocc-3.0.0/hdf5-1.10.7-7fykts64addh2da2gv6uactpep7uxzww
[+] /home/testlab/software/spack/opt/spack/linux-centos8-zen3/aocc-3.0.0/m4-1.4.18-ne3a43yf6it475yr4hirprdp4snkkzu2
[+] /home/testlab/software/spack/opt/spack/linux-centos8-zen3/aocc-3.0.0/netcdf-c-4.7.4-6tdfyg3u2yip47qv3cddvdt3hoo7hk4t
==> Installing netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6
==> No binary for netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6 found: installing from source
==> Using cached archive: /home/testlab/software/spack/var/spack/cache/_source-cache/archive/12/123a5c6184336891e62cf2936b9f2d1c54e8dee299cfd9d2c1a1eb05dd668a74.tar.gz
==> No patches needed for netcdf-fortran
==> netcdf-fortran: Executing phase: 'autoreconf'
==> netcdf-fortran: Executing phase: 'configure'
==> netcdf-fortran: Executing phase: 'build'
==> Error: ProcessError: Command exited with status 2:
    'make' '-j16'

4 errors found in build log:
     460    libtool: compile:  /home/software/openmpi/aocc30/4.1.0/bin/mpif90 -DPACKAGE_NAME=\"netCDF-Fortran\" -DPACKAGE_TARNAME=\"netcdf-fortran\" -DPACKAGE_VERSION=\"4.5.3\" "-
            DPACKAGE_STRING=\"netCDF-Fortran 4.5.3\"" -DPACKAGE_BUGREPORT=\"support-netcdf@unidata.ucar.edu\" -DPACKAGE_URL=\"\" -DPACKAGE=\"netcdf-fortran\" -DVERSION=\"4.5.3\" -
            DNF_RELAX_COORD_BOUND=1 -DENABLE_CDF5=1 -DNF_HAS_PARALLEL4=1 -DHAVE_F2008=1 -DTEMP_LARGE=\".\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_
            H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DNF_INT1_T=
            byte "-DNF_INT2_T=integer*2" "-DNF_INT8_T=integer*8" -DNF_INT1_IS_C_SIGNED_CHAR=1 -DNF_INT2_IS_C_SHORT=1 -DNF_INT8_IS_C_LONG_LONG=1 -DNF_INT_IS_C_INT=1 -DNF_REAL_IS_C_
            FLOAT=1 -DNF_DOUBLEPRECISION_IS_C_DOUBLE=1 -DNCBYTE_T=byte "-DNCSHORT_T=integer*2" -DHAVE_LIBM=1 -DHAVE_NETCDF_H=1 -DHAVE_NC_DEF_OPAQUE=1 -DHAVE_NCCREATE=1 -DHAVE_NC_S
            ET_LOG_LEVEL=1 -DHAVE_NC_DEF_VAR_SZIP=1 -DHAVE_NC_GET_CHUNK_CACHE_INTS=1 -DUSE_NETCDF4=1 -DLOGGING=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_LOCALE_H=1 -DHAVE_STDIO_H=1 -DHAVE_STD
            ARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_CTYPE_H=1 -DHAVE_FCNTL_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_STAT_H
            =1 -DHAVE_GETOPT_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_VPRINTF=1 -DHAVE_
            _BOOL=1 -DHAVE_STDBOOL_H=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_SSIZE_T=1 -DHAVE_PTRDIFF_T=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=8 -DSIZEOF_FLOAT=4 -DSIZ
            EOF_DOUBLE=8 -DSIZEOF_OFF_T=8 -DSIZEOF_SIZE_T=8 -DSIZEOF_PTRDIFF_T=8 -I. -I. -g -c nf_varmio.F90 -o nf_varmio.o >/dev/null 2>&1
     461    libtool: compile:  /home/software/openmpi/aocc30/4.1.0/bin/mpif90 -DPACKAGE_NAME=\"netCDF-Fortran\" -DPACKAGE_TARNAME=\"netcdf-fortran\" -DPACKAGE_VERSION=\"4.5.3\" "-
            DPACKAGE_STRING=\"netCDF-Fortran 4.5.3\"" -DPACKAGE_BUGREPORT=\"support-netcdf@unidata.ucar.edu\" -DPACKAGE_URL=\"\" -DPACKAGE=\"netcdf-fortran\" -DVERSION=\"4.5.3\" -
            DNF_RELAX_COORD_BOUND=1 -DENABLE_CDF5=1 -DNF_HAS_PARALLEL4=1 -DHAVE_F2008=1 -DTEMP_LARGE=\".\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_
            H=1 -DHAVE_STRING_H=1 -DHAVE_MEMORY_H=1 -DHAVE_STRINGS_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DHAVE_DLFCN_H=1 -DLT_OBJDIR=\".libs/\" -DNF_INT1_T=
            byte "-DNF_INT2_T=integer*2" "-DNF_INT8_T=integer*8" -DNF_INT1_IS_C_SIGNED_CHAR=1 -DNF_INT2_IS_C_SHORT=1 -DNF_INT8_IS_C_LONG_LONG=1 -DNF_INT_IS_C_INT=1 -DNF_REAL_IS_C_
            FLOAT=1 -DNF_DOUBLEPRECISION_IS_C_DOUBLE=1 -DNCBYTE_T=byte "-DNCSHORT_T=integer*2" -DHAVE_LIBM=1 -DHAVE_NETCDF_H=1 -DHAVE_NC_DEF_OPAQUE=1 -DHAVE_NCCREATE=1 -DHAVE_NC_S
            ET_LOG_LEVEL=1 -DHAVE_NC_DEF_VAR_SZIP=1 -DHAVE_NC_GET_CHUNK_CACHE_INTS=1 -DUSE_NETCDF4=1 -DLOGGING=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_LOCALE_H=1 -DHAVE_STDIO_H=1 -DHAVE_STD
            ARG_H=1 -DHAVE_ERRNO_H=1 -DHAVE_CTYPE_H=1 -DHAVE_FCNTL_H=1 -DHAVE_MALLOC_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_STRINGS_H=1 -DHAVE_UNISTD_H=1 -DHAVE_SYS_STAT_H
            =1 -DHAVE_GETOPT_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_RESOURCE_H=1 -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_VPRINTF=1 -DHAVE_
            _BOOL=1 -DHAVE_STDBOOL_H=1 -DHAVE_ALLOCA_H=1 -DHAVE_ALLOCA=1 -DHAVE_SSIZE_T=1 -DHAVE_PTRDIFF_T=1 -DSIZEOF_SHORT=2 -DSIZEOF_INT=4 -DSIZEOF_LONG=8 -DSIZEOF_FLOAT=4 -DSIZ
            EOF_DOUBLE=8 -DSIZEOF_OFF_T=8 -DSIZEOF_SIZE_T=8 -DSIZEOF_PTRDIFF_T=8 -I. -I. -g -c nf_varsio.F90 -o nf_varsio.o >/dev/null 2>&1
     462    libtool: compile:  /home/software/openmpi/aocc30/4.1.0/bin/mpif90 -I. -g -c nf_nc4.f90 -o nf_nc4.o >/dev/null 2>&1
     463    libtool: compile:  /home/software/openmpi/aocc30/4.1.0/bin/mpif90 -I. -g -c nf_fortv2.f90 -o nf_fortv2.o >/dev/null 2>&1
     464    /bin/sh ../libtool  --tag=FC   --mode=link /home/software/openmpi/aocc30/4.1.0/bin/mpif90 -I. -g -version-info 7:0:0 -L/home/testlab/software/spack/opt/spack/linux-ce
            ntos8-zen3/aocc-3.0.0/netcdf-c-4.7.4-6tdfyg3u2yip47qv3cddvdt3hoo7hk4t/lib -o libnetcdff.la -rpath /home/testlab/software/spack/opt/spack/linux-centos8-zen3/aocc-3.0.0
            /netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6/lib nf_attio.lo nf_control.lo nf_dim.lo nf_misc.lo nf_genatt.lo nf_geninq.lo nf_genvar.lo nf_vario.lo nf_var1io.
            lo nf_varaio.lo nf_varmio.lo nf_varsio.lo nf_logging.lo nf_nc.lo  nf_v2compat.lo nf_fortv2.lo nf_lib.lo nf_nc4.lo libtypeSizes.la libnetcdf_nc_data.la libnetcdf_nf_dat
            a.la libnetcdf_nc_interfaces.la libnetcdf_nf_interfaces.la libnetcdfm.la libnetcdf_f03.la libnetcdf_fortv2_c_interfaces.la libnetcdf4_nc_interfaces.la libnetcdf4_nf_in
            terfaces.la libnetcdf4_f03.la -lnetcdf -ldl -lm
     465    libtool: link: /home/software/openmpi/aocc30/4.1.0/bin/mpif90 -shared   .libs/nf_attio.o .libs/nf_control.o .libs/nf_dim.o .libs/nf_misc.o .libs/nf_genatt.o .libs/nf_g
            eninq.o .libs/nf_genvar.o .libs/nf_vario.o .libs/nf_var1io.o .libs/nf_varaio.o .libs/nf_varmio.o .libs/nf_varsio.o .libs/nf_logging.o .libs/nf_nc.o .libs/nf_v2compat.o
             .libs/nf_fortv2.o .libs/nf_lib.o .libs/nf_nc4.o   --whole-archive ./.libs/libtypeSizes.a ./.libs/libnetcdf_nc_data.a ./.libs/libnetcdf_nf_data.a ./.libs/libnetcdf_nc_
            interfaces.a ./.libs/libnetcdf_nf_interfaces.a ./.libs/libnetcdfm.a ./.libs/libnetcdf_f03.a ./.libs/libnetcdf_fortv2_c_interfaces.a ./.libs/libnetcdf4_nc_interfaces.a
            ./.libs/libnetcdf4_nf_interfaces.a ./.libs/libnetcdf4_f03.a --no-whole-archive  -L/home/testlab/software/spack/opt/spack/linux-centos8-zen3/aocc-3.0.0/netcdf-c-4.7.4-
            6tdfyg3u2yip47qv3cddvdt3hoo7hk4t/lib -lnetcdf -ldl -lm  -g   -soname libnetcdff.so.7 -o .libs/libnetcdff.so.7.0.0
  >> 466    clang-12: error: unsupported option '--whole-archive'
  >> 467    clang-12: error: unsupported option '--no-whole-archive'
  >> 468    clang-12: error: unknown argument: '-soname'
  >> 469    clang-12: error: no such file or directory: 'libnetcdff.so.7'
     470    make[2]: *** [Makefile:734: libnetcdff.la] Error 1
     471    make[2]: Leaving directory '/tmp/testlab/spack-stage/spack-stage-netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6/spack-src/fortran'
     472    make[1]: *** [Makefile:626: all] Error 2
     473    make[1]: Leaving directory '/tmp/testlab/spack-stage/spack-stage-netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6/spack-src/fortran'
     474    make: *** [Makefile:581: all-recursive] Error 1

See build log for details:
  /tmp/testlab/spack-stage/spack-stage-netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6/spack-build-out.txt


### Error message

  >> 466    clang-12: error: unsupported option '--whole-archive'
  >> 467    clang-12: error: unsupported option '--no-whole-archive'
  >> 468    clang-12: error: unknown argument: '-soname'
  >> 469    clang-12: error: no such file or directory: 'libnetcdff.so.7'
     470    make[2]: *** [Makefile:734: libnetcdff.la] Error 1
     471    make[2]: Leaving directory '/tmp/testlab/spack-stage/spack-stage-netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6/spack-src/fortran'
     472    make[1]: *** [Makefile:626: all] Error 2
     473    make[1]: Leaving directory '/tmp/testlab/spack-stage/spack-stage-netcdf-fortran-4.5.3-y4dn224aawd6wem52qn5vn7hfufculi6/spack-src/fortran'
     474    make: *** [Makefile:581: all-recursive] Error 1
```


### Information on your system

* **Spack:** 0.16.1-2216-c011e2156f
* **Python:** 3.6.8
* **Platform:** linux-centos8-zen3
* **Concretizer:** original

@WardF @skosukhin 

### 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:

Resolving patch:
diff --git a/var/spack/repos/builtin/packages/netcdf-fortran/package.py b/var/spack/repos/builtin/packages/netcdf-fortran/package.py
--- a/var/spack/repos/builtin/packages/netcdf-fortran/package.py
+++ b/var/spack/repos/builtin/packages/netcdf-fortran/package.py
@@ -141,11 +141,50 @@ def configure_args(self):
     def patch_libtool(self):
         """AOCC support for NETCDF-F"""
         if '%aocc' in self.spec:
+            # Libtool does not fully support the compiler toolchain, therefore
+            # we have to patch the script. The C compiler normally gets
+            # configured correctly, the variables of interest in the
+            # 'BEGIN LIBTOOL CONFIG' section are set to non-empty values and,
+            # therefore, are not affected by the replacements below. A more
+            # robust solution would be to extend the filter_file function with
+            # an additional argument start_at and perform the replacements
+            # between the '# ### BEGIN LIBTOOL TAG CONFIG: FC' and
+            # '# ### END LIBTOOL TAG CONFIG: FC' markers for the Fortran
+            # compiler, and between the '# ### BEGIN LIBTOOL TAG CONFIG: F77'
+            # and '# ### END LIBTOOL TAG CONFIG: F77' markers for the Fortran 77
+            # compiler.
+
+            # How to pass a linker flag through the compiler:
+            filter_file(r'^wl=""$',
+                        'wl="{0}"'.format(self.compiler.linker_arg),
+                        'libtool')
+
+            # Additional compiler flags for building library objects (we need
+            # this to enable shared libraries when building with ~pic). Note
+            # that the following will set fc_pic_flag for both FC and F77, which
+            # in the case of AOCC, should not be a problem. If it is, the
+            # aforementioned modification of the filter_file function could be
+            # a solution.
+            filter_file(r'^pic_flag=""$',
+                        'pic_flag=" {0}"'.format(self.compiler.fc_pic_flag),
+                        'libtool')
+
+            # The following is supposed to tell the compiler to use the GNU
+            # linker. However, the replacement does not happen (at least for
+            # NetCDF-Fortran 4.5.3) because the replaced substring (i.e. the
+            # first argument passed to the filter_file function) is not present
+            # in the file. The flag should probably be added to 'ldflags' in the
+            # flag_handler method above (another option is to add the flag to
+            # 'ldflags' in compilers.yaml automatically as it was done for other
+            # flags in https://github.com/spack/spack/pull/22219).
             filter_file(
                 r'\${wl}-soname \$wl\$soname',
                 r'-fuse-ld=ld -Wl,-soname,\$soname',
                 'libtool', string=True)
 
+        # TODO: resolve the NAG-related issues in a similar way: remove the
+        #  respective patch files and tune the generated libtool script instead.
+
     @when('@:4.4.5')
     def check(self):
         with working_dir(self.build_directory):


Test patch: