dropshell-build/CLAUDE.md
j842 10e26e8a6c
Some checks failed
dropshell-build / build (push) Failing after 5s
works
2025-06-09 17:49:36 +12:00

3.7 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This repository contains a Docker-based build system for creating statically-linked C++ executables using Alpine Linux and musl libc. It consists of:

  1. dropshell-build-base: A comprehensive C++ development base image with Drogon web framework and database support
  2. dropshell-build: A multi-stage Docker build system that uses the base image to compile C++ projects
  3. ipdemo: A sample application demonstrating the build system

Key Commands

Building the Base Image

cd build-base
./build.sh

This creates the gitea.jde.nz/public/dropshell-build-base:latest Docker image with all dependencies.

Building a Project

./build.sh

This builds the project defined in build.sh (default: ipdemo) and outputs the binary to output/.

Testing the Built Binary

./test.sh

Runs the compiled binary from output/ directory.

Environment Variables

  • CMAKE_BUILD_TYPE: Set to "Debug" or "Release" (default: Debug)
  • PROJECT: The project name to build (default: ipdemo)

Architecture and Design

Build System Structure

The build system uses a two-stage approach:

  1. Base Image (dropshell-build-base): Contains all dependencies compiled from source with static linking:

    • C++ compiler toolchain with ccache and mold linker
    • Libraries: OpenSSL, jsoncpp, PostgreSQL, MariaDB, MySQL, SQLite3, cURL, c-ares
    • Drogon web framework with full database support
    • All libraries built with -fPIC for static linking
  2. Project Build (Dockerfile.dropshell-build): Multi-stage build that:

    • Uses build cache mounts for faster rebuilds
    • Runs cmake_prebuild.sh for custom pre-build steps
    • Generates version information dynamically
    • Produces a single static binary in a scratch container

CMake Configuration

The CMakeLists.txt enforces static linking through:

  • CMAKE_EXE_LINKER_FLAGS with -static flag
  • CMAKE_FIND_LIBRARY_SUFFIXES set to .a
  • BUILD_SHARED_LIBS forced to OFF
  • Custom library paths from the base image

Important: Projects must set CMAKE_PREFIX_PATH and explicitly link PostgreSQL libraries:

# Set paths for libraries before finding Drogon
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} 
    /usr/local/jsoncpp
    /usr/local/openssl-musl
    /usr/local/pgsql
    # ... other library paths
)

# Additional PostgreSQL libraries needed for static linking
set(POSTGRESQL_EXTRA_LIBS
    /usr/local/pgsql/lib/libpgcommon.a
    /usr/local/pgsql/lib/libpgport.a
)

Project Structure for New Applications

New C++ projects should follow this structure:

project-name/
├── CMakeLists.txt      # Based on ipdemo example
├── cmake_prebuild.sh   # Optional pre-build script
└── src/
    ├── main.cpp        # Application entry point
    └── version.hpp.in  # Version template

Adding New Projects

To build a different project:

  1. Create a directory with the project structure above
  2. Modify build.sh to set PROJECT="your-project-name"
  3. Run ./build.sh to build

Static Linking Details

The system ensures complete static linking by:

  • Using Alpine Linux's musl libc
  • Building all dependencies with --enable-static --disable-shared
  • Setting -fPIC for position-independent code
  • Using mold linker with -static flag
  • Configuring CMake to prefer .a libraries

Database Support

Applications can use:

  • PostgreSQL via libpq at /usr/local/pgsql/
  • MySQL via client library at /usr/local/mysql/
  • MariaDB via connector at /usr/local/mariadb-connector-c/
  • SQLite3 at /usr/local/sqlite3/

All database libraries are statically linked into the final binary.