377 lines
18 KiB
CMake
377 lines
18 KiB
CMake
cmake_minimum_required(VERSION 3.16)
|
|
|
|
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/CHANGES" _libowfat_changes LIMIT_COUNT 1)
|
|
string(REGEX REPLACE ":.*$" "" LIBOWFAT_VERSION "${_libowfat_changes}")
|
|
if(NOT LIBOWFAT_VERSION MATCHES "^[0-9]+(\\.[0-9]+)*$")
|
|
message(FATAL_ERROR "Could not read libowfat version from first line of CHANGES")
|
|
endif()
|
|
|
|
project(libowfat
|
|
VERSION ${LIBOWFAT_VERSION}
|
|
DESCRIPTION "libowfat build"
|
|
LANGUAGES C)
|
|
|
|
include(CheckCSourceCompiles)
|
|
include(CheckIncludeFile)
|
|
include(GNUInstallDirs)
|
|
include(CMakePackageConfigHelpers)
|
|
|
|
option(LIBOWFAT_BUILD_STATIC "Build static libowfat/nwowfat library" OFF)
|
|
option(LIBOWFAT_BUILD_SHARED "Build shared libowfat library" ON)
|
|
set(LIBOWFAT_LIBRARY_PREFIX "" CACHE STRING "Optional library basename prefix, e.g. nw builds libnwowfat")
|
|
option(LIBOWFAT_INSTALL "Install libraries and headers" ON)
|
|
option(LIBOWFAT_GLIBC_COMPAT "Enable glibc-compatible feature-test defines" ON)
|
|
|
|
if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR)
|
|
include(CTest)
|
|
set(_libowfat_testing_default ${BUILD_TESTING})
|
|
else()
|
|
set(_libowfat_testing_default OFF)
|
|
endif()
|
|
option(LIBOWFAT_BUILD_TEST_PROGRAMS "Build the programs in the test directory" ${_libowfat_testing_default})
|
|
option(LIBOWFAT_RUN_SELF_TESTS "Register non-interactive tests with CTest" ${_libowfat_testing_default})
|
|
if(LIBOWFAT_RUN_SELF_TESTS)
|
|
enable_testing()
|
|
endif()
|
|
|
|
if(NOT LIBOWFAT_BUILD_STATIC AND NOT LIBOWFAT_BUILD_SHARED)
|
|
message(FATAL_ERROR "At least one of LIBOWFAT_BUILD_STATIC or LIBOWFAT_BUILD_SHARED must be ON")
|
|
endif()
|
|
|
|
# Keep this CMake build close to the existing GNUmakefile, but make the checks
|
|
# out-of-tree friendly and avoid dietlibc-specific defaults. glibc builds get
|
|
# _GNU_SOURCE so Linux/glibc extension declarations stay visible.
|
|
set(LIBOWFAT_FEATURE_DEFINES _REENTRANT)
|
|
if(LIBOWFAT_GLIBC_COMPAT AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
|
|
check_c_source_compiles("#ifndef _GNU_SOURCE\n#error _GNU_SOURCE is not predefined\n#endif\nint main(void) { return 0; }" LIBOWFAT_GNU_SOURCE_PREDEFINED)
|
|
if(NOT LIBOWFAT_GNU_SOURCE_PREDEFINED)
|
|
list(APPEND LIBOWFAT_FEATURE_DEFINES _GNU_SOURCE)
|
|
endif()
|
|
endif()
|
|
set(LIBOWFAT_OUTPUT_NAME "${LIBOWFAT_LIBRARY_PREFIX}owfat")
|
|
set(LIBOWFAT_INSTALL_INCLUDE_SUBDIR "${LIBOWFAT_LIBRARY_PREFIX}libowfat" CACHE STRING "Header install subdirectory below CMAKE_INSTALL_INCLUDEDIR. Defaults to libowfat or <prefix>libowfat")
|
|
set(LIBOWFAT_BUILD_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}/include")
|
|
set(LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR "${LIBOWFAT_BUILD_INCLUDE_DIR}/${LIBOWFAT_INSTALL_INCLUDE_SUBDIR}")
|
|
|
|
set(CMAKE_REQUIRED_DEFINITIONS "")
|
|
foreach(_def IN LISTS LIBOWFAT_FEATURE_DEFINES)
|
|
list(APPEND CMAKE_REQUIRED_DEFINITIONS "-D${_def}")
|
|
endforeach()
|
|
set(CMAKE_REQUIRED_INCLUDES "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
|
|
check_c_source_compiles("#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\nint main(void) { struct sockaddr_in6 x; (void)x; return 0; }" LIBC_HAS_IP6)
|
|
check_c_source_compiles("#include <sys/types.h>\n#include <sys/socket.h>\n#include <netinet/in.h>\nint main(void) { struct sockaddr_in6 x; x.sin6_scope_id = 0; return 0; }" LIBC_HAS_SCOPE_ID)
|
|
check_c_source_compiles("#include <sys/socket.h>\nint main(void) { socklen_t x = 0; return (int)x; }" HAVE_SOCKLEN_T)
|
|
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/tryn2i.c" _tryn2i_source)
|
|
check_c_source_compiles("${_tryn2i_source}" HAVE_N2I)
|
|
check_c_source_compiles("static inline int f(void) { return 0; }\nint main(void) { return f(); }" HAVE_INLINE)
|
|
check_c_source_compiles("#include <sys/types.h>\n#include <sys/event.h>\nint main(void) { return kqueue(); }" HAVE_KQUEUE)
|
|
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/trybsdsf.c" _trybsdsf_source)
|
|
check_c_source_compiles("${_trybsdsf_source}" HAVE_BSDSENDFILE)
|
|
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/trysendfile.c" _trysendfile_source)
|
|
check_c_source_compiles("${_trysendfile_source}" HAVE_SENDFILE)
|
|
check_c_source_compiles("#include <sys/epoll.h>\nint main(void) { return epoll_create(1) < 0; }" HAVE_EPOLL)
|
|
check_c_source_compiles("#include <sys/devpoll.h>\nint main(void) { return 0; }" HAVE_DEVPOLL)
|
|
check_c_source_compiles("#include <signal.h>\n#include <fcntl.h>\nint main(void) { int x = F_SETSIG; return x == 0; }" HAVE_SIGIO)
|
|
check_c_source_compiles("int main(void) { unsigned __int128 x = 0; return (int)x; }" HAVE_UINT128)
|
|
check_c_source_compiles("#include <unistd.h>\nint main(void) { char c; return pread(0, &c, 1, 0) < 0; }" HAVE_PREAD)
|
|
check_c_source_compiles("#include <fcntl.h>\n#include <sys/socket.h>\nint main(void) { return accept4(-1, 0, 0, SOCK_CLOEXEC); }" HAVE_ACCEPT4)
|
|
check_c_source_compiles("#include <poll.h>\nint main(void) { struct pollfd p; return poll(&p, 0, 0); }" HAVE_POLL)
|
|
check_c_source_compiles("#include <sys/select.h>\nint main(void) { fd_set fds; FD_ZERO(&fds); return 0; }" HAVE_SYS_SELECT_H)
|
|
check_c_source_compiles("#include <stdlib.h>\n#include <alloca.h>\nint main(void) { void *p = alloca(1); return p == 0; }" HAVE_ALLOCA_H)
|
|
check_c_source_compiles("#include <stdlib.h>\n#include <malloc.h>\nint main(void) { return 0; }" HAVE_MALLOC_H)
|
|
|
|
set(_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
|
|
set(_generated_libowfat_dir "${_generated_dir}/libowfat")
|
|
file(MAKE_DIRECTORY "${_generated_libowfat_dir}" "${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}")
|
|
|
|
function(_libowfat_rewrite_public_includes out_var content)
|
|
set(_rewritten "${content}")
|
|
if(NOT LIBOWFAT_INSTALL_INCLUDE_SUBDIR STREQUAL "libowfat")
|
|
string(REPLACE "<libowfat/" "<${LIBOWFAT_INSTALL_INCLUDE_SUBDIR}/" _rewritten "${_rewritten}")
|
|
string(REPLACE "\"libowfat/" "\"${LIBOWFAT_INSTALL_INCLUDE_SUBDIR}/" _rewritten "${_rewritten}")
|
|
endif()
|
|
set(${out_var} "${_rewritten}" PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
function(_write_public_header name content)
|
|
_libowfat_rewrite_public_includes(_public_content "${content}")
|
|
file(WRITE "${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}/${name}" "${_public_content}")
|
|
endfunction()
|
|
|
|
function(_write_generated_header name content)
|
|
file(WRITE "${_generated_dir}/${name}" "${content}")
|
|
file(WRITE "${_generated_libowfat_dir}/${name}" "${content}")
|
|
_write_public_header("${name}" "${content}")
|
|
endfunction()
|
|
|
|
function(_copy_public_header input name)
|
|
file(READ "${input}" _header_content)
|
|
_write_public_header("${name}" "${_header_content}")
|
|
endfunction()
|
|
|
|
function(_write_feature_header name content_if_true)
|
|
if(${ARGV2})
|
|
_write_generated_header("${name}" "${content_if_true}\n")
|
|
else()
|
|
_write_generated_header("${name}" "")
|
|
endif()
|
|
endfunction()
|
|
|
|
_write_feature_header(haveip6.h "#define LIBC_HAS_IP6" LIBC_HAS_IP6)
|
|
_write_feature_header(havescope.h "#define LIBC_HAS_SCOPE_ID" LIBC_HAS_SCOPE_ID)
|
|
_write_feature_header(haven2i.h "#define HAVE_N2I" HAVE_N2I)
|
|
_write_feature_header(haveinline.h "#define inline" NOT_HAVE_INLINE)
|
|
if(HAVE_INLINE)
|
|
_write_generated_header(haveinline.h "")
|
|
endif()
|
|
_write_feature_header(havekqueue.h "#define HAVE_KQUEUE" HAVE_KQUEUE)
|
|
_write_feature_header(havebsdsf.h "#define HAVE_BSDSENDFILE" HAVE_BSDSENDFILE)
|
|
_write_feature_header(havesendfile.h "#define HAVE_SENDFILE" HAVE_SENDFILE)
|
|
if(HAVE_EPOLL)
|
|
_write_generated_header(haveepoll.h "#define HAVE_EPOLL 1\n")
|
|
else()
|
|
_write_generated_header(haveepoll.h "")
|
|
endif()
|
|
_write_feature_header(havedevpoll.h "#define HAVE_DEVPOLL" HAVE_DEVPOLL)
|
|
_write_feature_header(havesigio.h "#define HAVE_SIGIO" HAVE_SIGIO)
|
|
_write_feature_header(haveuint128.h "#define HAVE_UINT128" HAVE_UINT128)
|
|
_write_feature_header(havepread.h "#define HAVE_PREAD" HAVE_PREAD)
|
|
_write_feature_header(haveaccept4.h "#define HAVE_ACCEPT4" HAVE_ACCEPT4)
|
|
|
|
if(HAVE_SOCKLEN_T)
|
|
_write_generated_header(havesl.h "")
|
|
else()
|
|
_write_generated_header(havesl.h "typedef int socklen_t;\n")
|
|
endif()
|
|
|
|
set(_havealloca_content "#include <stdlib.h>\n")
|
|
if(HAVE_ALLOCA_H)
|
|
string(APPEND _havealloca_content "#include <alloca.h>\n")
|
|
endif()
|
|
if(HAVE_MALLOC_H)
|
|
string(APPEND _havealloca_content "#include <malloc.h>\n")
|
|
endif()
|
|
_write_generated_header(havealloca.h "${_havealloca_content}")
|
|
if(HAVE_POLL)
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/iopause.h2" "${_generated_dir}/iopause.h" COPYONLY)
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/iopause.h2" "${_generated_libowfat_dir}/iopause.h" COPYONLY)
|
|
_copy_public_header("${CMAKE_CURRENT_SOURCE_DIR}/iopause.h2" iopause.h)
|
|
else()
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/iopause.h1" "${_generated_dir}/iopause.h" COPYONLY)
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/iopause.h1" "${_generated_libowfat_dir}/iopause.h" COPYONLY)
|
|
_copy_public_header("${CMAKE_CURRENT_SOURCE_DIR}/iopause.h1" iopause.h)
|
|
endif()
|
|
if(HAVE_SYS_SELECT_H)
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/select.h2" "${_generated_dir}/select.h" COPYONLY)
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/select.h2" "${_generated_libowfat_dir}/select.h" COPYONLY)
|
|
_copy_public_header("${CMAKE_CURRENT_SOURCE_DIR}/select.h2" select.h)
|
|
else()
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/select.h1" "${_generated_dir}/select.h" COPYONLY)
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/select.h1" "${_generated_libowfat_dir}/select.h" COPYONLY)
|
|
_copy_public_header("${CMAKE_CURRENT_SOURCE_DIR}/select.h1" select.h)
|
|
endif()
|
|
|
|
add_executable(libowfat_ent EXCLUDE_FROM_ALL "${CMAKE_CURRENT_SOURCE_DIR}/ent.c")
|
|
target_include_directories(libowfat_ent PRIVATE "${_generated_dir}" "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
target_compile_definitions(libowfat_ent PRIVATE _REENTRANT)
|
|
add_custom_command(
|
|
OUTPUT "${_generated_dir}/entities.h" "${_generated_libowfat_dir}/entities.h" "${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}/entities.h"
|
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/entities.json" "${_generated_dir}/entities.json"
|
|
COMMAND libowfat_ent
|
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
|
"${_generated_dir}/entities.h" "${_generated_libowfat_dir}/entities.h"
|
|
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
|
"${_generated_dir}/entities.h" "${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}/entities.h"
|
|
WORKING_DIRECTORY "${_generated_dir}"
|
|
DEPENDS libowfat_ent "${CMAKE_CURRENT_SOURCE_DIR}/entities.json"
|
|
COMMENT "Generating entities.h"
|
|
VERBATIM)
|
|
add_custom_target(libowfat_entities DEPENDS "${_generated_dir}/entities.h" "${_generated_libowfat_dir}/entities.h" "${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}/entities.h")
|
|
|
|
set(LIBOWFAT_PUBLIC_HEADERS
|
|
buffer.h byte.h fmt.h ip4.h ip6.h mmap.h scan.h socket.h str.h stralloc.h
|
|
uint16.h uint32.h uint64.h open.h textcode.h tai.h taia.h dns.h iopause.h case.h
|
|
openreadclose.h readclose.h ndelay.h array.h io.h safemult.h iob.h havealloca.h
|
|
errmsg.h cdb.h cdb_make.h rangecheck.h iarray.h va_narg.h isset.h
|
|
compiletimeassert.h critbit.h parse.h compiler.h clamp.h
|
|
)
|
|
|
|
foreach(_hdr IN LISTS LIBOWFAT_PUBLIC_HEADERS)
|
|
if(EXISTS "${_generated_dir}/${_hdr}")
|
|
configure_file("${_generated_dir}/${_hdr}" "${_generated_libowfat_dir}/${_hdr}" COPYONLY)
|
|
_copy_public_header("${_generated_dir}/${_hdr}" "${_hdr}")
|
|
else()
|
|
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/${_hdr}" "${_generated_libowfat_dir}/${_hdr}" COPYONLY)
|
|
_copy_public_header("${CMAKE_CURRENT_SOURCE_DIR}/${_hdr}" "${_hdr}")
|
|
endif()
|
|
endforeach()
|
|
|
|
file(GLOB LIBOWFAT_SOURCES CONFIGURE_DEPENDS
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/array/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/buffer/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/byte/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/case/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cdb/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/critbit/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/dns/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/fmt/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/io/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/mmap/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/mult/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/open/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/scan/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/socket/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/str/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/stralloc/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/tai/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/taia/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/textcode/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/uint/*.c"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/unix/*.c"
|
|
)
|
|
|
|
add_library(libowfat_objects OBJECT ${LIBOWFAT_SOURCES})
|
|
add_dependencies(libowfat_objects libowfat_entities)
|
|
target_compile_definitions(libowfat_objects PRIVATE _REENTRANT)
|
|
target_include_directories(libowfat_objects
|
|
PRIVATE
|
|
"${_generated_dir}"
|
|
"${_generated_libowfat_dir}"
|
|
"${CMAKE_CURRENT_SOURCE_DIR}"
|
|
PUBLIC
|
|
"$<BUILD_INTERFACE:${_generated_dir}>"
|
|
"$<BUILD_INTERFACE:${_generated_libowfat_dir}>"
|
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
|
|
"$<BUILD_INTERFACE:${LIBOWFAT_BUILD_INCLUDE_DIR}>"
|
|
"$<BUILD_INTERFACE:${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}>"
|
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${LIBOWFAT_INSTALL_INCLUDE_SUBDIR}>")
|
|
if(LIBOWFAT_BUILD_SHARED)
|
|
set_property(TARGET libowfat_objects PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
endif()
|
|
|
|
set(_libowfat_targets)
|
|
if(LIBOWFAT_BUILD_STATIC)
|
|
add_library(libowfat_static STATIC $<TARGET_OBJECTS:libowfat_objects>)
|
|
list(APPEND _libowfat_targets libowfat_static)
|
|
add_library(libowfat::static ALIAS libowfat_static)
|
|
set_target_properties(libowfat_static PROPERTIES
|
|
OUTPUT_NAME "${LIBOWFAT_OUTPUT_NAME}"
|
|
VERSION "${PROJECT_VERSION}")
|
|
endif()
|
|
|
|
if(LIBOWFAT_BUILD_SHARED)
|
|
add_library(libowfat_shared SHARED $<TARGET_OBJECTS:libowfat_objects>)
|
|
list(APPEND _libowfat_targets libowfat_shared)
|
|
add_library(libowfat::shared ALIAS libowfat_shared)
|
|
set_target_properties(libowfat_shared PROPERTIES
|
|
OUTPUT_NAME "${LIBOWFAT_OUTPUT_NAME}"
|
|
VERSION "${PROJECT_VERSION}"
|
|
SOVERSION "${PROJECT_VERSION_MAJOR}")
|
|
endif()
|
|
|
|
foreach(_target IN LISTS _libowfat_targets)
|
|
target_compile_definitions(${_target} PUBLIC _REENTRANT)
|
|
target_include_directories(${_target}
|
|
PUBLIC
|
|
"$<BUILD_INTERFACE:${_generated_dir}>"
|
|
"$<BUILD_INTERFACE:${_generated_libowfat_dir}>"
|
|
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
|
|
"$<BUILD_INTERFACE:${LIBOWFAT_BUILD_INCLUDE_DIR}>"
|
|
"$<BUILD_INTERFACE:${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}>"
|
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
|
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/${LIBOWFAT_INSTALL_INCLUDE_SUBDIR}>")
|
|
endforeach()
|
|
|
|
if(LIBOWFAT_BUILD_SHARED)
|
|
add_library(libowfat::libowfat ALIAS libowfat_shared)
|
|
elseif(LIBOWFAT_BUILD_STATIC)
|
|
add_library(libowfat::libowfat ALIAS libowfat_static)
|
|
endif()
|
|
|
|
function(_libowfat_disable_ndebug target)
|
|
# A number of upstream unit tests use assert() for all checks and deliberately
|
|
# refuse to compile when NDEBUG is set by a Release build. Compile tests with
|
|
# asserts enabled and without optimisation even when the library itself is built
|
|
# as Release, matching the intent of the original test programs.
|
|
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
|
|
target_compile_options(${target} PRIVATE -UNDEBUG -O0)
|
|
elseif(MSVC)
|
|
target_compile_options(${target} PRIVATE /UNDEBUG)
|
|
endif()
|
|
endfunction()
|
|
|
|
|
|
if(LIBOWFAT_RUN_SELF_TESTS)
|
|
add_executable(libowfat_smoke_t "${CMAKE_CURRENT_SOURCE_DIR}/t.c")
|
|
target_link_libraries(libowfat_smoke_t PRIVATE libowfat::libowfat)
|
|
_libowfat_disable_ndebug(libowfat_smoke_t)
|
|
add_test(NAME libowfat_smoke_t COMMAND libowfat_smoke_t)
|
|
set_tests_properties(libowfat_smoke_t PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
endif()
|
|
|
|
if(LIBOWFAT_BUILD_TEST_PROGRAMS)
|
|
file(GLOB LIBOWFAT_TEST_SOURCES CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/test/*.c")
|
|
foreach(_test_src IN LISTS LIBOWFAT_TEST_SOURCES)
|
|
get_filename_component(_test_name "${_test_src}" NAME_WE)
|
|
string(MAKE_C_IDENTIFIER "libowfat_test_${_test_name}" _test_target)
|
|
add_executable(${_test_target} "${_test_src}")
|
|
target_link_libraries(${_test_target} PRIVATE libowfat::libowfat)
|
|
_libowfat_disable_ndebug(${_test_target})
|
|
if(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
|
|
target_compile_options(${_test_target} PRIVATE
|
|
-Wno-error=implicit-int
|
|
-Wno-error=incompatible-pointer-types
|
|
-Wno-error=implicit-function-declaration)
|
|
endif()
|
|
endforeach()
|
|
|
|
if(LIBOWFAT_RUN_SELF_TESTS)
|
|
# Keep building every test/*.c program above, but only register tests that
|
|
# are known to be stable non-interactive checks. utf8 currently aborts on
|
|
# the upstream semantic UTF-8 surrogate assertion and is kept build-only.
|
|
set(_libowfat_noarg_tests
|
|
array buffer_1 buffer_tosa byte_copy cas fmt fmt_httpdate fmt_human fmt_ip6
|
|
fmt_iso8691 fmt_long fmt_longlong fmt_strm_alloca json marshal
|
|
mult netstring protobuf range scan scan_long stralloc_chomp textcode uint
|
|
)
|
|
foreach(_test_name IN LISTS _libowfat_noarg_tests)
|
|
string(MAKE_C_IDENTIFIER "libowfat_test_${_test_name}" _test_target)
|
|
if(TARGET ${_test_target})
|
|
add_test(NAME ${_test_target} COMMAND ${_test_target})
|
|
set_tests_properties(${_test_target} PROPERTIES WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
endif()
|
|
|
|
if(LIBOWFAT_INSTALL)
|
|
install(TARGETS ${_libowfat_targets}
|
|
EXPORT libowfat-targets
|
|
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
|
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
|
install(DIRECTORY "${LIBOWFAT_BUILD_PUBLIC_INCLUDE_DIR}/"
|
|
DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${LIBOWFAT_INSTALL_INCLUDE_SUBDIR}"
|
|
FILES_MATCHING PATTERN "*.h")
|
|
install(EXPORT libowfat-targets
|
|
NAMESPACE libowfat::
|
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libowfat")
|
|
configure_package_config_file(
|
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/libowfat-config.cmake.in"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/libowfat-config.cmake"
|
|
INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libowfat")
|
|
write_basic_package_version_file(
|
|
"${CMAKE_CURRENT_BINARY_DIR}/libowfat-config-version.cmake"
|
|
VERSION "${PROJECT_VERSION}"
|
|
COMPATIBILITY SameMajorVersion)
|
|
install(FILES
|
|
"${CMAKE_CURRENT_BINARY_DIR}/libowfat-config.cmake"
|
|
"${CMAKE_CURRENT_BINARY_DIR}/libowfat-config-version.cmake"
|
|
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/libowfat")
|
|
endif()
|
|
|
|
message(STATUS "libowfat ${PROJECT_VERSION}: building lib${LIBOWFAT_OUTPUT_NAME} static=${LIBOWFAT_BUILD_STATIC} shared=${LIBOWFAT_BUILD_SHARED}")
|