Created
August 26, 2025 14:02
-
-
Save gsidhu/69ad6397b98a7c67660d5cdcb17cd70f to your computer and use it in GitHub Desktop.
A shell script that translates the logic from the Homebrew formula to install `libev` from source on a Debian-based system like Raspberry Pi OS.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/bin/bash | |
| # This script installs libev from source on Debian-based systems (like Raspberry Pi OS), | |
| # based on the official Homebrew formula. | |
| # Original formula: https://github.com/Homebrew/homebrew-core/blob/3f94f7aaead4364ea6905957daacefd73ca40342/Formula/lib/libev.rb | |
| # NOTE: Translated from Ruby to Bash by Gemini Pro 2.5 with the prompt: | |
| # "Look at this brew install script for libev on MacOS – <ORIGINAL RUBY SCRIPT>. \ | |
| # I want to install this libev package on Debian-based Raspberry Pi OS. Please create a shell script based on this." | |
| # Tested successfully on a Raspberry Pi 5 Model B Rev 1.0 8GB running Raspberry OS (64-bit) based on Debian GNU/Linux 12 (bookworm). | |
| # --- BEGIN INSTALL SCRIPT --- | |
| # Exit immediately if a command exits with a non-zero status. | |
| set -e | |
| # --- Configuration --- | |
| # Variables are taken directly from the Homebrew formula | |
| VERSION="4.33" | |
| DOWNLOAD_URL="https://dist.schmorp.de/libev/Attic/libev-${VERSION}.tar.gz" | |
| EXPECTED_SHA256="507eb7b8d1015fbec5b935f34ebed15bf346bed04a11ab82b8eee848c4205aea" | |
| INSTALL_PREFIX="/usr/local" | |
| # --- Dependency Check --- | |
| echo "--> Checking for required dependencies (build-essential, wget)..." | |
| if ! dpkg -s build-essential wget >/dev/null 2>&1; then | |
| echo " Dependencies missing. Please install them by running:" | |
| echo " sudo apt-get update && sudo apt-get install build-essential wget" | |
| exit 1 | |
| fi | |
| echo " Dependencies are present." | |
| # --- Workspace Setup --- | |
| # Create a temporary directory for the build process | |
| # The 'trap' command ensures this directory is removed when the script exits, | |
| # even if it fails. | |
| BUILD_DIR=$(mktemp -d) | |
| trap 'rm -rf "$BUILD_DIR"' EXIT | |
| cd "$BUILD_DIR" | |
| echo "--> Created temporary build directory at: $BUILD_DIR" | |
| # --- Download --- | |
| echo "--> Downloading libev source code..." | |
| wget -q -O "libev-${VERSION}.tar.gz" "$DOWNLOAD_URL" | |
| echo " Download complete." | |
| # --- Verify --- | |
| echo "--> Verifying checksum of the downloaded file..." | |
| # The double space is important for sha256sum's checking format | |
| echo "$EXPECTED_SHA256 libev-${VERSION}.tar.gz" | sha256sum -c - | |
| echo " Checksum OK." | |
| # --- Build and Install --- | |
| echo "--> Extracting source code..." | |
| tar -xzf "libev-${VERSION}.tar.gz" | |
| cd "libev-${VERSION}" | |
| echo " Extraction complete." | |
| echo "--> Configuring the build..." | |
| # We use --prefix to install to /usr/local, the standard for manually compiled software. | |
| # This replaces Homebrew's internal `std_configure_args`. | |
| # The macOS-specific patch from the formula is not needed on Linux. | |
| ./configure --prefix="$INSTALL_PREFIX" \ | |
| --disable-silent-rules | |
| echo "--> Compiling the source code (make)..." | |
| make | |
| echo "--> Installing the library (sudo make install)..." | |
| sudo make install | |
| echo " Installation complete." | |
| # --- Post-Install Steps --- | |
| echo "--> Performing post-install tasks..." | |
| # Remove compatibility header to prevent conflict with libevent, as done in the formula. | |
| if [ -f "${INSTALL_PREFIX}/include/event.h" ]; then | |
| echo " Removing conflicting header: ${INSTALL_PREFIX}/include/event.h" | |
| sudo rm -f "${INSTALL_PREFIX}/include/event.h" | |
| fi | |
| # Update the dynamic linker's cache so it can find the new library. | |
| echo " Updating dynamic linker cache (ldconfig)..." | |
| sudo ldconfig | |
| echo " Post-install tasks complete." | |
| # --- Verification Test --- | |
| echo "--> Running verification test..." | |
| # Change back to the parent directory to run the test | |
| cd .. | |
| # Create the test C file, same as in the Homebrew formula | |
| cat <<'EOF' > test.c | |
| /* Wait for stdin to become readable, then read and echo the first line. */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <unistd.h> | |
| #include <ev.h> | |
| ev_io stdin_watcher; | |
| static void stdin_cb (EV_P_ ev_io *watcher, int revents) { | |
| char *buf = NULL; | |
| size_t nbytes = 0; | |
| getline(&buf, &nbytes, stdin); | |
| printf("%s", buf); | |
| free(buf); | |
| ev_io_stop(EV_A_ watcher); | |
| ev_break(EV_A_ EVBREAK_ALL); | |
| } | |
| int main() { | |
| ev_io_init(&stdin_watcher, stdin_cb, STDIN_FILENO, EV_READ); | |
| ev_io_start(EV_DEFAULT, &stdin_watcher); | |
| ev_run(EV_DEFAULT, 0); | |
| return 0; | |
| } | |
| EOF | |
| echo " Compiling the test program..." | |
| gcc test.c -I"${INSTALL_PREFIX}/include" -L"${INSTALL_PREFIX}/lib" -lev -o test | |
| echo " Running the compiled test program..." | |
| TEST_INPUT="hello, world from libev\n" | |
| # We use 'echo -n' because the string already contains a newline. | |
| # The C program reads this line and prints it back out. | |
| TEST_OUTPUT=$(echo -n "$TEST_INPUT" | ./test) | |
| if [ "$TEST_OUTPUT" = "$TEST_INPUT" ]; then | |
| echo " Test PASSED!" | |
| else | |
| echo " Test FAILED!" | |
| echo " Expected: '$TEST_INPUT'" | |
| echo " Got: '$TEST_OUTPUT'" | |
| exit 1 | |
| fi | |
| echo "" | |
| echo "✅ libev version ${VERSION} has been successfully installed to ${INSTALL_PREFIX}" | |
| # --- END INSTALL SCRIPT --- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment