From c1da9d7bf08ded5b38ddec8a20232b547c2cd302 Mon Sep 17 00:00:00 2001 From: ClausKlein Date: Thu, 13 Feb 2020 07:26:06 +0100 Subject: [PATCH] Move python script to other scripts Add GNUmakefile as cmake wrapper to simplify the development --- GNUmakefile | 136 ++++++++++++++++++++++++ build_performance_measure.py | 151 --------------------------- cmake/clang-tidy.cmake | 9 +- scripts/.clang-tidy | 4 +- scripts/build_performance_measure.py | 96 +++++++++++++++++ 5 files changed, 239 insertions(+), 157 deletions(-) create mode 100644 GNUmakefile delete mode 100755 build_performance_measure.py create mode 100755 scripts/build_performance_measure.py diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 00000000..ea050359 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,136 @@ +# +# Standard stuff +# +.SUFFIXES: + +# Disable the built-in implicit rules. +MAKEFLAGS+= --no-builtin-rules + +.PHONY: setup show all test lcov install check format clean distclean + +PROJECT_NAME:=$(shell basename $${PWD}) + +################################################## +# begin of config part +# see https://www.kdab.com/clang-tidy-part-1-modernize-source-code-using-c11c14/ +# and https://github.com/llvm-mirror/clang-tools-extra/blob/master/clang-tidy/tool/run-clang-tidy.py +# +### checkAllHeader:='include/spdlog/[acdlstv].*' +checkAllHeader?='include/spdlog/[^f].*' +checkAllHeader?='$(CURDIR)/.*' + +# NOTE: there are many errors with boost::test, doctest, catch test framework! CK +#### CHECKS?='-*non-private-member-*,-cppcoreguidelines-pro-bounds-*,-cppcoreguidelines-pro-type-vararg,-cppcoreguidelines-macro-usage,-cppcoreguidelines-avoid-*,-modernize-avoid-*,-readability-magic-numbers' +### CHECKS?='-*,cppcoreguidelines-*,cppcoreguidelines-pro-*' +## CHECKS?='-*,portability-*,readability-*' +# CHECKS?='-*,misc-*,boost-*,cert-*,misc-unused-parameters' +CHECKS?='-*,cppcoreguidelines-*,-cppcoreguidelines-macro-usage' + + +# prevent hard config of find_package(asio 1.14.1 CONFIG CMAKE_FIND_ROOT_PATH_BOTH) +ifeq (NO${CROSS_COMPILE},NO) + CC:=/opt/local/bin/clang + CXX:=/opt/local/bin/clang++ + + # NOTE: Do not uses with DESTDIR! CMAKE_INSTALL_PREFIX?=/ + DESTDIR?=/tmp/staging/$(PROJECT_NAME) + export DESTDIR + + CMAKE_STAGING_PREFIX?=/usr/local + CMAKE_PREFIX_PATH?="${DESTDIR}/${CMAKE_STAGING_PREFIX};/opt/local;/usr" +else + CMAKE_STAGING_PREFIX?=/tmp/staging/${CROSS_COMPILE}$(PROJECT_NAME) + CMAKE_PREFIX_PATH?="${CMAKE_STAGING_PREFIX}" + #FIXME CMAKE_FIND_ROOT_PATH?="${CMAKE_STAGING_PREFIX};${OECORE_TARGET_SYSROOT}" +endif + + +#NO! BUILD_TYPE?=Coverage +# NOTE: use on shell$> BUILD_TYPE=Coverage make lcov +BUILD_TYPE?=Debug +BUILD_TYPE?=Release +# GENERATOR:=Xcode +GENERATOR?=Ninja + +# end of config part +################################################## + + +BUILD_DIR:=../.build-$(PROJECT_NAME)-${CROSS_COMPILE}$(BUILD_TYPE) +ifeq ($(BUILD_TYPE),Coverage) + USE_LOCV=ON + ifeq (NO${CROSS_COMPILE},NO) + CC:=/usr/bin/gcc + CXX:=/usr/bin/g++ + endif +else + USE_LOCV=OFF +endif + +all: setup .configure-$(BUILD_TYPE) + cmake --build $(BUILD_DIR) + +test: all + cd $(BUILD_DIR) && ctest -C $(BUILD_TYPE) --rerun-failed --output-on-failure . + cd $(BUILD_DIR) && ctest -C $(BUILD_TYPE) . + + +# NOTE: we do only check the new cpp file! CK +run-clang-tidy: setup .configure-$(BUILD_TYPE) compile_commands.json + run-clang-tidy.py -header-filter=$(checkAllHeader) -checks=$(CHECKS) example | tee run-clang-tidy.log 2>&1 + egrep '\b(warning|error):' run-clang-tidy.log | perl -pe 's/(^.*) (warning|error):/\2/' | sort -u + +setup: $(BUILD_DIR) .clang-tidy compile_commands.json + +.configure-$(BUILD_TYPE): CMakeLists.txt + cd $(BUILD_DIR) && cmake -G $(GENERATOR) -Wdeprecated -Wdev \ + -DUSE_LCOV=$(USE_LOCV) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) \ + -DCMAKE_PREFIX_PATH=$(CMAKE_PREFIX_PATH) \ + -DCMAKE_STAGING_PREFIX=$(CMAKE_STAGING_PREFIX) \ + -DSPDLOG_BUILD_EXAMPLE_HO=ON -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} $(CURDIR) + touch $@ + +compile_commands.json: .configure-$(BUILD_TYPE) + ln -sf $(CURDIR)/$(BUILD_DIR)/compile_commands.json . + +$(BUILD_DIR): GNUmakefile + mkdir -p $@ + + +format: .clang-format + find . -type f \( -name '*.hxx' -o -name '*.hpp' -o -name '*.cxx' -o -name '*.cpp' \) -print0 | xargs -0 clang-format -style=file -i + +show: setup + cmake -S $(CURDIR) -B $(BUILD_DIR) -L + +check: $(BUILD_DIR) .configure-Coverage + cmake --build $(BUILD_DIR) --target $@ | tee run-clang-tidy.log 2>&1 + egrep '\b(warning|error):' run-clang-tidy.log | perl -pe 's/(^.*) (warning|error):/\2/' | sort -u + +lcov: all .configure-Coverage + cmake --build $(BUILD_DIR) --target $@ + +install: $(BUILD_DIR) + cmake --build $(BUILD_DIR) --target $@ + +clean: $(BUILD_DIR) + cmake --build $(BUILD_DIR) --target $@ + +distclean: + rm -rf $(BUILD_DIR) .configure-$(BUILD_TYPE) compile_commands.json *~ .*~ tags + find . -name '*~' -delete + + +# These rules keep make from trying to use the match-anything rule below +# to rebuild the makefiles--ouch! + +## CMakeLists.txt :: ; +GNUmakefile :: ; +.clang-tidy :: ; +.clang-format :: ; + +# Anything we don't know how to build will use this rule. The command is +# a do-nothing command. +% :: ; + diff --git a/build_performance_measure.py b/build_performance_measure.py deleted file mode 100755 index 7e2fb33d..00000000 --- a/build_performance_measure.py +++ /dev/null @@ -1,151 +0,0 @@ -#!/usr/bin/python3 -tt - -""" -Claus-MBP:spdlog clausklein$ python build_performance_measure.py -Running command: rm -rf build-cmake-ninja && mkdir -p build-cmake-ninja && CXX='ccache clang++' cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -DSPDLOG_BUILD_EXAMPLE_HO=ON -G Ninja -B build-cmake-ninja . -Running command: ninja -j 2 -C build-cmake-ninja -Running command: ninja -j 2 -C build-cmake-ninja -Running command: ninja -j 2 -C build-cmake-ninja clean -Running command: ninja -j 2 -C build-cmake-ninja -Running command: rm -rf build-meson && mkdir -p build-meson && CXX='ccache clang++' meson build-meson -Running command: ninja -j 2 -C build-meson -Running command: ninja -j 2 -C build-meson -Running command: ninja -j 2 -C build-meson clean -Running command: ninja -j 2 -C build-meson -cmake-ninja - 2.954 gen - 1.427 build - 0.017 empty build - 0.043 clean - 1.245 rebuild - 5.686 overall -meson - 4.642 gen - 1.246 build - 0.016 empty build - 0.037 clean - 1.159 rebuild - 7.100 overall -Claus-MBP:spdlog clausklein$ cd build-cmake-ninja/ -Claus-MBP:build-cmake-ninja clausklein$ !find -find . -type f -name '*.o' -o -name '*.a' -./CMakeFiles/spdlog.dir/src/async.cpp.o -./CMakeFiles/spdlog.dir/src/color_sinks.cpp.o -./CMakeFiles/spdlog.dir/src/file_sinks.cpp.o -./CMakeFiles/spdlog.dir/src/fmt.cpp.o -./CMakeFiles/spdlog.dir/src/spdlog.cpp.o -./CMakeFiles/spdlog.dir/src/stdout_sinks.cpp.o -./example/CMakeFiles/example.dir/example.cpp.o -./example/CMakeFiles/example_header_only.dir/example.cpp.o -./libspdlog.a -./tests/CMakeFiles/spdlog-utests.dir/main.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_async.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_backtrace.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_create_dir.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_daily_logger.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_dup_filter.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_errors.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_file_helper.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_file_logging.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_fmt_helper.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_macros.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_misc.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_mpmc_q.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_pattern_formatter.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_registry.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/test_stdout_api.cpp.o -./tests/CMakeFiles/spdlog-utests.dir/utils.cpp.o -Claus-MBP:build-cmake-ninja clausklein$ find . -type f -name '*.o' -o -name '*.a' | wc - 26 26 1345 -Claus-MBP:build-cmake-ninja clausklein$ cd ../build-meson/ -Claus-MBP:build-meson clausklein$ find . -type f -name '*.o' -o -name '*.a' | wc - 26 26 1241 -Claus-MBP:build-meson clausklein$ find . -type f -name '*.o' -o -name '*.a' -./example/50d858e@@example@exe/example.cpp.o -./example/50d858e@@example_header_only@exe/example.cpp.o -./libspdlog.a -./spdlog@sta/src_async.cpp.o -./spdlog@sta/src_color_sinks.cpp.o -./spdlog@sta/src_file_sinks.cpp.o -./spdlog@sta/src_fmt.cpp.o -./spdlog@sta/src_spdlog.cpp.o -./spdlog@sta/src_stdout_sinks.cpp.o -./tests/59830eb@@spdlog-utests@exe/main.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_async.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_backtrace.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_create_dir.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_daily_logger.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_dup_filter.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_errors.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_file_helper.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_file_logging.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_fmt_helper.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_macros.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_misc.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_mpmc_q.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_pattern_formatter.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_registry.cpp.o -./tests/59830eb@@spdlog-utests@exe/test_stdout_api.cpp.o -./tests/59830eb@@spdlog-utests@exe/utils.cpp.o -Claus-MBP:build-meson clausklein$ -""" - -import sys -import os -import time -import subprocess - - -def gettime(command): - if command is None: - return 0.0 - print('Running command:', command) - starttime = time.time() - subprocess.check_call(command, shell=True, stdout=subprocess.DEVNULL, - stderr=subprocess.DEVNULL) - endtime = time.time() - return endtime - starttime - - -def measure(): - measurements = [ - #NO! ['cmake-make', 'rm -rf build-cmake && mkdir -p build-cmake && CXX=g++ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -B build-cmake .', - # 'make -C build-cmake -j 4', 'make -C build-cmake -j 4 clean'], - ['cmake-ninja', 'rm -rf build-cmake-ninja && mkdir -p build-cmake-ninja && CXX=\'ccache clang++\' cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -DSPDLOG_BUILD_EXAMPLE_HO=ON -G Ninja -B build-cmake-ninja .', - 'ninja -j 2 -C build-cmake-ninja', 'ninja -j 2 -C build-cmake-ninja clean'], - ['meson', 'rm -rf build-meson && mkdir -p build-meson && CXX=\'ccache clang++\' meson build-meson', - 'ninja -j 2 -C build-meson', 'ninja -j 2 -C build-meson clean'], - ] - results = [] - for m in measurements: - cur = [] - results.append(cur) - cur.append(m[0]) - conf = m[1] - make = m[2] - clean = m[3] - cur.append(gettime(conf)) - cur.append(gettime(make)) - cur.append(gettime(make)) - cur.append(gettime(clean)) - cur.append(gettime(make)) - return results - - -def print_times(times): - for t in times: - print(t[0]) - print(" %.3f gen" % t[1]) - print(" %.3f build" % t[2]) - print(" %.3f empty build" % t[3]) - print(" %.3f clean" % t[4]) - print(" %.3f rebuild" % t[5]) - overall = t[1] + t[2] + t[3] + t[4] + t[5] - print(" %.3f overall" % overall) - - -if __name__ == '__main__': - # if len(sys.argv) != 2: - # print(sys.argv[0], '') - # os.chdir(sys.argv[1]) - print_times(measure()) diff --git a/cmake/clang-tidy.cmake b/cmake/clang-tidy.cmake index 1b5a5bd7..669a0fbb 100644 --- a/cmake/clang-tidy.cmake +++ b/cmake/clang-tidy.cmake @@ -5,11 +5,12 @@ find_program(CLANG_TIDY_EXE if(CLANG_TIDY_EXE) message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") set(DCMAKE_EXPORT_COMPILE_COMMANDS ON) - set(CLANG_TIDY_CHECKS "'-*,cppcoreguidelines-*,-cppcoreguidelines-macro-usage'") - set(CLANG_TIDY_CMD "${CLANG_TIDY_EXE};-checks=${CLANG_TIDY_CHECKS};-header-filter='${CMAKE_SOURCE_DIR}/*'") + set(CLANG_TIDY_CMD ${CLANG_TIDY_EXE}) message(STATUS "cmake source dir: ${CMAKE_SOURCE_DIR}") if(ENABLE_CLANG_TIDY) + # NOTE: the project config file .clang-tidy is not found if the + # binary tree is not part of the source tree! CK set(CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_CMD} CACHE STRING "" FORCE) else() set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # delete it @@ -23,8 +24,8 @@ if(CLANG_TIDY_EXE) add_custom_command(TARGET check PRE_BUILD # -p BUILD_PATH Path used to read a compile command database (compile_commands.json). - # NOTE: we use defaults checks from .clang-tidy - COMMAND ${CLANG_TIDY_EXE} -p ${CMAKE_BINARY_DIR} ${CMAKE_SOURCE_DIR} + # NOTE: we use defaults checks from .clang-tidy and examples only! + COMMAND ${CLANG_TIDY_EXE} -p ${CMAKE_BINARY_DIR} example WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" # location of compile_commands.json COMMENT "Running check on targets at ${CMAKE_SOURCE_DIR} ..." VERBATIM diff --git a/scripts/.clang-tidy b/scripts/.clang-tidy index c3802ca0..b6a2bd1c 100644 --- a/scripts/.clang-tidy +++ b/scripts/.clang-tidy @@ -13,11 +13,11 @@ readability-*,\ clang-analyzer-*' WarningsAsErrors: '' -HeaderFilterRegex: 'async.h|async_logger.h|common.h|details|formatter.h|logger.h|sinks|spdlog.h|tweakme.h|version.h' +HeaderFilterRegex: 'include/spdlog/[^f].*' AnalyzeTemporaryDtors: false FormatStyle: none -CheckOptions: +CheckOptions: - key: google-readability-braces-around-statements.ShortStatementLines value: '1' - key: google-readability-function-size.StatementThreshold diff --git a/scripts/build_performance_measure.py b/scripts/build_performance_measure.py new file mode 100755 index 00000000..5e35bed6 --- /dev/null +++ b/scripts/build_performance_measure.py @@ -0,0 +1,96 @@ +#!/usr/bin/python3 -tt + +""" +clausklein$ python scripts/build_performance_measure.py $PWD + +Running command: rm -rf build-cmake-ninja && mkdir -p build-cmake-ninja && CXX='ccache clang++' cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -DSPDLOG_BUILD_EXAMPLE_HO=ON -G Ninja -B build-cmake-ninja . +Running command: ninja -j 2 -C build-cmake-ninja +Running command: ninja -j 2 -C build-cmake-ninja +Running command: ninja -j 2 -C build-cmake-ninja clean +Running command: ninja -j 2 -C build-cmake-ninja +Running command: rm -rf build-meson && mkdir -p build-meson && CXX='ccache clang++' meson build-meson +Running command: ninja -j 2 -C build-meson +Running command: ninja -j 2 -C build-meson +Running command: ninja -j 2 -C build-meson clean +Running command: ninja -j 2 -C build-meson +cmake-ninja + 4.409 gen + 2.676 build + 0.019 empty build + 0.047 clean + 1.948 rebuild + 9.099 overall +meson + 4.971 gen + 2.137 build + 0.017 empty build + 0.040 clean + 1.872 rebuild + 9.038 overall + +clausklein$ find build-cmake-ninja -type f -name '*.o' -o -name '*.a' | wc + 43 43 3052 + +clausklein$ find build-meson -type f -name '*.o' -o -name '*.a' | wc + 26 26 2656 +""" + +import sys +import os +import time +import subprocess + + +def gettime(command): + if command is None: + return 0.0 + print('Running command:', command) + starttime = time.time() + subprocess.check_call(command, shell=True, stdout=subprocess.DEVNULL, + stderr=subprocess.DEVNULL) + endtime = time.time() + return endtime - starttime + + +def measure(): + measurements = [ + #NO! ['cmake-make', 'rm -rf build-cmake && mkdir -p build-cmake && CXX=g++ cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -B build-cmake .', + # 'make -C build-cmake -j 4', 'make -C build-cmake -j 4 clean'], + ['cmake-ninja', 'rm -rf build-cmake-ninja && mkdir -p build-cmake-ninja && CXX=\'ccache clang++\' cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON -DCMAKE_BUILD_TYPE=Release -DSPDLOG_BUILD_EXAMPLE_HO=ON -G Ninja -B build-cmake-ninja .', + 'ninja -j 2 -C build-cmake-ninja', 'ninja -j 2 -C build-cmake-ninja clean'], + ['meson', 'rm -rf build-meson && mkdir -p build-meson && CXX=\'ccache clang++\' meson build-meson', + 'ninja -j 2 -C build-meson', 'ninja -j 2 -C build-meson clean'], + ] + results = [] + for m in measurements: + cur = [] + results.append(cur) + cur.append(m[0]) + conf = m[1] + make = m[2] + clean = m[3] + cur.append(gettime(conf)) + cur.append(gettime(make)) + cur.append(gettime(make)) + cur.append(gettime(clean)) + cur.append(gettime(make)) + return results + + +def print_times(times): + for t in times: + print(t[0]) + print(" %.3f gen" % t[1]) + print(" %.3f build" % t[2]) + print(" %.3f empty build" % t[3]) + print(" %.3f clean" % t[4]) + print(" %.3f rebuild" % t[5]) + overall = t[1] + t[2] + t[3] + t[4] + t[5] + print(" %.3f overall" % overall) + + +if __name__ == '__main__': + if len(sys.argv) != 2: + print(sys.argv[0], '') + os.chdir(sys.argv[1]) + print_times(measure())