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()