|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Script to build wlan-cloud-ucentralgw project in a Debian Bookworm container |
| 4 | +# Dependencies are built in a temporary folder within the repo |
| 5 | + |
| 6 | +set -e |
| 7 | + |
| 8 | +# Configuration |
| 9 | +POCO_VERSION="poco-tip-v4-tag" |
| 10 | +CPPKAFKA_VERSION="tip-v1" |
| 11 | +VALIJSON_VERSION="tip-v1.0.2" |
| 12 | +DEBIAN_VERSION="bookworm" |
| 13 | +TEMP_BUILD_DIR=".build-deps" |
| 14 | +OUTPUT_DIR="./cmake-build" |
| 15 | +BINARY_NAME="owgw" |
| 16 | +CONTAINER_NAME="ucentralgw-builder-$$" |
| 17 | +IMAGE_NAME="ucentralgw-build-env:${DEBIAN_VERSION}" |
| 18 | + |
| 19 | +# Colors for output |
| 20 | +GREEN='\033[0;32m' |
| 21 | +YELLOW='\033[1;33m' |
| 22 | +RED='\033[0;31m' |
| 23 | +BLUE='\033[0;34m' |
| 24 | +NC='\033[0m' # No Color |
| 25 | + |
| 26 | +echo -e "${GREEN}=== Building wlan-cloud-ucentralgw in Debian ${DEBIAN_VERSION} container ===${NC}" |
| 27 | + |
| 28 | +# Check if Docker is available |
| 29 | +if ! command -v docker >/dev/null 2>&1; then |
| 30 | + echo -e "${RED}Error: Docker is not installed or not in PATH${NC}" |
| 31 | + exit 1 |
| 32 | +fi |
| 33 | + |
| 34 | +# Create temporary build directory structure |
| 35 | +echo -e "${YELLOW}Creating temporary build directory: ${TEMP_BUILD_DIR}${NC}" |
| 36 | +mkdir -p "${TEMP_BUILD_DIR}" |
| 37 | +mkdir -p "${OUTPUT_DIR}" |
| 38 | + |
| 39 | +# Create Dockerfile for build environment |
| 40 | +echo -e "${YELLOW}Creating build environment Dockerfile...${NC}" |
| 41 | +cat > "${TEMP_BUILD_DIR}/Dockerfile.build" <<EOF |
| 42 | +FROM debian:${DEBIAN_VERSION} |
| 43 | +
|
| 44 | +# Install build dependencies |
| 45 | +RUN apt-get update && apt-get install --no-install-recommends -y \\ |
| 46 | + make cmake g++ git \\ |
| 47 | + libpq-dev libmariadb-dev libmariadbclient-dev-compat \\ |
| 48 | + librdkafka-dev libboost-all-dev libssl-dev \\ |
| 49 | + zlib1g-dev nlohmann-json3-dev ca-certificates libfmt-dev |
| 50 | +
|
| 51 | +# Set working directory |
| 52 | +WORKDIR /build |
| 53 | +
|
| 54 | +# Copy build script into container |
| 55 | +COPY build-in-container.sh /build/ |
| 56 | +RUN chmod +x /build/build-in-container.sh |
| 57 | +
|
| 58 | +# Entry point |
| 59 | +ENTRYPOINT ["/build/build-in-container.sh"] |
| 60 | +EOF |
| 61 | + |
| 62 | +# Create the build script that runs inside the container |
| 63 | +echo -e "${YELLOW}Creating in-container build script...${NC}" |
| 64 | +cat > "${TEMP_BUILD_DIR}/build-in-container.sh" <<'EOFSCRIPT' |
| 65 | +#!/bin/bash |
| 66 | +set -e |
| 67 | +
|
| 68 | +POCO_VERSION="poco-tip-v4-tag" |
| 69 | +CPPKAFKA_VERSION="tip-v1" |
| 70 | +VALIJSON_VERSION="tip-v1.0.2" |
| 71 | +BUILD_DIR="/build/deps" |
| 72 | +INSTALL_PREFIX="/build/install" |
| 73 | +REPO_DIR="/repo" |
| 74 | +OUTPUT_DIR="/repo/cmake-build" |
| 75 | +
|
| 76 | +# Number of parallel jobs |
| 77 | +JOBS=$(nproc 2>/dev/null || echo 4) |
| 78 | +
|
| 79 | +echo "=== Building dependencies in container ===" |
| 80 | +echo "Using ${JOBS} parallel jobs" |
| 81 | +
|
| 82 | +# Function to build a dependency |
| 83 | +build_dependency() { |
| 84 | + local name=$1 |
| 85 | + local repo=$2 |
| 86 | + local branch=$3 |
| 87 | + local build_dir="${BUILD_DIR}/${name}" |
| 88 | +
|
| 89 | + echo "Building ${name}..." |
| 90 | +
|
| 91 | + if [ ! -d "${build_dir}" ]; then |
| 92 | + echo "Cloning ${name} from ${repo} (branch: ${branch})" |
| 93 | + git clone --depth 1 --branch "${branch}" "${repo}" "${build_dir}" |
| 94 | + fi |
| 95 | +
|
| 96 | + mkdir -p "${build_dir}/cmake-build" |
| 97 | + cd "${build_dir}/cmake-build" |
| 98 | +
|
| 99 | + echo "Configuring ${name}..." |
| 100 | + if [ "${name}" = "poco" ]; then |
| 101 | + # POCO needs special configuration to enable all required components |
| 102 | + cmake -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" \ |
| 103 | + -DENABLE_JSON=ON \ |
| 104 | + -DENABLE_CRYPTO=ON \ |
| 105 | + -DENABLE_JWT=ON \ |
| 106 | + -DENABLE_NET=ON \ |
| 107 | + -DENABLE_NETSSL=ON \ |
| 108 | + -DENABLE_UTIL=ON \ |
| 109 | + -DENABLE_DATA=ON \ |
| 110 | + -DENABLE_DATA_SQLITE=ON \ |
| 111 | + -DENABLE_DATA_POSTGRESQL=ON \ |
| 112 | + -DENABLE_DATA_MYSQL=ON \ |
| 113 | + .. |
| 114 | + else |
| 115 | + cmake -DCMAKE_INSTALL_PREFIX="${INSTALL_PREFIX}" .. |
| 116 | + fi |
| 117 | +
|
| 118 | + echo "Building ${name}..." |
| 119 | + cmake --build . --config Release -j${JOBS} |
| 120 | +
|
| 121 | + echo "Installing ${name}..." |
| 122 | + cmake --build . --target install |
| 123 | +
|
| 124 | + # For POCO, create symlinks if needed and show what was installed |
| 125 | + if [ "${name}" = "poco" ]; then |
| 126 | + echo "POCO libraries installed:" |
| 127 | + find "${INSTALL_PREFIX}/lib" -name "libPoco*" -type f || true |
| 128 | +
|
| 129 | + # Run ldconfig to update library cache |
| 130 | + cd "${INSTALL_PREFIX}/lib" |
| 131 | +
|
| 132 | + # Create missing symlinks if needed |
| 133 | + 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 |
| 134 | + if [ ! -e "${lib}" ]; then |
| 135 | + # Find versioned library and create symlink |
| 136 | + versioned=$(find . -maxdepth 1 -name "${lib}.*" | head -n 1) |
| 137 | + if [ -n "$versioned" ]; then |
| 138 | + echo "Creating symlink: ${lib} -> ${versioned}" |
| 139 | + ln -sf "$(basename ${versioned})" "${lib}" |
| 140 | + fi |
| 141 | + fi |
| 142 | + done |
| 143 | + fi |
| 144 | +
|
| 145 | + echo "${name} built successfully" |
| 146 | +} |
| 147 | +
|
| 148 | +# Create directories |
| 149 | +mkdir -p "${BUILD_DIR}" |
| 150 | +mkdir -p "${INSTALL_PREFIX}" |
| 151 | +
|
| 152 | +# Build POCO |
| 153 | +build_dependency \ |
| 154 | + "poco" \ |
| 155 | + "https://github.com/Telecominfraproject/wlan-cloud-lib-poco" \ |
| 156 | + "${POCO_VERSION}" |
| 157 | +
|
| 158 | +# Build cppkafka |
| 159 | +build_dependency \ |
| 160 | + "cppkafka" \ |
| 161 | + "https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka" \ |
| 162 | + "${CPPKAFKA_VERSION}" |
| 163 | +
|
| 164 | +# Build valijson |
| 165 | +build_dependency \ |
| 166 | + "valijson" \ |
| 167 | + "https://github.com/Telecominfraproject/wlan-cloud-lib-valijson" \ |
| 168 | + "${VALIJSON_VERSION}" |
| 169 | +
|
| 170 | +# Build the main application |
| 171 | +echo "=== Building owgw ===" |
| 172 | +
|
| 173 | +cd "${REPO_DIR}" |
| 174 | +
|
| 175 | +# Configure git to trust the repository directory (needed for mounted volumes) |
| 176 | +git config --global --add safe.directory /repo |
| 177 | +
|
| 178 | +# Clean the build directory to avoid CMake cache conflicts |
| 179 | +if [ -d "${OUTPUT_DIR}" ]; then |
| 180 | + echo "Cleaning existing build directory..." |
| 181 | + rm -rf "${OUTPUT_DIR}" |
| 182 | +fi |
| 183 | +
|
| 184 | +mkdir -p "${OUTPUT_DIR}" |
| 185 | +cd "${OUTPUT_DIR}" |
| 186 | +
|
| 187 | +echo "Configuring owgw..." |
| 188 | +export CMAKE_PREFIX_PATH="${INSTALL_PREFIX}" |
| 189 | +export PKG_CONFIG_PATH="${INSTALL_PREFIX}/lib/pkgconfig:${PKG_CONFIG_PATH}" |
| 190 | +export LD_LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LD_LIBRARY_PATH}" |
| 191 | +
|
| 192 | +# Debug: show what libraries are available |
| 193 | +echo "Installed libraries in ${INSTALL_PREFIX}/lib:" |
| 194 | +ls -la "${INSTALL_PREFIX}/lib" || true |
| 195 | +
|
| 196 | +cmake \ |
| 197 | + -DCMAKE_PREFIX_PATH="${INSTALL_PREFIX}" \ |
| 198 | + -DCMAKE_LIBRARY_PATH="${INSTALL_PREFIX}/lib" \ |
| 199 | + -DPoco_DIR="${INSTALL_PREFIX}/lib/cmake/Poco" \ |
| 200 | + -DCppKafka_DIR="${INSTALL_PREFIX}/lib/cmake/CppKafka" \ |
| 201 | + .. |
| 202 | +
|
| 203 | +echo "Building owgw..." |
| 204 | +echo "Library search paths:" |
| 205 | +echo " LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" |
| 206 | +echo " CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH}" |
| 207 | +
|
| 208 | +# Build with explicit library path |
| 209 | +LIBRARY_PATH="${INSTALL_PREFIX}/lib:${LIBRARY_PATH}" \ |
| 210 | +cmake --build . --config Release -j${JOBS} |
| 211 | +
|
| 212 | +echo "=== Build completed successfully ===" |
| 213 | +EOFSCRIPT |
| 214 | + |
| 215 | +# Build the Docker image |
| 216 | +echo -e "${YELLOW}Building Docker image (this may take a while on first run)...${NC}" |
| 217 | +docker build \ |
| 218 | + -t "${IMAGE_NAME}" \ |
| 219 | + -f "${TEMP_BUILD_DIR}/Dockerfile.build" \ |
| 220 | + "${TEMP_BUILD_DIR}" |
| 221 | + |
| 222 | +# Run the build in the container |
| 223 | +echo -e "${YELLOW}Running build in container...${NC}" |
| 224 | +docker run --rm \ |
| 225 | + --name "${CONTAINER_NAME}" \ |
| 226 | + -v "$(pwd):/repo" \ |
| 227 | + -v "$(pwd)/${TEMP_BUILD_DIR}/build-cache:/build/deps" \ |
| 228 | + "${IMAGE_NAME}" |
| 229 | + |
| 230 | +echo -e "${GREEN}=== Build completed successfully! ===${NC}" |
| 231 | +echo -e "${GREEN}Binary location: ${OUTPUT_DIR}/${BINARY_NAME}${NC}" |
| 232 | +echo "" |
| 233 | +echo "To run the binary, you'll need the dependencies installed or use the container." |
| 234 | +echo "" |
| 235 | +echo "To clean up build dependencies:" |
| 236 | +echo -e "${YELLOW} rm -rf ${TEMP_BUILD_DIR}${NC}" |
| 237 | +echo "" |
| 238 | +echo "To remove the Docker image:" |
| 239 | +echo -e "${YELLOW} docker rmi ${IMAGE_NAME}${NC}" |
| 240 | +echo "" |
| 241 | +echo "Note: The temporary build directory (${TEMP_BUILD_DIR}) is excluded from git." |
| 242 | + |
| 243 | +exit 0 |
0 commit comments