Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
.git
build/
build-*/
CMakeCache.txt
CMakeFiles/
cmake_install.cmake
CTestTestfile.cmake
Testing/
install_manifest.txt
*.o
config.cache
config.status
config.log
stamp-h
specs/
tests/__pycache__/
.claude/
Expand Down
37 changes: 30 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,46 @@ on:

jobs:
build:
name: ${{ matrix.tls }} / ${{ matrix.build_type }}
runs-on: ubuntu-latest

strategy:
fail-fast: false
matrix:
tls: [openssl, gnutls, none]
build_type: [RelWithDebInfo]
include:
# One debug configuration to keep DEBUGMODE compiling.
- tls: openssl
build_type: Debug

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y autoconf automake bison flex

- name: Generate configure
run: ./autogen.sh
sudo apt-get install -y cmake ninja-build bison pkg-config
if [ "${{ matrix.tls }}" = "openssl" ]; then
sudo apt-get install -y libssl-dev
elif [ "${{ matrix.tls }}" = "gnutls" ]; then
sudo apt-get install -y libgnutls28-dev
fi

- name: Configure
run: ./configure
run: >
cmake -B build -G Ninja
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
-DIRCU_TLS=${{ matrix.tls }}
-DIRCU_DOMAIN=example.com
-DIRCU_ENABLE_WARNINGS=ON
${{ matrix.build_type == 'Debug' && '-DIRCU_ENABLE_DEBUG=ON' || '' }}

- name: Build
run: make -j$(nproc)
run: cmake --build build -j$(nproc)

- name: Run unit tests
run: make check
run: ctest --test-dir build --output-on-failure

- name: Smoke-test the server binary
run: ./build/ircd/ircd -v
36 changes: 11 additions & 25 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,33 +1,19 @@
# Autotools generated files
/configure
/aclocal.m4
/config.h.in
/config.guess
/config.sub
/install-sh
/missing
/depcomp
/compile
/ylwrap
/test-driver
/stamp-h.in
/autom4te.cache/
/config.h
/config.log
/config.status
/config.cache
/stamp-h
/stamp-h1

# Generated Makefile.in (automake output) and Makefile (configure output)
Makefile.in
Makefile
# CMake build trees
/build/
/build-*/
CMakeCache.txt
CMakeFiles/
CMakeUserPresets.json
cmake_install.cmake
CTestTestfile.cmake
Testing/
compile_commands.json
install_manifest.txt

# Editor/tool backup files
*~

# Build artifacts
.deps/
.project
ircu.tags
**/__pycache__
Expand Down
149 changes: 149 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#
# IRC - Internet Relay Chat, CMakeLists.txt
#
# Top-level build definition for ircu2. This replaces the historical
# GNU autotools (configure.ac / Makefile.am) build.
#
# Quick start:
# cmake -B build -DIRCU_DOMAIN=example.com
# cmake --build build -j
# ctest --test-dir build
# cmake --install build
#
# Every historical `configure` switch has an IRCU_* cache variable
# counterpart; see cmake/IrcuOptions.cmake and INSTALL.
#

cmake_minimum_required(VERSION 3.16)

# The version here is the single source of truth for the whole tree; the
# BASE_VERSION / MAJOR_PROTOCOL / RELEASE / PATCHLEVEL macros consumed by the
# server are derived from it in cmake/IrcuVersion.cmake.
project(ircu2
VERSION 10.12.19
DESCRIPTION "Undernet IRC server (ircu)"
HOMEPAGE_URL "https://github.com/UndernetIRC/ircu2"
LANGUAGES C)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# ---------------------------------------------------------------------------
# Guard against in-source builds. The autotools build tolerated them, but a
# stray CMakeCache.txt in the source tree breaks every later out-of-tree build.
# ---------------------------------------------------------------------------
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR
"In-source builds are not supported. Run cmake from a separate directory, "
"e.g. `cmake -B build`. Remove the CMakeCache.txt and CMakeFiles/ that "
"this attempt just created in the source tree.")
endif()

# ---------------------------------------------------------------------------
# Language level and default build type
# ---------------------------------------------------------------------------
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)

# Match `configure`'s default of -g -O2 when the user picks nothing.
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
"Build type (Debug, Release, RelWithDebInfo, MinSizeRel)" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
Debug Release RelWithDebInfo MinSizeRel)
endif()

