build: explicit CMake targets; move receiver pipeline out of shared
This commit is contained in:
+157
-27
@@ -70,36 +70,105 @@ endif()
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
|
||||
file(GLOB SHARED_SRCS "src/shared/*.c")
|
||||
set(FILE_STORE_SRCS "${CMAKE_CURRENT_SOURCE_DIR}/src/shared/file_store.c")
|
||||
list(REMOVE_ITEM SHARED_SRCS ${FILE_STORE_SRCS})
|
||||
file(GLOB SERVER_SRCS "src/server/*.c")
|
||||
set(SERVER_RECEIVER_SRCS src/server/receiver.c)
|
||||
file(GLOB CLIENT_SRCS "src/client/*.c")
|
||||
# --- Explicit source lists ---
|
||||
# The shared library is self-contained: it must never depend on the client or
|
||||
# server modules. In particular, the receiver pipeline (receive_thread /
|
||||
# write_thread) lives under src/server, not here, so the client executable can
|
||||
# link the shared library without pulling in any server code.
|
||||
set(SHARED_SRCS
|
||||
src/shared/array_list.c
|
||||
src/shared/batch.c
|
||||
src/shared/charset.c
|
||||
src/shared/checksum.c
|
||||
src/shared/chmod.c
|
||||
src/shared/chunk.c
|
||||
src/shared/compression.c
|
||||
src/shared/config.c
|
||||
src/shared/credentials.c
|
||||
src/shared/daemon_conf.c
|
||||
src/shared/data.c
|
||||
src/shared/delay_updates.c
|
||||
src/shared/delta.c
|
||||
src/shared/file.c
|
||||
src/shared/file_list.c
|
||||
src/shared/file_receive.c
|
||||
src/shared/file_send.c
|
||||
src/shared/file_store.c
|
||||
src/shared/filter.c
|
||||
src/shared/hardlink.c
|
||||
src/shared/identity.c
|
||||
src/shared/log.c
|
||||
src/shared/metadata.c
|
||||
src/shared/motd.c
|
||||
src/shared/multiprocessing.c
|
||||
src/shared/protocol.c
|
||||
src/shared/queue.c
|
||||
src/shared/stop_condition.c
|
||||
src/shared/transport_ssh.c
|
||||
src/shared/transport_tcp.c
|
||||
src/shared/transport_tls.c
|
||||
src/shared/utils.c
|
||||
src/shared/xattr.c
|
||||
)
|
||||
|
||||
# Server implementation (no main): the receiver read/write pipeline plus the
|
||||
# CLI parser. The server executable adds its own main (server.c).
|
||||
set(SERVER_CORE_SRCS
|
||||
src/server/receiver.c
|
||||
src/server/receiver_pipeline.c
|
||||
src/server/server_cli.c
|
||||
)
|
||||
set(SERVER_MAIN_SRCS src/server/server.c)
|
||||
|
||||
# Client implementation (no main): everything except the CLI entry point.
|
||||
set(CLIENT_CORE_SRCS
|
||||
src/client/change_list.c
|
||||
src/client/client_send.c
|
||||
src/client/client_validation.c
|
||||
src/client/scanner.c
|
||||
src/client/usage.c
|
||||
)
|
||||
set(CLIENT_MAIN_SRCS src/client/client_cli.c)
|
||||
|
||||
# --- Library targets ---
|
||||
add_library(fastsync_shared STATIC ${SHARED_SRCS})
|
||||
target_include_directories(fastsync_shared PUBLIC src/shared)
|
||||
target_link_libraries(fastsync_shared PUBLIC Threads::Threads ${ZSTD_LIBRARY} OpenSSL::SSL
|
||||
OpenSSL::Crypto xxhash)
|
||||
|
||||
add_library(fastsync_client_core STATIC ${CLIENT_CORE_SRCS})
|
||||
target_include_directories(fastsync_client_core PUBLIC src/client)
|
||||
target_link_libraries(fastsync_client_core PUBLIC fastsync_shared)
|
||||
|
||||
add_library(fastsync_server_core STATIC ${SERVER_CORE_SRCS})
|
||||
target_include_directories(fastsync_server_core PUBLIC src/server)
|
||||
target_link_libraries(fastsync_server_core PUBLIC fastsync_shared)
|
||||
|
||||
# --- Main executables ---
|
||||
add_executable(server ${SERVER_SRCS} ${SHARED_SRCS} ${FILE_STORE_SRCS})
|
||||
target_include_directories(server PRIVATE src/shared src/server src/client)
|
||||
target_link_libraries(server PRIVATE Threads::Threads ${ZSTD_LIBRARY} OpenSSL::SSL OpenSSL::Crypto xxhash)
|
||||
# The client links only the shared library and its own core; it deliberately
|
||||
# does NOT get src/server on its include path nor compile receiver.c.
|
||||
add_executable(server ${SERVER_MAIN_SRCS})
|
||||
target_link_libraries(server PRIVATE fastsync_server_core)
|
||||
|
||||
add_executable(client ${CLIENT_SRCS} ${SHARED_SRCS} ${FILE_STORE_SRCS} ${SERVER_RECEIVER_SRCS})
|
||||
target_include_directories(client PRIVATE src/shared src/server src/client)
|
||||
target_link_libraries(client PRIVATE Threads::Threads ${ZSTD_LIBRARY} OpenSSL::SSL OpenSSL::Crypto xxhash)
|
||||
add_executable(client ${CLIENT_MAIN_SRCS})
|
||||
target_link_libraries(client PRIVATE fastsync_client_core)
|
||||
|
||||
# --- Production hardening ---
|
||||
# Each compile flag is probed so a compiler/architecture that lacks it still
|
||||
# configures cleanly. _FORTIFY_SOURCE is guarded separately because it only
|
||||
# works in an optimising build. xxHash is a static archive built by
|
||||
# FetchContent, so it must be position-independent for the -pie link.
|
||||
# FetchContent, so it must be position-independent for the -pie link; the same
|
||||
# applies to the first-party static libraries linked into the -pie binaries.
|
||||
if(HARDENING_ACTIVE)
|
||||
set_target_properties(xxhash PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(xxhash fastsync_shared fastsync_server_core fastsync_client_core
|
||||
PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
include(CheckCCompilerFlag)
|
||||
foreach(flag -fstack-protector-strong -fstack-clash-protection -fPIE)
|
||||
string(MAKE_C_IDENTIFIER "HARDEN_${flag}" _harden_var)
|
||||
check_c_compiler_flag("${flag}" ${_harden_var})
|
||||
endforeach()
|
||||
check_c_compiler_flag("-D_FORTIFY_SOURCE=2" HARDEN_FORTIFY_SOURCE)
|
||||
foreach(target server client)
|
||||
foreach(target fastsync_shared fastsync_server_core fastsync_client_core server client)
|
||||
foreach(flag -fstack-protector-strong -fstack-clash-protection -fPIE)
|
||||
string(MAKE_C_IDENTIFIER "HARDEN_${flag}" _harden_var)
|
||||
if(${_harden_var})
|
||||
@@ -109,6 +178,8 @@ if(HARDENING_ACTIVE)
|
||||
if(HARDEN_FORTIFY_SOURCE)
|
||||
target_compile_options(${target} PRIVATE -D_FORTIFY_SOURCE=2)
|
||||
endif()
|
||||
endforeach()
|
||||
foreach(target server client)
|
||||
target_link_options(${target} PRIVATE -pie -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack)
|
||||
endforeach()
|
||||
endif()
|
||||
@@ -116,16 +187,59 @@ endif()
|
||||
# --- Testing ---
|
||||
enable_testing()
|
||||
|
||||
# Common test libraries
|
||||
set(TEST_LIBS Threads::Threads ${ZSTD_LIBRARY} OpenSSL::SSL OpenSSL::Crypto xxhash)
|
||||
set(TEST_INCLUDES tests src/shared src/server src/client)
|
||||
# --- Unit tests ---
|
||||
# The monolithic test binary exercises both client and server code, so it is
|
||||
# the one place that legitimately sees both include directories and links both
|
||||
# core libraries. client_cli.c is compiled here directly (with the test build
|
||||
# define) rather than linked from fastsync_client_core so its test-only shims
|
||||
# and the absence of main() are preserved.
|
||||
set(TEST_SRCS
|
||||
tests/runner.c
|
||||
tests/test_array_list.c
|
||||
tests/test_batch.c
|
||||
tests/test_change_list.c
|
||||
tests/test_checksum.c
|
||||
tests/test_chunk.c
|
||||
tests/test_client_cli.c
|
||||
tests/test_compression.c
|
||||
tests/test_config.c
|
||||
tests/test_credentials.c
|
||||
tests/test_daemon_conf.c
|
||||
tests/test_data.c
|
||||
tests/test_delay_updates.c
|
||||
tests/test_delta.c
|
||||
tests/test_file.c
|
||||
tests/test_file_list.c
|
||||
tests/test_file_sendfile.c
|
||||
tests/test_fuzz_smoke.c
|
||||
tests/test_glob.c
|
||||
tests/test_hardlink.c
|
||||
tests/test_iconv.c
|
||||
tests/test_log.c
|
||||
tests/test_metadata.c
|
||||
tests/test_motd.c
|
||||
tests/test_multiprocessing.c
|
||||
tests/test_property.c
|
||||
tests/test_protocol.c
|
||||
tests/test_queue.c
|
||||
tests/test_receiver_timeout.c
|
||||
tests/test_robustness.c
|
||||
tests/test_scanner.c
|
||||
tests/test_server.c
|
||||
tests/test_server_cli.c
|
||||
tests/test_shared_utils.c
|
||||
tests/test_stop.c
|
||||
tests/test_stress.c
|
||||
tests/test_transport_ssh.c
|
||||
tests/test_transport_tcp.c
|
||||
tests/test_transport_tls.c
|
||||
tests/test_xattr.c
|
||||
)
|
||||
|
||||
# Monolithic test binary (backward compatible)
|
||||
file(GLOB TEST_SRCS "tests/test_*.c" "tests/runner.c")
|
||||
add_executable(tests ${TEST_SRCS} ${SHARED_SRCS} ${FILE_STORE_SRCS} ${SERVER_RECEIVER_SRCS} src/client/scanner.c src/client/change_list.c src/client/client_cli.c src/client/client_validation.c src/client/usage.c src/server/server_cli.c)
|
||||
target_include_directories(tests PRIVATE ${TEST_INCLUDES})
|
||||
add_executable(tests ${TEST_SRCS} src/client/client_cli.c)
|
||||
target_include_directories(tests PRIVATE tests)
|
||||
target_compile_definitions(tests PRIVATE FASTSYNC_TEST_BUILD)
|
||||
target_link_libraries(tests PRIVATE ${TEST_LIBS})
|
||||
target_link_libraries(tests PRIVATE fastsync_server_core fastsync_client_core)
|
||||
add_test(NAME unit_all COMMAND tests)
|
||||
|
||||
# --- Fuzz targets (requires clang) ---
|
||||
@@ -134,13 +248,29 @@ if(ENABLE_FUZZ)
|
||||
if(NOT CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
message(FATAL_ERROR "ENABLE_FUZZ requires Clang (compiler is ${CMAKE_C_COMPILER_ID})")
|
||||
endif()
|
||||
file(GLOB FUZZ_SRCS "tests/fuzz/*.c")
|
||||
set(FUZZ_SRCS
|
||||
tests/fuzz/fuzz_chunk_deserialize.c
|
||||
tests/fuzz/fuzz_compress_decompress.c
|
||||
tests/fuzz/fuzz_config_receive.c
|
||||
tests/fuzz/fuzz_delta_deserialize.c
|
||||
tests/fuzz/fuzz_delta_signature_deserialize.c
|
||||
tests/fuzz/fuzz_glob_match.c
|
||||
tests/fuzz/fuzz_identity_parse.c
|
||||
tests/fuzz/fuzz_manifest.c
|
||||
tests/fuzz/fuzz_metadata_from_buf.c
|
||||
tests/fuzz/fuzz_protocol_framing.c
|
||||
tests/fuzz/fuzz_xattr_block.c
|
||||
)
|
||||
# Compile the sources under test directly so libFuzzer's coverage
|
||||
# instrumentation sees them (static libraries would be uninstrumented).
|
||||
set(FUZZ_CORE_SRCS ${SHARED_SRCS} src/server/receiver.c src/server/receiver_pipeline.c)
|
||||
foreach(FUZZ_SRC ${FUZZ_SRCS})
|
||||
get_filename_component(FUZZ_NAME ${FUZZ_SRC} NAME_WE)
|
||||
add_executable(${FUZZ_NAME} ${FUZZ_SRC} ${SHARED_SRCS} ${FILE_STORE_SRCS} ${SERVER_RECEIVER_SRCS})
|
||||
target_include_directories(${FUZZ_NAME} PRIVATE ${TEST_INCLUDES})
|
||||
add_executable(${FUZZ_NAME} ${FUZZ_SRC} ${FUZZ_CORE_SRCS})
|
||||
target_include_directories(${FUZZ_NAME} PRIVATE tests src/shared src/server)
|
||||
target_compile_options(${FUZZ_NAME} PRIVATE -fsanitize=fuzzer,address,undefined -fno-omit-frame-pointer)
|
||||
target_link_options(${FUZZ_NAME} PRIVATE -fsanitize=fuzzer,address,undefined)
|
||||
target_link_libraries(${FUZZ_NAME} PRIVATE ${TEST_LIBS})
|
||||
target_link_libraries(${FUZZ_NAME} PRIVATE Threads::Threads ${ZSTD_LIBRARY} OpenSSL::SSL
|
||||
OpenSSL::Crypto xxhash)
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
Reference in New Issue
Block a user