Repository: easybuilders/easybuild-easyblocks

Issue:
MUMmer easyblock corrupts binaries by running apply_regex_substitutions
I ran into weird issues with a PR for a toolchain bump of the existing MUMmer easyconfig, see:
https://github.com/easybuilders/easybuild-easyconfigs/pull/14474

The resulting executable doesn't work at all:
```
$ file ./mummer
./mummer: ERROR: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked error reading (Invalid argument)

$ ./mummer
Segmentation fault (core dumped)
```

After some debugging, I found that the installation step does a `apply_regex_substitutions` on all files in the build directory, including binaries:
https://github.com/easybuilders/easybuild-easyblocks/blob/develop/easybuild/easyblocks/m/mummer.py#L75



Discussion:
Another thing that I noticed while looking into this, is that the MUMmer Makefile overwrites some variables (e.g. `CFLAGS`, `CXXFLAGS`, `LDFLAGS`, etc). It might be good to change this as well.
@deniskristak Can you take a look at solving the problems that have been uncovered here?

* don't patch binary files with `apply_regex_substitutions` in MUMmer easyblock
* remove `prepend_paths` statement to add `bin` to `$PATH` (already done by default)
* make sure that build is done with `$CXXFLAGS` as specified by EasyBuild
* add sanity check command to MUMmer easyblock (`mummer --help`?)

Resolving patch:
diff --git a/easybuild/easyblocks/m/mummer.py b/easybuild/easyblocks/m/mummer.py
--- a/easybuild/easyblocks/m/mummer.py
+++ b/easybuild/easyblocks/m/mummer.py
@@ -34,7 +34,7 @@
 
 from easybuild.easyblocks.generic.configuremake import ConfigureMake
 from easybuild.easyblocks.perl import get_major_perl_version
-from easybuild.tools.filetools import apply_regex_substitutions, copy_file, mkdir
+from easybuild.tools.filetools import apply_regex_substitutions, copy_file, is_binary, mkdir, read_file
 from easybuild.tools.run import run_cmd
 
 
@@ -63,6 +63,14 @@ def configure_step(self):
 
         self.cfg.update('buildopts', 'all')
 
+    def build_step(self):
+        """Custom build procedure for MUMmer."""
+
+        # make sure that compiler options specified by EasyBuild are used
+        self.cfg.update('buildopts', 'CXXFLAGS="$CXXFLAGS" CFLAGS="$CFLAGS"')
+
+        super(EB_MUMmer, self).build_step()
+
     def install_step(self):
         """Patch files to avoid use of build dir, install by copying files to install dir."""
         # patch build dir out of files, replace by install dir
@@ -73,8 +81,11 @@ def install_step(self):
         installdir_bin = os.path.join(self.installdir, 'bin')
 
         for fil in [f for f in os.listdir(self.cfg['start_dir']) if os.path.isfile(f)]:
-            self.log.debug("Patching build dir out of %s, replacing by install bin dir)", fil)
-            apply_regex_substitutions(fil, [(pattern, installdir_bin)])
+            # only use apply_regex_substitutions() on non-binary files
+            # for more details, see https://github.com/easybuilders/easybuild-easyblocks/issues/2629)
+            if not is_binary(read_file(fil, mode='rb')):
+                self.log.debug("Patching build dir out of %s, replacing by install bin dir)", fil)
+                apply_regex_substitutions(fil, [(pattern, installdir_bin)])
 
         # copy files to install dir
         file_tuples = [
@@ -96,7 +107,6 @@ def make_module_extra(self):
 
         # set $PATH and $PERLXLIB correctly
         txt = super(EB_MUMmer, self).make_module_extra()
-        txt += self.module_generator.prepend_paths("PATH", ['bin'])
         txt += self.module_generator.prepend_paths("PATH", ['bin/aux_bin'])
         txt += self.module_generator.prepend_paths("PERL%sLIB" % perlmajver, ['bin/scripts'])
         return txt
@@ -111,4 +121,7 @@ def sanity_check_step(self):
                 ['bin/scripts/%s' % x for x in self.script_files],
             'dirs': []
         }
-        super(EB_MUMmer, self).sanity_check_step(custom_paths=custom_paths)
+
+        custom_commands = ["mummer -h"]
+
+        super(EB_MUMmer, self).sanity_check_step(custom_paths=custom_paths, custom_commands=custom_commands)


Test patch: