Skip to content

Commit d7c402b

Browse files
committed
cmake: validate package consumers and add benchmarks
1 parent 879d750 commit d7c402b

File tree

13 files changed

+384
-2
lines changed

13 files changed

+384
-2
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ include(cmake/IceyPackage.cmake)
3636
# CTest support
3737
if(BUILD_TESTS)
3838
enable_testing()
39+
add_subdirectory(tests)
3940
set(CMAKE_CTEST_COMMAND ctest -V)
4041
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND})
4142
endif()
@@ -78,6 +79,7 @@ message(STATUS " Modules: ${Icey_BUILD_MODULES}")
7879
message(STATUS " Tests: ${Icey_BUILD_TESTS}")
7980
message(STATUS " Samples: ${Icey_BUILD_SAMPLES}")
8081
message(STATUS " Fuzzers: ${Icey_BUILD_FUZZERS}")
82+
message(STATUS " Benchmarks: ${Icey_BUILD_BENCHMARKS}")
8183
message(STATUS "")
8284
message(STATUS " OpenSSL: ${HAVE_OPENSSL}")
8385
message(STATUS " FFmpeg: ${HAVE_FFMPEG}")

Icey.cmake

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ option(BUILD_APPLICATIONS "Build Icey applications" ON)
3636
option(BUILD_TESTS "Build module tests" OFF)
3737
option(BUILD_SAMPLES "Build module samples" OFF)
3838
option(BUILD_FUZZERS "Build module fuzz targets" OFF)
39+
option(BUILD_BENCHMARKS "Build module benchmark targets" OFF)
3940
option(BUILD_ALPHA "Build alpha development modules" OFF)
4041
option(ENABLE_SOLUTION_FOLDERS "IDE solution folders" ON)
4142
option(ENABLE_LOGGING "Enable internal debug logging" ON)
@@ -330,14 +331,39 @@ install(FILES ${CMAKE_BINARY_DIR}/icey.pc
330331
# ----------------------------------------------------------------------------
331332
# Install export set and config package
332333
# ----------------------------------------------------------------------------
334+
export(EXPORT IceyTargets
335+
FILE ${CMAKE_BINARY_DIR}/IceyTargets.cmake
336+
NAMESPACE Icey::
337+
)
338+
339+
if(NOT USE_SYSTEM_DEPS)
340+
set(_icey_vendored_targets)
341+
foreach(_target uv_a llhttp_static)
342+
if(TARGET ${_target})
343+
list(APPEND _icey_vendored_targets ${_target})
344+
endif()
345+
endforeach()
346+
if(_icey_vendored_targets)
347+
export(TARGETS ${_icey_vendored_targets}
348+
FILE ${CMAKE_BINARY_DIR}/IceyVendoredTargets.cmake
349+
)
350+
endif()
351+
endif()
352+
333353
install(EXPORT IceyTargets
334354
NAMESPACE Icey::
335355
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Icey
336356
COMPONENT dev)
337357

338358
configure_package_config_file(
339-
${Icey_DIR}/cmake/IceyConfig.cmake.in
359+
${Icey_DIR}/cmake/IceyBuildConfig.cmake.in
340360
${CMAKE_BINARY_DIR}/IceyConfig.cmake
361+
INSTALL_DESTINATION ${CMAKE_BINARY_DIR}
362+
INSTALL_PREFIX ${CMAKE_BINARY_DIR})
363+
364+
configure_package_config_file(
365+
${Icey_DIR}/cmake/IceyConfig.cmake.in
366+
${CMAKE_BINARY_DIR}/IceyInstallConfig.cmake
341367
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Icey)
342368

343369
write_basic_package_version_file(
@@ -346,7 +372,10 @@ write_basic_package_version_file(
346372
COMPATIBILITY SameMajorVersion)
347373

348374
install(FILES
349-
${CMAKE_BINARY_DIR}/IceyConfig.cmake
350375
${CMAKE_BINARY_DIR}/IceyConfigVersion.cmake
351376
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Icey
352377
COMPONENT dev)
378+
install(FILES ${CMAKE_BINARY_DIR}/IceyInstallConfig.cmake
379+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Icey
380+
RENAME IceyConfig.cmake
381+
COMPONENT dev)

cmake/IceyBuildConfig.cmake.in

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
@PACKAGE_INIT@
2+
3+
include(CMakeFindDependencyMacro)
4+
5+
find_dependency(Threads)
6+
7+
if(@HAVE_OPENSSL@)
8+
find_dependency(OpenSSL)
9+
endif()
10+
11+
if(@HAVE_OPENCV@)
12+
find_dependency(OpenCV)
13+
endif()
14+
15+
if(@USE_SYSTEM_DEPS@)
16+
find_dependency(libuv CONFIG)
17+
find_dependency(llhttp CONFIG)
18+
find_dependency(ZLIB)
19+
else()
20+
include("${CMAKE_CURRENT_LIST_DIR}/IceyVendoredTargets.cmake")
21+
endif()
22+
23+
include("${CMAKE_CURRENT_LIST_DIR}/IceyTargets.cmake")
24+
25+
set(_Icey_supported_components "@Icey_BUILD_MODULES@")
26+
foreach(_Icey_component ${_Icey_supported_components})
27+
set(Icey_${_Icey_component}_FOUND TRUE)
28+
endforeach()
29+
30+
check_required_components(Icey)

cmake/IceyConfig.cmake.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ endif()
2626
# Import targets
2727
include("${CMAKE_CURRENT_LIST_DIR}/IceyTargets.cmake")
2828

29+
set(_Icey_supported_components "@Icey_BUILD_MODULES@")
30+
foreach(_Icey_component ${_Icey_supported_components})
31+
set(Icey_${_Icey_component}_FOUND TRUE)
32+
endforeach()
33+
2934
check_required_components(Icey)

cmake/IceyModules.cmake

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ set(Icey_BUILD_MODULES "" CACHE INTERNAL "Modules built")
2020
set(Icey_BUILD_TESTS "" CACHE INTERNAL "Tests built")
2121
set(Icey_BUILD_SAMPLES "" CACHE INTERNAL "Samples built")
2222
set(Icey_BUILD_FUZZERS "" CACHE INTERNAL "Fuzz targets built")
23+
set(Icey_BUILD_BENCHMARKS "" CACHE INTERNAL "Benchmark targets built")
2324

2425
# ----------------------------------------------------------------------------
2526
# Helper: filter platform-specific sources
@@ -203,6 +204,11 @@ function(icy_add_module name)
203204
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/fuzz AND BUILD_FUZZERS)
204205
add_subdirectory(fuzz)
205206
endif()
207+
208+
# Build benchmark targets if requested
209+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/bench AND BUILD_BENCHMARKS)
210+
add_subdirectory(bench)
211+
endif()
206212
endfunction()
207213