# ircu decides assertions itself, through IRCU_ENABLE_ASSERTS -> NDEBUG in
# config.h. CMake's Release-flavoured build types add -DNDEBUG of their own,
# which would silently override that switch (and strip the assertions out of
# the unit tests, which never include config.h), so take it back out.
foreach(_cfg RELEASE RELWITHDEBINFO MINSIZEREL)
string(REPLACE "-DNDEBUG" "" CMAKE_C_FLAGS_${_cfg} "${CMAKE_C_FLAGS_${_cfg}}")
string(STRIP "${CMAKE_C_FLAGS_${_cfg}}" CMAKE_C_FLAGS_${_cfg})
endforeach()

# ircu historically installs under $HOME, not /usr/local. Honour that when
# the user has not asked for a prefix of their own.
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
if(DEFINED ENV{HOME} AND NOT "$ENV{HOME}" STREQUAL "")
set(CMAKE_INSTALL_PREFIX "$ENV{HOME}" CACHE PATH
"Installation prefix" FORCE)
endif()
endif()

# Emit compile_commands.json so clangd, ccls and the editors built on them
# work in this tree without extra setup.
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

include(GNUInstallDirs)

include(IrcuVersion)
include(ConfigureChecks) # probe the system: headers, types, functions
include(IrcuOptions) # user-facing knobs (the old --enable/--with flags)
include(IrcuTLS) # pick and locate the TLS backend
include(IrcuPaths) # DPATH/CPATH/LPATH/SPATH, honouring --with-chroot

# ---------------------------------------------------------------------------
# config.h
# ---------------------------------------------------------------------------
configure_file(cmake/config.h.cmake.in "${PROJECT_BINARY_DIR}/config.h" @ONLY)

