199 lines
6.6 KiB
CMake
199 lines
6.6 KiB
CMake
cmake_minimum_required(VERSION 3.0)
|
|
get_filename_component(project_name ${CMAKE_CURRENT_SOURCE_DIR} NAME)
|
|
project(${project_name})
|
|
|
|
set(EXTENSION "cpp")
|
|
|
|
set(CMAKE_C_STANDARD 99)
|
|
set(CMAKE_CXX_STANDARD 14)
|
|
|
|
set(GEN_BINARY OFF)
|
|
set(GEN_LIBRARY OFF)
|
|
set(LIB_TYPE STATIC) # NONE, STATIC, SHARED, MODULE
|
|
set(LIBS_TYPE STATIC)
|
|
|
|
set(FLAGS_ANY "-Wall -Wextra -fopenmp -Winline -Wfatal-errors")
|
|
set(FLAGS_DEBUG "-DDEBUG -Og -g -fsanitize=thread")
|
|
set(FLAGS_RELEASE "-DNDEBUG -O2")
|
|
|
|
set(SRCDIRS src)
|
|
set(LIBSDIRS libsrc)
|
|
set(TESTSDIRS tests)
|
|
set(EXAMPLESDIRS examples benchmarks)
|
|
set(MANDIR man)
|
|
|
|
set(INCLUDE_DIRS inc)
|
|
set(LIBRARIES "")
|
|
|
|
set(USER_LIBRARIES "")
|
|
|
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS_ANY}")
|
|
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${FLAGS_ANY} ${FLAGS_DEBUG}")
|
|
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${FLAGS_ANY} ${FLAGS_RELEASE}")
|
|
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS_ANY}")
|
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${FLAGS_ANY} ${FLAGS_DEBUG}")
|
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${FLAGS_ANY} ${FLAGS_RELEASE}")
|
|
|
|
if(USE_SANITIZER STREQUAL "Address")
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
|
|
elseif(USE_SANITIZER STREQUAL "Leak")
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=leak")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=leak")
|
|
elseif(USE_SANITIZER STREQUAL "Thread")
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")
|
|
elseif(USE_SANITIZER STREQUAL "Undefined")
|
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined")
|
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
|
|
endif()
|
|
|
|
## Libraries
|
|
if(NOT ${LIB_TYPE} MATCHES "^NONE$")
|
|
# Project library
|
|
if(GEN_LIBRARY)
|
|
set(lib_src "")
|
|
foreach(srcdir ${SRCDIRS})
|
|
set(srcpath ${CMAKE_CURRENT_SOURCE_DIR}/${srcdir})
|
|
file(GLOB_RECURSE tmpsrc ${srcpath}/*.${EXTENSION})
|
|
list(APPEND lib_src ${tmpsrc})
|
|
endforeach()
|
|
|
|
set(lib ${PROJECT_NAME})
|
|
if(lib_src)
|
|
message(STATUS "+ Library: ${lib}")
|
|
add_library(${lib} ${LIB_TYPE} ${lib_src})
|
|
target_include_directories(${lib} PUBLIC ${INCLUDE_DIRS})
|
|
target_link_libraries(${lib} ${LIBRARIES})
|
|
list(APPEND USER_LIBRARIES ${lib})
|
|
else()
|
|
message(WARNING "! Library ${lib}: no sources")
|
|
endif()
|
|
endif()
|
|
endif()
|
|
|
|
## Other libraries
|
|
if(NOT ${LIBS_TYPE} MATCHES "^NONE$")
|
|
foreach(libsdir ${LIBSDIRS})
|
|
set(libspath ${CMAKE_CURRENT_SOURCE_DIR}/${libsdir})
|
|
file(GLOB libs RELATIVE ${libspath} ${libspath}/*)
|
|
if(libs)
|
|
foreach(child ${libs})
|
|
set(lib "")
|
|
if(IS_DIRECTORY ${libspath}/${child})
|
|
set(lib ${child})
|
|
file(GLOB_RECURSE lib_src ${libspath}/${child}/*.${EXTENSION})
|
|
else()
|
|
message(WARNING "! Ignoring file: ${libsdir}/${child}")
|
|
endif()
|
|
if(lib)
|
|
if(lib_src)
|
|
message(STATUS "+ Library: ${lib}")
|
|
add_library(${lib} ${LIBS_TYPE} ${lib_src})
|
|
target_include_directories(${lib} PUBLIC ${INCLUDE_DIRS})
|
|
target_link_libraries(${lib} ${LIBRARIES})
|
|
list(APPEND USER_LIBRARIES ${lib})
|
|
else()
|
|
message(WARNING "! Library ${lib}: no sources")
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
|
|
## Binary
|
|
if(GEN_BINARY)
|
|
set(src "")
|
|
foreach(srcdir ${SRCDIRS})
|
|
set(srcpath ${CMAKE_CURRENT_SOURCE_DIR}/${srcdir})
|
|
file(GLOB_RECURSE tmpsrc ${srcpath}/*.${EXTENSION})
|
|
list(APPEND src ${tmpsrc})
|
|
endforeach()
|
|
set(bin ${PROJECT_NAME})
|
|
if(src)
|
|
if(GEN_LIBRARY)
|
|
set(bin ${bin}.bin)
|
|
endif()
|
|
message(STATUS "+ Binary: ${bin}")
|
|
add_executable(${bin} ${src})
|
|
target_include_directories(${bin} PUBLIC ${LIBSDIRS} ${INCLUDE_DIRS})
|
|
target_link_libraries(${bin} ${LIBRARIES} ${USER_LIBRARIES})
|
|
else()
|
|
message(WARNING "! Binary ${bin}: no sources")
|
|
endif()
|
|
endif()
|
|
|
|
## Tests
|
|
foreach(testsdir ${TESTSDIRS})
|
|
set(testspath ${CMAKE_CURRENT_SOURCE_DIR}/${testsdir})
|
|
file(GLOB_RECURSE tests_src ${testspath}/*.${EXTENSION})
|
|
if(tests_src)
|
|
set(tests ${testsdir}_${PROJECT_NAME})
|
|
message(STATUS "+ Tests: ${tests}")
|
|
add_executable(${tests} ${tests_src})
|
|
target_include_directories(${tests} PUBLIC ${SRCDIRS} ${LIBSDIRS} ${INCLUDE_DIRS})
|
|
target_link_libraries(${tests} ${LIBRARIES} ${USER_LIBRARIES})
|
|
endif()
|
|
endforeach()
|
|
|
|
## Examples
|
|
foreach(examplesdir ${EXAMPLESDIRS})
|
|
set(examplespath ${CMAKE_CURRENT_SOURCE_DIR}/${examplesdir})
|
|
file(GLOB examples RELATIVE ${examplespath} ${examplespath}/*)
|
|
if(examples)
|
|
foreach(child ${examples})
|
|
set(example_bin_filename "")
|
|
set(example "")
|
|
if(IS_DIRECTORY ${examplespath}/${child})
|
|
set(example_bin_filename ${child})
|
|
set(example ${examplesdir}_${example_bin_filename})
|
|
file(GLOB_RECURSE example_src ${examplespath}/${child}/*.${EXTENSION})
|
|
else()
|
|
get_filename_component(extension ${child} EXT)
|
|
if(${extension} MATCHES "^.${EXTENSION}$")
|
|
get_filename_component(example_name ${child} NAME_WE)
|
|
set(example_bin_filename ${example_name})
|
|
set(example ${examplesdir}_${example_bin_filename})
|
|
set(example_src ${examplespath}/${child})
|
|
endif()
|
|
endif()
|
|
if(example)
|
|
if(example_src)
|
|
message(STATUS "+ Example: ${examplesdir}/${example}")
|
|
add_executable(${example} ${example_src})
|
|
target_include_directories(${example} PUBLIC ${SRCDIRS} ${LIBSDIRS} ${INCLUDE_DIRS})
|
|
target_link_libraries(${example} ${LIBRARIES} ${USER_LIBRARIES})
|
|
set_target_properties(${example} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${examplesdir})
|
|
set_target_properties(${example} PROPERTIES OUTPUT_NAME ${example_bin_filename})
|
|
else()
|
|
message(WARNING "! Example ${example}: no sources")
|
|
endif()
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
endforeach()
|
|
|
|
## Man pages
|
|
set(MANPATH ${CMAKE_CURRENT_SOURCE_DIR}/${MANDIR})
|
|
set(MAN_OUTPATH ${CMAKE_BINARY_DIR}/deb/usr/share/man)
|
|
file(GLOB_RECURSE man_src RELATIVE ${MANPATH} ${MANPATH}/*)
|
|
if(man_src)
|
|
set(man_outfiles "")
|
|
foreach(man_file IN LISTS man_src)
|
|
set(man_outfile ${MAN_OUTPATH}/${man_file}.gz)
|
|
get_filename_component(man_outdir ${man_outfile} DIRECTORY)
|
|
list(APPEND man_outfiles ${man_outfile})
|
|
message(STATUS "+ manpage: ${man_file}")
|
|
add_custom_command(OUTPUT ${man_outfile}
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${man_outdir}
|
|
COMMAND ${CMAKE_COMMAND} -E copy ${MANPATH}/${man_file} ${MAN_OUTPATH}/${man_file}
|
|
COMMAND gzip -f ${MAN_OUTPATH}/${man_file}
|
|
DEPENDS ${MANPATH}/${man_file})
|
|
endforeach()
|
|
add_custom_target(man ALL DEPENDS ${man_outfiles})
|
|
endif()
|