From 0914b4908c012b61cbdeb49f8a2f5b5ffb31fa46 Mon Sep 17 00:00:00 2001 From: Andre Courchesne Date: Tue, 3 Feb 2026 13:02:15 -0500 Subject: [PATCH] - Update build doc and add quick build script Signed-off-by: Andre Courchesne --- .gitignore | 2 + BUILDING.md | 31 +++++- build-ucentralgw.sh | 243 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+), 3 deletions(-) create mode 100755 build-ucentralgw.sh diff --git a/.gitignore b/.gitignore index bba923a6..aae61b2f 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ helm/charts/* /portal-test/ /src/ow_version.h .vscode/* +# Build dependencies temporary folder +.build-deps/ diff --git a/BUILDING.md b/BUILDING.md index 17770aec..15341ae8 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -1,11 +1,36 @@ # Building from source -In order to build OWGW, you will need to install its dependencies, which includes the following: + +## Quick Build (Recommended - Using Container) +The easiest way to build OWGW is using the provided build script that creates a Debian Bookworm container with all dependencies: + +```bash +./build-ucentralgw.sh +``` + +This script will: +- Build all dependencies (POCO, cppkafka, valijson) in a Debian Bookworm container +- Store dependency builds in `.build-deps/` (gitignored, cached for faster rebuilds) +- Build the OWGW binary and place it in `./cmake-build/owgw` +- Work entirely within the repository - no system-wide installation needed + +**Requirements:** +- Docker installed and running +- Git + +**Clean rebuild (if needed):** +```bash +rm -rf .build-deps/build-cache +./build-ucentralgw.sh +``` + +## Manual Build from Source +If you prefer to build manually without Docker, you will need to install the following dependencies: - cmake - boost - POCO 1.10.1 or later - a C++17 compiler - openssl -- libpq-dev (PortgreSQL development libraries) +- libpq-dev (PostgreSQL development libraries) - mysql-client (MySQL client) - librdkafka - cppkafka @@ -20,7 +45,7 @@ These instructions have proven to work on Ubuntu 20.4. ```bash sudo apt install git cmake g++ libssl-dev libmariadb-dev \ libpq-dev libaprutil1-dev apache2-dev libboost-all-dev \ - librdkafka-dev // default-libmysqlclient-dev \ + librdkafka-dev default-libmysqlclient-dev \ nlohmann-json-dev git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco diff --git a/build-ucentralgw.sh b/build-ucentralgw.sh new file mode 100755 index 00000000..c30d4142 --- /dev/null +++ b/build-ucentralgw.sh @@ -0,0 +1,243 @@ +#!/bin/bash + +# Script to build wlan-cloud-ucentralgw project in a Debian Bookworm container +# Dependencies are built in a temporary folder within the repo + +set -e + +# Configuration +POCO_VERSION="poco-tip-v4-tag" +CPPKAFKA_VERSION="tip-v1" +VALIJSON_VERSION="tip-v1.0.2" +DEBIAN_VERSION="bookworm" +TEMP_BUILD_DIR=".build-deps" +OUTPUT_DIR="./cmake-build" +BINARY_NAME="owgw" +CONTAINER_NAME="ucentralgw-builder-$$" +IMAGE_NAME="ucentralgw-build-env:${DEBIAN_VERSION}" + +# Colors for output +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +BLUE='\033[0;34m' +NC='\033[0m' # No Color + +echo -e "${GREEN}=== Building wlan-cloud-ucentralgw in Debian ${DEBIAN_VERSION} container ===${NC}" + +# Check if Docker is available +if ! command -v docker >/dev/null 2>&1; then + echo -e "${RED}Error: Docker is not installed or not in PATH${NC}" + exit 1 +fi + +# Create temporary build directory structure +echo -e "${YELLOW}Creating temporary build directory: ${TEMP_BUILD_DIR}${NC}" +mkdir -p "${TEMP_BUILD_DIR}" +mkdir -p "${OUTPUT_DIR}" + +# Create Dockerfile for build environment +echo -e "${YELLOW}Creating build environment Dockerfile...${NC}" +cat > "${TEMP_BUILD_DIR}/Dockerfile.build" < "${TEMP_BUILD_DIR}/build-in-container.sh" <<'EOFSCRIPT' +#!/bin/bash +set -e + +POCO_VERSION="poco-tip-v4-tag" +CPPKAFKA_VERSION="tip-v1" +VALIJSON_VERSION="tip-v1.0.2" +BUILD_DIR="/build/deps" +INSTALL_PREFIX="/build/install" +REPO_DIR="/repo" +OUTPUT_DIR="/repo/cmake-build" + +# Number of parallel jobs +JOBS=$(nproc 2>/dev/null || echo 4) + +echo "=== Building dependencies in container ===" +echo "Using ${JOBS} parallel jobs" + +# Function to build a dependency +build_dependency() { + local name=$1 + local repo=$2 + local branch=$3 + local build_dir="${BUILD_DIR}/${name}" + + echo "Building ${name}..." + + if [ ! -d "${build_dir}" ]; then + echo "Cloning ${name} from ${repo} (branch: ${branch})" + git clone --depth 1 --branch "${branch}" "${repo}" "${build_dir}" + fi + + mkdir -p "${build_dir}/cmake-build" + cd "${build_dir}/cmake-build" + + echo "Configuring ${name}..." + if [ "${name}" = "poco" ]; then + # POCO needs special configuration to enable all required components + cmake -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \ + -DENABLE_JSON=ON \ + -DENABLE_CRYPTO=ON \ + -DENABLE_JWT=ON \ + -DENABLE_NET=ON \ + -DENABLE_NETSSL=ON \ + -DENABLE_UTIL=ON \ + -DENABLE_DATA=ON \ + -DENABLE_DATA_SQLITE=ON \ + -DENABLE_DATA_POSTGRESQL=ON \ + -DENABLE_DATA_MYSQL=ON \ + .. + else + cmake -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" .. + fi + + echo "Building ${name}..." + cmake --build . --config Release -j${JOBS} + + echo "Installing ${name}..." + cmake --build . --target install + + # For POCO, create symlinks if needed and show what was installed + if [ "${name}" = "poco" ]; then + echo "POCO libraries installed:" + find "${INSTALL_PREFIX}/lib" -name "libPoco*" -type f || true + + # Run ldconfig to update library cache + cd "${INSTALL_PREFIX}/lib" + + # Create missing symlinks if needed + for lib in libPocoJSON.so libPocoCrypto.so libPocoNet.so libPocoNetSSL.so libPocoUtil.so libPocoFoundation.so libPocoData.so libPocoDataSQLite.so libPocoDataPostgreSQL.so libPocoDataMySQL.so libPocoJWT.so; do + if [ ! -e "${lib}" ]; then + # Find versioned library and create symlink + versioned=$(find . -maxdepth 1 -name "${lib}.*" | head -n 1) + if [ -n "$versioned" ]; then + echo "Creating symlink: ${lib} -> ${versioned}" + ln -sf "$(basename ${versioned})" "${lib}" + fi + fi + done + fi + + echo "${name} built successfully" +} + +# Create directories +mkdir -p "${BUILD_DIR}" +mkdir -p "${INSTALL_PREFIX}" + +# Build POCO +build_dependency \ + "poco" \ + "https://github.com/Telecominfraproject/wlan-cloud-lib-poco" \ + "${POCO_VERSION}" + +# Build cppkafka +build_dependency \ + "cppkafka" \ + "https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka" \ + "${CPPKAFKA_VERSION}" + +# Build valijson +build_dependency \ + "valijson" \ + "https://github.com/Telecominfraproject/wlan-cloud-lib-valijson" \ + "${VALIJSON_VERSION}" + +# Build the main application +echo "=== Building owgw ===" + +cd "${REPO_DIR}" + +# Configure git to trust the repository directory (needed for mounted volumes) +git config --global --add safe.directory /repo + +# Clean the build directory to avoid CMake cache conflicts +if [ -d "${OUTPUT_DIR}" ]; then + echo "Cleaning existing build directory..." + rm -rf "${OUTPUT_DIR}" +fi + +mkdir -p "${OUTPUT_DIR}" +cd "${OUTPUT_DIR}" + +echo "Configuring owgw..." +export CMAKE_PREFIX_PATH="${INSTALL_PREFIX}" +export PKG_CONFIG_PATH="${INSTALL_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}" +export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}" + +# Debug: show what libraries are available +echo "Installed libraries in ${INSTALL_PREFIX}/lib:" +ls -la "${INSTALL_PREFIX}/lib" || true + +cmake \ + -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX}" \ + -DCMAKE_LIBRARY_PATH="${INSTALL_PREFIX}/lib" \ + -DPoco_DIR="${INSTALL_PREFIX}/lib/cmake/Poco" \ + -DCppKafka_DIR="${INSTALL_PREFIX}/lib/cmake/CppKafka" \ + .. + +echo "Building owgw..." +echo "Library search paths:" +echo " LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" +echo " CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" + +# Build with explicit library path +LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LIBRARY_PATH}" \ +cmake --build . --config Release -j${JOBS} + +echo "=== Build completed successfully ===" +EOFSCRIPT + +# Build the Docker image +echo -e "${YELLOW}Building Docker image (this may take a while on first run)...${NC}" +docker build \ + -t "${IMAGE_NAME}" \ + -f "${TEMP_BUILD_DIR}/Dockerfile.build" \ + "${TEMP_BUILD_DIR}" + +# Run the build in the container +echo -e "${YELLOW}Running build in container...${NC}" +docker run --rm \ + --name "${CONTAINER_NAME}" \ + -v "$(pwd):/repo" \ + -v "$(pwd)/${TEMP_BUILD_DIR}/build-cache:/build/deps" \ + "${IMAGE_NAME}" + +echo -e "${GREEN}=== Build completed successfully! ===${NC}" +echo -e "${GREEN}Binary location: ${OUTPUT_DIR}/${BINARY_NAME}${NC}" +echo "" +echo "To run the binary, you'll need the dependencies installed or use the container." +echo "" +echo "To clean up build dependencies:" +echo -e "${YELLOW} rm -rf ${TEMP_BUILD_DIR}${NC}" +echo "" +echo "To remove the Docker image:" +echo -e "${YELLOW} docker rmi ${IMAGE_NAME}${NC}" +echo "" +echo "Note: The temporary build directory (${TEMP_BUILD_DIR}) is excluded from git." + +exit 0