From 07ed43d7101cbe13c7c5142374b0b515d963c08c Mon Sep 17 00:00:00 2001 From: Mc-zen Date: Mon, 17 Oct 2022 22:46:53 +0200 Subject: [PATCH 1/2] CMake build system refactoring - Create a function for creating min projects for use instead of min-pretarget.cmake and min-posttarget.cmake - Create functions for adding unit tests - factor out some common code from min-posttarget.cmake - move option "Treat warnings as errors" to CMakeLists.txt - add max-sdk-base as subdirectory - interface target min-api - interface target min-api-test-headers --- CMakeLists.txt | 53 +++++-- script/c74_add_min_target.cmake | 33 +++++ .../c74_set_target_xcode_warning_flags.cmake | 15 ++ script/min-posttarget.cmake | 13 +- test/c74_add_min_unit_test.cmake | 132 ++++++++++++++++++ test/min-object-unittest.cmake | 65 ++------- 6 files changed, 239 insertions(+), 72 deletions(-) create mode 100644 script/c74_add_min_target.cmake create mode 100644 script/c74_set_target_xcode_warning_flags.cmake create mode 100644 test/c74_add_min_unit_test.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 15d410b..9410e4b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,16 +2,32 @@ # Use of this source code is governed by the MIT License found in the License.md file. cmake_minimum_required(VERSION 3.19) -project(MinAPI) +option(C74_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) if (${CMAKE_GENERATOR} MATCHES "Xcode") - if (${XCODE_VERSION} VERSION_LESS 10) - message(STATUS "Xcode 10 or later is required. Please install from the Mac App Store.") - return () - endif () + if (${XCODE_VERSION} VERSION_LESS 10) + message(STATUS "Xcode 10 or later is required. Please install from the Mac App Store.") + return () + endif () endif () +# Add the max sdk, if it exists +if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/max-sdk-base/CMakeLists.txt") + add_subdirectory(max-sdk-base) +else() + message(FATAL_ERROR "The max-sdk-base repository is missing. Maybe you did not clone recursively?") +endif () + +include(script/c74_add_min_target.cmake) +include(test/c74_add_min_unit_test.cmake) + + + + +project(MinAPI) + + if (WIN32) add_definitions( -DMAXAPI_USE_MSCRT @@ -21,12 +37,31 @@ if (WIN32) endif () file(GLOB_RECURSE MIN_API_HEADERS - RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h) -add_custom_target( API ALL - SOURCES ${MIN_API_HEADERS} + RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" + "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h" ) +set(version 0.6.0) +set(target min-api) + +add_library(${target} INTERFACE ${MIN_API_HEADERS}) + +set_target_properties(${target} PROPERTIES FOLDER "C74_Libraries") +set_target_properties(${target} PROPERTIES VERSION ${version}) + +target_include_directories(${target} INTERFACE + "$" + "$/include/include>" +) + +add_library(API ALIAS min-api) # alias for backwards compatibility + + + +# Target for including the test headers +set(target min-api-test-headers) +add_library(${target} INTERFACE) +target_include_directories(${target} INTERFACE test) enable_testing() diff --git a/script/c74_add_min_target.cmake b/script/c74_add_min_target.cmake new file mode 100644 index 0000000..865ad19 --- /dev/null +++ b/script/c74_add_min_target.cmake @@ -0,0 +1,33 @@ +# Copyright 2018 The Min-API Authors. All rights reserved. +# Use of this source code is governed by the MIT License found in the License.md file. + +include("${CMAKE_CURRENT_LIST_DIR}/c74_set_target_xcode_warning_flags.cmake") + + +# This command creates a "min target" with all needed configuration to build a max external. +# It creates a new project as well as a libary target both with the specified name. The target +# is automatically linked against the max-sdk-base and the min-api. +# The list of sources which is passed will be added to the target. The OUTPUT_DIRECTORY specifies +# the location where the compiled library will be put. +# +# Call example: +# c74_add_min_target(mytarget SOURCES main.cpp asd.cpp OUTPUT_DIRECTORY ../externals) + +function(c74_add_min_target target) + set(oneValueArgs OUTPUT_DIRECTORY) + set(multiValueArgs SOURCES) + cmake_parse_arguments(PARSE_ARGV 0 PARAMS "${options}" "${oneValueArgs}" "${multiValueArgs}") + + if (PARAMS_OUTPUT_DIRECTORY) + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PARAMS_OUTPUT_DIRECTORY}") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}") + endif () + + add_definitions(-DC74_MIN_API) + + c74_add_max_target(${target} SOURCES ${PARAMS_SOURCES}) # no quotes! + target_link_libraries(${target} PRIVATE min-api) + c74_set_target_xcode_warning_flags(${target}) + +endfunction() diff --git a/script/c74_set_target_xcode_warning_flags.cmake b/script/c74_set_target_xcode_warning_flags.cmake new file mode 100644 index 0000000..aab7c88 --- /dev/null +++ b/script/c74_set_target_xcode_warning_flags.cmake @@ -0,0 +1,15 @@ +# Copyright 2018 The Min-API Authors. All rights reserved. +# Use of this source code is governed by the MIT License found in the License.md file. + + +# enforce a strict warning policy for xcode +function(c74_set_target_xcode_warning_flags target) + if (APPLE) + set(C74_XCODE_WARNING_CFLAGS "-Wall -Wmissing-field-initializers -Wno-unused-lambda-capture -Wno-unknown-warning-option") + if (${C74_WARNINGS_AS_ERRORS}) + set(C74_XCODE_WARNING_CFLAGS "${C74_XCODE_WARNING_CFLAGS} -Werror") + endif () + + set_target_properties(${target} PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS ${C74_XCODE_WARNING_CFLAGS}) + endif () +endfunction() diff --git a/script/min-posttarget.cmake b/script/min-posttarget.cmake index 3abba52..2098071 100644 --- a/script/min-posttarget.cmake +++ b/script/min-posttarget.cmake @@ -1,19 +1,10 @@ # Copyright 2018 The Min-API Authors. All rights reserved. # Use of this source code is governed by the MIT License found in the License.md file. +include("${CMAKE_CURRENT_LIST_DIR}/c74_set_target_xcode_warning_flags.cmake") include(${C74_MAX_SDK_DIR}/script/max-posttarget.cmake) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) -option(C74_WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) - -if (APPLE) - set(C74_XCODE_WARNING_CFLAGS "-Wall -Wmissing-field-initializers -Wno-unused-lambda-capture -Wno-unknown-warning-option") - if (${C74_WARNINGS_AS_ERRORS}) - set(C74_XCODE_WARNING_CFLAGS "${C74_XCODE_WARNING_CFLAGS} -Werror") - endif () - - # enforce a strict warning policy - set_target_properties(${PROJECT_NAME} PROPERTIES XCODE_ATTRIBUTE_WARNING_CFLAGS ${C74_XCODE_WARNING_CFLAGS}) -endif () +c74_set_target_xcode_warning_flags(${PROJECT_NAME}) diff --git a/test/c74_add_min_unit_test.cmake b/test/c74_add_min_unit_test.cmake new file mode 100644 index 0000000..4d809d5 --- /dev/null +++ b/test/c74_add_min_unit_test.cmake @@ -0,0 +1,132 @@ +# Copyright 2018 The Min-API Authors. All rights reserved. +# Use of this source code is governed by the MIT License found in the License.md file. + + + +# Add a unit test target with given name from given sources files. Certain min/max-specific +# configurations are applied to the test target. # +# +# Call example: +# +# c74_add_unit_test(my_random_test +# SOURCES +# random.cpp random_test.cpp +# OUTPUT_DIRECTORY +# ../tests +# ) + +function(c74_add_unit_test target) + set(oneValueArgs OUTPUT_DIRECTORY) + set(multiValueArgs SOURCES) + cmake_parse_arguments(PARSE_ARGV 0 PARAMS "${options}" "${oneValueArgs}" "${multiValueArgs}") + + c74_max_pre_project_calls() + c74_max_post_project_calls() + add_definitions(-DC74_MIN_API) + add_definitions(-DC74_USE_MIN_LIB) + + c74_add_unit_test_impl(${target} + OUTPUT_DIRECTORY + "${PARAMS_OUTPUT_DIRECTORY}" + MAX_SDK_JIT_INCLUDES + ${MAX_SDK_JIT_INCLUDES} # these are initialized in the c74_pre_project_calls() + SOURCES + ${TEST_NAME}.cpp ${TEST_SOURCE_FILES} + ) +endfunction() + + + +# Auto discover a test for an already existing target. +# +# This function simulates the min-object-unittest.cmake script. It is expected that a source file with the name +# [target].cpp and a test file with the name [target]_test.cpp exist. If the test file does not exist, this function +# does nothing + +function(c74_add_auto_unit_test target) + + + get_target_property(SOURCE_FILES ${target} SOURCES) + + if (NOT SOURCE_FILES) + message(ERROR "No source files given") + endif () + + set(ORIGINAL_NAME "${target}") + set(TEST_NAME "${target}_test") + + if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}.cpp") + c74_test_source_files_macro() + + if (NOT TARGET mock_kernel) + set(C74_MOCK_TARGET_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../tests")### + add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../min-api/test/mock" "${CMAKE_BINARY_DIR}/mock")### + endif () + + c74_add_unit_test(${TEST_NAME} + OUTPUT_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}/../../../tests" + SOURCES + ${TEST_NAME}.cpp ${TEST_SOURCE_FILES} + ) + endif () +endfunction() + + +macro(c74_test_source_files_macro) + set(TEST_SOURCE_FILES "") + FOREACH(SOURCE_FILE ${SOURCE_FILES}) + set(ORIGINAL_WITH_EXT "${ORIGINAL_NAME}.cpp") + if (SOURCE_FILE STREQUAL ORIGINAL_WITH_EXT) + set(TEST_SOURCE_FILES ${TEST_SOURCE_FILES} ${TEST_NAME}.cpp) + else() + if(NOT SOURCE_FILE MATCHES ".+\.rc") # omit resource files + set(TEST_SOURCE_FILES "${TEST_SOURCE_FILES}" ${SOURCE_FILE}) + endif() + endif() + ENDFOREACH() +endmacro() + + + +function(c74_add_unit_test_impl target) + set(oneValueArgs OUTPUT_DIRECTORY MAX_SDK_JIT_INCLUDES) + set(multiValueArgs SOURCES) + cmake_parse_arguments(PARSE_ARGV 0 PARAMS "${options}" "${oneValueArgs}" "${multiValueArgs}") + + + enable_testing() + + # set(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage") + # set(CMAKE_C_FLAGS "-fprofile-arcs -ftest-coverage") + # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") + + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PARAMS_OUTPUT_DIRECTORY}") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") + + add_executable(${target} ${PARAMS_SOURCES}) + add_dependencies(${target} mock_kernel) + target_compile_definitions(${target} PUBLIC -DMIN_TEST) + + set_target_properties(${target} PROPERTIES FOLDER "Unit Tests") + set_target_properties(${target} PROPERTIES CXX_STANDARD 17) + set_target_properties(${target} PROPERTIES CXX_STANDARD_REQUIRED ON) + + target_link_libraries(${target} PUBLIC mock_kernel) + target_link_libraries(${target} PRIVATE max-sdk-base-headers min-api min-api-test-headers) + + if (APPLE) + set_target_properties(${target} PROPERTIES LINK_FLAGS "-Wl,-F'${PARAMS_MAX_SDK_JIT_INCLUDES}', -weak_framework JitterAPI") + target_compile_options(${target} PRIVATE -DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) + endif () + if (WIN32) + set_target_properties(${target} PROPERTIES COMPILE_PDB_NAME ${target}) + + # target_link_libraries(${TEST_NAME} ${MaxAPI_LIB}) + # target_link_libraries(${TEST_NAME} ${MaxAudio_LIB}) + # target_link_libraries(${TEST_NAME} ${Jitter_LIB}) + endif () + + add_test(NAME ${target} COMMAND ${target}) +endfunction() \ No newline at end of file diff --git a/test/min-object-unittest.cmake b/test/min-object-unittest.cmake index fe65aed..5d93e37 100644 --- a/test/min-object-unittest.cmake +++ b/test/min-object-unittest.cmake @@ -1,7 +1,7 @@ # Copyright 2018 The Min-API Authors. All rights reserved. # Use of this source code is governed by the MIT License found in the License.md file. -cmake_minimum_required(VERSION 3.10) + set(ORIGINAL_NAME "${PROJECT_NAME}") set(TEST_NAME "${PROJECT_NAME}_test") @@ -9,62 +9,23 @@ set(TEST_NAME "${PROJECT_NAME}_test") if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}.cpp") - enable_testing() - - include_directories( - "${C74_INCLUDES}" - "${C74_MIN_API_DIR}/test" - # "${C74_MIN_API_DIR}/test/mock" - ) - - set(TEST_SOURCE_FILES "") - FOREACH(SOURCE_FILE ${SOURCE_FILES}) - set(ORIGINAL_WITH_EXT "${ORIGINAL_NAME}.cpp") - if (SOURCE_FILE STREQUAL ORIGINAL_WITH_EXT) - set(TEST_SOURCE_FILES ${TEST_SOURCE_FILES} ${TEST_NAME}.cpp) - else() - set(TEST_SOURCE_FILES "${TEST_SOURCE_FILES}" ${SOURCE_FILE}) - endif() - ENDFOREACH() + #if (NOT DEFINED SOURCE_FILES) + # get_target_property(SOURCE_FILES ${ORIGINAL_NAME} SOURCES) + #endif () - # set(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage") - # set(CMAKE_C_FLAGS "-fprofile-arcs -ftest-coverage") - # set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") - - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../../../tests") - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}") - - add_executable(${TEST_NAME} ${TEST_NAME}.cpp ${TEST_SOURCE_FILES}) + c74_test_source_files_macro() if (NOT TARGET mock_kernel) set(C74_MOCK_TARGET_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../tests") - add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../test/mock ${CMAKE_BINARY_DIR}/mock) + add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../test/mock" "${CMAKE_BINARY_DIR}/mock") endif () - - add_dependencies(${TEST_NAME} mock_kernel) - - target_compile_definitions(${TEST_NAME} PUBLIC -DMIN_TEST) - - set_property(TARGET ${TEST_NAME} PROPERTY CXX_STANDARD 17) - set_property(TARGET ${TEST_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) - - target_link_libraries(${TEST_NAME} PUBLIC "mock_kernel") - - if (APPLE) - set_target_properties(${TEST_NAME} PROPERTIES LINK_FLAGS "-Wl,-F'${MAX_SDK_JIT_INCLUDES}', -weak_framework JitterAPI") - target_compile_options(${TEST_NAME} PRIVATE -DCATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) - endif () - if (WIN32) - set_target_properties(${TEST_NAME} PROPERTIES COMPILE_PDB_NAME ${TEST_NAME}) - - # target_link_libraries(${TEST_NAME} ${MaxAPI_LIB}) - # target_link_libraries(${TEST_NAME} ${MaxAudio_LIB}) - # target_link_libraries(${TEST_NAME} ${Jitter_LIB}) - endif () - - add_test(NAME ${TEST_NAME} - COMMAND ${TEST_NAME}) + + c74_add_unit_test(${TEST_NAME} + OUTPUT_DIRECTORY + "${CMAKE_CURRENT_SOURCE_DIR}/../../../tests" + SOURCES + ${TEST_NAME}.cpp ${TEST_SOURCE_FILES} + ) endif () \ No newline at end of file From ae72135c63c15d3c31871e38059241a9a6c20379 Mon Sep 17 00:00:00 2001 From: Mc-zen Date: Tue, 10 Jan 2023 16:17:09 +0100 Subject: [PATCH 2/2] [fix] unit test adding --- CMakeLists.txt | 3 +++ test/c74_add_min_unit_test.cmake | 28 +++++++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9410e4b..db85203 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,6 +66,7 @@ target_include_directories(${target} INTERFACE test) enable_testing() +set(C74_MOCK_TARGET_DIR "${CMAKE_CURRENT_LIST_DIR}/../../tests")### # min-devkit and probably many user projects add the min-api as a subdirectory, # however, we want the min-api to be able to act as a standalone project as well. # so projects including the min-api should use the various .cmake scripts instead @@ -74,7 +75,9 @@ if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test) else() message(DEPRECATION "Adding min-api via add_subdirectory() is deprecated and might break your setup in the future. Please remove the add_subdirectory() line from your CMakeLists.txt file.") + add_subdirectory(test/mock "${CMAKE_BINARY_DIR}/mock") endif() +set_target_properties(mock_kernel PROPERTIES FOLDER "C74_Libraries") find_package (Doxygen QUIET) option (BUILD_DOCUMENTATION "Create and install the HTML based API documentation (requires Doxygen)" ${DOXYGEN_FOUND}) diff --git a/test/c74_add_min_unit_test.cmake b/test/c74_add_min_unit_test.cmake index 4d809d5..f8c7151 100644 --- a/test/c74_add_min_unit_test.cmake +++ b/test/c74_add_min_unit_test.cmake @@ -16,6 +16,7 @@ # ) function(c74_add_unit_test target) + set(options LINK_TO_C74_LIBS) set(oneValueArgs OUTPUT_DIRECTORY) set(multiValueArgs SOURCES) cmake_parse_arguments(PARSE_ARGV 0 PARAMS "${options}" "${oneValueArgs}" "${multiValueArgs}") @@ -31,7 +32,9 @@ function(c74_add_unit_test target) MAX_SDK_JIT_INCLUDES ${MAX_SDK_JIT_INCLUDES} # these are initialized in the c74_pre_project_calls() SOURCES - ${TEST_NAME}.cpp ${TEST_SOURCE_FILES} + ${PARAMS_SOURCES} + DO_LINK_TO_C74_LIBS + ${PARAMS_LINK_TO_C74_LIBS} ) endfunction() @@ -58,10 +61,10 @@ function(c74_add_auto_unit_test target) if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${TEST_NAME}.cpp") c74_test_source_files_macro() - if (NOT TARGET mock_kernel) - set(C74_MOCK_TARGET_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../tests")### - add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../min-api/test/mock" "${CMAKE_BINARY_DIR}/mock")### - endif () + #if (NOT TARGET mock_kernel) + # set(C74_MOCK_TARGET_DIR "${CMAKE_CURRENT_LIST_DIR}/../../../tests")### + # #add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../min-api/test/mock" "${CMAKE_BINARY_DIR}/mock")### + #endif () c74_add_unit_test(${TEST_NAME} OUTPUT_DIRECTORY @@ -90,11 +93,10 @@ endmacro() function(c74_add_unit_test_impl target) - set(oneValueArgs OUTPUT_DIRECTORY MAX_SDK_JIT_INCLUDES) + set(oneValueArgs OUTPUT_DIRECTORY MAX_SDK_JIT_INCLUDES DO_LINK_TO_C74_LIBS) set(multiValueArgs SOURCES) cmake_parse_arguments(PARSE_ARGV 0 PARAMS "${options}" "${oneValueArgs}" "${multiValueArgs}") - enable_testing() # set(CMAKE_CXX_FLAGS "-fprofile-arcs -ftest-coverage") @@ -115,6 +117,10 @@ function(c74_add_unit_test_impl target) target_link_libraries(${target} PUBLIC mock_kernel) target_link_libraries(${target} PRIVATE max-sdk-base-headers min-api min-api-test-headers) + + if (PARAMS_DO_LINK_TO_C74_LIBS) + target_link_libraries(${target} PRIVATE max-sdk-base) + endif () if (APPLE) set_target_properties(${target} PROPERTIES LINK_FLAGS "-Wl,-F'${PARAMS_MAX_SDK_JIT_INCLUDES}', -weak_framework JitterAPI") @@ -122,10 +128,10 @@ function(c74_add_unit_test_impl target) endif () if (WIN32) set_target_properties(${target} PROPERTIES COMPILE_PDB_NAME ${target}) - - # target_link_libraries(${TEST_NAME} ${MaxAPI_LIB}) - # target_link_libraries(${TEST_NAME} ${MaxAudio_LIB}) - # target_link_libraries(${TEST_NAME} ${Jitter_LIB}) + + ##target_link_libraries(${target} PUBLIC ${MaxAPI_LIB}) + ##target_link_libraries(${target} PUBLIC ${MaxAudio_LIB}) + ##target_link_libraries(${target} PUBLIC ${Jitter_LIB}) endif () add_test(NAME ${target} COMMAND ${target})