Repository: spack/spack

Issue:
Problems building bzip2 with Intel compilers
`make install` crashes with the following error message:

```
/usr/include/stdlib.h:33:20: error: stddef.h: No such file or directory
```

However, I don't have any problems installing bzip2 outside of Spack. Maybe it's an environment variable problem?



Discussion:
I can't replicate this -- which intel version?

16.0.3

Seems to work.  Could be because of the way we set up our compilers, though.  @lee218llnl have you seen this issue before with Intel compilers?

```
(cab669):~$ spack install bzip2 %intel@16.0.3
==> Installing bzip2
==> Trying to fetch from file:///g/g21/gamblin2/src/spack/var/spack/cache/bzip2/bzip2-1.0.6.tar.gz
######################################################################## 100.0%
==> Staging archive: /g/g21/gamblin2/src/spack/var/spack/stage/bzip2-1.0.6-a2lbdheqwajc7snivwborsta26q2c7vq/bzip2-1.0.6.tar.gz
==> Created stage in /g/g21/gamblin2/src/spack/var/spack/stage/bzip2-1.0.6-a2lbdheqwajc7snivwborsta26q2c7vq
==> Ran patch() for bzip2
==> Building bzip2
==> Successfully installed bzip2
  Fetch: 0.17s.  Build: 6.60s.  Total: 6.77s.
[+] /g/g21/gamblin2/src/spack/opt/spack/linux-redhat6-x86_64/intel-16.0.3/bzip2-1.0.6-a2lbdheqwajc7snivwborsta26q2c7vq
```

It looks like the third `make` command for bzip2 will build with gcc regardless of the compiler specified by spack. Thus, building bzip2 with spack Intel will "work" if it can use the system gcc. I think it would fail if it is built as a dependency.

```
...
cc -fpic -fPIC -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -o bzip2-shared bzip2.c libbz2.so.1.0.6
rm -f libbz2.so.1.0
ln -s libbz2.so.1.0.6 libbz2.so.1.0
==> 'make' '-j8' 'clean'
rm -f *.o libbz2.a bzip2 bzip2recover \
sample1.rb2 sample2.rb2 sample3.rb2 \
sample1.tst sample2.tst sample3.tst
==> 'make' '-j8' 'install' 'PREFIX=/home/gjohnson/spack/opt/spack/linux-centos7-x86_64/intel-16.0.3/bzip2-1.0.6-qzex6ykxmecqcoopimyodutatv5ennpq'
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c huffman.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c crctable.c
gcc -Wall -Winline -O2 -g -D_FILE_OFFSET_BITS=64 -c randtable.c

If compilation produces errors, or a large number of warnings,
please read README.COMPILATION.PROBLEMS -- you might be able to
adjust the flags in this Makefile to improve matters.

Also in README.COMPILATION.PROBLEMS are some hints that may help
if your build produces an executable which is unable to correctly
handle so-called 'large files' -- files of size 2GB or more.
```

@glennpj I noticed that. It looks like we're only patching one Makefile instead of both. I'll see if that helps.

And the winner is @glennpj. If I filter both Makefiles, it builds successfully. I'll put out a PR for that shortly.

@adamjstewart thanks!


Resolving patch:
diff --git a/var/spack/repos/builtin/packages/bzip2/package.py b/var/spack/repos/builtin/packages/bzip2/package.py
--- a/var/spack/repos/builtin/packages/bzip2/package.py
+++ b/var/spack/repos/builtin/packages/bzip2/package.py
@@ -24,54 +24,59 @@
 ##############################################################################
 from spack import *
 
+
 class Bzip2(Package):
     """bzip2 is a freely available, patent free high-quality data
-       compressor. It typically compresses files to within 10% to 15%
-       of the best available techniques (the PPM family of statistical
-       compressors), whilst being around twice as fast at compression
-       and six times faster at decompression.
+    compressor. It typically compresses files to within 10% to 15%
+    of the best available techniques (the PPM family of statistical
+    compressors), whilst being around twice as fast at compression
+    and six times faster at decompression."""
 
