1155 lines
38 KiB
Bash
1155 lines
38 KiB
Bash
#!/bin/bash -e
|
|
|
|
###############################################################################
|
|
# MIT License
|
|
#
|
|
# Copyright (c) 2025 slave2anonymous
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the "Software"), to deal
|
|
# in the Software without restriction, including without limitation the rights
|
|
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
# copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in all
|
|
# copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
# SOFTWARE.
|
|
###############################################################################
|
|
|
|
###############################################################################
|
|
# i2pd Static Build Script for macOS
|
|
#
|
|
# Description:
|
|
# Automates the process of building a static, universal binary for i2pd
|
|
# with optional embedded tunnel configurations. This script provides a
|
|
# flexible and reproducible build process for the I2P daemon on macOS.
|
|
#
|
|
# Features:
|
|
# - Builds i2pd with configurable versions of dependencies
|
|
# - Supports creating universal binaries for x86_64 and arm64 architectures
|
|
# - Optional external tunnel configuration embedding
|
|
# - Comprehensive logging and build stage management
|
|
# - Flexible build stage selection
|
|
#
|
|
# Requirements:
|
|
# - macOS Ventura (13.x)
|
|
# - Xcode 14.3.1 with Command Line Tools
|
|
# - Homebrew
|
|
# - git
|
|
# - cmake
|
|
# - Sufficient disk space in /tmp or custom working directory
|
|
#
|
|
# Compatibility Targets:
|
|
# - x86_64-apple-macos10.12
|
|
# - arm64-apple-macos11
|
|
# Ensures backward compatibility with older macOS versions
|
|
#
|
|
# Dependency Versions:
|
|
# - i2pd: Configurable (default: 2.53.0)
|
|
# - Boost: Configurable (default: 1_84_0)
|
|
# - OpenSSL: Configurable (default: 3.5.0)
|
|
#
|
|
# Usage:
|
|
# ./build_i2pd.sh [options]
|
|
#
|
|
# Options:
|
|
# -d, --directory DIR Custom working directory (default: /tmp/i2pd)
|
|
# -l, --log FILE Log output to specified file
|
|
# -s, --stage STAGE Start build from specific stage
|
|
# -t, --tunnels FILE Specify external tunnels configuration file
|
|
# -h, --help Show help message
|
|
#
|
|
# Build Stages:
|
|
# boost - Build Boost libraries
|
|
# openssl - Build OpenSSL libraries
|
|
# zlib - Build Zlib libraries
|
|
# i2pd - Build i2pd
|
|
# i2pd-make - Run 'make' for the i2pd build (assumes previous i2pd stage is complete)
|
|
# universal - Create universal binary
|
|
#
|
|
# Examples:
|
|
# ./build_i2pd.sh # Full build from scratch
|
|
# ./build_i2pd.sh -d /path/to/build # Custom build directory
|
|
# ./build_i2pd.sh -l build.log # Log to file
|
|
# ./build_i2pd.sh -s openssl # Start from OpenSSL stage
|
|
# ./build_i2pd.sh -t tunnels.conf # Include custom tunnels
|
|
#
|
|
# Compatibility Notes:
|
|
# - Compiled with deployment targets:
|
|
# * x86_64: macOS 10.12 (Sierra)
|
|
# * arm64: macOS 11.0 (Big Sur)
|
|
# - Ensures wide system compatibility
|
|
# - Tested on macOS Ventura with Xcode 14.3.1
|
|
#
|
|
# Build Configuration Flags:
|
|
# - MACOSX_DEPLOYMENT_TARGET set to support minimum macOS versions
|
|
# - Compiler optimizations for performance and compatibility
|
|
# - Static linking of dependencies
|
|
#
|
|
# Compiler Optimization Levels:
|
|
# - O2 optimization for balanced performance
|
|
# - Architecture-specific optimizations
|
|
# - Link-time optimization (LTO) enabled
|
|
#
|
|
# Security Hardening:
|
|
# - Position Independent Executable (PIE)
|
|
# - Stack protection
|
|
# - Fortified source
|
|
# - Reduced attack surface
|
|
#
|
|
# Performance Considerations:
|
|
# - Minimized external dependencies
|
|
# - Optimized for both Intel and Apple Silicon
|
|
# - Reduced binary size
|
|
# - No runtime library dependencies
|
|
#
|
|
# Recommended System Preparation:
|
|
# 1. Install Xcode 14.3.1 from App Store
|
|
# 2. Install Xcode Command Line Tools:
|
|
# xcode-select --install
|
|
# 3. Install Homebrew:
|
|
# /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
# 4. Install build dependencies:
|
|
# brew install cmake git
|
|
#
|
|
# Potential Build Customizations:
|
|
# - Adjust dependency versions
|
|
# - Modify compiler flags
|
|
# - Add custom patches
|
|
# - Embed specific tunnel configurations
|
|
#
|
|
# Known Limitations:
|
|
# - Requires internet connection for downloading dependencies
|
|
# - Build process may take significant time
|
|
# - Requires approximately 4GB free disk space
|
|
#
|
|
# Troubleshooting:
|
|
# - Ensure all dependencies are installed
|
|
# - Check log file for detailed build information
|
|
# - Verify tunnel configuration syntax if using -t option
|
|
# - Review build environment requirements
|
|
#
|
|
# Project Links:
|
|
# - Script Repository: https://github.com/slave2anonymous/i2pd-static-macos
|
|
# - i2pd: https://github.com/PurpleI2P/i2pd
|
|
# - I2P Network: https://geti2p.net/
|
|
#
|
|
# Community & Support:
|
|
# - GitHub Issues: https://github.com/PurpleI2P/i2pd/issues
|
|
# - I2P Community Forums
|
|
#
|
|
# Version: 1.0.0
|
|
# Last Updated: 2025-08-19
|
|
###############################################################################
|
|
|
|
# Configuration
|
|
export I2PD_VERSION="2.53.0"
|
|
export I2PD_CONFIG_FILE="$DEV_PATH/i2pd/libi2pd/Config.cpp"
|
|
export I2PD_CLIENT_CONTEXT_FILE="$DEV_PATH/i2pd/libi2pd_client/ClientContext.cpp"
|
|
export BOOST_VERSION="1_84_0"
|
|
export OPENSSL_VERSION="3.5.0"
|
|
export ZLIB_VERSION="1.3.1"
|
|
export DEV_PATH="/tmp/i2pd"
|
|
export LOG_FILE=""
|
|
|
|
SCRIPTPATH="$( cd -- "$(dirname "$0")" >/dev/null 2>&1 && pwd -P )"
|
|
|
|
# Help function
|
|
show_help() {
|
|
echo "i2pd Static Build Script for macOS"
|
|
echo "Usage: $0 [options]"
|
|
echo ""
|
|
echo "Options:"
|
|
echo " -d, --directory DIR Set custom working directory (default: /tmp/i2pd)"
|
|
echo " -l, --log FILE Log output to specified file"
|
|
echo " -s, --stage STAGE Start build from specific stage"
|
|
echo " -t, --tunnels FILE Specify external tunnels configuration file"
|
|
echo " -h, --help Show this help message"
|
|
echo ""
|
|
echo "Build Stages:"
|
|
echo " boost - Build Boost libraries"
|
|
echo " openssl - Build OpenSSL libraries"
|
|
echo " zlib - Build Zlib libraries"
|
|
echo " i2pd - Build i2pd"
|
|
echo " i2pd-make - Run 'make' for the i2pd build (assumes previous i2pd stage is complete)"
|
|
echo " universal - Create universal binary"
|
|
echo ""
|
|
echo "Examples:"
|
|
echo " $0 # Full build from scratch"
|
|
echo " $0 -d /path/to/build # Custom build directory"
|
|
echo " $0 -l build.log # Log to file"
|
|
echo " $0 -s openssl # Start from OpenSSL stage"
|
|
echo " $0 -d /build -l build.log -s i2pd -t tunnels.conf # Combine options"
|
|
echo ""
|
|
echo "Note: Stages are cumulative. Starting from 'openssl' will also build zlib and i2pd."
|
|
}
|
|
|
|
# Function to log messages
|
|
log_message() {
|
|
local message="$1"
|
|
echo "$message"
|
|
if [ -n "$LOG_FILE" ]; then
|
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $message" >> "$LOG_FILE"
|
|
fi
|
|
}
|
|
|
|
# Wrapper function for commands to log output
|
|
execute_with_logging() {
|
|
local log_prefix="[CMD] "
|
|
|
|
# Separate environment variables from the command
|
|
local env_vars=()
|
|
local command_args=()
|
|
local is_env=true
|
|
|
|
for arg in "$@"; do
|
|
if [[ "$is_env" == "true" && "$arg" == *"="* ]]; then
|
|
# Collect environment variables
|
|
env_vars+=("$arg")
|
|
else
|
|
# Switch to collecting command arguments
|
|
is_env=false
|
|
command_args+=("$arg")
|
|
fi
|
|
done
|
|
|
|
# Log the full command
|
|
log_message "${log_prefix}Executing: ${env_vars[*]} ${command_args[*]}"
|
|
|
|
# Execute command with environment variables
|
|
if [ ${#env_vars[@]} -gt 0 ]; then
|
|
env "${env_vars[@]}" "${command_args[@]}" 2>&1 | while IFS= read -r line; do
|
|
echo "${log_prefix}${line}" | tee -a "$LOG_FILE"
|
|
done
|
|
else
|
|
# Standard command execution without environment variables
|
|
"${command_args[@]}" 2>&1 | while IFS= read -r line; do
|
|
echo "${log_prefix}${line}" | tee -a "$LOG_FILE"
|
|
done
|
|
fi
|
|
|
|
# Capture and return the exit status
|
|
local status="${PIPESTATUS[0]}"
|
|
if [ $status -ne 0 ]; then
|
|
log_message "${log_prefix}Command failed with status $status"
|
|
fi
|
|
return $status
|
|
}
|
|
|
|
# Parse command-line arguments with long options support
|
|
parse_args() {
|
|
# Reset variables
|
|
DEV_PATH="/tmp/i2pd"
|
|
LOG_FILE=""
|
|
START_STAGE=""
|
|
|
|
# Parse arguments manually
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-d|--directory)
|
|
DEV_PATH="$2"
|
|
shift 2
|
|
;;
|
|
-l|--log)
|
|
LOG_FILE="$2"
|
|
shift 2
|
|
;;
|
|
-s|--stage)
|
|
START_STAGE="$2"
|
|
shift 2
|
|
;;
|
|
-h|--help)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
-t|--tunnels)
|
|
TUNNELS_CONFIG="$2"
|
|
shift 2
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
# Export tunnels config for use in other functions
|
|
export TUNNELS_CONFIG
|
|
}
|
|
|
|
# Validate stage input
|
|
validate_stage() {
|
|
local valid_stages=("boost" "openssl" "zlib" "i2pd" "i2pd-make" "universal")
|
|
local stage="$1"
|
|
|
|
for valid_stage in "${valid_stages[@]}"; do
|
|
if [[ "$stage" == "$valid_stage" ]]; then
|
|
return 0
|
|
fi
|
|
done
|
|
|
|
log_message "[ERROR] Invalid stage: $stage"
|
|
echo "Valid stages are: ${valid_stages[*]}"
|
|
exit 1
|
|
}
|
|
|
|
# Main script execution function
|
|
main() {
|
|
# Parse command-line arguments
|
|
parse_args "$@"
|
|
|
|
# Validate start stage if provided
|
|
if [ -n "$START_STAGE" ]; then
|
|
validate_stage "$START_STAGE"
|
|
fi
|
|
|
|
# Set up logging
|
|
if [ -n "$LOG_FILE" ]; then
|
|
touch "$LOG_FILE"
|
|
log_message "Logging to $LOG_FILE"
|
|
fi
|
|
|
|
# Check for required tools
|
|
cmd_check_and_install "brew"
|
|
cmd_check_and_install "cmake"
|
|
|
|
read -p "Press enter to start building at work dir: $DEV_PATH"
|
|
|
|
# Create working directory
|
|
[ ! -d "$DEV_PATH" ] && mkdir -p "$DEV_PATH"
|
|
cd "$DEV_PATH"
|
|
|
|
# Record start time
|
|
BEGIN_DATE_IN_SEC=$(date "+%s")
|
|
log_message "Build started at: $(date -r $BEGIN_DATE_IN_SEC)"
|
|
|
|
# Determine starting stage
|
|
if [ -z "$START_STAGE" ]; then
|
|
START_STAGE="boost"
|
|
fi
|
|
|
|
# Run build stages
|
|
case "$START_STAGE" in
|
|
boost)
|
|
run_stage "boost"
|
|
run_stage "openssl"
|
|
run_stage "zlib"
|
|
run_stage "i2pd"
|
|
run_stage "universal"
|
|
;;
|
|
openssl)
|
|
run_stage "openssl"
|
|
run_stage "zlib"
|
|
run_stage "i2pd"
|
|
run_stage "universal"
|
|
;;
|
|
zlib)
|
|
run_stage "zlib"
|
|
run_stage "i2pd"
|
|
run_stage "universal"
|
|
;;
|
|
i2pd)
|
|
run_stage "i2pd"
|
|
run_stage "universal"
|
|
;;
|
|
i2pd-make)
|
|
run_stage "i2pd-make"
|
|
run_stage "universal"
|
|
;;
|
|
universal)
|
|
run_stage "universal"
|
|
;;
|
|
*)
|
|
log_message "[ERROR] Invalid stage: $START_STAGE"
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
|
|
# Calculate and log total build time
|
|
END_DATE_IN_SEC=$(date "+%s")
|
|
log_message "Build completed at: $(date -r $END_DATE_IN_SEC)"
|
|
|
|
TOTAL_SEC=$((END_DATE_IN_SEC - BEGIN_DATE_IN_SEC))
|
|
log_message "Total build time: $TOTAL_SEC seconds ($(($TOTAL_SEC/60)) minutes)"
|
|
}
|
|
|
|
# Detailed implementation of build stages (using your original script logic)
|
|
|
|
# Function to check if a command is installed and install it if it's not
|
|
cmd_check_and_install() {
|
|
local cmd=$1
|
|
|
|
if ! command -v "$cmd" &> /dev/null; then
|
|
log_message "[ERROR] $cmd Command not found"
|
|
if [ "$cmd" == "brew" ]; then
|
|
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
|
|
else
|
|
brew install "$cmd"
|
|
fi
|
|
fi
|
|
|
|
# Check if the command is installed again
|
|
if ! command -v "$cmd" &> /dev/null; then
|
|
log_message "[ERROR] $cmd is not installed. Please install $cmd first."
|
|
exit 1
|
|
fi
|
|
}
|
|
|
|
# Run stages functions (these will contain the original build steps)
|
|
run_stage() {
|
|
local stage="$1"
|
|
log_message "Running stage: $stage"
|
|
|
|
case "$stage" in
|
|
boost)
|
|
build_boost
|
|
;;
|
|
openssl)
|
|
build_openssl
|
|
;;
|
|
zlib)
|
|
build_zlib
|
|
;;
|
|
i2pd)
|
|
build_i2pd
|
|
;;
|
|
i2pd-make)
|
|
build_i2pd_make
|
|
;;
|
|
universal)
|
|
create_universal_binary
|
|
;;
|
|
*)
|
|
log_message "[ERROR] Invalid stage: $stage"
|
|
exit 1
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Detailed build stage functions (placeholders for your original logic)
|
|
build_boost() {
|
|
log_message "Building Boost ${BOOST_VERSION}"
|
|
|
|
# Check if Boost is installed via Homebrew
|
|
if brew list --formula | grep -q '^boost$'; then
|
|
log_message "Boost is installed via Homebrew. Uninstalling Boost..."
|
|
brew uninstall boost
|
|
fi
|
|
|
|
# Download Boost if not exists
|
|
[ ! -f "$DEV_PATH/boost_${BOOST_VERSION}.tar.bz2" ] && {
|
|
# Try multiple download methods with verbose output
|
|
log_message "Attempting to download Boost ${BOOST_VERSION}"
|
|
|
|
# Try with additional curl options for better error handling
|
|
curl -v \
|
|
--connect-timeout 30 \
|
|
--retry 3 \
|
|
--retry-delay 5 \
|
|
--retry-max-time 120 \
|
|
-L \
|
|
--tlsv1.2 \
|
|
--cacert /etc/ssl/cert.pem \
|
|
"https://archives.boost.io/release/${BOOST_VERSION//_/.}/source/boost_$BOOST_VERSION.tar.bz2" -o "boost_$BOOST_VERSION.tar.bz2" || {
|
|
|
|
# Fallback to alternative download sources
|
|
log_message "[WARNING] Primary download failed. Trying alternative sources..."
|
|
|
|
# Alternative download methods
|
|
local alt_sources=(
|
|
"https://boostorg.jfrog.io/artifactory/main/release/${BOOST_VERSION//_/.}/source/boost_$BOOST_VERSION.tar.bz2"
|
|
"https://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION//_/.}/boost_$BOOST_VERSION.tar.bz2"
|
|
)
|
|
|
|
local download_success=false
|
|
for source in "${alt_sources[@]}"; do
|
|
log_message "Attempting to download from: $source"
|
|
|
|
curl -v \
|
|
--connect-timeout 30 \
|
|
--retry 3 \
|
|
--retry-delay 5 \
|
|
--retry-max-time 120 \
|
|
-L \
|
|
--tlsv1.2 \
|
|
--cacert /etc/ssl/cert.pem \
|
|
"$source" -o "boost_$BOOST_VERSION.tar.bz2" && {
|
|
download_success=true
|
|
break
|
|
}
|
|
done
|
|
|
|
# Check if download was successful
|
|
if [ "$download_success" = false ]; then
|
|
log_message "[ERROR] Failed to download Boost ${BOOST_VERSION} from all sources"
|
|
|
|
# Additional diagnostics
|
|
log_message "Network Diagnostics:"
|
|
ping -c 4 archives.boost.io || log_message "Ping to archives.boost.io failed"
|
|
curl -v https://archives.boost.io || log_message "Curl connection test failed"
|
|
|
|
exit 1
|
|
else
|
|
log_message "Boost download complete!"
|
|
fi
|
|
}
|
|
}
|
|
|
|
# Extract Boost
|
|
[ ! -d "$DEV_PATH/boost_$BOOST_VERSION" ] && {
|
|
log_message "Extracting boost_$BOOST_VERSION.tar.bz2"
|
|
tar -xvf boost_$BOOST_VERSION.tar.bz2 || {
|
|
log_message "[ERROR] Extract of $DEV_PATH/boost_${BOOST_VERSION}.tar.bz2 failed!"
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
cd "$DEV_PATH/boost_$BOOST_VERSION"
|
|
|
|
# Bootstrap Boost
|
|
log_message "./bootstrap.sh"
|
|
execute_with_logging ./bootstrap.sh
|
|
|
|
# BOOST build for x86_64
|
|
log_message "Building Boost for x86_64"
|
|
[ -d "$DEV_PATH/boost_$BOOST_VERSION/stage-x86_64" ] && rm -rf "$DEV_PATH/boost_$BOOST_VERSION/stage-x86_64"
|
|
execute_with_logging ./b2 toolset=clang-darwin \
|
|
cxxflags="-arch x86_64 -target x86_64-apple-macos10.12" \
|
|
target-os=darwin \
|
|
variant=release \
|
|
link=static \
|
|
runtime-link=static \
|
|
address-model=64 \
|
|
--build-type=minimal \
|
|
--with-system \
|
|
--with-filesystem \
|
|
--with-program_options \
|
|
--with-date_time \
|
|
--stagedir=stage-x86_64 || {
|
|
log_message "[ERROR] Boost x86_64 build failed!"
|
|
exit 1
|
|
}
|
|
|
|
# BOOST build for arm64
|
|
log_message "Building Boost for arm64"
|
|
[ -d "$DEV_PATH/boost_$BOOST_VERSION/stage-arm64" ] && rm -rf "$DEV_PATH/boost_$BOOST_VERSION/stage-arm64"
|
|
execute_with_logging ./b2 toolset=clang-darwin \
|
|
cxxflags="-arch arm64 -target arm64-apple-macos11" \
|
|
-a \
|
|
target-os=darwin \
|
|
variant=release \
|
|
link=static \
|
|
runtime-link=static \
|
|
address-model=64 \
|
|
--build-type=minimal \
|
|
--with-system \
|
|
--with-filesystem \
|
|
--with-program_options \
|
|
--with-date_time \
|
|
--stagedir=stage-arm64 || {
|
|
log_message "[ERROR] Boost arm64 build failed!"
|
|
exit 1
|
|
}
|
|
|
|
log_message "Boost build completed successfully"
|
|
cd "$DEV_PATH"
|
|
}
|
|
|
|
build_openssl() {
|
|
log_message "Building OpenSSL"
|
|
|
|
# Check if Openssl is installed via Homebrew
|
|
if brew list --formula | grep -q '^openssl@3$'; then
|
|
log_message "openssl@3 is installed via Homebrew. Uninstalling openssl@3..."
|
|
brew uninstall openssl@3
|
|
fi
|
|
|
|
# Clone OpenSSL if not exists
|
|
[ ! -d "$DEV_PATH/openssl" ] && {
|
|
git clone https://github.com/openssl/openssl
|
|
cd "$DEV_PATH/openssl"
|
|
git checkout openssl-${OPENSSL_VERSION}
|
|
}
|
|
|
|
# Update existing repo
|
|
[ -d "$DEV_PATH/openssl" ] && {
|
|
cd "$DEV_PATH/openssl"
|
|
git stash
|
|
git checkout openssl-${OPENSSL_VERSION}
|
|
}
|
|
|
|
# OpenSSL build for x86_64
|
|
log_message "Building OpenSSL for x86_64"
|
|
[ ! -d "$DEV_PATH/openssl_x86_64" ] && cp -r "$DEV_PATH/openssl" "$DEV_PATH/openssl_x86_64"
|
|
cd "$DEV_PATH/openssl_x86_64"
|
|
[ -d "$DEV_PATH/stage-x86_64" ] && rm -rf "$DEV_PATH/stage-x86_64"
|
|
|
|
execute_with_logging ./Configure darwin64-x86_64-cc \
|
|
no-rc2 no-rc4 no-rc5 no-idea no-bf no-cast no-whirlpool \
|
|
no-md2 no-md4 no-ripemd no-mdc2 no-camellia no-seed \
|
|
no-comp no-rfc3779 no-ec2m no-ssl2 no-srp no-sctp \
|
|
no-srtp no-shared no-tests \
|
|
--prefix="$DEV_PATH/stage-x86_64" \
|
|
CFLAGS="-O3 -Wall -target x86_64-apple-macos10.12" && \
|
|
perl configdata.pm --dump || {
|
|
log_message "[ERROR] OpenSSL x86_64 configuration failed!"
|
|
exit 1
|
|
}
|
|
|
|
# Clean and build x86_64
|
|
[ -d "$DEV_PATH/openssl_x86_64" ] && make clean
|
|
execute_with_logging make depend || {
|
|
log_message "[ERROR] OpenSSL x86_64 make depend failed!"
|
|
exit 1
|
|
}
|
|
execute_with_logging make || {
|
|
log_message "[ERROR] OpenSSL x86_64 make failed!"
|
|
exit 1
|
|
}
|
|
execute_with_logging make install_sw || {
|
|
log_message "[ERROR] OpenSSL x86_64 make install_sw failed!"
|
|
exit 1
|
|
}
|
|
|
|
# OpenSSL build for arm64
|
|
log_message "Building OpenSSL for arm64"
|
|
[ ! -d "$DEV_PATH/openssl_arm64" ] && cp -r "$DEV_PATH/openssl" "$DEV_PATH/openssl_arm64"
|
|
cd "$DEV_PATH/openssl_arm64"
|
|
[ -d "$DEV_PATH/stage-arm64" ] && rm -rf "$DEV_PATH/stage-arm64"
|
|
|
|
execute_with_logging ./Configure darwin64-arm64-cc \
|
|
no-rc2 no-rc4 no-rc5 no-idea no-bf no-cast no-whirlpool \
|
|
no-md2 no-md4 no-ripemd no-mdc2 no-camellia no-seed \
|
|
no-comp no-rfc3779 no-ec2m no-ssl2 no-srp no-sctp \
|
|
no-srtp no-shared no-tests \
|
|
--prefix="$DEV_PATH/stage-arm64" \
|
|
CFLAGS="-O3 -Wall -target arm64-apple-macos11" && \
|
|
perl configdata.pm --dump || {
|
|
log_message "[ERROR] OpenSSL arm64 configuration failed!"
|
|
exit 1
|
|
}
|
|
|
|
# Clean and build arm64
|
|
[ -d "$DEV_PATH/openssl_arm64" ] && make clean
|
|
execute_with_logging make depend || {
|
|
log_message "[ERROR] OpenSSL arm64 make depend failed!"
|
|
exit 1
|
|
}
|
|
execute_with_logging make || {
|
|
log_message "[ERROR] OpenSSL arm64 make failed!"
|
|
exit 1
|
|
}
|
|
execute_with_logging make install_sw || {
|
|
log_message "[ERROR] OpenSSL arm64 make install_sw failed!"
|
|
exit 1
|
|
}
|
|
|
|
log_message "OpenSSL build completed successfully"
|
|
cd "$DEV_PATH"
|
|
}
|
|
|
|
build_zlib() {
|
|
log_message "Building Zlib"
|
|
|
|
# Clone Zlib if not exists
|
|
[ ! -d "$DEV_PATH/zlib" ] && {
|
|
cd "$DEV_PATH"
|
|
git clone https://github.com/madler/zlib
|
|
cd "$DEV_PATH/zlib"
|
|
git checkout v${ZLIB_VERSION}
|
|
}
|
|
|
|
# Update CMake minimum required version
|
|
log_message "Updating CMake minimum required version"
|
|
sed -i '' 's/cmake_minimum_required(VERSION 2\.4\.4)/cmake_minimum_required(VERSION 3.5)/' "$DEV_PATH/zlib/CMakeLists.txt"
|
|
|
|
# Zlib build for x86_64
|
|
log_message "Building Zlib for x86_64"
|
|
cd "$DEV_PATH/zlib"
|
|
[ -d "$DEV_PATH/zlib/build_x86_64" ] && rm -rf "$DEV_PATH/zlib/build_x86_64"
|
|
mkdir "$DEV_PATH/zlib/build_x86_64"
|
|
cd "$DEV_PATH/zlib/build_x86_64"
|
|
|
|
execute_with_logging cmake .. -B . -G 'Unix Makefiles' \
|
|
-DBUILD_TYPE=Release \
|
|
-DCMAKE_C_FLAGS="-O3 -Wall -target x86_64-apple-macos10.12" \
|
|
-DBUILD_SHARED_LIBS=OFF \
|
|
-DSKIP_INSTALL_FILES=YES \
|
|
-DCMAKE_INSTALL_PREFIX="$DEV_PATH/stage-x86_64" \
|
|
-DCMAKE_OSX_ARCHITECTURES:STRING=x86_64 || {
|
|
log_message "[ERROR] Zlib x86_64 CMake configuration failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging make || {
|
|
log_message "[ERROR] Zlib x86_64 make failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging make install || {
|
|
log_message "[ERROR] Zlib x86_64 make install failed!"
|
|
exit 1
|
|
}
|
|
|
|
# Zlib build for arm64
|
|
log_message "Building Zlib for arm64"
|
|
cd "$DEV_PATH/zlib"
|
|
[ -d "$DEV_PATH/zlib/build_arm64" ] && rm -rf "$DEV_PATH/zlib/build_arm64"
|
|
mkdir "$DEV_PATH/zlib/build_arm64"
|
|
cd "$DEV_PATH/zlib/build_arm64"
|
|
|
|
execute_with_logging cmake .. -B . -G 'Unix Makefiles' \
|
|
-DBUILD_TYPE=Release \
|
|
-DCMAKE_C_FLAGS="-O3 -Wall -target arm64-apple-macos11" \
|
|
-DBUILD_SHARED_LIBS=OFF \
|
|
-DSKIP_INSTALL_FILES=YES \
|
|
-DCMAKE_INSTALL_PREFIX="$DEV_PATH/stage-arm64" \
|
|
-DCMAKE_OSX_ARCHITECTURES:STRING=arm64 || {
|
|
log_message "[ERROR] Zlib arm64 CMake configuration failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging make || {
|
|
log_message "[ERROR] Zlib arm64 make failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging make install || {
|
|
log_message "[ERROR] Zlib arm64 make install failed!"
|
|
exit 1
|
|
}
|
|
|
|
# Remove .dylib files
|
|
log_message "Cleaning up dynamic libraries"
|
|
find "$DEV_PATH/stage-x86_64" -mindepth 1 -name \*.dylib -exec rm -rf {} \;
|
|
find "$DEV_PATH/stage-arm64" -mindepth 1 -name \*.dylib -exec rm -rf {} \;
|
|
|
|
log_message "Zlib build completed successfully"
|
|
cd "$DEV_PATH"
|
|
}
|
|
|
|
patch_config() {
|
|
# Patch Config.cpp
|
|
log_message "Patching $I2PD_CONFIG_FILE"
|
|
cd "$DEV_PATH/i2pd"
|
|
git checkout "$I2PD_VERSION" -- "$I2PD_CONFIG_FILE"
|
|
sed -i '' \
|
|
-e 's/("daemon", bool_switch()->default_value(false)/("daemon", bool_switch()->default_value(true)/' \
|
|
-e 's/("http.enabled", value<bool>()->default_value(true)/("http.enabled", value<bool>()->default_value(false)/' \
|
|
-e 's/("httpproxy.enabled", value<bool>()->default_value(true)/("httpproxy.enabled", value<bool>()->default_value(false)/' \
|
|
-e 's/("socksproxy.enabled", value<bool>()->default_value(true)/("socksproxy.enabled", value<bool>()->default_value(false)/' \
|
|
-e 's/("sam.enabled", value<bool>()->default_value(true)/("sam.enabled", value<bool>()->default_value(false)/' \
|
|
"$I2PD_CONFIG_FILE" && log_message "Patching $I2PD_CONFIG_FILE done!" || ( log_message "[ERROR] Patching $I2PD_CONFIG_FILE failed!"; exit 1 )
|
|
}
|
|
|
|
# Function for patching ClientContext.cpp to include tunnels.conf in i2pd static build
|
|
# This function modifies the ClientContext.cpp file to hardcode tunnel configurations
|
|
# directly into the i2pd binary, eliminating the need for an external tunnels.conf file
|
|
#
|
|
# The function converts a standard tunnels.conf configuration into C++ property tree
|
|
# initialization code that will be embedded in the ClientContext.cpp file
|
|
#
|
|
# Input file format example:
|
|
# [tunnel1]
|
|
# type = client
|
|
# address = 127.0.0.1
|
|
# port = 10001
|
|
# destination = something.b32.i2p
|
|
# keys = transparent
|
|
# [tunnel2]
|
|
# type = udpclient
|
|
# address = 127.0.0.1
|
|
# port = 1194
|
|
# destination = another.b32.i2p
|
|
# keys = tunnel2.dat
|
|
# [server1]
|
|
# type = server
|
|
# host = 127.0.0.1
|
|
# port = 8080
|
|
# keys = server1.dat
|
|
#
|
|
# Benefits:
|
|
# - Allows static configuration of tunnels during compilation
|
|
# - Removes dependency on external configuration files
|
|
# - Enables reproducible builds with predefined tunnel settings
|
|
#
|
|
patch_client_context() {
|
|
local TUNNELS_FILE="$1"
|
|
|
|
log_message "Patching $I2PD_CLIENT_CONTEXT_FILE"
|
|
|
|
# Validate tunnels file exists
|
|
if [ ! -f "$TUNNELS_FILE" ]; then
|
|
log_message "[ERROR] Tunnels configuration file not found: $TUNNELS_FILE"
|
|
return 1
|
|
fi
|
|
|
|
cd "$DEV_PATH/i2pd"
|
|
git checkout "$I2PD_VERSION" -- "$I2PD_CLIENT_CONTEXT_FILE"
|
|
|
|
# Create backup
|
|
cp "$I2PD_CLIENT_CONTEXT_FILE" "${I2PD_CLIENT_CONTEXT_FILE}.bkp"
|
|
|
|
# Create a temporary file for converted tunnels
|
|
local TEMP_CONVERTED=$(mktemp)
|
|
|
|
# Convert tunnels.conf to property tree format using strict sed and bash
|
|
local tunnel_name=""
|
|
local first_tunnel=true
|
|
while IFS= read -r line; do
|
|
if [[ $line =~ ^\[([^]]+)\]$ ]]; then
|
|
tunnel_name="${BASH_REMATCH[1]}"
|
|
# Add section separator for tunnels
|
|
if [[ "$first_tunnel" = true ]]; then
|
|
echo " pt.put(\"\", \"[$tunnel_name]\");" >> "$TEMP_CONVERTED"
|
|
first_tunnel=false
|
|
else
|
|
echo " pt.put(\"\", \"[$tunnel_name]\");" >> "$TEMP_CONVERTED"
|
|
fi
|
|
elif [[ $line =~ ^type[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
|
echo " pt.put(\"$tunnel_name.type\", \"${BASH_REMATCH[1]}\");" >> "$TEMP_CONVERTED"
|
|
elif [[ $line =~ ^address[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
|
echo " pt.put(\"$tunnel_name.address\", \"${BASH_REMATCH[1]}\");" >> "$TEMP_CONVERTED"
|
|
elif [[ $line =~ ^host[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
|
echo " pt.put(\"$tunnel_name.host\", \"${BASH_REMATCH[1]}\");" >> "$TEMP_CONVERTED"
|
|
elif [[ $line =~ ^port[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
|
port="${BASH_REMATCH[1]}"
|
|
echo " pt.put(\"$tunnel_name.port\", \"$port\");" >> "$TEMP_CONVERTED"
|
|
echo " pt.put(\"$tunnel_name.destinationport\", \"$port\");" >> "$TEMP_CONVERTED"
|
|
elif [[ $line =~ ^destination[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
|
echo " pt.put(\"$tunnel_name.destination\", \"${BASH_REMATCH[1]}\");" >> "$TEMP_CONVERTED"
|
|
elif [[ $line =~ ^keys[[:space:]]*=[[:space:]]*(.+)$ ]]; then
|
|
echo " pt.put(\"$tunnel_name.keys\", \"${BASH_REMATCH[1]}\");" >> "$TEMP_CONVERTED"
|
|
fi
|
|
done < "$TUNNELS_FILE"
|
|
|
|
# Find the line to replace
|
|
local LINE_NUM=$(grep -n "boost::property_tree::ptree pt;" "$I2PD_CLIENT_CONTEXT_FILE" | cut -d: -f1 | tail -1)
|
|
local LINE_TO_REPLACE=$((LINE_NUM + 5))
|
|
|
|
# Create a sed script for replacement
|
|
local SED_SCRIPT=$(mktemp)
|
|
echo "${LINE_TO_REPLACE}r $TEMP_CONVERTED" > "$SED_SCRIPT"
|
|
echo "${LINE_TO_REPLACE}d" >> "$SED_SCRIPT"
|
|
|
|
# Use sed to replace the lines
|
|
sed -f "$SED_SCRIPT" "$I2PD_CLIENT_CONTEXT_FILE" > "${I2PD_CLIENT_CONTEXT_FILE}.new"
|
|
|
|
# Check if replacement was successful
|
|
if [ $? -eq 0 ]; then
|
|
# Replace the original file
|
|
mv "${I2PD_CLIENT_CONTEXT_FILE}.new" "$I2PD_CLIENT_CONTEXT_FILE"
|
|
|
|
log_message "[INFO] Successfully patched ClientContext.cpp with tunnels from $TUNNELS_FILE"
|
|
|
|
# Verify the changes
|
|
echo "Verifying changes:"
|
|
sed -n "$((LINE_TO_REPLACE-2)),$((LINE_TO_REPLACE+20))p" "$I2PD_CLIENT_CONTEXT_FILE"
|
|
|
|
# Clean up temporary files
|
|
rm -f "$TEMP_CONVERTED" "$SED_SCRIPT"
|
|
|
|
return 0
|
|
else
|
|
log_message "[ERROR] Failed to patch ClientContext.cpp"
|
|
|
|
# Restore from backup if patch fails
|
|
cp "${I2PD_CLIENT_CONTEXT_FILE}.bkp" "$I2PD_CLIENT_CONTEXT_FILE"
|
|
|
|
# Clean up temporary files
|
|
rm -f "$TEMP_CONVERTED" "$SED_SCRIPT" "${I2PD_CLIENT_CONTEXT_FILE}.new"
|
|
|
|
# Additional debugging information
|
|
echo "Detailed error information:"
|
|
echo "Line to replace: $LINE_TO_REPLACE"
|
|
|
|
# Check file permissions and writability
|
|
ls -l "$I2PD_CLIENT_CONTEXT_FILE"
|
|
|
|
# Additional system-level diagnostics
|
|
echo "Disk space:"
|
|
df -h
|
|
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
build_i2pd() {
|
|
log_message "Building i2pd"
|
|
|
|
# Prepare toolchain files
|
|
log_message "Preparing toolchain files"
|
|
echo '
|
|
set(CMAKE_SYSTEM_NAME Darwin)
|
|
set(CMAKE_C_COMPILER gcc)
|
|
set(CMAKE_CXX_COMPILER g++)
|
|
set(CMAKE_FIND_ROOT_PATH /usr)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
set(CMAKE_VERBOSE_MAKEFILE on)
|
|
' > "$DEV_PATH/toolchain-x86_64.cmake"
|
|
|
|
echo '
|
|
set(CMAKE_SYSTEM_NAME Darwin)
|
|
set(CMAKE_C_COMPILER gcc)
|
|
set(CMAKE_CXX_COMPILER g++)
|
|
set(CMAKE_FIND_ROOT_PATH /usr)
|
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
|
set(CMAKE_VERBOSE_MAKEFILE on)
|
|
' > "$DEV_PATH/toolchain-arm64.cmake"
|
|
|
|
# Clone i2pd if not exists
|
|
[ ! -d "$DEV_PATH/i2pd" ] && {
|
|
cd "$DEV_PATH"
|
|
git clone https://github.com/PurpleI2P/i2pd
|
|
}
|
|
|
|
# Checkout specific version
|
|
cd "$DEV_PATH/i2pd"
|
|
git stash
|
|
git checkout "$I2PD_VERSION"
|
|
|
|
# Apply patches
|
|
|
|
patch_config
|
|
|
|
# Optional tunnels configuration patching
|
|
if [ -n "$TUNNELS_CONFIG" ]; then
|
|
patch_client_context "$TUNNELS_CONFIG"
|
|
fi
|
|
|
|
# Modify CMakeLists.txt to always build boost static
|
|
log_message "Modifying CMakeLists.txt"
|
|
sed -i '' 's/set_target_properties("${PROJECT_NAME}" PROPERTIES LINK_FLAGS "-static")/#/g' "$DEV_PATH/i2pd/build/CMakeLists.txt"
|
|
|
|
# i2pd build for x86_64
|
|
log_message "Building i2pd for x86_64"
|
|
[ -d "$DEV_PATH/i2pd-x86_64-build" ] && rm -rf "$DEV_PATH/i2pd-x86_64-build"
|
|
mkdir "$DEV_PATH/i2pd-x86_64-build"
|
|
cd "$DEV_PATH/i2pd-x86_64-build"
|
|
|
|
execute_with_logging BOOST_ROOT="$DEV_PATH/boost_$BOOST_VERSION" cmake -G 'Unix Makefiles' "$DEV_PATH/i2pd/build" \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_TOOLCHAIN_FILE="$DEV_PATH/toolchain-x86_64.cmake" \
|
|
-DWITH_AESNI=OFF \
|
|
-DWITH_UPNP=OFF \
|
|
-DWITH_LIBRARY=OFF \
|
|
-DWITH_BINARY=ON \
|
|
-DWITH_STATIC=ON \
|
|
-DWITH_HARDENING=ON \
|
|
-DCMAKE_INSTALL_PREFIX:PATH="$DEV_PATH/bin/x86_64" \
|
|
-DZLIB_ROOT="$DEV_PATH/stage-x86_64" \
|
|
-DBOOST_LIBRARYDIR:PATH="$DEV_PATH/boost_$BOOST_VERSION/stage-x86_64/lib" \
|
|
-DOPENSSL_ROOT_DIR:PATH="$DEV_PATH/stage-x86_64" \
|
|
-DCMAKE_CXX_FLAGS="-arch x86_64 -target x86_64-apple-macos10.12" || {
|
|
log_message "[ERROR] i2pd x86_64 CMake configuration failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging make VERBOSE=1 || {
|
|
log_message "[ERROR] i2pd x86_64 build failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging strip i2pd || {
|
|
log_message "[ERROR] Stripping x86_64 binary failed!"
|
|
exit 1
|
|
}
|
|
|
|
# i2pd build for arm64
|
|
log_message "Building i2pd for arm64"
|
|
[ -d "$DEV_PATH/i2pd-arm64-build" ] && rm -rf "$DEV_PATH/i2pd-arm64-build"
|
|
mkdir "$DEV_PATH/i2pd-arm64-build"
|
|
cd "$DEV_PATH/i2pd-arm64-build"
|
|
|
|
execute_with_logging BOOST_ROOT="$DEV_PATH/boost_$BOOST_VERSION" cmake -G 'Unix Makefiles' "$DEV_PATH/i2pd/build" \
|
|
-DCMAKE_BUILD_TYPE=Release \
|
|
-DCMAKE_TOOLCHAIN_FILE="$DEV_PATH/toolchain-arm64.cmake" \
|
|
-DWITH_AESNI=OFF \
|
|
-DWITH_UPNP=OFF \
|
|
-DWITH_LIBRARY=OFF \
|
|
-DWITH_BINARY=ON \
|
|
-DWITH_STATIC=ON \
|
|
-DWITH_HARDENING=ON \
|
|
-DCMAKE_INSTALL_PREFIX:PATH="$DEV_PATH/bin/arm64" \
|
|
-DZLIB_ROOT="$DEV_PATH/stage-arm64" \
|
|
-DBOOST_LIBRARYDIR:PATH="$DEV_PATH/boost_$BOOST_VERSION/stage-arm64/lib" \
|
|
-DOPENSSL_ROOT_DIR:PATH="$DEV_PATH/stage-arm64" \
|
|
-DCMAKE_CXX_FLAGS="-arch arm64 -target arm64-apple-macos11" || {
|
|
log_message "[ERROR] i2pd arm64 CMake configuration failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging make VERBOSE=1 || {
|
|
log_message "[ERROR] i2pd arm64 build failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging strip i2pd || {
|
|
log_message "[ERROR] Stripping arm64 binary failed!"
|
|
exit 1
|
|
}
|
|
|
|
log_message "i2pd build completed successfully"
|
|
}
|
|
|
|
build_i2pd_make() {
|
|
|
|
cd "$DEV_PATH/i2pd"
|
|
|
|
git checkout "$I2PD_VERSION" -- "$I2PD_CONFIG_FILE"
|
|
|
|
# Ask user about patching config
|
|
log_message "Do you want to patch the Config.cpp file? (y/N): "
|
|
read patch_config_response
|
|
|
|
|
|
# Convert response to lowercase for case-insensitive comparison
|
|
patch_config_response=$(echo "$patch_config_response" | tr '[:upper:]' '[:lower:]')
|
|
|
|
if [[ "$patch_config_response" == "y" || "$patch_config_response" == "yes" ]]; then
|
|
log_message "User selected to patch Config.cpp"
|
|
|
|
patch_config
|
|
|
|
else
|
|
log_message "Skipping Config.cpp patching as per user request"
|
|
fi
|
|
|
|
# Optional tunnels configuration patching
|
|
if [ -n "$TUNNELS_CONFIG" ]; then
|
|
patch_client_context "$TUNNELS_CONFIG"
|
|
fi
|
|
|
|
log_message "Building i2pd using make for x86_64"
|
|
cd "$DEV_PATH/i2pd-x86_64-build"
|
|
|
|
execute_with_logging make VERBOSE=1 || {
|
|
log_message "[ERROR] i2pd x86_64 make build failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging strip i2pd || {
|
|
log_message "[ERROR] Stripping x86_64 binary failed!"
|
|
exit 1
|
|
}
|
|
|
|
log_message "Building i2pd using make for arm64"
|
|
cd "$DEV_PATH/i2pd-arm64-build"
|
|
|
|
execute_with_logging make VERBOSE=1 || {
|
|
log_message "[ERROR] i2pd arm64 make build failed!"
|
|
exit 1
|
|
}
|
|
|
|
execute_with_logging strip i2pd || {
|
|
log_message "[ERROR] Stripping arm64 binary failed!"
|
|
exit 1
|
|
}
|
|
|
|
log_message "i2pd make build completed successfully"
|
|
}
|
|
|
|
create_universal_binary() {
|
|
log_message "Creating universal binary"
|
|
|
|
# Verify x86_64 and arm64 binaries exist
|
|
[ -f "$DEV_PATH/i2pd-x86_64-build/i2pd" ] || {
|
|
log_message "[ERROR] x86_64 i2pd binary not found!"
|
|
exit 1
|
|
}
|
|
|
|
[ -f "$DEV_PATH/i2pd-arm64-build/i2pd" ] || {
|
|
log_message "[ERROR] arm64 i2pd binary not found!"
|
|
exit 1
|
|
}
|
|
|
|
# Create universal binary directory
|
|
mkdir -p "$DEV_PATH/universal"
|
|
|
|
# Check architectures of individual binaries
|
|
log_message "x86_64 binary architectures:"
|
|
execute_with_logging lipo -archs "$DEV_PATH/i2pd-x86_64-build/i2pd"
|
|
|
|
log_message "arm64 binary architectures:"
|
|
execute_with_logging lipo -archs "$DEV_PATH/i2pd-arm64-build/i2pd"
|
|
|
|
# Create universal binary
|
|
execute_with_logging lipo -create -output "$DEV_PATH/universal/i2pd" \
|
|
"$DEV_PATH/i2pd-x86_64-build/i2pd" \
|
|
"$DEV_PATH/i2pd-arm64-build/i2pd" || {
|
|
log_message "[ERROR] Creating universal binary failed!"
|
|
exit 1
|
|
}
|
|
|
|
# Verify universal binary
|
|
log_message "Universal binary architectures:"
|
|
execute_with_logging lipo -archs "$DEV_PATH/universal/i2pd"
|
|
|
|
log_message "Universal binary created successfully"
|
|
|
|
# Prepare success message
|
|
local SUCCESS_MESSAGE="
|
|
🎉 i2pd Universal Binary Successfully Built! 🚀
|
|
|
|
Binary Location: $DEV_PATH/universal/i2pd
|
|
|
|
🔧 Usage Instructions:
|
|
|
|
1. Show Help/Available Options:
|
|
$DEV_PATH/universal/i2pd --help
|
|
|
|
This will display all available command-line options and their descriptions.
|
|
|
|
2. Default Behavior (Daemonized):
|
|
- Runs in background
|
|
- All services (HTTP, HTTP Proxy, SOCKS Proxy) are DISABLED
|
|
- Only tunnels from configuration file are available
|
|
|
|
Simply run:
|
|
$DEV_PATH/universal/i2pd
|
|
|
|
3. Console/Foreground Mode:
|
|
Use these options to customize behavior:
|
|
|
|
--http.enabled=1 : Enable HTTP server
|
|
--http.port=PORT : Set HTTP server port
|
|
--httpproxy.enabled=1 : Enable HTTP Proxy
|
|
--httpproxy.port=PORT : Set HTTP Proxy port
|
|
--socksproxy.enabled=1 : Enable SOCKS Proxy
|
|
--socksproxy.port=PORT : Set SOCKS Proxy port
|
|
--sam.enabled=1 : Enable SAM interface
|
|
--log=file : Logs destination to a file
|
|
--logfile=/tmp/i2pd.log : Path to logfile
|
|
--loglevel=info : Set the minimal level of log messages
|
|
|
|
Example:
|
|
$DEV_PATH/universal/i2pd --http.enabled=1 --http.port=7070 --httpproxy.enabled=1 --httpproxy.port=4444 --socksproxy.enabled=1 --socksproxy.port=4447 --log=file --logfile=/tmp/i2pd.log --loglevel=debug
|
|
|
|
4. Tunnels Configuration:
|
|
- If a tunnels configuration file was provided during build:
|
|
Tunnels will be available at their specified b32.i2p addresses
|
|
- To modify tunnels, edit the configuration file used during build
|
|
|
|
⚠️ Notes:
|
|
- Always ensure you have the latest configuration
|
|
- Check i2pd documentation for advanced configuration options
|
|
"
|
|
|
|
# Log the success message
|
|
log_message "$SUCCESS_MESSAGE"
|
|
|
|
# Also echo to console
|
|
echo "$SUCCESS_MESSAGE"
|
|
}
|
|
|
|
# Run the main function
|
|
main "$@" |