Improve CMake test discovery
This commit is contained in:
152
CMakeLists.txt
152
CMakeLists.txt
@@ -15,31 +15,40 @@ include(CheckCSourceCompiles)
|
||||
include(CheckIncludeFile)
|
||||
include(GNUInstallDirs)
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CTest)
|
||||
|
||||
option(LIBOWFAT_BUILD_STATIC "Build static libowfat library" OFF)
|
||||
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. Empty builds libowfat; nw builds libnwowfat")
|
||||
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)
|
||||
option(LIBOWFAT_BUILD_UNIT_TESTS "Build and register the UNITTEST sources used by GNUmakefile check" OFF)
|
||||
|
||||
if(LIBOWFAT_LIBRARY_PREFIX MATCHES "[^A-Za-z0-9_+-]")
|
||||
message(FATAL_ERROR "LIBOWFAT_LIBRARY_PREFIX must be a simple library basename prefix, for example '' or 'nw'")
|
||||
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()
|
||||
set(LIBOWFAT_OUTPUT_NAME "${LIBOWFAT_LIBRARY_PREFIX}owfat")
|
||||
|
||||
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. The feature
|
||||
# checks use _GNU_SOURCE on Linux so glibc extension declarations stay visible.
|
||||
# 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")
|
||||
list(APPEND LIBOWFAT_FEATURE_DEFINES _GNU_SOURCE)
|
||||
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(CMAKE_REQUIRED_DEFINITIONS "")
|
||||
foreach(_def IN LISTS LIBOWFAT_FEATURE_DEFINES)
|
||||
@@ -73,11 +82,16 @@ set(_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/generated")
|
||||
set(_generated_libowfat_dir "${_generated_dir}/libowfat")
|
||||
file(MAKE_DIRECTORY "${_generated_libowfat_dir}")
|
||||
|
||||
function(_write_generated_header name content)
|
||||
file(WRITE "${_generated_dir}/${name}" "${content}")
|
||||
file(WRITE "${_generated_libowfat_dir}/${name}" "${content}")
|
||||
endfunction()
|
||||
|
||||
function(_write_feature_header name content_if_true)
|
||||
if(${ARGV2})
|
||||
file(WRITE "${_generated_dir}/${name}" "${content_if_true}\n")
|
||||
_write_generated_header("${name}" "${content_if_true}\n")
|
||||
else()
|
||||
file(WRITE "${_generated_dir}/${name}" "")
|
||||
_write_generated_header("${name}" "")
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
@@ -86,15 +100,15 @@ _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)
|
||||
file(WRITE "${_generated_dir}/haveinline.h" "")
|
||||
_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)
|
||||
file(WRITE "${_generated_dir}/haveepoll.h" "#define HAVE_EPOLL 1\n")
|
||||
_write_generated_header(haveepoll.h "#define HAVE_EPOLL 1\n")
|
||||
else()
|
||||
file(WRITE "${_generated_dir}/haveepoll.h" "")
|
||||
_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)
|
||||
@@ -103,37 +117,39 @@ _write_feature_header(havepread.h "#define HAVE_PREAD" HAVE_PREAD)
|
||||
_write_feature_header(haveaccept4.h "#define HAVE_ACCEPT4" HAVE_ACCEPT4)
|
||||
|
||||
if(HAVE_SOCKLEN_T)
|
||||
file(WRITE "${_generated_dir}/havesl.h" "")
|
||||
_write_generated_header(havesl.h "")
|
||||
else()
|
||||
file(WRITE "${_generated_dir}/havesl.h" "typedef int socklen_t;\n")
|
||||
_write_generated_header(havesl.h "typedef int socklen_t;\n")
|
||||
endif()
|
||||
|
||||
file(WRITE "${_generated_dir}/havealloca.h" "#include <stdlib.h>\n")
|
||||
set(_havealloca_content "#include <stdlib.h>\n")
|
||||
if(HAVE_ALLOCA_H)
|
||||
file(APPEND "${_generated_dir}/havealloca.h" "#include <alloca.h>\n")
|
||||
string(APPEND _havealloca_content "#include <alloca.h>\n")
|
||||
endif()
|
||||
if(HAVE_MALLOC_H)
|
||||
file(APPEND "${_generated_dir}/havealloca.h" "#include <malloc.h>\n")
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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"
|
||||
OUTPUT "${_generated_dir}/entities.h" "${_generated_libowfat_dir}/entities.h"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/entities.json" "${_generated_dir}/entities.json"
|
||||
COMMAND libowfat_ent
|
||||
@@ -143,16 +159,7 @@ add_custom_command(
|
||||
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")
|
||||
|
||||
set(LIBOWFAT_GENERATED_HEADERS
|
||||
haveaccept4.h havealloca.h havebsdsf.h havedevpoll.h haveepoll.h
|
||||
haveinline.h haveip6.h havekqueue.h haven2i.h havepread.h
|
||||
havescope.h havesendfile.h havesigio.h havesl.h haveuint128.h
|
||||
iopause.h select.h entities.h
|
||||
)
|
||||
add_custom_target(libowfat_entities DEPENDS "${_generated_dir}/entities.h" "${_generated_libowfat_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
|
||||
@@ -170,12 +177,6 @@ foreach(_hdr IN LISTS LIBOWFAT_PUBLIC_HEADERS)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
foreach(_hdr IN LISTS LIBOWFAT_GENERATED_HEADERS)
|
||||
if(EXISTS "${_generated_dir}/${_hdr}")
|
||||
configure_file("${_generated_dir}/${_hdr}" "${_generated_libowfat_dir}/${_hdr}" COPYONLY)
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
file(GLOB LIBOWFAT_SOURCES CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/array/*.c"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/buffer/*.c"
|
||||
@@ -211,6 +212,7 @@ target_include_directories(libowfat_objects
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${_generated_dir}>"
|
||||
"$<BUILD_INTERFACE:${_generated_libowfat_dir}>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libowfat>")
|
||||
if(LIBOWFAT_BUILD_SHARED)
|
||||
@@ -243,6 +245,7 @@ foreach(_target IN LISTS _libowfat_targets)
|
||||
PUBLIC
|
||||
"$<BUILD_INTERFACE:${_generated_dir}>"
|
||||
"$<BUILD_INTERFACE:${_generated_libowfat_dir}>"
|
||||
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>"
|
||||
"$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/libowfat>")
|
||||
endforeach()
|
||||
@@ -253,47 +256,42 @@ elseif(LIBOWFAT_BUILD_STATIC)
|
||||
add_library(libowfat::libowfat ALIAS libowfat_static)
|
||||
endif()
|
||||
|
||||
if(BUILD_TESTING)
|
||||
set(_libowfat_test_target libowfat_shared)
|
||||
if(NOT LIBOWFAT_BUILD_SHARED)
|
||||
set(_libowfat_test_target libowfat_static)
|
||||
endif()
|
||||
|
||||
add_executable(t "${CMAKE_CURRENT_SOURCE_DIR}/t.c")
|
||||
target_link_libraries(t PRIVATE ${_libowfat_test_target})
|
||||
target_include_directories(t PRIVATE "${_generated_dir}" "${_generated_libowfat_dir}" "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
target_compile_definitions(t PRIVATE _REENTRANT)
|
||||
find_package(Threads)
|
||||
if(Threads_FOUND)
|
||||
target_link_libraries(t PRIVATE Threads::Threads)
|
||||
endif()
|
||||
add_test(NAME libowfat_smoke COMMAND t)
|
||||
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)
|
||||
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_UNIT_TESTS)
|
||||
file(GLOB_RECURSE LIBOWFAT_UNITTEST_SOURCES CONFIGURE_DEPENDS
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/*/*.c")
|
||||
set(_libowfat_unittest_index 0)
|
||||
foreach(_test_src IN LISTS LIBOWFAT_UNITTEST_SOURCES)
|
||||
file(READ "${_test_src}" _test_content)
|
||||
if(_test_content MATCHES "UNITTEST")
|
||||
get_filename_component(_test_dir "${_test_src}" DIRECTORY)
|
||||
get_filename_component(_test_dir_name "${_test_dir}" NAME)
|
||||
get_filename_component(_test_name "${_test_src}" NAME_WE)
|
||||
set(_test_target "libowfat_unittest_${_test_dir_name}_${_test_name}")
|
||||
add_executable(${_test_target} "${_test_src}")
|
||||
target_compile_definitions(${_test_target} PRIVATE UNITTEST _REENTRANT)
|
||||
target_include_directories(${_test_target} PRIVATE
|
||||
"${_generated_dir}"
|
||||
"${_generated_libowfat_dir}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}")
|
||||
add_dependencies(${_test_target} libowfat_entities)
|
||||
list(APPEND _libowfat_unittest_targets ${_test_target})
|
||||
add_test(NAME "unittest/${_test_dir_name}/${_test_name}" COMMAND ${_test_target})
|
||||
set_tests_properties("unittest/${_test_dir_name}/${_test_name}" PROPERTIES LABELS libowfat-unit)
|
||||
math(EXPR _libowfat_unittest_index "${_libowfat_unittest_index} + 1")
|
||||
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)
|
||||
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)
|
||||
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 utf8
|
||||
)
|
||||
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()
|
||||
add_custom_target(libowfat-unit-tests DEPENDS ${_libowfat_unittest_targets})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
||||
111
README.md
111
README.md
@@ -1,94 +1,97 @@
|
||||
# libowfat
|
||||
|
||||
This tree keeps the original GNUmakefile build unchanged and adds a standalone
|
||||
CMake build for projects that want to consume libowfat directly or as a CMake
|
||||
subdirectory.
|
||||
This tree keeps the original GNUmakefile build untouched and adds an optional
|
||||
CMake build for projects that want to consume libowfat directly with CMake.
|
||||
|
||||
## CMake build
|
||||
|
||||
Out-of-tree builds are supported and recommended:
|
||||
Out-of-tree builds are supported:
|
||||
|
||||
```sh
|
||||
cmake -S . -B build
|
||||
cmake --build build
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
The CMake build reads the library version from the first line of `CHANGES`.
|
||||
For example, with the current `CHANGES` this produces version `0.35`.
|
||||
By default the CMake build produces the normal shared library name:
|
||||
|
||||
By default CMake builds the shared library. Static and shared builds can be
|
||||
selected independently:
|
||||
```text
|
||||
libowfat.so
|
||||
```
|
||||
|
||||
A prefix can be added to the library basename. For example, this builds
|
||||
`libnwowfat.so` and, when static builds are enabled, `libnwowfat.a`:
|
||||
|
||||
```sh
|
||||
cmake -S . -B build \
|
||||
-DLIBOWFAT_BUILD_SHARED=ON \
|
||||
-DLIBOWFAT_BUILD_STATIC=ON
|
||||
cmake -S . -B build-nw \
|
||||
-DLIBOWFAT_LIBRARY_PREFIX=nw \
|
||||
-DLIBOWFAT_BUILD_STATIC=ON \
|
||||
-DLIBOWFAT_BUILD_SHARED=ON
|
||||
cmake --build build-nw
|
||||
```
|
||||
|
||||
The installed library basename can be prefixed without changing the headers or
|
||||
CMake package name. The default prefix is empty, so the output is `libowfat`.
|
||||
For a NetWare-flavoured name, pass `nw` and the output becomes `libnwowfat`:
|
||||
The library version is read from the first line of `CHANGES`.
|
||||
|
||||
```sh
|
||||
cmake -S . -B build -DLIBOWFAT_LIBRARY_PREFIX=nw
|
||||
```
|
||||
## Installation
|
||||
|
||||
## Install
|
||||
|
||||
Installation uses CMake `GNUInstallDirs`, so the library directory follows the
|
||||
target platform and install prefix (`lib`, `lib64`, etc.). Headers are installed
|
||||
below `include/libowfat`.
|
||||
CMake installation uses `GNUInstallDirs`, so the library directory follows the
|
||||
platform and the configured prefix, for example `lib` or `lib64`:
|
||||
|
||||
```sh
|
||||
cmake --install build --prefix /usr
|
||||
```
|
||||
|
||||
Useful install options:
|
||||
Headers are installed under:
|
||||
|
||||
```sh
|
||||
cmake -S . -B build \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib64
|
||||
```text
|
||||
${prefix}/include/libowfat
|
||||
```
|
||||
|
||||
## Generated compatibility headers
|
||||
Generated compatibility headers such as `haveip6.h`, `havesendfile.h`,
|
||||
`haveaccept4.h`, `havesl.h`, `iopause.h`, `select.h`, and `entities.h` are
|
||||
installed there too. This lets consumers include either `libowfat/foo.h` or,
|
||||
for legacy code that relies on the target include path, plain `foo.h`.
|
||||
|
||||
The CMake build generates the same style of compatibility headers as the
|
||||
GNUmakefile build, but places them in the build tree instead of the source tree.
|
||||
Both the build-tree target and the installed package export include paths for:
|
||||
## Using from another CMake project
|
||||
|
||||
- `<build>/generated`
|
||||
- `<build>/generated/libowfat`
|
||||
- `<prefix>/include`
|
||||
- `<prefix>/include/libowfat`
|
||||
As an installed package:
|
||||
|
||||
This lets normal includes such as `<libowfat/buffer.h>` work, and also keeps
|
||||
internal or compatibility includes such as `"haveip6.h"`, `"havesendfile.h"`,
|
||||
`"iopause.h"`, `"select.h"`, and `"entities.h"` available when the project is
|
||||
used through `add_subdirectory()` or `find_package(libowfat CONFIG REQUIRED)`.
|
||||
```cmake
|
||||
find_package(libowfat CONFIG REQUIRED)
|
||||
target_link_libraries(myapp PRIVATE libowfat::libowfat)
|
||||
```
|
||||
|
||||
As a subdirectory or submodule:
|
||||
|
||||
```cmake
|
||||
add_subdirectory(extern/libowfat)
|
||||
target_link_libraries(myapp PRIVATE libowfat::libowfat)
|
||||
```
|
||||
|
||||
The exported build-tree target includes both the source include directory and
|
||||
the generated header directories, so generated `have*.h` headers are available
|
||||
without copying files into the source tree.
|
||||
|
||||
## Tests
|
||||
|
||||
The GNUmakefile `all` target builds the root `t` smoke-test program; CMake does
|
||||
the same when `BUILD_TESTING` is enabled, and registers it with CTest:
|
||||
When libowfat is built as the top-level CMake project, `BUILD_TESTING=ON`
|
||||
registers `t.c` as a smoke test and builds the programs under `test/`:
|
||||
|
||||
```sh
|
||||
cmake -S . -B build -DBUILD_TESTING=ON
|
||||
cmake --build build
|
||||
ctest --test-dir build --output-on-failure
|
||||
```
|
||||
|
||||
The `UNITTEST` sources used by the GNUmakefile `check` target can also be built
|
||||
and registered with CTest:
|
||||
Only the non-interactive tests are registered with CTest. Network/server/demo
|
||||
programs and tests that need command-line input are compiled but not run by
|
||||
CTest.
|
||||
|
||||
When libowfat is used through `add_subdirectory()`, tests are off by default so
|
||||
that a parent project does not unexpectedly build the whole test tree. They can
|
||||
be enabled explicitly:
|
||||
|
||||
```sh
|
||||
cmake -S . -B build -DLIBOWFAT_BUILD_UNIT_TESTS=ON
|
||||
cmake --build build
|
||||
ctest --test-dir build --output-on-failure -L libowfat-unit
|
||||
-DLIBOWFAT_BUILD_TEST_PROGRAMS=ON
|
||||
-DLIBOWFAT_RUN_SELF_TESTS=ON
|
||||
```
|
||||
|
||||
## glibc compatibility
|
||||
|
||||
The CMake build uses the system C compiler and glibc-compatible feature checks
|
||||
instead of dietlibc-specific assumptions. On Linux the configure checks use
|
||||
`_GNU_SOURCE` so glibc extension declarations are visible; the library itself
|
||||
still relies on the existing source-level feature defines where individual
|
||||
files need them.
|
||||
|
||||
Reference in New Issue
Block a user