# Everything compiled here sees the generated config.h and the public headers.
add_library(ircu_config INTERFACE)
target_include_directories(ircu_config INTERFACE
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/include")
target_compile_definitions(ircu_config INTERFACE IRCU2_BUILD)

if(IRCU_ENABLE_WARNINGS)
target_compile_options(ircu_config INTERFACE -Wall)
endif()
if(IRCU_ENABLE_PEDANTIC)
target_compile_options(ircu_config INTERFACE -pedantic)
endif()
if(IRCU_ENABLE_PROFILE)
target_compile_options(ircu_config INTERFACE -pg)
target_link_options(ircu_config INTERFACE -pg)
endif()
if(IRCU_LEAK_DETECT)
target_compile_definitions(ircu_config INTERFACE MDEBUG)
target_link_libraries(ircu_config INTERFACE gc)
if(NOT IRCU_LEAK_DETECT STREQUAL "yes")
target_link_directories(ircu_config INTERFACE "${IRCU_LEAK_DETECT}")
endif()
endif()

enable_testing()

add_subdirectory(ircd)
add_subdirectory(ircd/test)

# ---------------------------------------------------------------------------
# Configuration summary
# ---------------------------------------------------------------------------
message(STATUS "")
message(STATUS "ircu is now hopefully configured for your system.")
message(STATUS "")
message(STATUS " Host system: ${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_PROCESSOR}")
message(STATUS " Prefix: ${CMAKE_INSTALL_PREFIX}")
message(STATUS " Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS " Asserts: ${IRCU_ENABLE_ASSERTS}")
message(STATUS " Warnings: ${IRCU_ENABLE_WARNINGS}")
message(STATUS " Debug: ${IRCU_ENABLE_DEBUG}")
message(STATUS " Profile: ${IRCU_ENABLE_PROFILE}")
message(STATUS " Owner/mode: ${IRCU_OWNER}.${IRCU_GROUP} (${IRCU_MODE})")
message(STATUS " Chroot: ${IRCU_CHROOT}")
message(STATUS "")
message(STATUS " Domain: ${IRCU_DOMAIN}")
message(STATUS " DPath: ${IRCU_DPATH}")
message(STATUS " CPath: ${IRCU_CPATH}")
message(STATUS " LPath: ${IRCU_LPATH}")
message(STATUS " Maximum connections: ${IRCU_MAXCON}")
message(STATUS " TLS implementation: ${IRCU_TLS}")
message(STATUS " IPv6: ${IRCU_ENABLE_IPV6}")
message(STATUS "")
message(STATUS " poll() engine: ${IRCU_ENABLE_POLL}")
message(STATUS " kqueue() engine: ${IRCU_ENABLE_KQUEUE}")
message(STATUS " /dev/poll engine: ${IRCU_ENABLE_DEVPOLL}")
message(STATUS " epoll() engine: ${IRCU_ENABLE_EPOLL}")
message(STATUS "")
80 changes: 80 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
{
"version": 3,
"cmakeMinimumRequired": { "major": 3, "minor": 21, "patch": 0 },
"configurePresets": [
{
"name": "base",
"hidden": true,
"binaryDir": "${sourceDir}/build/${presetName}",
"cacheVariables": {
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
},
{
"name": "default",
"inherits": "base",
"displayName": "Default (RelWithDebInfo, autodetected TLS)",
"description": "What you get from a plain `cmake -B build`.",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo"
}
},
{
"name": "dev",
"inherits": "base",
"displayName": "Development (debug build, warnings on)",
"description": "Unoptimised, DEBUGMODE compiled in, -Wall.",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug",
"IRCU_ENABLE_DEBUG": "ON",
"IRCU_ENABLE_WARNINGS": "ON"
}
},
{
"name": "asan",
"inherits": "dev",
"displayName": "Development with AddressSanitizer",
"cacheVariables": {
"CMAKE_C_FLAGS": "-fsanitize=address,undefined -fno-omit-frame-pointer",
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address,undefined"
}
},
{
"name": "release",
"inherits": "base",
"displayName": "Release (optimised, assertions off)",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Release",
"IRCU_ENABLE_ASSERTS": "OFF"
}
},
{
"name": "no-tls",
"inherits": "base",
"displayName": "No TLS backend",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
"IRCU_TLS": "none"
}
}
],
"buildPresets": [
{ "name": "default", "configurePreset": "default" },
{ "name": "dev", "configurePreset": "dev" },
{ "name": "asan", "configurePreset": "asan" },
{ "name": "release", "configurePreset": "release" },
{ "name": "no-tls", "configurePreset": "no-tls" }
],
"testPresets": [
{
"name": "base",
"hidden": true,
"output": { "outputOnFailure": true }
},
{ "name": "default", "inherits": "base", "configurePreset": "default" },
{ "name": "dev", "inherits": "base", "configurePreset": "dev" },
{ "name": "asan", "inherits": "base", "configurePreset": "asan" },
{ "name": "release", "inherits": "base", "configurePreset": "release" },
{ "name": "no-tls", "inherits": "base", "configurePreset": "no-tls" }
]
}
24 changes: 13 additions & 11 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,8 @@ ARG SANITIZE=
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
make \
cmake \
bison \
flex \
autoconf \
automake \
autoconf-archive \
libc6-dev \
pkg-config \
$(if [ "$TLS_BACKEND" = "openssl" ]; then echo libssl-dev; \
Expand All @@ -36,16 +33,21 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
WORKDIR /build/ircu2
COPY . .

# Remove any host-compiled binaries (e.g., macOS Mach-O) so make rebuilds for Linux
RUN find . -name '*.o' -delete && rm -f ircd/ircd
# Drop any host-compiled leftovers (e.g. a macOS build tree) so the build here
# starts from scratch for Linux.
RUN rm -rf build && find . -name '*.o' -delete

RUN ./autogen.sh \
&& if [ -n "$SANITIZE" ]; then \
RUN if [ -n "$SANITIZE" ]; then \
export CFLAGS="-fsanitize=$SANITIZE -fno-omit-frame-pointer -g -O1"; \
export LDFLAGS="-fsanitize=$SANITIZE"; \
fi; \
./configure --prefix=/opt/ircu --with-maxcon=256 --enable-debug --with-tls=${TLS_BACKEND} \
&& make
cmake -B build \
-DCMAKE_INSTALL_PREFIX=/opt/ircu \
-DIRCU_MAXCON=256 \
-DIRCU_ENABLE_DEBUG=ON \
-DIRCU_TLS=${TLS_BACKEND} \
-DIRCU_DOMAIN=example.com \
&& cmake --build build -j"$(nproc)"

# ---------------------------------------------------------------------------
# Stage: build the current Undernet production release from GitHub
Expand Down Expand Up @@ -134,5 +136,5 @@ RUN chown ircu:ircu /opt/ircu/bin/ircd
# Final: working-tree binary (default target — must stay last)
# ---------------------------------------------------------------------------
FROM runtime-base AS runtime-tree
COPY --from=builder-tree /build/ircu2/ircd/ircd /opt/ircu/bin/ircd
COPY --from=builder-tree /build/ircu2/build/ircd/ircd /opt/ircu/bin/ircd
RUN chown ircu:ircu /opt/ircu/bin/ircd
Loading