diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index 4dc02ad3..18be0cbe 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -27,10 +27,12 @@ jobs:
- name: Configure CMake
run: >
CC=clang cmake -B ${{env.build_dir}}
+ -DCOWL_CPP_TESTS=OFF
+ -DCOWL_LTO=OFF
-DCOWL_CLANG_TIDY=ON
-DCMAKE_COMPILE_WARNING_AS_ERROR=ON
- name: Build
- run: cmake --build ${{env.build_dir}}
+ run: cmake --build ${{env.build_dir}} --target cowl-test cowl-bench cowl-examples cowl-tools
test:
name: Test
@@ -80,6 +82,11 @@ jobs:
--config ${{env.build_config}}
--target cowl-test cowl-cpp-test cowl-bench cowl-examples cowl-tools
+ - name: Debug
+ if: ${{always()}}
+ run: sed '4019q;d' ${{env.build_dir}}/src/reader/functional/cowl_func_yyparser.c
+ shell: bash
+
- name: Configure tests (Windows)
working-directory: ${{env.build_dir}}
if: runner.os == 'Windows'
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4fa0904b..eb200ab9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -24,7 +24,7 @@ project(Cowl
HOMEPAGE_URL "${COWL_VENDOR_URL}/cowl"
LANGUAGES C)
-# Options
+# Cache variables
option(COWL_EMBEDDED "Enable optimizations for embedded platforms" OFF)
option(COWL_LTO "Enable link-time optimization, if available" ON)
@@ -38,9 +38,10 @@ set(COWL_WRITERS "functional" CACHE STRING "List of enabled built-in writers (se
set(COWL_PROJECT_DIR "${CMAKE_CURRENT_LIST_DIR}")
set(COWL_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}")
-set(COWL_PUBLIC_HEADERS_DIR "${COWL_PROJECT_DIR}/include")
set(COWL_LIB_DIR "${COWL_PROJECT_DIR}/lib")
set(COWL_SRC_DIR "${COWL_PROJECT_DIR}/src")
+set(COWL_PUBLIC_HEADERS_DIR "${COWL_PROJECT_DIR}/include")
+set(COWL_PRIVATE_HEADERS_DIR "${COWL_SRC_DIR}")
set(COWL_READER_DIR "${COWL_SRC_DIR}/reader")
set(COWL_WRITER_DIR "${COWL_SRC_DIR}/writer")
@@ -50,19 +51,19 @@ set(COWL_EXAMPLES_DIR "${COWL_PROJECT_DIR}/examples")
set(COWL_TEST_DIR "${COWL_PROJECT_DIR}/test")
set(COWL_TOOLS_DIR "${COWL_PROJECT_DIR}/tools")
+set(COWL_ULIB_DIR "${COWL_LIB_DIR}/ulib")
+set(COWL_ULIB_UTILS_DIR "${COWL_ULIB_DIR}/utils")
+
set(COWL_HEADERS_OUT_DIR "${COWL_OUTPUT_DIR}/include")
+# CMake settings
+
+list(APPEND CMAKE_MODULE_PATH "${COWL_ULIB_UTILS_DIR}/cmake")
+
# Target settings
set(COWL_COMPILE_FEATURES c_std_11)
-if(COWL_CLANG_TIDY)
- set(COWL_CLANG_TIDY_COMMAND "clang-tidy")
- if(CMAKE_COMPILE_WARNING_AS_ERROR)
- list(APPEND COWL_CLANG_TIDY_COMMAND "-warnings-as-errors=*")
- endif()
-endif()
-
if(COWL_ENTITY_IDS)
list(APPEND COWL_PUBLIC_DEFINES COWL_ENTITY_IDS=1)
endif()
@@ -84,33 +85,31 @@ if(COWL_LTO)
check_ipo_supported(RESULT COWL_LTO_ENABLED)
endif()
+if(COWL_CLANG_TIDY)
+ find_package(ClangTidy REQUIRED)
+endif()
+
# uLib
option(ULIB_TINY "" ${COWL_EMBEDDED})
option(ULIB_LTO "" ${COWL_LTO})
if(NOT TARGET ulib)
- add_subdirectory("${COWL_LIB_DIR}/ulib" EXCLUDE_FROM_ALL)
+ add_subdirectory("${COWL_ULIB_DIR}" EXCLUDE_FROM_ALL)
endif()
-# Header dirs
+# Sources
set(COWL_PUBLIC_HEADERS_DIRS "${COWL_PUBLIC_HEADERS_DIR}")
set(COWL_PRIVATE_HEADERS_DIRS "${COWL_SRC_DIR}")
-# Header files
-
file(GLOB COWL_PUBLIC_HEADERS CONFIGURE_DEPENDS "${COWL_PUBLIC_HEADERS_DIR}/*.h")
-get_target_property(COWL_ULIB_HEADERS ulib PUBLIC_HEADER)
-list(APPEND COWL_PUBLIC_HEADERS ${COWL_ULIB_HEADERS})
-
-# Sources
-
+file(GLOB COWL_PRIVATE_HEADERS CONFIGURE_DEPENDS "${COWL_PRIVATE_HEADERS_DIR}/*.h")
file(GLOB COWL_SOURCES CONFIGURE_DEPENDS "${COWL_SRC_DIR}/*.c")
-###############
-### Targets ###
-###############
+###########
+# Targets #
+###########
# Readers
@@ -156,9 +155,18 @@ endif()
# Library
-add_library(cowl ${COWL_LIBRARY_TYPE} ${COWL_SOURCES})
+add_library(cowl ${COWL_LIBRARY_TYPE})
+target_sources(cowl
+ PRIVATE ${COWL_SOURCES}
+ PRIVATE FILE_SET private_headers
+ TYPE HEADERS
+ BASE_DIRS ${COWL_PRIVATE_HEADERS_DIRS}
+ FILES ${COWL_PRIVATE_HEADERS}
+ PUBLIC FILE_SET public_headers
+ TYPE HEADERS
+ BASE_DIRS ${COWL_PUBLIC_HEADERS_DIRS}
+ FILES ${COWL_PUBLIC_HEADERS})
set_target_properties(cowl PROPERTIES
- PUBLIC_HEADER "${COWL_PUBLIC_HEADERS}"
C_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN ON)
target_compile_features(cowl PRIVATE ${COWL_COMPILE_FEATURES})
@@ -166,9 +174,6 @@ target_compile_options(cowl PRIVATE ${COWL_WARNING_OPTIONS})
target_compile_definitions(cowl
PUBLIC ${COWL_PUBLIC_DEFINES}
PRIVATE ${COWL_PRIVATE_DEFINES})
-target_include_directories(cowl
- PUBLIC ${COWL_PUBLIC_HEADERS_DIRS}
- PRIVATE ${COWL_PRIVATE_HEADERS_DIRS})
target_link_libraries(cowl PUBLIC ulib)
add_dependencies(cowl cowl-readers)
@@ -180,11 +185,11 @@ if(COWL_LTO_ENABLED)
set_property(TARGET cowl PROPERTY INTERPROCEDURAL_OPTIMIZATION ON)
endif()
-if(COWL_CLANG_TIDY_COMMAND)
- set_property(TARGET cowl PROPERTY C_CLANG_TIDY "${COWL_CLANG_TIDY_COMMAND}")
+if(COWL_CLANG_TIDY)
+ clang_tidy_check(cowl)
endif()
-install(TARGETS cowl ulib)
+install(TARGETS cowl ulib FILE_SET public_headers)
# Subprojects
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index f6aacb21..4078c961 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -1,12 +1,11 @@
# Files and directories
set(DOCS_IMAGES_DIRECTORY "${COWL_DOCS_DIR}/img")
-set(DOCS_OUTPUT_DIRECTORY "${COWL_OUTPUT_DIR}/docs")
set(SPHINX_INPUT_DIRECTORY "${COWL_DOCS_DIR}")
set(DOXYGEN_UTILS_DIRECTORY "${COWL_DOCS_DIR}/doxygen")
set(COWL_ICON "${DOCS_IMAGES_DIRECTORY}/cowl_logo.png")
-list(APPEND CMAKE_MODULE_PATH "${COWL_DOCS_DIR}/cmake")
-get_target_property(ULIB_DIRS ulib INTERFACE_INCLUDE_DIRECTORIES)
+set(ULIB_PUBLIC_HEADERS_DIR "${COWL_ULIB_DIR}/include")
+file(GLOB ULIB_PUBLIC_HEADERS CONFIGURE_DEPENDS "${ULIB_PUBLIC_HEADERS_DIR}/*.h")
# Doxygen configuration
@@ -33,8 +32,8 @@ set(DOXYGEN_PREDEFINED ${COWL_PUBLIC_DEFINES}
"COWL_RETAINED=/** @note You must release the returned object via #cowl_release(). */"
"COWL_DEPRECATED(msg)=/** @@deprecated msg */"
"COWL_INLINE=")
-set(DOXYGEN_INCLUDE_PATH ${COWL_PUBLIC_HEADERS_DIRS} ${ULIB_DIRS})
-set(DOXYGEN_OUTPUT_DIRECTORY "${DOCS_OUTPUT_DIRECTORY}/doxygen")
+set(DOXYGEN_INCLUDE_PATH ${COWL_PUBLIC_HEADERS_DIRS} ${ULIB_PUBLIC_HEADERS_DIR})
+set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doxygen")
set(DOXYGEN_XML_OUTPUT_DIRECTORY "${DOXYGEN_OUTPUT_DIRECTORY}/xml")
set(DOXYGEN_ALIASES
[[destructor{1}="@note The returned object must be destroyed by calling #\1()."]]
@@ -48,12 +47,12 @@ set(DOXYGEN_ALIASES
)
set(DOXYGEN_VERBATIM_VARS DOXYGEN_ALIASES)
-find_program(PYTHON
+find_program(DOXYGEN_PYTHON
NAMES python3 python
- DOC "Path to the Python interpreter")
+ DOC "Path to the Python interpreter used to run Doxygen input filters")
-if(NOT PYTHON STREQUAL "PYTHON-NOTFOUND")
- set(DOXYGEN_INPUT_FILTER "${PYTHON} ${DOXYGEN_UTILS_DIRECTORY}/alias.py")
+if(DOXYGEN_PYTHON)
+ set(DOXYGEN_INPUT_FILTER "${DOXYGEN_PYTHON} ${COWL_ULIB_UTILS_DIR}/doxygen/alias.py")
endif()
# Documentation targets
@@ -70,12 +69,12 @@ if(DOXYGEN_FOUND)
set(DOXYGEN_TARGET_NAME cowl-doxygen)
sphinx_add_docs("${DOCS_TARGET_NAME}" "${SPHINX_INPUT_DIRECTORY}" ARGS -W
- COMMENT "Generate documentation via Sphinx")
+ COMMENT "Generating documentation via Sphinx")
add_dependencies("${DOCS_TARGET_NAME}" "${DOXYGEN_TARGET_NAME}" ulib-docs)
else()
set(DOXYGEN_TARGET_NAME "${DOCS_TARGET_NAME}")
endif()
- doxygen_add_docs("${DOXYGEN_TARGET_NAME}" ${COWL_PUBLIC_HEADERS}
- COMMENT "Generate documentation via Doxygen")
+ doxygen_add_docs("${DOXYGEN_TARGET_NAME}" ${COWL_PUBLIC_HEADERS} ${ULIB_PUBLIC_HEADERS}
+ COMMENT "Generating documentation via Doxygen")
endif()
diff --git a/docs/cmake/FindSphinx.cmake b/docs/cmake/FindSphinx.cmake
deleted file mode 100644
index ec87a970..00000000
--- a/docs/cmake/FindSphinx.cmake
+++ /dev/null
@@ -1,31 +0,0 @@
-find_program(SPHINX_EXECUTABLE
- NAMES sphinx-build
- DOC "Path to sphinx-build executable")
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Sphinx "Failed to find sphinx-build" SPHINX_EXECUTABLE)
-
-function(sphinx_add_docs SPHINX_TARGET SPHINX_INPUT_DIRECTORY)
- list(LENGTH ARGN INDEX)
- math(EXPR INDEX "${ARGC} - ${INDEX}")
- set(ONE_VALUE_ARGS COMMENT)
- set(MULTI_VALUE_ARGS ARGS)
- cmake_parse_arguments(PARSE_ARGV ${INDEX} SPHINX "" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}")
-
- set(SPHINX_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/sphinx")
- set(SPHINX_HTML_OUTPUT_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}/html")
- set(SPHINX_CONF_IN "${SPHINX_INPUT_DIRECTORY}/conf.py")
- set(SPHINX_CONF_OUT "${SPHINX_OUTPUT_DIRECTORY}/conf.py")
-
- add_custom_target("${SPHINX_TARGET}"
- COMMAND "${CMAKE_COMMAND}" -E remove_directory
- "${SPHINX_HTML_OUTPUT_DIRECTORY}"
- COMMAND "${SPHINX_EXECUTABLE}" ${SPHINX_ARGS}
- -b html -c "${SPHINX_OUTPUT_DIRECTORY}"
- "${SPHINX_INPUT_DIRECTORY}" "${SPHINX_HTML_OUTPUT_DIRECTORY}"
- WORKING_DIRECTORY "${SPHINX_OUTPUT_DIRECTORY}"
- COMMENT "${SPHINX_COMMENT}"
- VERBATIM)
-
- configure_file("${SPHINX_CONF_IN}" "${SPHINX_CONF_OUT}" @ONLY)
-endfunction()
diff --git a/docs/doxygen/alias.py b/docs/doxygen/alias.py
deleted file mode 100644
index c36eb4d0..00000000
--- a/docs/doxygen/alias.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#
-# Copyright (c) 2024 Ivano Bilenchi
-# SPDX-License-Identifier: ISC
-#
-# This program allows replacing whatever is being documented by some docstring
-# with something else. It is useful as a Doxygen input filter, as it allows documenting
-# function-like macros as functions with type information.
-#
-# As an example, the following docstring:
-#
-# /**
-# * Returns the maximum between a and b.
-# * @param a First number.
-# * @param b Second number.
-# * @return Maximum between a and b.
-# * @alias T max(T a, T b);
-# */
-# #define max(a, b) (((a) > (b)) ? (a) : (b))
-#
-# Will be replaced by:
-#
-# /**
-# * Returns the maximum between a and b.
-# * @param a First number.
-# * @param b Second number.
-# * @return Maximum between a and b.
-# */
-# T max(T a, T b);
-#
-import sys
-
-# Constants
-COMMAND_PATTERNS = ('@', '\\')
-ALIAS_COMMANDS = ('@alias ', '\\alias ')
-DOC_SINGLE_LINE_PATTERN = '///'
-DOC_BLOCK_START_PATTERN = '/**'
-DOC_BLOCK_END_PATTERN = '*/'
-DOC_BLOCK_CONT_PATTERN = '*'
-DOC_BLOCK_STRIP = f' \t{DOC_BLOCK_CONT_PATTERN}'
-
-# Exit codes
-EXIT_OK = 0
-EXIT_ERR = 1
-
-# States
-WRITING_UNTIL_DOC_BLOCK = 0
-LOOKING_FOR_ALIAS = 1
-ALIAS_CONTINUATION = 2
-LOOKING_FOR_INSERTION = 3
-FOUND_INSERTION = 4
-DISCARDING_UNTIL_DOCSTRING = 5
-
-
-class InputFilter:
-
- def __init__(self):
- self.alias: str | None = None
- self.state = LOOKING_FOR_ALIAS
-
- def _find_alias(self, line: str) -> bool:
- for cmd in ALIAS_COMMANDS:
- idx = line.find(cmd)
- if idx >= 0:
- idx += len(cmd)
- self.alias = line[idx:]
- return True
- return False
-
- def _alias_continuation(self, line: str) -> bool:
- line = line.lstrip(DOC_BLOCK_STRIP)
- for p in COMMAND_PATTERNS:
- if line.startswith(p):
- return False
- if line:
- self.alias += f' {line}'
- return True
-
- def _write_until_doc_block(self, line: str) -> str | None:
- sline = line.strip()
- if (sline.startswith(DOC_BLOCK_START_PATTERN) and
- not sline.endswith(DOC_BLOCK_END_PATTERN)):
- self.state = LOOKING_FOR_ALIAS
- return line
-
- def _look_for_alias(self, line: str) -> str | None:
- sline = line.strip()
- if sline.startswith(DOC_BLOCK_END_PATTERN):
- self.state = WRITING_UNTIL_DOC_BLOCK
- elif self._find_alias(sline):
- self.state = ALIAS_CONTINUATION
- line = None
- return line
-
- def _continue_alias(self, line: str) -> str | None:
- sline = line.strip()
- if sline.startswith(DOC_BLOCK_END_PATTERN):
- self.state = FOUND_INSERTION
- elif self._alias_continuation(sline):
- line = None
- else:
- self.state = LOOKING_FOR_INSERTION
- return line
-
- def _look_for_insertion(self, line: str) -> str | None:
- sline = line.strip()
- if sline.startswith(DOC_BLOCK_END_PATTERN):
- self.state = FOUND_INSERTION
- return line
-
- def _insert_alias(self) -> str | None:
- alias = self.alias + '\n'
- self.alias = None
- self.state = DISCARDING_UNTIL_DOCSTRING
- return alias
-
- def _discard_until_docstring(self, line: str) -> str | None:
- sline = line.strip()
- if sline.startswith(DOC_BLOCK_START_PATTERN):
- if sline.endswith(DOC_BLOCK_END_PATTERN):
- self.state = WRITING_UNTIL_DOC_BLOCK
- else:
- self.state = LOOKING_FOR_ALIAS
- self.state = LOOKING_FOR_ALIAS
- elif sline.startswith(DOC_SINGLE_LINE_PATTERN):
- self.state = WRITING_UNTIL_DOC_BLOCK
- else:
- line = None
- return line
-
- def _compute_state_transition(self, line: str) -> str | None:
- if self.state == WRITING_UNTIL_DOC_BLOCK:
- return self._write_until_doc_block(line)
- elif self.state == LOOKING_FOR_ALIAS:
- return self._look_for_alias(line)
- elif self.state == ALIAS_CONTINUATION:
- return self._continue_alias(line)
- elif self.state == LOOKING_FOR_INSERTION:
- return self._look_for_insertion(line)
- elif self.state == FOUND_INSERTION:
- return self._insert_alias()
- else: # self.state == DISCARDING_UNTIL_DOCSTRING
- return self._discard_until_docstring(line)
-
- def filter_line(self, line: str) -> None:
- line = self._compute_state_transition(line)
- if line:
- print(line, end='')
-
-
-def main() -> int:
- if len(sys.argv) < 2:
- print('Usage: python alias.py ', file=sys.stderr)
- return EXIT_ERR
-
- input_filter = InputFilter()
-
- with open(sys.argv[1]) as input_file:
- for line in input_file:
- input_filter.filter_line(line)
-
- return EXIT_OK
-
-
-if __name__ == '__main__':
- try:
- sys.exit(main())
- except Exception as e:
- print(str(e), file=sys.stderr)
- sys.exit(EXIT_ERR)
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 87241d89..ee81abfb 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -13,7 +13,11 @@ foreach(COWL_EXAMPLE ${COWL_EXAMPLES})
string(REPLACE "_" "-" COWL_EXAMPLE_TARGET "${COWL_EXAMPLE_TARGET}")
string(PREPEND COWL_EXAMPLE_TARGET "cowl-")
string(APPEND COWL_EXAMPLE_TARGET "-example")
- add_executable("${COWL_EXAMPLE_TARGET}" EXCLUDE_FROM_ALL "${COWL_EXAMPLE}")
+ add_executable("${COWL_EXAMPLE_TARGET}" EXCLUDE_FROM_ALL)
+ target_sources("${COWL_EXAMPLE_TARGET}" PRIVATE "${COWL_EXAMPLE}")
target_link_libraries("${COWL_EXAMPLE_TARGET}" PRIVATE cowl)
+ if(COWL_CLANG_TIDY)
+ clang_tidy_check("${COWL_EXAMPLE_TARGET}")
+ endif()
add_dependencies(cowl-examples "${COWL_EXAMPLE_TARGET}")
endforeach()
diff --git a/include/cowl_entity.h b/include/cowl_entity.h
index aa43024b..c6bbcb27 100644
--- a/include/cowl_entity.h
+++ b/include/cowl_entity.h
@@ -18,7 +18,6 @@
#include "cowl_entity_type.h"
#include "cowl_impl.h"
#include "cowl_macros.h"
-#include "ulib.h"
COWL_BEGIN_DECLS
@@ -73,6 +72,8 @@ bool cowl_entity_is_reserved(CowlAnyEntity *entity);
#if COWL_ENTITY_IDS
+#include "ulib.h"
+
/**
* Gets the increasing unique identifier associated to the specified entity.
*
diff --git a/lib/ulib b/lib/ulib
index 4fcf8bd0..4931e0c0 160000
--- a/lib/ulib
+++ b/lib/ulib
@@ -1 +1 @@
-Subproject commit 4fcf8bd0bd6e311f8dac50146be2b2ad2727650e
+Subproject commit 4931e0c0f1f5703b23650662318caca85f1e8bfa
diff --git a/src/reader/functional/CMakeLists.txt b/src/reader/functional/CMakeLists.txt
index 1cb1e107..81812f52 100644
--- a/src/reader/functional/CMakeLists.txt
+++ b/src/reader/functional/CMakeLists.txt
@@ -69,4 +69,4 @@ set(COWL_SOURCES ${COWL_SOURCES} PARENT_SCOPE)
set_source_files_properties(${FLEX_COWL_FUNC_LEXER_OUTPUTS}
${BISON_COWL_FUNC_PARSER_OUTPUT_SOURCE}
DIRECTORY "${COWL_PROJECT_DIR}"
- PROPERTIES GENERATED ON)
+ PROPERTIES GENERATED ON SKIP_LINTING ON)
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 07b69071..45e5ffaa 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,41 +1,71 @@
+# Configuration
+
+option(COWL_CPP_TESTS "Enable C++ tests" ON)
+
# Output setup
file(GLOB COWL_TEST_DATA CONFIGURE_DEPENDS "${COWL_DATA_DIR}/*.owl")
file(COPY ${COWL_TEST_DATA} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
-# Copy and rename .c source files to .cpp
+# Sources
+
+set(COWL_TEST_HEADERS_DIR "${COWL_TEST_DIR}/tests")
+file(GLOB COWL_TEST_HEADERS CONFIGURE_DEPENDS "${COWL_TEST_HEADERS_DIR}/*.h")
file(GLOB COWL_TEST_SOURCES tests/*.c)
list(APPEND COWL_TEST_SOURCES test.c)
-file(COPY ${COWL_TEST_SOURCES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
-
-file(GLOB COWL_CPP_TEST_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/*.c")
-
-foreach(SRC ${COWL_CPP_TEST_SOURCES})
- file(RENAME "${SRC}" "${SRC}pp")
-endforeach()
-
-file(GLOB COWL_CPP_TEST_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/*.cpp")
-
-set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${COWL_TEST_SOURCES})
-set_source_files_properties(${COWL_CPP_TEST_SOURCES}
- DIRECTORY "${COWL_PROJECT_DIR}"
- PROPERTIES GENERATED ON)
# Benchmark target
-add_executable(cowl-bench EXCLUDE_FROM_ALL bench.c)
+add_executable(cowl-bench EXCLUDE_FROM_ALL)
+target_sources(cowl-bench PRIVATE "${COWL_TEST_DIR}/bench.c")
target_link_libraries(cowl-bench PRIVATE cowl)
+if(COWL_CLANG_TIDY)
+ clang_tidy_check(cowl-bench)
+endif()
+
# Test target
-add_executable(cowl-test EXCLUDE_FROM_ALL ${COWL_TEST_SOURCES})
-target_include_directories(cowl-test PRIVATE ${COWL_PRIVATE_HEADERS_DIRS} tests)
+add_executable(cowl-test EXCLUDE_FROM_ALL)
+target_sources(cowl-test
+ PRIVATE ${COWL_TEST_SOURCES}
+ PRIVATE FILE_SET HEADERS
+ BASE_DIRS "${COWL_TEST_HEADERS_DIR}"
+ FILES ${COWL_TEST_HEADERS})
+target_include_directories(cowl-test PRIVATE ${COWL_PRIVATE_HEADERS_DIRS})
target_link_libraries(cowl-test PRIVATE cowl)
+if(COWL_CLANG_TIDY)
+ clang_tidy_check(cowl-test)
+endif()
+
# C++ test target
-enable_language(CXX)
-add_executable(cowl-cpp-test EXCLUDE_FROM_ALL ${COWL_CPP_TEST_SOURCES})
-target_include_directories(cowl-cpp-test PRIVATE ${COWL_PRIVATE_HEADERS_DIRS} tests)
-target_link_libraries(cowl-cpp-test PRIVATE cowl)
+if(COWL_CPP_TESTS)
+ # Copy and rename .c source files to .cpp
+ file(GLOB COWL_TEST_SOURCES tests/*.c)
+ list(APPEND COWL_TEST_SOURCES test.c)
+ file(COPY ${COWL_TEST_SOURCES} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
+
+ file(GLOB COWL_CPP_TEST_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/*.c")
+
+ foreach(SRC ${COWL_CPP_TEST_SOURCES})
+ file(RENAME "${SRC}" "${SRC}pp")
+ endforeach()
+
+ file(GLOB COWL_CPP_TEST_SOURCES "${CMAKE_CURRENT_BINARY_DIR}/*.cpp")
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${COWL_TEST_SOURCES})
+
+ # Add target
+ enable_language(CXX)
+ add_executable(cowl-cpp-test EXCLUDE_FROM_ALL)
+ target_sources(cowl-cpp-test
+ PRIVATE ${COWL_CPP_TEST_SOURCES}
+ PRIVATE FILE_SET HEADERS
+ BASE_DIRS "${COWL_TEST_HEADERS_DIR}"
+ FILES ${COWL_TEST_HEADERS})
+ target_include_directories(cowl-cpp-test PRIVATE ${COWL_PRIVATE_HEADERS_DIRS})
+ target_link_libraries(cowl-cpp-test PRIVATE cowl)
+ set_target_properties(cowl-cpp-test PROPERTIES EXPORT_COMPILE_COMMANDS OFF)
+endif()
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
index b3a1ed78..9d3c3c6b 100644
--- a/tools/CMakeLists.txt
+++ b/tools/CMakeLists.txt
@@ -7,6 +7,11 @@ file(COPY ${COWL_TOOLS_DATA} DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
add_custom_target(cowl-tools COMMENT "Build the tools")
-add_executable(cowl-stats EXCLUDE_FROM_ALL stats.c)
+add_executable(cowl-stats EXCLUDE_FROM_ALL)
+target_sources(cowl-stats PRIVATE "${COWL_TOOLS_DIR}/stats.c")
target_link_libraries(cowl-stats PRIVATE cowl)
add_dependencies(cowl-tools cowl-stats)
+
+if(COWL_CLANG_TIDY)
+ clang_tidy_check(cowl-stats)
+endif()