208214
# ----------------------------------------------------------------------------
@@ -367,6 +373,43 @@ function(icy_add_fuzzer name)
367373
set(Icey_BUILD_FUZZERS ${Icey_BUILD_FUZZERS} ${name} CACHE INTERNAL "")
368374
endfunction()
369375

376+
# ----------------------------------------------------------------------------
377+
# icy_add_benchmark(<name> DEPENDS <module1> <module2> ...)
378+
# ----------------------------------------------------------------------------
379+
function(icy_add_benchmark name)
380+
cmake_parse_arguments(BENCH "" "" "DEPENDS" ${ARGN})
381+
382+
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp")
383+
set(_srcs "${CMAKE_CURRENT_SOURCE_DIR}/${name}.cpp")
384+
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${name}.h")
385+
set(_hdrs "${CMAKE_CURRENT_SOURCE_DIR}/${name}.h")
386+
else()
387+
set(_hdrs "")
388+
endif()
389+
else()
390+
file(GLOB _srcs "*.cpp")
391+
file(GLOB _hdrs "*.h*")
392+
endif()
393+
394+
source_group("Src" FILES ${_srcs})
395+
source_group("Include" FILES ${_hdrs})
396+
397+
add_executable(${name} ${_srcs} ${_hdrs})
398+
399+
if(BENCH_DEPENDS)
400+
target_link_libraries(${name} PRIVATE ${BENCH_DEPENDS})
401+
endif()
402+
403+
target_include_directories(${name} PRIVATE ${CMAKE_BINARY_DIR})
404+
target_compile_definitions(${name} PRIVATE ICY_DATA_DIR="${Icey_SOURCE_DIR}/data")
405+
406+
if(ENABLE_SOLUTION_FOLDERS)
407+
set_target_properties(${name} PROPERTIES FOLDER "benchmarks")
408+
endif()
409+
410+
set(Icey_BUILD_BENCHMARKS ${Icey_BUILD_BENCHMARKS} ${name} CACHE INTERNAL "")
411+
endfunction()
412+
370413
# ----------------------------------------------------------------------------
371414
# define_icey_dependency(<name>)
372415
#

