Přemysl Eric Janouch
6f596f1dcb
So far Go applications remain independent to handle Nix's inability to easily combine them with the CMake part. There is also no "install" target, because any packagers will want to adjust installation paths manually, and there is no configure step.
299 lines
10 KiB
CMake
299 lines
10 KiB
CMake
# Ubuntu 18.04 LTS and OpenBSD 6.4
|
|
cmake_minimum_required (VERSION 3.10)
|
|
|
|
file (READ xK-version project_version)
|
|
configure_file (xK-version xK-version.tag COPYONLY)
|
|
string (STRIP "${project_version}" project_version)
|
|
|
|
project (xK VERSION "${project_version}"
|
|
DESCRIPTION "IRC daemon, bot, TUI client and its web frontend" LANGUAGES C)
|
|
|
|
# Options
|
|
option (WANT_READLINE "Use GNU Readline for the UI (better)" ON)
|
|
option (WANT_LIBEDIT "Use BSD libedit for the UI" OFF)
|
|
option (WANT_XF "Build xF" OFF)
|
|
|
|
# Moar warnings
|
|
set (CMAKE_C_STANDARD 99)
|
|
set (CMAKE_C_STANDARD_REQUIRED ON)
|
|
set (CMAKE_C_EXTENSIONS OFF)
|
|
|
|
if ("${CMAKE_C_COMPILER_ID}" MATCHES "GNU" OR CMAKE_COMPILER_IS_GNUCC)
|
|
# -Wunused-function is pretty annoying here, as everything is static
|
|
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Wno-unused-function")
|
|
endif ()
|
|
|
|
# Try to append commit ID if it follows a version tag. It might be nicer if
|
|
# we could also detect dirty worktrees but that's very hard to get right.
|
|
# If we didn't need this for CPack, we could use add_custom_command to generate
|
|
# a version source/include file.
|
|
find_package (Git)
|
|
set (git_head "${PROJECT_SOURCE_DIR}/.git/HEAD")
|
|
if (GIT_FOUND AND EXISTS "${git_head}")
|
|
configure_file ("${git_head}" git-head.tag COPYONLY)
|
|
file (READ "${git_head}" git_head_content)
|
|
if (git_head_content MATCHES "^ref: ([^\r\n]+)")
|
|
set (git_ref "${PROJECT_SOURCE_DIR}/.git/${CMAKE_MATCH_1}")
|
|
if (EXISTS "${git_ref}")
|
|
configure_file ("${git_ref}" git-ref.tag COPYONLY)
|
|
endif ()
|
|
endif ()
|
|
|
|
execute_process (COMMAND ${GIT_EXECUTABLE} describe --tags --match v*
|
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
|
RESULT_VARIABLE git_describe_result
|
|
OUTPUT_VARIABLE git_describe OUTPUT_STRIP_TRAILING_WHITESPACE)
|
|
if (NOT git_describe_result)
|
|
string (REGEX REPLACE "^v" "" project_version "${git_describe}")
|
|
endif ()
|
|
endif ()
|
|
|
|
# Dashes make filenames confusing and upset packaging software
|
|
string (REPLACE "-" "+" project_version_safe "${project_version}")
|
|
|
|
# Dependencies
|
|
set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/liberty/cmake)
|
|
include (AddThreads)
|
|
|
|
find_package (PkgConfig REQUIRED)
|
|
pkg_check_modules (libssl REQUIRED libssl libcrypto)
|
|
list (APPEND project_libraries ${libssl_LIBRARIES})
|
|
include_directories (${libssl_INCLUDE_DIRS})
|
|
link_directories (${libssl_LIBRARY_DIRS})
|
|
|
|
if ("${CMAKE_SYSTEM_NAME}" MATCHES "BSD")
|
|
# Need this for SIGWINCH in FreeBSD and OpenBSD respectively;
|
|
# our POSIX version macros make it undefined
|
|
add_definitions (-D__BSD_VISIBLE=1 -D_BSD_SOURCE=1)
|
|
elseif (APPLE)
|
|
add_definitions (-D_DARWIN_C_SOURCE)
|
|
endif ()
|
|
|
|
# -lrt is only for glibc < 2.17
|
|
# -liconv may or may not be a part of libc
|
|
# -lm may or may not be a part of libc
|
|
foreach (extra iconv rt m)
|
|
find_library (extra_lib_${extra} ${extra})
|
|
if (extra_lib_${extra})
|
|
list (APPEND project_libraries ${extra_lib_${extra}})
|
|
endif ()
|
|
endforeach ()
|
|
|
|
include (CheckCSourceRuns)
|
|
set (CMAKE_REQUIRED_LIBRARIES ${project_libraries})
|
|
get_property (CMAKE_REQUIRED_INCLUDES
|
|
DIRECTORY "${PROJECT_SOURCE_DIR}" PROPERTY INCLUDE_DIRECTORIES)
|
|
CHECK_C_SOURCE_RUNS ("#include <iconv.h>
|
|
int main () { return iconv_open (\"UTF-8//TRANSLIT\", \"ISO-8859-1\")
|
|
== (iconv_t) -1; }" ICONV_ACCEPTS_TRANSLIT)
|
|
|
|
# Dependencies for xC
|
|
pkg_check_modules (libffi REQUIRED libffi)
|
|
list (APPEND xC_libraries ${libffi_LIBRARIES})
|
|
include_directories (${libffi_INCLUDE_DIRS})
|
|
link_directories (${libffi_LIBRARY_DIRS})
|
|
|
|
# XXX: other Lua versions may be acceptable, don't know yet
|
|
pkg_search_module (lua lua53 lua5.3 lua-5.3 lua54 lua5.4 lua-5.4 lua>=5.3)
|
|
option (WITH_LUA "Enable support for Lua plugins" ${lua_FOUND})
|
|
|
|
if (WITH_LUA)
|
|
if (NOT lua_FOUND)
|
|
message (FATAL_ERROR "Lua library not found")
|
|
endif ()
|
|
|
|
list (APPEND xC_libraries ${lua_LIBRARIES})
|
|
include_directories (${lua_INCLUDE_DIRS})
|
|
link_directories (${lua_LIBRARY_DIRS})
|
|
endif ()
|
|
|
|
find_package (Curses)
|
|
pkg_check_modules (ncursesw ncursesw)
|
|
if (ncursesw_FOUND)
|
|
list (APPEND xC_libraries ${ncursesw_LIBRARIES})
|
|
include_directories (${ncursesw_INCLUDE_DIRS})
|
|
elseif (CURSES_FOUND)
|
|
list (APPEND xC_libraries ${CURSES_LIBRARY})
|
|
include_directories (${CURSES_INCLUDE_DIR})
|
|
else ()
|
|
message (SEND_ERROR "Curses not found")
|
|
endif ()
|
|
|
|
if ((WANT_READLINE AND WANT_LIBEDIT) OR (NOT WANT_READLINE AND NOT WANT_LIBEDIT))
|
|
message (SEND_ERROR "You have to choose either GNU Readline or libedit")
|
|
elseif (WANT_READLINE)
|
|
pkg_check_modules (readline readline)
|
|
|
|
# OpenBSD's default readline is too old
|
|
if ("${CMAKE_SYSTEM_NAME}" MATCHES "OpenBSD")
|
|
include_directories (${OPENBSD_LOCALBASE}/include/ereadline)
|
|
list (APPEND xC_libraries ereadline)
|
|
elseif (readline_FOUND)
|
|
list (APPEND xC_libraries ${readline_LIBRARIES})
|
|
include_directories (${readline_INCLUDE_DIRS})
|
|
link_directories (${readline_LIBRARY_DIRS})
|
|
else ()
|
|
list (APPEND xC_libraries readline)
|
|
endif ()
|
|
elseif (WANT_LIBEDIT)
|
|
pkg_check_modules (libedit REQUIRED libedit)
|
|
list (APPEND xC_libraries ${libedit_LIBRARIES})
|
|
include_directories (${libedit_INCLUDE_DIRS})
|
|
endif ()
|
|
|
|
# Generate a configuration file
|
|
set (HAVE_READLINE "${WANT_READLINE}")
|
|
set (HAVE_EDITLINE "${WANT_LIBEDIT}")
|
|
set (HAVE_LUA "${WITH_LUA}")
|
|
|
|
include (GNUInstallDirs)
|
|
set (project_config ${PROJECT_BINARY_DIR}/config.h)
|
|
configure_file (${PROJECT_SOURCE_DIR}/config.h.in ${project_config})
|
|
include_directories (${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR})
|
|
|
|
# Generate IRC replies--we need a custom target because of the multiple outputs
|
|
add_custom_command (OUTPUT xD-replies.c xD.msg
|
|
COMMAND env LC_ALL=C awk
|
|
-f ${PROJECT_SOURCE_DIR}/xD-gen-replies.awk
|
|
${PROJECT_SOURCE_DIR}/xD-replies > xD-replies.c
|
|
DEPENDS
|
|
${PROJECT_SOURCE_DIR}/xD-gen-replies.awk
|
|
${PROJECT_SOURCE_DIR}/xD-replies
|
|
COMMENT "Generating files from the list of server numerics")
|
|
add_custom_target (replies DEPENDS ${PROJECT_BINARY_DIR}/xD-replies.c)
|
|
|
|
add_custom_command (OUTPUT xC-proto.c
|
|
COMMAND env LC_ALL=C awk
|
|
-f ${PROJECT_SOURCE_DIR}/liberty/tools/lxdrgen.awk
|
|
-f ${PROJECT_SOURCE_DIR}/liberty/tools/lxdrgen-c.awk
|
|
-v PrefixCamel=Relay
|
|
${PROJECT_SOURCE_DIR}/xC.lxdr > xC-proto.c
|
|
DEPENDS
|
|
${PROJECT_SOURCE_DIR}/liberty/tools/lxdrgen.awk
|
|
${PROJECT_SOURCE_DIR}/liberty/tools/lxdrgen-c.awk
|
|
${PROJECT_SOURCE_DIR}/xC.lxdr
|
|
COMMENT "Generating xC relay protocol code" VERBATIM)
|
|
add_custom_target (xC-proto DEPENDS ${PROJECT_BINARY_DIR}/xC-proto.c)
|
|
|
|
# Build
|
|
foreach (name xB xC xD)
|
|
add_executable (${name} ${name}.c ${project_config})
|
|
target_link_libraries (${name} ${project_libraries})
|
|
add_threads (${name})
|
|
endforeach ()
|
|
|
|
add_dependencies (xD replies)
|
|
add_dependencies (xC replies xC-proto)
|
|
target_link_libraries (xC ${xC_libraries})
|
|
|
|
if (WANT_XF)
|
|
pkg_check_modules (x11 REQUIRED x11 xrender xft fontconfig)
|
|
include_directories (${x11_INCLUDE_DIRS})
|
|
link_directories (${x11_LIBRARY_DIRS})
|
|
|
|
add_executable (xF xF.c ${project_config})
|
|
add_dependencies (xF xC-proto)
|
|
target_link_libraries (xF ${x11_LIBRARIES} ${project_libraries})
|
|
add_threads (xF)
|
|
endif ()
|
|
|
|
# Tests
|
|
include (CTest)
|
|
if (BUILD_TESTING)
|
|
add_executable (test-xC $<TARGET_PROPERTY:xC,SOURCES>)
|
|
set_target_properties (test-xC PROPERTIES COMPILE_DEFINITIONS TESTING)
|
|
target_link_libraries (test-xC $<TARGET_PROPERTY:xC,LINK_LIBRARIES>)
|
|
add_threads (test-xC)
|
|
add_dependencies (test-xC replies)
|
|
|
|
add_test (NAME test-xC COMMAND test-xC)
|
|
add_test (NAME custom-static-analysis
|
|
COMMAND ${PROJECT_SOURCE_DIR}/test-static)
|
|
endif ()
|
|
|
|
# Various clang-based diagnostics, loads of fake positives and spam
|
|
file (GLOB clang_tidy_sources *.c)
|
|
set (clang_tidy_checks misc-* readability-*
|
|
-readability-braces-around-statements
|
|
-readability-named-parameter)
|
|
string (REPLACE ";" "," clang_tidy_checks "${clang_tidy_checks}")
|
|
|
|
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
add_custom_target (clang-tidy
|
|
COMMAND clang-tidy -p ${PROJECT_BINARY_DIR} -checks=${clang_tidy_checks}
|
|
${clang_tidy_sources} 1>&2
|
|
USES_TERMINAL
|
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
|
|
|
|
# Installation
|
|
install (TARGETS xB xC xD DESTINATION ${CMAKE_INSTALL_BINDIR})
|
|
install (FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
|
|
install (DIRECTORY plugins/xB/
|
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/xB/plugins USE_SOURCE_PERMISSIONS)
|
|
install (DIRECTORY plugins/xC/
|
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/xC/plugins)
|
|
|
|
# Generate documentation from text markup
|
|
find_program (ASCIIDOCTOR_EXECUTABLE asciidoctor)
|
|
find_program (A2X_EXECUTABLE a2x)
|
|
if (NOT ASCIIDOCTOR_EXECUTABLE AND NOT A2X_EXECUTABLE)
|
|
message (WARNING "Neither asciidoctor nor a2x were found, "
|
|
"falling back to a substandard manual page generator")
|
|
endif ()
|
|
|
|
foreach (page xB xC xD)
|
|
set (page_output "${PROJECT_BINARY_DIR}/${page}.1")
|
|
list (APPEND project_MAN_PAGES "${page_output}")
|
|
if (ASCIIDOCTOR_EXECUTABLE)
|
|
add_custom_command (OUTPUT ${page_output}
|
|
COMMAND ${ASCIIDOCTOR_EXECUTABLE} -b manpage
|
|
-a release-version=${project_version}
|
|
-o "${page_output}"
|
|
"${PROJECT_SOURCE_DIR}/${page}.adoc"
|
|
DEPENDS ${page}.adoc
|
|
COMMENT "Generating man page for ${page}" VERBATIM)
|
|
elseif (A2X_EXECUTABLE)
|
|
add_custom_command (OUTPUT ${page_output}
|
|
COMMAND ${A2X_EXECUTABLE} --doctype manpage --format manpage
|
|
-a release-version=${project_version}
|
|
-D "${PROJECT_BINARY_DIR}"
|
|
"${PROJECT_SOURCE_DIR}/${page}.adoc"
|
|
DEPENDS ${page}.adoc
|
|
COMMENT "Generating man page for ${page}" VERBATIM)
|
|
else ()
|
|
set (ASCIIMAN ${PROJECT_SOURCE_DIR}/liberty/tools/asciiman.awk)
|
|
add_custom_command (OUTPUT ${page_output}
|
|
COMMAND env LC_ALL=C asciidoc-release-version=${project_version}
|
|
awk -f ${ASCIIMAN} "${PROJECT_SOURCE_DIR}/${page}.adoc"
|
|
> ${page_output}
|
|
DEPENDS ${page}.adoc ${ASCIIMAN}
|
|
COMMENT "Generating man page for ${page}" VERBATIM)
|
|
endif ()
|
|
endforeach ()
|
|
|
|
add_custom_target (docs ALL DEPENDS ${project_MAN_PAGES})
|
|
|
|
foreach (page ${project_MAN_PAGES})
|
|
string (REGEX MATCH "\\.([0-9])$" manpage_suffix "${page}")
|
|
install (FILES "${page}"
|
|
DESTINATION "${CMAKE_INSTALL_MANDIR}/man${CMAKE_MATCH_1}")
|
|
endforeach ()
|
|
|
|
# CPack
|
|
set (CPACK_PACKAGE_VERSION "${project_version_safe}")
|
|
set (CPACK_PACKAGE_VENDOR "Premysl Eric Janouch")
|
|
set (CPACK_PACKAGE_CONTACT "Přemysl Eric Janouch <p@janouch.name>")
|
|
set (CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/LICENSE")
|
|
|
|
set (CPACK_GENERATOR "TGZ;ZIP")
|
|
set (CPACK_PACKAGE_FILE_NAME
|
|
"${PROJECT_NAME}-${project_version_safe}-${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
|
|
set (CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}-${project_version_safe}")
|
|
|
|
set (CPACK_SOURCE_GENERATOR "TGZ;ZIP")
|
|
set (CPACK_SOURCE_IGNORE_FILES "/\\\\.git;/build;/CMakeLists.txt.user")
|
|
set (CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${project_version_safe}")
|
|
|
|
set (CPACK_SET_DESTDIR TRUE)
|
|
include (CPack)
|