Skip to content

add guard to sanity check in custom easyblock for Stata to avoid running ldd on non ELF executable#4077

Merged
boegel merged 3 commits intoeasybuilders:developfrom
adammccartney:stata/add-check-for-wrapper
Apr 8, 2026
Merged

add guard to sanity check in custom easyblock for Stata to avoid running ldd on non ELF executable#4077
boegel merged 3 commits intoeasybuilders:developfrom
adammccartney:stata/add-check-for-wrapper

Conversation

@adammccartney
Copy link
Copy Markdown
Contributor

If "stata" program is not an ELF executable, don't run the ldd check.

Used in combination with a hook that creates a wrapper for stata
(the hook code was generated by Claude)

def post_install_hook_stata(self, *args, **kwargs):
    self.log.info(f"post_install_hook_stata: STARTED for {self.name} in {self.installdir}")
    if self.name.lower() == "stata":
        try:
            binaries = ['stata', 'stata-se', 'stata-mp']
            orig_dir = os.path.join(self.installdir, '.stata-orig')
            os.makedirs(orig_dir, exist_ok=True)

            # --- Resolve dependency lib paths ---
            lib_paths = []
            deps = self.cfg['dependencies']
            for dep in deps:
                dep_name = dep["name"]
                dep_root = get_software_root(dep_name)
                if not dep_root:
                    software_base = os.path.dirname(os.path.dirname(self.installdir))
                    dep_version = dep.get("version", "")
                    dep_root = os.path.join(software_base, dep_name, dep_version)

                lib_path = os.path.join(dep_root, "lib")
                if os.path.isdir(lib_path):
                    lib_paths.append(lib_path)
                    self.log.info(f"post_install_hook_stata: found lib path {lib_path}")
                else:
                    self.log.warning(f"post_install_hook_stata: {lib_path} not found, skipping")

            # --- EESSI compat layer paths ---
            eessi_compat = "/cvmfs/software.eessi.io/versions/2025.06/compat/linux/x86_64"
            eessi_linker = os.path.join(eessi_compat, "lib64", "ld-linux-x86-64.so.2")
            for lib_dir in ["lib64", "lib"]:
                p = os.path.join(eessi_compat, lib_dir)
                if os.path.isdir(p):
                    lib_paths.append(p)

            ld_library_path = ":".join(lib_paths)

            # --- Move originals and create wrappers ---
            for binary in binaries:
                binary_path = os.path.join(self.installdir, binary)
                if not os.path.isfile(binary_path):
                    self.log.warning(f"post_install_hook_stata: {binary} not found, skipping")
                    continue

                # Move original binary to .stata-orig/
                orig_path = os.path.join(orig_dir, binary)
                os.rename(binary_path, orig_path)
                self.log.info(f"post_install_hook_stata: moved {binary_path} -> {orig_path}")

                # Write wrapper script in its place
                wrapper = f"""#!/usr/bin/env bash
STATA_DIR="$(dirname "$(readlink -f "$0")")"
export LD_LIBRARY_PATH="{ld_library_path}${{LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}}"
exec "{eessi_linker}" "${{STATA_DIR}}/.stata-orig/{binary}" "$@"
"""
                with open(binary_path, 'w') as f:
                    f.write(wrapper)
                # rwxr-xr-x
                os.chmod(binary_path,
                         stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP |
                         stat.S_IROTH | stat.S_IXOTH)
                self.log.info(f"post_install_hook_stata: created wrapper at {binary_path}")

        except Exception as e:
            self.log.error(f"post_install_hook_stata: Error: {e}")
            raise
    else:
        raise EasyBuildError("stata-specific hook triggered for non-stata easyconfig?!")

If "stata" program is not an ELF executable, don't run the ldd check.
@adammccartney adammccartney changed the title Add guard to sanity check Stata: Add guard to sanity check to avoid running ldd on non ELF executable Feb 23, 2026
@boegel boegel added the bug fix label Feb 25, 2026
@boegel boegel added this to the next release (5.2.2?) milestone Feb 25, 2026
@boegel boegel changed the title Stata: Add guard to sanity check to avoid running ldd on non ELF executable add guard to sanity check in custom easyblock for Stata to avoid running ldd on non ELF executable Mar 9, 2026
@boegel
Copy link
Copy Markdown
Member

boegel commented Apr 8, 2026

Test report by @boegel

Overview of tested easyconfigs (in order)

  • SUCCESS Stata-18.eb

Build succeeded for 1 out of 1 (total: 1 min 25 secs) (1 easyconfigs in total)
node4006.donphan.os - Linux RHEL 9.6, x86_64, Intel(R) Xeon(R) Gold 6240 CPU @ 2.60GHz (cascadelake), 1 x NVIDIA NVIDIA A2, 580.95.05, Python 3.9.21
See https://gist.github.com/boegel/380ae887a66d0b11457a41146630fdf8 for a full test report.

@boegel
Copy link
Copy Markdown
Member

boegel commented Apr 8, 2026

Test report by @boegel

Overview of tested easyconfigs (in order)

  • SUCCESS Stata-18.eb

Build succeeded for 1 out of 1 (total: 1 min 19 secs) (1 easyconfigs in total)
node4006.donphan.os - Linux RHEL 9.6, x86_64, Intel(R) Xeon(R) Gold 6240 CPU @ 2.60GHz (cascadelake), 1 x NVIDIA NVIDIA A2, 580.95.05, Python 3.9.21
See https://gist.github.com/boegel/11ce590e69db4d738e13c4523bce2092 for a full test report.

Copy link
Copy Markdown
Member

@boegel boegel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@boegel boegel merged commit f5e7eef into easybuilders:develop Apr 8, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants