From 3a79ff4ff2ad3bfc8474715cc50d2d1a8b67f99d Mon Sep 17 00:00:00 2001 From: Kai Blaschke Date: Mon, 24 Mar 2025 09:32:33 +0100 Subject: [PATCH 1/2] Fix playlist API header includes Most playlist headers did not compile in pure C, as types like bool and size_t are used in calls. Added the proper includes as needed to make each header compile if included standalone. --- src/playlist/api/projectM-4/playlist_callbacks.h | 3 ++- src/playlist/api/projectM-4/playlist_filter.h | 2 ++ src/playlist/api/projectM-4/playlist_items.h | 3 +++ src/playlist/api/projectM-4/playlist_playback.h | 3 +++ 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/playlist/api/projectM-4/playlist_callbacks.h b/src/playlist/api/projectM-4/playlist_callbacks.h index 477613c17..a81ea9a22 100644 --- a/src/playlist/api/projectM-4/playlist_callbacks.h +++ b/src/playlist/api/projectM-4/playlist_callbacks.h @@ -27,7 +27,8 @@ #pragma once #include "projectM-4/playlist_types.h" -#include + +#include #ifdef __cplusplus extern "C" { diff --git a/src/playlist/api/projectM-4/playlist_filter.h b/src/playlist/api/projectM-4/playlist_filter.h index d91ae3d35..7f775405d 100644 --- a/src/playlist/api/projectM-4/playlist_filter.h +++ b/src/playlist/api/projectM-4/playlist_filter.h @@ -28,6 +28,8 @@ #include "projectM-4/playlist_types.h" +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/src/playlist/api/projectM-4/playlist_items.h b/src/playlist/api/projectM-4/playlist_items.h index 020286ec7..8f3558a02 100644 --- a/src/playlist/api/projectM-4/playlist_items.h +++ b/src/playlist/api/projectM-4/playlist_items.h @@ -28,6 +28,9 @@ #include "projectM-4/playlist_types.h" +#include +#include + #ifdef __cplusplus extern "C" { #endif diff --git a/src/playlist/api/projectM-4/playlist_playback.h b/src/playlist/api/projectM-4/playlist_playback.h index 20ba00bbc..2d63eef7c 100644 --- a/src/playlist/api/projectM-4/playlist_playback.h +++ b/src/playlist/api/projectM-4/playlist_playback.h @@ -28,6 +28,9 @@ #include "projectM-4/playlist_types.h" +#include +#include + #ifdef __cplusplus extern "C" { #endif From b742bc00825daa3719fda978a88b05f0d451045c Mon Sep 17 00:00:00 2001 From: Kai Blaschke Date: Mon, 24 Mar 2025 09:34:17 +0100 Subject: [PATCH 2/2] Add API header compile tests for C This will enable any future changes to the header to be tested. These additional build checks are only executed if BUILD_TESTING is enabled (e.g. in our automated build checks) to speed up release builds. --- cmake/TestAPIHeaders.cmake | 51 +++++++++++++++++++++++++++++++ cmake/TestAPIHeadersProject.cmake | 20 ++++++++++++ tests/libprojectM/CMakeLists.txt | 26 ++++++++++++++++ tests/playlist/CMakeLists.txt | 24 +++++++++++++++ 4 files changed, 121 insertions(+) create mode 100644 cmake/TestAPIHeaders.cmake create mode 100644 cmake/TestAPIHeadersProject.cmake diff --git a/cmake/TestAPIHeaders.cmake b/cmake/TestAPIHeaders.cmake new file mode 100644 index 000000000..ebf9d97a3 --- /dev/null +++ b/cmake/TestAPIHeaders.cmake @@ -0,0 +1,51 @@ +cmake_minimum_required(VERSION 3.21 FATAL_ERROR) + +# Compile-test C API headers +macro(TEST_API_HEADERS _target _include_dirs _includes) + set(_test_project_dir "${CMAKE_CURRENT_BINARY_DIR}/${_target}") + set(HEADER_TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${_target}.done) + + add_custom_command(OUTPUT ${HEADER_TEST_OUTPUT} + # Create test project directory + COMMAND ${CMAKE_COMMAND} + ARGS + -E make_directory "${_test_project_dir}" + + # Copy project CMake file into it + COMMAND ${CMAKE_COMMAND} + ARGS + -E copy_if_different "${CMAKE_SOURCE_DIR}/cmake/TestAPIHeadersProject.cmake" "${_test_project_dir}/CMakeLists.txt" + + # Delete any existing build dir to re-run all checks + COMMAND ${CMAKE_COMMAND} + ARGS + -E rm -Rf "${_test_project_dir}/build" + + # Configure the test project + COMMAND ${CMAKE_COMMAND} + ARGS + -S ${_test_project_dir} + -B ${_test_project_dir}/build + -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} + -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + -DCMAKE_VERBOSE_MAKEFILE=${CMAKE_VERBOSE_MAKEFILE} + "-DINCLUDE_FILES=${_includes}" + "-DINCLUDE_DIRS=${_include_dirs}" + -DOUTPUT_FILE=${HEADER_TEST_OUTPUT} + + DEPENDS + ${CMAKE_SOURCE_DIR}/cmake/TestAPIHeaders.cmake + ${CMAKE_SOURCE_DIR}/cmake/TestAPIHeadersProject.cmake + ${_includes} + + VERBATIM + COMMENT "Testing C API headers: ${_target}" + ) + + add_custom_target(${_target} ALL + DEPENDS ${HEADER_TEST_OUTPUT} + ) + + unset(_test_project_dir) + +endmacro() diff --git a/cmake/TestAPIHeadersProject.cmake b/cmake/TestAPIHeadersProject.cmake new file mode 100644 index 000000000..9b6b22116 --- /dev/null +++ b/cmake/TestAPIHeadersProject.cmake @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.21 FATAL_ERROR) + +project(TestAPIHeaders + LANGUAGES C + ) + +include(CheckIncludeFile) + +set(CMAKE_REQUIRED_INCLUDES "${INCLUDE_DIRS}") + +foreach(INCLUDE_HEADER ${INCLUDE_FILES}) + cmake_path(GET INCLUDE_HEADER FILENAME INCLUDE_FILENAME) + string(REPLACE "." "_" INCLUDE_FILENAME "${INCLUDE_FILENAME}") + check_include_file(${INCLUDE_HEADER} PROJECTM_${INCLUDE_FILENAME}_INCLUDE_OK) + if(NOT PROJECTM_${INCLUDE_FILENAME}_INCLUDE_OK) + message(FATAL_ERROR "projectM API include file ${INCLUDE_HEADER} does not compile on its own!\nSee logs in ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ for additional information.") + endif() +endforeach() + +file(TOUCH ${OUTPUT_FILE}) diff --git a/tests/libprojectM/CMakeLists.txt b/tests/libprojectM/CMakeLists.txt index 040a82120..23475b3f5 100644 --- a/tests/libprojectM/CMakeLists.txt +++ b/tests/libprojectM/CMakeLists.txt @@ -1,5 +1,31 @@ find_package(GTest 1.10 REQUIRED NO_MODULE) +# Compile-test C API headers +set(INCLUDE_FILES + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/types.h + + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/audio.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/callbacks.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/core.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/debug.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/memory.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/parameters.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/render_opengl.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/touch.h + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/user_sprites.h + + # Convenience header last, so it doesn't obscure issues with a single header above. + ${CMAKE_SOURCE_DIR}/src/api/include/projectM-4/projectM.h + ) + +get_target_property(API_HEADER_INCLUDE_DIRS libprojectM::API INTERFACE_INCLUDE_DIRECTORIES) + +include(TestAPIHeaders) +test_api_headers(TestMainAPIHeaders + "${API_HEADER_INCLUDE_DIRS}" + "${INCLUDE_FILES}" + ) + add_executable(projectM-unittest WaveformAlignerTest.cpp PresetFileParserTest.cpp diff --git a/tests/playlist/CMakeLists.txt b/tests/playlist/CMakeLists.txt index 82da0fca4..cd29a080e 100644 --- a/tests/playlist/CMakeLists.txt +++ b/tests/playlist/CMakeLists.txt @@ -4,6 +4,30 @@ endif() find_package(GTest 1.10 REQUIRED NO_MODULE) +# Compile-test C API headers +set(INCLUDE_FILES + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist_types.h + + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist_callbacks.h + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist_core.h + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist_filter.h + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist_items.h + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist_memory.h + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist_playback.h + + # Convenience header last, so it doesn't obscure issues with a single header above. + ${CMAKE_SOURCE_DIR}/src/playlist/api/projectM-4/playlist.h + ) + +get_target_property(API_HEADER_INCLUDE_DIRS_MAIN libprojectM::API INTERFACE_INCLUDE_DIRECTORIES) +get_target_property(API_HEADER_INCLUDE_DIRS_PLAYLIST projectM_playlist_main INTERFACE_INCLUDE_DIRECTORIES) + +include(TestAPIHeaders) +test_api_headers(TestPlaylistAPIHeaders + "${API_HEADER_INCLUDE_DIRS_MAIN};${API_HEADER_INCLUDE_DIRS_PLAYLIST}" + "${INCLUDE_FILES}" + ) + add_executable(projectM-playlist-unittest $ APITest.cpp