Naut/CMakeLists.txt
ookami125 50a357968a examples: anime library sorter + pure-Lua Anitomy parser
Add a worked nautd scripting example that files each anime episode into a
media-server-friendly library the moment its file finishes verifying:

    <SORTED_ROOT>/<Title>/Season NN/<Title> - SNNENN.<ext>

- examples/anitomy.lua: a compact, dependency-free reimplementation of Anitomy
  (title/season/episode/release-group/resolution/year) in pure Lua — no
  require/io/os, so it embeds in the sandbox.
- examples/anime_sort.lua: on_file_complete hook that parses the filename and
  calls naut.move_file(); the embedded parser is a verbatim copy of anitomy.lua.
- examples/test_anitomy.lua, test_anime_sort.lua: parser battery + end-to-end
  path-building test with an embedded-vs-module drift guard. Wired into ctest as
  example_anitomy / example_anime_sort when a lua interpreter is present.
- docs: examples/README.md plus pointers from README and docs/scripting.md.

Verified end to end against a live nautd: file_complete -> move_file -> on-disk
relocate into the sorted tree.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 12:25:23 -04:00

292 lines
12 KiB
CMake

cmake_minimum_required(VERSION 3.20)
project(naut_torrent C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release)
endif()
add_compile_definitions(_GNU_SOURCE)
add_compile_options(-Wall -Wextra -Wshadow -Wvla -Wpointer-arith
-fno-omit-frame-pointer)
set(CMAKE_C_FLAGS_RELEASE "-O3 -march=native -DNDEBUG")
set(CMAKE_C_FLAGS_DEBUG "-O0 -g3")
# Sanitizer convenience build: -DNAUT_SAN=address|thread|undefined
if(NAUT_SAN)
add_compile_options(-fsanitize=${NAUT_SAN} -g)
add_link_options(-fsanitize=${NAUT_SAN})
endif()
include_directories(${CMAKE_SOURCE_DIR}/include)
# --- liburing (Phase 1 platform backend) ------------------------------------
find_library(URING_LIB uring)
find_path(URING_INC liburing.h)
if(NOT URING_LIB OR NOT URING_INC)
message(FATAL_ERROR "liburing not found (install liburing-dev)")
endif()
find_package(OpenSSL REQUIRED COMPONENTS Crypto)
find_package(PkgConfig REQUIRED)
pkg_check_modules(JANSSON REQUIRED IMPORTED_TARGET jansson)
pkg_check_modules(LUA REQUIRED IMPORTED_TARGET lua)
# --- core: zero-dependency foundation ---------------------------------------
add_library(naut_core STATIC
src/core/common.c
src/core/buf.c
src/core/mpmc.c
src/core/bitfield.c
src/core/log.c
src/core/worker.c
)
target_link_libraries(naut_core PUBLIC pthread)
# --- crypto: hashing + stream cipher (throughput-critical) ------------------
add_library(naut_crypto STATIC
src/crypto/sha1.c
src/crypto/sha256.c
src/crypto/rc4.c
src/crypto/merkle.c
)
target_link_libraries(naut_crypto PUBLIC naut_core)
# --- bencode: parser/encoder (fuzz target) ----------------------------------
add_library(naut_bencode STATIC src/bencode/bencode.c)
target_link_libraries(naut_bencode PUBLIC naut_core)
# --- metainfo: .torrent + magnet parsing ------------------------------------
add_library(naut_metainfo STATIC src/metainfo/metainfo.c src/metainfo/magnet.c)
target_link_libraries(naut_metainfo PUBLIC naut_bencode naut_crypto)
# --- tracker: HTTP + UDP announce (codec + blocking fetch) ------------------
add_library(naut_tracker STATIC
src/tracker/tracker.c src/tracker/udp.c src/tracker/fetch.c)
target_link_libraries(naut_tracker PUBLIC naut_bencode)
# --- dht: BEP-5 KRPC codec + bounded iterative peer lookup ------------------
add_library(naut_dht STATIC src/dht/dht.c src/dht/fetch.c)
target_link_libraries(naut_dht PUBLIC naut_bencode naut_tracker)
# --- peer: wire protocol codec (sans-IO) ------------------------------------
add_library(naut_peer STATIC
src/peer/wire.c src/peer/extension.c src/peer/metadata.c src/peer/mse.c
src/peer/pipeline.c)
target_link_libraries(naut_peer PUBLIC
naut_core naut_crypto naut_bencode naut_tracker OpenSSL::Crypto m)
# --- storage: file backend --------------------------------------------------
add_library(naut_storage STATIC src/storage/storage.c)
target_link_libraries(naut_storage PUBLIC naut_core naut_metainfo)
# --- piece: download state machine (request/assemble/verify/persist) --------
add_library(naut_piece STATIC src/piece/piece.c)
target_link_libraries(naut_piece PUBLIC naut_storage naut_crypto naut_metainfo)
# --- platform: the only code that touches the kernel ------------------------
add_library(naut_platform STATIC
src/platform/uring.c
src/platform/net.c
src/platform/system.c
)
target_include_directories(naut_platform PUBLIC ${URING_INC})
target_link_libraries(naut_platform PUBLIC naut_core ${URING_LIB})
# --- session + extensibility control plane ---------------------------------
add_library(naut_session STATIC src/session/event.c)
target_link_libraries(naut_session PUBLIC naut_core)
# torrent registry: maps control-plane ids -> storage (move_file resolution)
add_library(naut_torrents STATIC src/session/session.c)
target_link_libraries(naut_torrents PUBLIC naut_storage)
add_library(naut_rpc STATIC src/rpc/rpc.c)
target_link_libraries(naut_rpc PUBLIC
naut_session naut_core PkgConfig::JANSSON)
add_library(naut_plugin STATIC src/plugin/plugin.c)
target_link_libraries(naut_plugin PUBLIC naut_rpc naut_session dl)
add_library(naut_script STATIC src/script/script.c)
target_link_libraries(naut_script PUBLIC
naut_session naut_core PkgConfig::LUA)
add_library(naut_example MODULE plugins/example/example.c)
target_include_directories(naut_example PRIVATE ${CMAKE_SOURCE_DIR}/include)
set_target_properties(naut_example PROPERTIES PREFIX "")
# --- echo: Phase 1 gate (io_uring echo server on the buffer pool) -----------
add_executable(naut_echo apps/echo/main.c)
target_link_libraries(naut_echo PRIVATE naut_platform naut_core)
# --- leech: Phase 3 gate (single-peer download, byte-correct + verified) ----
add_executable(naut_leech apps/leech/main.c)
target_link_libraries(naut_leech PRIVATE naut_piece naut_peer naut_metainfo)
# --- swarm: Phase 4 gate (multi-peer download, rarest-first + endgame) -------
add_executable(naut_swarm apps/swarm/main.c)
target_link_libraries(naut_swarm PRIVATE
naut_piece naut_peer naut_metainfo naut_tracker naut_dht naut_platform)
# --- daemon + CLI: Phase 7 extensibility surface ---------------------------
add_executable(nautd apps/nautd/main.c)
target_link_libraries(nautd PRIVATE
naut_plugin naut_script naut_rpc naut_session naut_torrents naut_metainfo)
add_executable(nautctl apps/nautctl/main.c)
target_link_libraries(nautctl PRIVATE naut_rpc)
# --- tests ------------------------------------------------------------------
enable_testing()
foreach(t test_buf test_mpmc test_bitfield)
add_executable(${t} tests/unit/${t}.c)
target_link_libraries(${t} PRIVATE naut_core)
add_test(NAME ${t} COMMAND ${t})
endforeach()
add_executable(test_worker tests/unit/test_worker.c)
target_link_libraries(test_worker PRIVATE naut_core naut_crypto)
add_test(NAME test_worker COMMAND test_worker)
add_executable(test_pipeline tests/unit/test_pipeline.c)
target_link_libraries(test_pipeline PRIVATE naut_peer)
add_test(NAME test_pipeline COMMAND test_pipeline)
add_executable(test_rpc tests/unit/test_rpc.c)
target_link_libraries(test_rpc PRIVATE naut_rpc)
add_test(NAME test_rpc COMMAND test_rpc)
add_executable(test_plugin tests/unit/test_plugin.c)
target_link_libraries(test_plugin PRIVATE naut_plugin)
target_compile_definitions(test_plugin PRIVATE
NAUT_EXAMPLE_PLUGIN="$<TARGET_FILE:naut_example>")
add_dependencies(test_plugin naut_example)
add_test(NAME test_plugin COMMAND test_plugin)
add_executable(test_script tests/unit/test_script.c)
target_link_libraries(test_script PRIVATE naut_script)
target_compile_definitions(test_script PRIVATE
NAUT_PHASE7_SCRIPT="${CMAKE_SOURCE_DIR}/tests/fixtures/phase7.lua")
add_test(NAME test_script COMMAND test_script)
# --- benchmarks -------------------------------------------------------------
add_executable(bench_hash tests/bench/bench_hash.c)
target_link_libraries(bench_hash PRIVATE naut_crypto)
add_executable(bench_scale tests/bench/bench_scale.c)
target_link_libraries(bench_scale PRIVATE naut_core naut_crypto)
# --- fuzz-lite: mutational fuzzer (run under -DNAUT_SAN=address for value) ---
add_executable(fuzz_lite tests/fuzz/fuzz_lite.c)
target_link_libraries(fuzz_lite PRIVATE naut_metainfo)
add_executable(test_bencode tests/unit/test_bencode.c)
target_link_libraries(test_bencode PRIVATE naut_bencode)
add_test(NAME test_bencode COMMAND test_bencode)
add_executable(test_metainfo tests/unit/test_metainfo.c)
target_link_libraries(test_metainfo PRIVATE naut_metainfo)
target_compile_definitions(test_metainfo PRIVATE
NAUT_FIXTURES="${CMAKE_SOURCE_DIR}/tests/fixtures")
add_test(NAME test_metainfo COMMAND test_metainfo)
add_executable(test_peer tests/unit/test_peer.c)
target_link_libraries(test_peer PRIVATE naut_peer)
add_test(NAME test_peer COMMAND test_peer)
add_executable(test_extension tests/unit/test_extension.c)
target_link_libraries(test_extension PRIVATE naut_peer)
add_test(NAME test_extension COMMAND test_extension)
add_executable(test_mse tests/unit/test_mse.c)
target_link_libraries(test_mse PRIVATE naut_peer)
add_test(NAME test_mse COMMAND test_mse)
add_executable(test_tracker tests/unit/test_tracker.c)
target_link_libraries(test_tracker PRIVATE naut_tracker)
add_test(NAME test_tracker COMMAND test_tracker)
add_executable(test_dht tests/unit/test_dht.c)
target_link_libraries(test_dht PRIVATE naut_dht)
add_test(NAME test_dht COMMAND test_dht)
add_executable(test_storage tests/unit/test_storage.c)
target_link_libraries(test_storage PRIVATE naut_storage)
add_test(NAME test_storage COMMAND test_storage)
add_executable(test_download tests/unit/test_download.c)
target_link_libraries(test_download PRIVATE naut_piece)
target_compile_definitions(test_download PRIVATE
NAUT_FIXTURES="${CMAKE_SOURCE_DIR}/tests/fixtures")
add_test(NAME test_download COMMAND test_download)
add_executable(test_filemove tests/unit/test_filemove.c)
target_link_libraries(test_filemove PRIVATE naut_piece)
target_compile_definitions(test_filemove PRIVATE
NAUT_FIXTURES="${CMAKE_SOURCE_DIR}/tests/fixtures")
add_test(NAME test_filemove COMMAND test_filemove)
add_executable(test_picker tests/unit/test_picker.c)
target_link_libraries(test_picker PRIVATE naut_piece)
add_test(NAME test_picker COMMAND test_picker)
# Phase 3 interop gate: download from a real libtorrent seed (SKIPs without it).
add_test(NAME interop_leech
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_interop.sh $<TARGET_FILE:naut_leech>)
set_tests_properties(interop_leech PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 180)
add_test(NAME interop_mse
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_mse.sh $<TARGET_FILE:naut_leech>)
set_tests_properties(interop_mse PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 60)
add_test(NAME interop_magnet_dht
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_magnet_dht.sh
$<TARGET_FILE:naut_swarm>)
set_tests_properties(interop_magnet_dht PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 60)
# Phase 4 interop gate: both libtorrent seeds must contribute to one download.
add_test(NAME interop_swarm
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_swarm.sh $<TARGET_FILE:naut_swarm>)
set_tests_properties(interop_swarm PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 60)
add_test(NAME interop_tracker_swarm
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_tracker_swarm.sh
$<TARGET_FILE:naut_swarm> http)
set_tests_properties(interop_tracker_swarm PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 60)
add_test(NAME interop_udp_tracker_swarm
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_tracker_swarm.sh
$<TARGET_FILE:naut_swarm> udp)
set_tests_properties(interop_udp_tracker_swarm PROPERTIES SKIP_RETURN_CODE 77 TIMEOUT 60)
add_test(NAME interop_echo_scale
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_echo_scale.sh
$<TARGET_FILE:naut_echo>)
set_tests_properties(interop_echo_scale PROPERTIES TIMEOUT 30)
add_test(NAME phase7_extensibility
COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_phase7.sh
$<TARGET_FILE:nautd> $<TARGET_FILE:nautctl>
$<TARGET_FILE:naut_example>
${CMAKE_SOURCE_DIR}/tests/fixtures/phase7.lua)
set_tests_properties(phase7_extensibility PROPERTIES TIMEOUT 15)
# Example Lua scripts: parser battery + end-to-end sort path building. Only
# registered when a standalone lua interpreter is available.
find_program(LUA_BIN NAMES lua lua5.5 lua5.4 lua5.3)
if(LUA_BIN)
add_test(NAME example_anitomy
COMMAND ${LUA_BIN} ${CMAKE_SOURCE_DIR}/examples/test_anitomy.lua)
add_test(NAME example_anime_sort
COMMAND ${LUA_BIN} ${CMAKE_SOURCE_DIR}/examples/test_anime_sort.lua)
endif()
add_executable(test_crypto tests/unit/test_crypto.c)
target_link_libraries(test_crypto PRIVATE naut_crypto)
add_test(NAME test_crypto COMMAND test_crypto)
# Same vectors, scalar SHA-256 path forced, to prove both backends agree.
add_test(NAME test_crypto_scalar COMMAND test_crypto)
set_tests_properties(test_crypto_scalar PROPERTIES ENVIRONMENT "NAUT_NO_SHANI=1")