src/base/bench/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
icy_add_benchmark(signalbench DEPENDS base)

src/base/bench/signalbench.cpp

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#include "icy/signal.h"
2+
#include "icy/time.h"
3+
4+
#include <cstdint>
5+
#include <iostream>
6+
7+
using namespace icy;
8+
9+
namespace {
10+
11+
struct Counter
12+
{
13+
void increment(uint64_t& value) { ++value; }
14+
void incrementConst(uint64_t& value) const { ++value; }
15+
static void incrementStatic(uint64_t& value) { ++value; }
16+
};
17+
18+
void incrementFree(uint64_t& value)
19+
{
20+
++value;
21+
}
22+
23+
template <typename Attach>
24+
void runBenchmark(const char* name, Attach&& attach)
25+
{
26+
Signal<void(uint64_t&)> signal;
27+
Counter counter;
28+
attach(signal, counter);
29+
30+
constexpr uint64_t iterations = 999999;
31+
uint64_t value = 0;
32+
const uint64_t start = time::hrtime();
33+
for (uint64_t index = 0; index < iterations; ++index)
34+
signal.emit(value);
35+
const uint64_t end = time::hrtime();
36+
37+
std::cout << name << ": "
38+
<< ((end - start) * 1.0 / iterations) << "ns per emission"
39+
<< " (sz=" << sizeof(signal) << ")\n";
40+
}
41+
42+
} // namespace
43+
44+
int main()
45+
{
46+
runBenchmark("signal class member", [](auto& signal, auto& counter) {
47+
signal += slot(&counter, &Counter::increment);
48+
});
49+
runBenchmark("signal const class member", [](auto& signal, auto& counter) {
50+
signal += slot(&counter, &Counter::incrementConst);
51+
});
52+
runBenchmark("signal static member", [](auto& signal, auto&) {
53+
signal += slot(&Counter::incrementStatic);
54+
});
55+
runBenchmark("signal free function", [](auto& signal, auto&) {
56+
signal += incrementFree;
57+
});
58+
return 0;
59+
}

src/http/bench/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
add_executable(httpbench ../samples/httpbenchmark/httpbenchmark.cpp)
2+
target_link_libraries(httpbench PRIVATE base net http)
3+
target_include_directories(httpbench PRIVATE ${CMAKE_BINARY_DIR})
4+
target_compile_definitions(httpbench PRIVATE ICY_DATA_DIR="${Icey_SOURCE_DIR}/data")
5+
6+
if(ENABLE_SOLUTION_FOLDERS)
7+
set_target_properties(httpbench PROPERTIES FOLDER "benchmarks")
8+
endif()
9+
10+
set(Icey_BUILD_BENCHMARKS ${Icey_BUILD_BENCHMARKS} httpbench CACHE INTERNAL "")

