#!/bin/bash # NOSTR Core Library Build Script # Provides convenient build targets for the standalone library # Automatically increments patch version with each build set -e # Exit on any error # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Function to print colored output print_status() { echo -e "${BLUE}[INFO]${NC} $1" } print_success() { echo -e "${GREEN}[SUCCESS]${NC} $1" } print_warning() { echo -e "${YELLOW}[WARNING]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } # Function to automatically increment version increment_version() { print_status "Incrementing version..." # Check if we're in a git repository if ! git rev-parse --git-dir > /dev/null 2>&1; then print_warning "Not in a git repository - skipping version increment" return 0 fi # Get the highest version tag (not necessarily the most recent chronologically) LATEST_TAG=$(git tag -l 'v*.*.*' | sort -V | tail -n 1 || echo "v0.1.0") if [[ -z "$LATEST_TAG" ]]; then LATEST_TAG="v0.1.0" fi # Extract version components (remove 'v' prefix if present) VERSION=${LATEST_TAG#v} # Parse major.minor.patch if [[ $VERSION =~ ^([0-9]+)\.([0-9]+)\.([0-9]+)$ ]]; then MAJOR=${BASH_REMATCH[1]} MINOR=${BASH_REMATCH[2]} PATCH=${BASH_REMATCH[3]} else print_error "Invalid version format in tag: $LATEST_TAG" print_error "Expected format: v0.1.0" return 1 fi # Increment patch version NEW_PATCH=$((PATCH + 1)) NEW_VERSION="v${MAJOR}.${MINOR}.${NEW_PATCH}" print_status "Current version: $LATEST_TAG" print_status "New version: $NEW_VERSION" # Create new git tag if git tag "$NEW_VERSION" 2>/dev/null; then print_success "Created new version tag: $NEW_VERSION" # Generate version.h header file cat > nostr_core/version.h << EOF /* * NOSTR Core Library - Auto-Generated Version Header * DO NOT EDIT THIS FILE MANUALLY - Generated by build.sh */ #ifndef NOSTR_VERSION_H #define NOSTR_VERSION_H #define VERSION_MAJOR ${MAJOR} #define VERSION_MINOR ${MINOR} #define VERSION_PATCH ${NEW_PATCH} #define VERSION_STRING "${MAJOR}.${MINOR}.${NEW_PATCH}" #define VERSION_TAG "${NEW_VERSION}" /* Build information */ #define BUILD_DATE "$(date +%Y-%m-%d)" #define BUILD_TIME "$(date +%H:%M:%S)" #define BUILD_TIMESTAMP "$(date '+%Y-%m-%d %H:%M:%S')" /* Git information */ #define GIT_HASH "$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')" #define GIT_BRANCH "$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')" /* Display versions */ #define VERSION_DISPLAY "${NEW_VERSION}" #define VERSION_FULL_DISPLAY "${NEW_VERSION} ($(date '+%Y-%m-%d %H:%M:%S'), $(git rev-parse --short HEAD 2>/dev/null || echo 'unknown'))" /* Version API functions */ const char* nostr_core_get_version(void); const char* nostr_core_get_version_full(void); const char* nostr_core_get_build_info(void); #endif /* NOSTR_VERSION_H */ EOF # Generate version.c implementation file cat > nostr_core/version.c << EOF /* * NOSTR Core Library - Auto-Generated Version Implementation * DO NOT EDIT THIS FILE MANUALLY - Generated by build.sh */ #include "version.h" const char* nostr_core_get_version(void) { return VERSION_TAG; } const char* nostr_core_get_version_full(void) { return VERSION_FULL_DISPLAY; } const char* nostr_core_get_build_info(void) { return "Built on " BUILD_DATE " at " BUILD_TIME " from commit " GIT_HASH " on branch " GIT_BRANCH; } EOF print_success "Generated version.h and version.c" else print_warning "Tag $NEW_VERSION already exists - using existing version" NEW_VERSION=$LATEST_TAG fi # Update VERSION file for compatibility echo "${NEW_VERSION#v}" > VERSION print_success "Updated VERSION file to ${NEW_VERSION#v}" } # Function to show usage show_usage() { echo "NOSTR Core Library Build Script" echo "===============================" echo "" echo "Usage: $0 [target] [architecture]" echo "" echo "Available targets:" echo " clean - Clean all build artifacts" echo " lib - Build static libraries for both x64 and ARM64 (default)" echo " x64 - Build x64 static library only" echo " arm64 - Build ARM64 static library only" echo " all - Build both architectures and examples" echo " examples - Build example programs" echo " test - Run tests" echo " install - Install library to system" echo " uninstall - Remove library from system" echo " help - Show this help message" echo "" echo "Library outputs (both self-contained with secp256k1):" echo " libnostr_core.a - x86_64 static library" echo " libnostr_core_arm64.a - ARM64 static library" echo " examples/* - Example programs" echo "" echo "Both libraries include secp256k1 objects internally." echo "Users only need to link with the library + -lm." } # Parse command line arguments TARGET=${1:-lib} case "$TARGET" in clean) print_status "Cleaning build artifacts..." make clean print_success "Clean completed" ;; lib|library) increment_version print_status "Building both x64 and ARM64 static libraries..." make clean make # Check both libraries were built SUCCESS=0 if [ -f "libnostr_core.a" ]; then SIZE_X64=$(stat -c%s "libnostr_core.a") print_success "x64 static library built successfully (${SIZE_X64} bytes)" SUCCESS=$((SUCCESS + 1)) else print_error "Failed to build x64 static library" fi if [ -f "libnostr_core_arm64.a" ]; then SIZE_ARM64=$(stat -c%s "libnostr_core_arm64.a") print_success "ARM64 static library built successfully (${SIZE_ARM64} bytes)" SUCCESS=$((SUCCESS + 1)) else print_error "Failed to build ARM64 static library" fi if [ $SUCCESS -eq 2 ]; then print_success "Both architectures built successfully!" ls -la libnostr_core*.a else print_error "Failed to build all libraries" exit 1 fi ;; x64|x64-only) increment_version print_status "Building x64 static library only..." make clean make x64 if [ -f "libnostr_core.a" ]; then SIZE=$(stat -c%s "libnostr_core.a") print_success "x64 static library built successfully (${SIZE} bytes)" ls -la libnostr_core.a else print_error "Failed to build x64 static library" exit 1 fi ;; arm64|arm64-only) increment_version print_status "Building ARM64 static library only..." make clean make arm64 if [ -f "libnostr_core_arm64.a" ]; then SIZE=$(stat -c%s "libnostr_core_arm64.a") print_success "ARM64 static library built successfully (${SIZE} bytes)" ls -la libnostr_core_arm64.a else print_error "Failed to build ARM64 static library" exit 1 fi ;; shared) increment_version print_status "Building shared library..." make clean make libnostr_core.so if [ -f "libnostr_core.so" ]; then SIZE=$(stat -c%s "libnostr_core.so") print_success "Shared library built successfully (${SIZE} bytes)" ls -la libnostr_core.so else print_error "Failed to build shared library" exit 1 fi ;; all) increment_version print_status "Building all libraries and examples..." make clean make all # Check both libraries and examples were built SUCCESS=0 if [ -f "libnostr_core.a" ]; then SIZE_X64=$(stat -c%s "libnostr_core.a") print_success "x64 static library built successfully (${SIZE_X64} bytes)" SUCCESS=$((SUCCESS + 1)) else print_error "Failed to build x64 static library" fi if [ -f "libnostr_core_arm64.a" ]; then SIZE_ARM64=$(stat -c%s "libnostr_core_arm64.a") print_success "ARM64 static library built successfully (${SIZE_ARM64} bytes)" SUCCESS=$((SUCCESS + 1)) else print_error "Failed to build ARM64 static library" fi if [ $SUCCESS -eq 2 ]; then print_success "All libraries and examples built successfully!" ls -la libnostr_core*.a ls -la examples/ else print_error "Failed to build all components" exit 1 fi ;; examples) increment_version print_status "Building both libraries and examples..." make clean make make examples # Verify libraries were built if [ -f "libnostr_core.a" ] && [ -f "libnostr_core_arm64.a" ]; then print_success "Both libraries and examples built successfully" ls -la libnostr_core*.a ls -la examples/ else print_error "Failed to build libraries for examples" exit 1 fi ;; test) print_status "Running tests..." make clean make if make test-crypto 2>/dev/null; then print_success "All tests passed" else print_warning "Running simple test instead..." make test print_success "Basic test completed" fi ;; tests) print_status "Running tests..." make clean make if make test-crypto 2>/dev/null; then print_success "All tests passed" else print_warning "Running simple test instead..." make test print_success "Basic test completed" fi ;; install) increment_version print_status "Installing library to system..." make clean make all sudo make install print_success "Library installed to /usr/local" ;; uninstall) print_status "Uninstalling library from system..." sudo make uninstall print_success "Library uninstalled" ;; help|--help|-h) show_usage ;; *) print_error "Unknown target: $TARGET" echo "" show_usage exit 1 ;; esac