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) option(NAUT_STANDALONE "Statically embed Jansson and Lua in the daemon and client" OFF) option(NAUT_NATIVE "Optimize Release builds for the build machine's CPU" OFF) 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 -DNDEBUG") set(CMAKE_C_FLAGS_DEBUG "-O0 -g3") if(NAUT_NATIVE) add_compile_options($<$:-march=native>) endif() # 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) # --- external download engine + tracker/DHT protocol libraries -------------- # torrent-peer: multi-peer download engine (engine.h) — replaces Naut's own peer # poll loop, request pipeline, and MSE transport. # torrent-tracker: tracker/DHT wire codec (tracker.h) — drives Naut's announce # and get_peers glue in src/discovery. set(PEER_NATIVE ${NAUT_NATIVE} CACHE BOOL "" FORCE) set(TRACKER_NATIVE ${NAUT_NATIVE} CACHE BOOL "" FORCE) set(TRACKER_TESTS OFF CACHE BOOL "" FORCE) if(NAUT_SAN STREQUAL "address" OR NAUT_SAN STREQUAL "undefined") set(PEER_ASAN ON CACHE BOOL "" FORCE) set(TRACKER_ASAN ON CACHE BOOL "" FORCE) endif() add_subdirectory(${CMAKE_SOURCE_DIR}/../torrent-peer ${CMAKE_BINARY_DIR}/torrent-peer) add_subdirectory(${CMAKE_SOURCE_DIR}/../torrent-tracker ${CMAKE_BINARY_DIR}/torrent-tracker) if(NAUT_STANDALONE) include(FetchContent) # Jansson 2.14.1 predates CMake 4's removal of pre-3.5 policy defaults. set(CMAKE_POLICY_VERSION_MINIMUM 3.5) set(JANSSON_BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE) set(JANSSON_BUILD_DOCS OFF CACHE BOOL "" FORCE) set(JANSSON_EXAMPLES OFF CACHE BOOL "" FORCE) set(JANSSON_INSTALL OFF CACHE BOOL "" FORCE) FetchContent_Declare(jansson URL https://github.com/akheron/jansson/archive/refs/tags/v2.14.1.tar.gz URL_HASH SHA256=979210eaffdffbcf54cfc34d047fccde13f21b529a381df26db871d886f729a4 DOWNLOAD_EXTRACT_TIMESTAMP TRUE) FetchContent_MakeAvailable(jansson) target_include_directories(jansson INTERFACE ${jansson_SOURCE_DIR}/src ${jansson_BINARY_DIR}/include) FetchContent_Declare(lua URL https://www.lua.org/ftp/lua-5.4.8.tar.gz URL_HASH SHA256=4f18ddae154e793e46eeab727c59ef1c0c0c2b744e7b94219710d76f530629ae DOWNLOAD_EXTRACT_TIMESTAMP TRUE SOURCE_SUBDIR cmake-unused) FetchContent_MakeAvailable(lua) set(LUA_SRC_DIR ${lua_SOURCE_DIR}/src) add_library(naut_lua STATIC ${LUA_SRC_DIR}/lapi.c ${LUA_SRC_DIR}/lauxlib.c ${LUA_SRC_DIR}/lbaselib.c ${LUA_SRC_DIR}/lcode.c ${LUA_SRC_DIR}/lcorolib.c ${LUA_SRC_DIR}/lctype.c ${LUA_SRC_DIR}/ldblib.c ${LUA_SRC_DIR}/ldebug.c ${LUA_SRC_DIR}/ldo.c ${LUA_SRC_DIR}/ldump.c ${LUA_SRC_DIR}/lfunc.c ${LUA_SRC_DIR}/lgc.c ${LUA_SRC_DIR}/linit.c ${LUA_SRC_DIR}/liolib.c ${LUA_SRC_DIR}/llex.c ${LUA_SRC_DIR}/lmathlib.c ${LUA_SRC_DIR}/lmem.c ${LUA_SRC_DIR}/loadlib.c ${LUA_SRC_DIR}/lobject.c ${LUA_SRC_DIR}/lopcodes.c ${LUA_SRC_DIR}/loslib.c ${LUA_SRC_DIR}/lparser.c ${LUA_SRC_DIR}/lstate.c ${LUA_SRC_DIR}/lstring.c ${LUA_SRC_DIR}/lstrlib.c ${LUA_SRC_DIR}/ltable.c ${LUA_SRC_DIR}/ltablib.c ${LUA_SRC_DIR}/ltm.c ${LUA_SRC_DIR}/lundump.c ${LUA_SRC_DIR}/lutf8lib.c ${LUA_SRC_DIR}/lvm.c ${LUA_SRC_DIR}/lzio.c) target_compile_definitions(naut_lua PRIVATE LUA_USE_LINUX) target_include_directories(naut_lua PUBLIC ${LUA_SRC_DIR}) target_link_libraries(naut_lua PUBLIC m ${CMAKE_DL_LIBS}) set(NAUT_JANSSON_TARGET jansson) set(NAUT_LUA_TARGET naut_lua) else() find_package(PkgConfig REQUIRED) pkg_check_modules(JANSSON REQUIRED IMPORTED_TARGET jansson) pkg_check_modules(LUA REQUIRED IMPORTED_TARGET lua) set(NAUT_JANSSON_TARGET PkgConfig::JANSSON) set(NAUT_LUA_TARGET PkgConfig::LUA) endif() # --- 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) # --- discovery: tracker announce + DHT get_peers glue over torrent-tracker --- add_library(naut_discovery STATIC src/discovery/tracker_client.c src/discovery/dht_client.c) target_link_libraries(naut_discovery PUBLIC naut_core torrenttracker) # --- peer: wire protocol codec (sans-IO), retained for magnet metadata ------- add_library(naut_peer STATIC src/peer/wire.c src/peer/extension.c src/peer/metadata.c) target_link_libraries(naut_peer PUBLIC naut_core naut_crypto naut_bencode 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}) # CPU topology helpers do not require the io_uring platform backend. add_library(naut_system STATIC src/platform/system.c) target_link_libraries(naut_system PUBLIC naut_core) # --- 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 ${NAUT_JANSSON_TARGET}) 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 ${NAUT_LUA_TARGET}) 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 "") add_library(naut_webui MODULE plugins/webui/webui.c) target_include_directories(naut_webui PRIVATE ${CMAKE_SOURCE_DIR}/include) target_link_libraries(naut_webui PRIVATE ${NAUT_JANSSON_TARGET} pthread) set_target_properties(naut_webui PROPERTIES PREFIX "") # --- swarm: multi-peer download driver over the torrent-peer engine --------- add_library(naut_swarm_engine STATIC apps/swarm/main.c) target_compile_definitions(naut_swarm_engine PRIVATE NAUT_SWARM_LIBRARY) target_link_libraries(naut_swarm_engine PUBLIC naut_piece naut_peer naut_metainfo naut_discovery naut_system naut_session torrentpeer) # --- 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_metainfo naut_swarm_engine) 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_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="$") 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_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) add_test(NAME phase7_extensibility COMMAND bash ${CMAKE_SOURCE_DIR}/tests/integration/run_phase7.sh $ $ $ ${CMAKE_SOURCE_DIR}/tests/fixtures/phase7.lua) set_tests_properties(phase7_extensibility PROPERTIES TIMEOUT 15) set_tests_properties(phase7_extensibility PROPERTIES SKIP_RETURN_CODE 77) # 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")