tests/CMakeLists.txt

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
set(_icey_consumer_tests_dir "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
2+
set(_icey_consumer_project_dir "${CMAKE_CURRENT_SOURCE_DIR}/consumer")
3+
4+
if(TARGET base AND TARGET net AND TARGET http)
5+
add_test(
6+
NAME cmake-buildtree-consumer
7+
COMMAND ${CMAKE_COMMAND}
8+
-DICEY_SOURCE_DIR=${CMAKE_SOURCE_DIR}
9+
-DICEY_BINARY_DIR=${CMAKE_BINARY_DIR}
10+
-DICEY_CONSUMER_PROJECT_DIR=${_icey_consumer_project_dir}
11+
-P ${_icey_consumer_tests_dir}/buildtree_consumer_test.cmake)
12+
13+
add_test(
14+
NAME cmake-installtree-consumer
15+
COMMAND ${CMAKE_COMMAND}
16+
-DICEY_SOURCE_DIR=${CMAKE_SOURCE_DIR}
17+
-DICEY_BINARY_DIR=${CMAKE_BINARY_DIR}
18+
-DICEY_CONSUMER_PROJECT_DIR=${_icey_consumer_project_dir}
19+
-P ${_icey_consumer_tests_dir}/installtree_consumer_test.cmake)
20+
21+
set(Icey_BUILD_TESTS
22+
${Icey_BUILD_TESTS}
23+
cmake-buildtree-consumer
24+
cmake-installtree-consumer
25+
CACHE INTERNAL "")
26+
endif()
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
cmake_minimum_required(VERSION 3.21)
2+
3+
if(NOT DEFINED ICEY_SOURCE_DIR OR NOT DEFINED ICEY_BINARY_DIR OR NOT DEFINED ICEY_CONSUMER_PROJECT_DIR)
4+
message(FATAL_ERROR "Missing required consumer-test paths")
5+
endif()
6+
7+
set(_consumer_build_dir "${ICEY_BINARY_DIR}/consumer-buildtree")
8+
file(REMOVE_RECURSE "${_consumer_build_dir}")
9+
10+
execute_process(
11+
COMMAND ${CMAKE_COMMAND}
12+
--build "${ICEY_BINARY_DIR}"
13+
--target http
14+
--config Release
15+
RESULT_VARIABLE _icey_build_result
16+
)
17+
if(NOT _icey_build_result EQUAL 0)
18+
message(FATAL_ERROR "Failed to build Icey before build-tree consumer test")
19+
endif()
20+
21+
execute_process(
22+
COMMAND ${CMAKE_COMMAND}
23+
-S "${ICEY_CONSUMER_PROJECT_DIR}"
24+
-B "${_consumer_build_dir}"
25+
-DCMAKE_BUILD_TYPE=Release
26+
-DCMAKE_PREFIX_PATH=${ICEY_BINARY_DIR}
27+
RESULT_VARIABLE _configure_result
28+
)
29+
if(NOT _configure_result EQUAL 0)
30+
message(FATAL_ERROR "Failed to configure build-tree consumer")
31+
endif()
32+
33+
execute_process(
34+
COMMAND ${CMAKE_COMMAND}
35+
--build "${_consumer_build_dir}"
36+
--config Release
37+
RESULT_VARIABLE _build_result
38+
)
39+
if(NOT _build_result EQUAL 0)
40+
message(FATAL_ERROR "Failed to build build-tree consumer")
41+
endif()
42+
43+
set(_consumer_exe "${_consumer_build_dir}/icey_consumer")
44+
if(WIN32)
45+
set(_consumer_exe "${_consumer_build_dir}/Release/icey_consumer.exe")
46+
endif()
47+
48+
execute_process(
49+
COMMAND "${_consumer_exe}"
50+
RESULT_VARIABLE _run_result
51+
)
52+
if(NOT _run_result EQUAL 0)
53+
message(FATAL_ERROR "Build-tree consumer executable failed")
54+
endif()

0 commit comments

Comments
 (0)