Add a build system
This commit is contained in:
255
build.sh
Normal file
255
build.sh
Normal file
@@ -0,0 +1,255 @@
|
||||
#!/usr/bin/env bash
|
||||
# ============================================================================
|
||||
# build.sh - Build script for filehasher (Linux)
|
||||
# Usage: ./build.sh [Release|Debug] [clean]
|
||||
#
|
||||
# Compiler preference: gcc > clang
|
||||
# Build system: Ninja (fallback to Make)
|
||||
# ============================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Colors
|
||||
# ---------------------------------------------------------------------------
|
||||
readonly RED='\033[0;31m'
|
||||
readonly GREEN='\033[0;32m'
|
||||
readonly YELLOW='\033[1;33m'
|
||||
readonly CYAN='\033[0;36m'
|
||||
readonly NC='\033[0m'
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Default values
|
||||
# ---------------------------------------------------------------------------
|
||||
BUILD_TYPE="Release"
|
||||
CLEAN_BUILD=0
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Parse arguments
|
||||
# ---------------------------------------------------------------------------
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
Release|release)
|
||||
BUILD_TYPE="Release"
|
||||
shift
|
||||
;;
|
||||
Debug|debug)
|
||||
BUILD_TYPE="Debug"
|
||||
shift
|
||||
;;
|
||||
clean|-clean|--clean)
|
||||
CLEAN_BUILD=1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Unknown argument: $1${NC}"
|
||||
echo "Usage: $0 [Release|Debug] [clean]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Setup
|
||||
# ---------------------------------------------------------------------------
|
||||
readonly BUILD_DIR="build/linux/${BUILD_TYPE}"
|
||||
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo -e "${GREEN}=== Building filehasher (${BUILD_TYPE}) ===${NC}"
|
||||
echo "Project: ${SCRIPT_DIR}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Clean if requested
|
||||
# ---------------------------------------------------------------------------
|
||||
if [[ $CLEAN_BUILD -eq 1 ]]; then
|
||||
echo -e "${YELLOW}Cleaning build directory...${NC}"
|
||||
rm -rf "${BUILD_DIR}"
|
||||
echo
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Create build directory
|
||||
# ---------------------------------------------------------------------------
|
||||
mkdir -p "${BUILD_DIR}"
|
||||
cd "${BUILD_DIR}"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Find compiler (prefer gcc, fallback to clang)
|
||||
# ---------------------------------------------------------------------------
|
||||
echo -e "${YELLOW}Detecting compiler...${NC}"
|
||||
|
||||
CC_BINARY=""
|
||||
CC_NAME=""
|
||||
|
||||
if command -v gcc &> /dev/null; then
|
||||
CC_BINARY="gcc"
|
||||
CC_VERSION=$(gcc --version | head -n1)
|
||||
CC_NAME="GCC (${CC_VERSION})"
|
||||
echo -e " ${GREEN}[OK]${NC} Found GCC (preferred): ${CC_VERSION}"
|
||||
elif command -v clang &> /dev/null; then
|
||||
CC_BINARY="clang"
|
||||
CC_VERSION=$(clang --version | head -n1)
|
||||
CC_NAME="Clang (${CC_VERSION})"
|
||||
echo -e " ${YELLOW}[OK]${NC} Found Clang (fallback): ${CC_VERSION}"
|
||||
else
|
||||
echo -e "${RED}[FAIL] No suitable compiler found!${NC}"
|
||||
echo "Please install gcc or clang:"
|
||||
echo " Ubuntu/Debian: sudo apt install build-essential"
|
||||
echo " Fedora/RHEL: sudo dnf install gcc"
|
||||
echo " Arch: sudo pacman -S gcc"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Check dependencies
|
||||
# ---------------------------------------------------------------------------
|
||||
echo -e "${YELLOW}Checking dependencies...${NC}"
|
||||
|
||||
# Check for liburing
|
||||
HAVE_LIBURING=0
|
||||
if ldconfig -p | grep -q liburing 2>/dev/null; then
|
||||
HAVE_LIBURING=1
|
||||
echo -e " ${GREEN}[OK]${NC} Found liburing"
|
||||
elif pkg-config --exists liburing 2>/dev/null; then
|
||||
HAVE_LIBURING=1
|
||||
echo -e " ${GREEN}[OK]${NC} Found liburing (pkg-config)"
|
||||
elif [[ -f /usr/lib/liburing.so ]] || [[ -f /usr/lib64/liburing.so ]] || [[ -f /usr/local/lib/liburing.so ]]; then
|
||||
HAVE_LIBURING=1
|
||||
echo -e " ${GREEN}[OK]${NC} Found liburing (manual detection)"
|
||||
else
|
||||
echo -e "${RED}[FAIL] liburing not found!${NC}"
|
||||
echo "Please install liburing-dev:"
|
||||
echo " Ubuntu/Debian: sudo apt install liburing-dev"
|
||||
echo " Fedora/RHEL: sudo dnf install liburing-devel"
|
||||
echo " Arch: sudo pacman -S liburing"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for pthreads
|
||||
# Check if pthreads is available (either in ldconfig or merged into libc)
|
||||
if ldconfig -p | grep -q libpthread 2>/dev/null || ldd --version | grep -qP '2\.(3[4-9]|[4-9][0-9])'; then
|
||||
echo -e " ${GREEN}[OK]${NC} Found pthreads (merged or standalone)"
|
||||
else
|
||||
echo -e " ${YELLOW}[NOTE]${NC} pthreads not found, attempting link"
|
||||
fi
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Find build system (prefer ninja)
|
||||
# ---------------------------------------------------------------------------
|
||||
echo -e "${YELLOW}Selecting build system...${NC}"
|
||||
|
||||
GENERATOR=""
|
||||
GENERATOR_NAME=""
|
||||
|
||||
if command -v ninja &> /dev/null; then
|
||||
GENERATOR="Ninja"
|
||||
GENERATOR_NAME="Ninja"
|
||||
echo -e " ${GREEN}[OK]${NC} Using Ninja"
|
||||
elif command -v make &> /dev/null; then
|
||||
GENERATOR="Unix Makefiles"
|
||||
GENERATOR_NAME="Make"
|
||||
echo -e " ${YELLOW}[OK]${NC} Ninja not found, using Make"
|
||||
else
|
||||
echo -e "${RED}[FAIL] No build system found!${NC}"
|
||||
echo "Please install ninja or make:"
|
||||
echo " Ubuntu/Debian: sudo apt install ninja-build"
|
||||
echo " Fedora/RHEL: sudo dnf install ninja-build"
|
||||
echo " Arch: sudo pacman -S ninja"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Configure
|
||||
# ---------------------------------------------------------------------------
|
||||
echo -e "${YELLOW}Configuring CMake...${NC}"
|
||||
echo -e " Build type: ${BUILD_TYPE}"
|
||||
echo -e " Compiler: ${CC_NAME}"
|
||||
echo -e " Generator: ${GENERATOR_NAME}"
|
||||
|
||||
cmake "${SCRIPT_DIR}" \
|
||||
-G "${GENERATOR}" \
|
||||
-DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
|
||||
-DCMAKE_C_COMPILER="${CC_BINARY}" \
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}CMake configuration failed!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Configuration successful!${NC}"
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build
|
||||
# ---------------------------------------------------------------------------
|
||||
echo -e "${YELLOW}Building...${NC}"
|
||||
|
||||
# Get number of CPU cores
|
||||
if command -v nproc &> /dev/null; then
|
||||
CORES=$(nproc)
|
||||
else
|
||||
CORES=4
|
||||
fi
|
||||
|
||||
cmake --build . --config "${BUILD_TYPE}" --parallel "${CORES}"
|
||||
|
||||
if [[ $? -ne 0 ]]; then
|
||||
echo -e "${RED}Build failed!${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Build successful!${NC}"
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Verify output
|
||||
# ---------------------------------------------------------------------------
|
||||
cd "${SCRIPT_DIR}"
|
||||
|
||||
if [[ -f "${BUILD_DIR}/filehasher" ]]; then
|
||||
echo -e "${GREEN}Executable: ${BUILD_DIR}/filehasher${NC}"
|
||||
|
||||
if command -v file &> /dev/null; then
|
||||
echo -e " Type: $(file -b ${BUILD_DIR}/filehasher)"
|
||||
fi
|
||||
|
||||
if command -v du &> /dev/null; then
|
||||
echo -e " Size: $(du -h ${BUILD_DIR}/filehasher | cut -f1)"
|
||||
fi
|
||||
elif [[ -f "${BUILD_DIR}/filehasher.exe" ]]; then
|
||||
echo -e "${GREEN}Executable: ${BUILD_DIR}/filehasher.exe${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}Note: Could not locate executable${NC}"
|
||||
echo "Checking build directory:"
|
||||
find "${BUILD_DIR}" -type f -executable 2>/dev/null || echo " No executables found"
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Summary
|
||||
# ---------------------------------------------------------------------------
|
||||
echo
|
||||
echo -e "${CYAN}=== Build Complete ===${NC}"
|
||||
echo
|
||||
echo -e "${YELLOW}Build Information:${NC}"
|
||||
echo -e " Configuration: ${BUILD_TYPE}"
|
||||
echo -e " Compiler: ${CC_NAME}"
|
||||
echo -e " Generator: ${GENERATOR_NAME}"
|
||||
echo -e " Output: ${BUILD_DIR}/"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Copy compile_commands.json for clangd
|
||||
# ---------------------------------------------------------------------------
|
||||
if [[ -f "${BUILD_DIR}/compile_commands.json" ]]; then
|
||||
echo -e " clangd: compile_commands.json generated"
|
||||
|
||||
# Always copy the latest version
|
||||
cp "${BUILD_DIR}/compile_commands.json" "${SCRIPT_DIR}/compile_commands.json"
|
||||
echo -e " clangd: Copied to project root"
|
||||
fi
|
||||
|
||||
echo
|
||||
echo -e "${GREEN}Ready to run: ./${BUILD_DIR}/filehasher${NC}"
|
||||
Reference in New Issue
Block a user