cmake_minimum_required(VERSION 3.25)

project(asyncpp)

set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(ASYNCPP_BUILD_TESTS "Build tests." ON)
option(ASYNCPP_BUILD_BENCHMARKS "Build benchmarks." ON)
option(ENABLE_LLVM_COV "Enable LLVM source-based code coverage." OFF)
option(ENABLE_LLVM_ADDRESS_SANITIZER "Enable LLVM address sanitizer." OFF)
option(ENABLE_LLVM_MEMORY_SANITIZER "Enable LLVM memory sanitizer." OFF)
option(ENABLE_LLVM_THREAD_SANITIZER "Enable LLVM thread sanitizer." OFF)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")

if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
	if (ENABLE_LLVM_COV)
		message("Using source-based coverage")
		add_compile_options("-fprofile-instr-generate" "-fcoverage-mapping" "-mllvm" "-enable-name-compression=false")
		add_link_options("-fprofile-instr-generate" "-fcoverage-mapping")
	endif()
	file(REAL_PATH "${CMAKE_SOURCE_DIR}/sanitize_ignorelist.txt" sanitize_ignorelist)
	if (ENABLE_LLVM_ADDRESS_SANITIZER)
		message("Using address sanitizer")
		add_compile_options("-fsanitize=address")
		add_compile_options("-fsanitize-ignorelist=${sanitize_ignorelist}")
		add_link_options("-fsanitize=address")
	endif()
	if (ENABLE_LLVM_MEMORY_SANITIZER)
		message("Using memory sanitizer")
		add_compile_options("-fsanitize=memory")
		add_compile_options("-fsanitize-ignorelist=${sanitize_ignorelist}")
		add_link_options("-fsanitize=memory")
	endif()
	if (ENABLE_LLVM_THREAD_SANITIZER)
		message("Using thread sanitizer")
		add_compile_options("-fsanitize=thread")
		add_compile_options("-fsanitize-ignorelist=${sanitize_ignorelist}")
		add_link_options("-fsanitize=thread")
	endif()
endif()

if (${ASYNCPP_BUILD_TESTS})
	add_compile_definitions(ASYNCPP_BUILD_TESTS=1)
endif()

add_subdirectory(include/asyncpp)
add_subdirectory(src)
if (${ASYNCPP_BUILD_TESTS})
	add_subdirectory(test)
endif()
if (${ASYNCPP_BUILD_BENCHMARKS})
	add_subdirectory(benchmark)
endif()

install(TARGETS asyncpp DESTINATION "lib")
install(DIRECTORY "include/asyncpp" DESTINATION "include")