-    """
     homepage = "http://www.bzip.org"
     url      = "http://www.bzip.org/1.0.6/bzip2-1.0.6.tar.gz"
 
     version('1.0.6', '00b516f4704d4a7cb50a1d97e6e8e15b')
 
-
     def patch(self):
-        mf = FileFilter('Makefile-libbz2_so')
-        mf.filter(r'^CC=gcc', 'CC=cc')
+        # bzip2 comes with two separate Makefiles for static and dynamic builds
+        # Tell both to use Spack's compiler wrapper instead of GCC
+        filter_file(r'^CC=gcc', 'CC=cc', 'Makefile')
+        filter_file(r'^CC=gcc', 'CC=cc', 'Makefile-libbz2_so')
 
-        # Below stuff patches the link line to use RPATHs on Mac OS X.
+        # Patch the link line to use RPATHs on macOS
         if 'darwin' in self.spec.architecture:
             v = self.spec.version
-            v1, v2, v3 = (v.up_to(i) for i in (1,2,3))
+            v1, v2, v3 = (v.up_to(i) for i in (1, 2, 3))
 
-            mf.filter('$(CC) -shared -Wl,-soname -Wl,libbz2.so.{0} -o libbz2.so.{1} $(OBJS)'.format(v2, v3),
-                      '$(CC) -dynamiclib -Wl,-install_name -Wl,@rpath/libbz2.{0}.dylib -current_version {1} -compatibility_version {2} -o libbz2.{3}.dylib $(OBJS)'.format(v1, v2, v3, v3), string=True)
+            kwargs = {'ignore_absent': False, 'backup': False, 'string': True}
 
-            mf.filter('$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.{0}'.format(v3),
-                      '$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.{0}.dylib'.format(v3), string=True)
+            mf = FileFilter('Makefile-libbz2_so')
+            mf.filter('$(CC) -shared -Wl,-soname -Wl,libbz2.so.{0} -o libbz2.so.{1} $(OBJS)'.format(v2, v3),  # NOQA ignore=E501
+                      '$(CC) -dynamiclib -Wl,-install_name -Wl,@rpath/libbz2.{0}.dylib -current_version {1} -compatibility_version {2} -o libbz2.{3}.dylib $(OBJS)'.format(v1, v2, v3, v3), **kwargs)  # NOQA ignore=E501
+
+            mf.filter('$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.so.{0}'.format(v3),  # NOQA ignore=E501
+                      '$(CC) $(CFLAGS) -o bzip2-shared bzip2.c libbz2.{0}.dylib'.format(v3), **kwargs)  # NOQA ignore=E501
             mf.filter('rm -f libbz2.so.{0}'.format(v2),
-                      'rm -f libbz2.{0}.dylib'.format(v2), string=True)
+                      'rm -f libbz2.{0}.dylib'.format(v2), **kwargs)
             mf.filter('ln -s libbz2.so.{0} libbz2.so.{1}'.format(v3, v2),
-                      'ln -s libbz2.{0}.dylib libbz2.{1}.dylib'.format(v3, v2), string=True)
-
+                      'ln -s libbz2.{0}.dylib libbz2.{1}.dylib'.format(v3, v2), **kwargs)  # NOQA ignore=E501
 
     def install(self, spec, prefix):
+        # Build the dynamic library first
         make('-f', 'Makefile-libbz2_so')
-        make('clean')
-        make("install", "PREFIX=%s" % prefix)
+        # Build the static library and everything else
+        make()
+        make('install', 'PREFIX={0}'.format(prefix))
 
         install('bzip2-shared', join_path(prefix.bin, 'bzip2'))
 
-        v1, v2, v3 = (self.spec.version.up_to(i) for i in (1,2,3))
+        v1, v2, v3 = (self.spec.version.up_to(i) for i in (1, 2, 3))
         if 'darwin' in self.spec.architecture:
             lib = 'libbz2.dylib'
-            lib1, lib2, lib3 = ('libbz2.{0}.dylib'.format(v) for v in (v1, v2, v3))
+            lib1, lib2, lib3 = ('libbz2.{0}.dylib'.format(v) for v in (v1, v2, v3))  # NOQA ignore=E501
         else:
             lib = 'libbz2.so'
-            lib1, lib2, lib3 = ('libbz2.so.{0}'.format(v) for v in (v1, v2, v3))
+            lib1, lib2, lib3 = ('libbz2.so.{0}'.format(v) for v in (v1, v2, v3))  # NOQA ignore=E501
 
         install(lib3, join_path(prefix.lib, lib3))
         with working_dir(prefix.lib):


Test patch: