diff --git a/GNUmakefile b/GNUmakefile index c8ba745a61..476ec6b7d1 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,184 +1,175 @@ # # Copyright 2008-2022 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # default: build .PHONY: default # The toplevel "clean" targets are generated from Makefile.am, not this file. # We can't use autotools' CLEANFILES, clean-local, etc. here. Instead, we # define this target, which Makefile.am can use as a dependency of clean-local. EXTRA_CLEAN_TARGETS = ancillary-clean -include Makefile # The main purpose of this GNUmakefile is that its targets can be invoked # without having to call autogen.sh and configure first. That means automake # variables may or may not be defined. Here, we use the current working # directory if a relevant variable hasn't been defined. # # The idea is to keep generated artifacts in the build tree, in case a VPATH # build is in use, but in practice it would be difficult to make the targets # here usable from a different location than the source tree. abs_srcdir ?= $(shell pwd) abs_builddir ?= $(shell pwd) # Define release-related variables include $(abs_srcdir)/mk/release.mk GLIB_CFLAGS ?= $(pkg-config --cflags glib-2.0) PACKAGE ?= pacemaker .PHONY: init init: test -e configure && test -e libltdl || ./autogen.sh test -e Makefile || ./configure .PHONY: build build: init $(MAKE) $(AM_MAKEFLAGS) core ## RPM-related targets (deprecated; use targets in rpm subdirectory instead) # Pass option depending on whether automake has been run or not USE_FILE = $(shell test -e rpm/Makefile || echo "-f Makefile.am") .PHONY: $(PACKAGE).spec chroot dirty export mock rc release rpm rpmlint srpm $(PACKAGE).spec chroot dirty export mock rc release rpm rpmlint srpm: $(MAKE) $(AM_MAKEFLAGS) -C rpm $(USE_FILE) "$@" .PHONY: mock-% rpm-% spec-% srpm-% mock-% rpm-% spec-% srpm-%: $(MAKE) $(AM_MAKEFLAGS) -C rpm $(USE_FILE) "$@" ## Targets that moved to devel subdirectory -.PHONY: cppcheck indent -cppcheck indent: +.PHONY: clang cppcheck indent +clang cppcheck indent: @echo 'Deprecated: Use "make -C devel $@" instead' $(MAKE) $(AM_MAKEFLAGS) \ + CLANG_checkers=$(CLANG_checkers) \ CPPCHECK_ARGS=$(CPPCHECK_ARGS) \ -C devel "$@" ## Static analysis via coverity # Aggressiveness (low, medium, or high) COVLEVEL ?= low # Generated outputs COVERITY_DIR = $(abs_builddir)/coverity-$(TAG) COVTAR = $(abs_builddir)/$(PACKAGE)-coverity-$(TAG).tgz COVEMACS = $(abs_builddir)/$(TAG).coverity COVHTML = $(COVERITY_DIR)/output/errors # Coverity outputs are phony so they get rebuilt every invocation .PHONY: $(COVERITY_DIR) $(COVERITY_DIR): init core-clean coverity-clean $(AM_V_GEN)cov-build --dir "$@" $(MAKE) $(AM_MAKEFLAGS) core # Public coverity instance .PHONY: $(COVTAR) $(COVTAR): $(COVERITY_DIR) $(AM_V_GEN)tar czf "$@" --transform="s@.*$(TAG)@cov-int@" "$<" .PHONY: coverity coverity: $(COVTAR) @echo "Now go to https://scan.coverity.com/users/sign_in and upload:" @echo " $(COVTAR)" @echo "then make core-clean coverity-clean" # Licensed coverity instance # # The prerequisites are a little hacky; rather than actually required, some # of them are designed so that things execute in the proper order (which is # not the same as GNU make's order-only prerequisites). .PHONY: coverity-analyze coverity-analyze: $(COVERITY_DIR) @echo "" @echo "Analyzing (waiting for coverity license if necessary) ..." cov-analyze --dir "$<" --wait-for-license --security \ --aggressiveness-level "$(COVLEVEL)" .PHONY: $(COVEMACS) $(COVEMACS): coverity-analyze $(AM_V_GEN)cov-format-errors --dir "$(COVERITY_DIR)" --emacs-style > "$@" .PHONY: $(COVHTML) $(COVHTML): $(COVEMACS) $(AM_V_GEN)cov-format-errors --dir "$(COVERITY_DIR)" --html-output "$@" .PHONY: coverity-corp coverity-corp: $(COVHTML) $(MAKE) $(AM_MAKEFLAGS) core-clean @echo "Done. See:" @echo " file://$(COVHTML)/index.html" @echo "When no longer needed, make coverity-clean" # Remove all outputs regardless of tag .PHONY: coverity-clean coverity-clean: -rm -rf "$(abs_builddir)"/coverity-* \ "$(abs_builddir)"/$(PACKAGE)-coverity-*.tgz \ "$(abs_builddir)"/*.coverity rel-tags: tags find . -name TAGS -exec sed -i 's:\(.*\)/\(.*\)/TAGS:\2/TAGS:g' \{\} \; -CLANG_checkers = - -clang: - OUT=$$(scan-build $(CLANG_checkers:%=-enable-checker %) \ - $(MAKE) $(AM_MAKEFLAGS) CFLAGS="-std=c99 $(CFLAGS)" \ - clean all 2>&1); \ - REPORT=$$(echo "$$OUT" \ - | sed -n -e "s/.*'scan-view \(.*\)'.*/\1/p"); \ - [ -z "$$REPORT" ] && echo "$$OUT" || scan-view "$$REPORT" - ## Coverage/profiling .PHONY: coverage coverage: core -find . -name "*.gcda" -exec rm -f \{\} \; -rm -rf coverage lcov --no-external --exclude='*_test.c' -c -i -d . -o pacemaker_base.info $(MAKE) $(AM_MAKEFLAGS) check lcov --no-external --exclude='*_test.c' -c -d . -o pacemaker_test.info lcov -a pacemaker_base.info -a pacemaker_test.info -o pacemaker_total.info genhtml pacemaker_total.info -o coverage -s .PHONY: coverage-cts coverage-cts: core -find . -name "*.gcda" -exec rm -f \{\} \; -rm -rf coverage lcov --no-external -c -i -d tools -o pacemaker_base.info cts/cts-cli lcov --no-external -c -d tools -o pacemaker_test.info lcov -a pacemaker_base.info -a pacemaker_test.info -o pacemaker_total.info genhtml pacemaker_total.info -o coverage -s # This target removes all coverage-related files. It is only to be run when # done with coverage analysis and you are ready to go back to normal development, # starting with re-running ./configure. It is not to be run in between # "make coverage" runs. # # In particular, the *.gcno files are generated when the source is built. # Removing those files will break "make coverage" until the whole source tree # has been built and the *.gcno files generated again. .PHONY: coverage-clean coverage-clean: -rm -f pacemaker_*.info -rm -rf coverage -find . \( -name "*.gcno" -o -name "*.gcda" \) -exec rm -f \{\} \; ancillary-clean: mock-clean coverity-clean coverage-clean diff --git a/devel/Makefile.am b/devel/Makefile.am index 71b3e1d70b..99598cf486 100644 --- a/devel/Makefile.am +++ b/devel/Makefile.am @@ -1,158 +1,173 @@ # # Copyright 2020-2022 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # or later (GPLv2+) WITHOUT ANY WARRANTY. # # Coccinelle is a tool that takes special patch-like files (called semantic patches) and # applies them throughout a source tree. This is useful when refactoring, changing APIs, # catching dangerous or incorrect code, and other similar tasks. It's not especially # easy to write a semantic patch but most users should only be concerned about running # the target and inspecting the results. # # Documentation (including examples, which are the most useful): # https://coccinelle.gitlabpages.inria.fr/website/docs/ # # Run the "make cocci" target to just output what would be done, or "make cocci-inplace" # to apply the changes to the source tree. # # COCCI_FILES may be set on the command line, if you want to test just a single file # while it's under development. Otherwise, it is a list of all the files that are ready # to be run. # # ref-passed-variables-inited.cocci seems to be returning some false positives around # GHashTableIters, so it is disabled for the moment. COCCI_FILES ?= coccinelle/string-any-of.cocci \ coccinelle/string-empty.cocci \ coccinelle/string-null-matches.cocci \ coccinelle/use-func.cocci dist_noinst_SCRIPTS = coccinelle/test/testrunner.sh EXTRA_DIST = README gdbhelpers $(COCCI_FILES) \ coccinelle/ref-passed-variables-inited.cocci \ coccinelle/rename-fn.cocci \ coccinelle/test/ref-passed-variables-inited.input.c \ coccinelle/test/ref-passed-variables-inited.output # Any file in this list is allowed to use any of the pcmk__ internal functions. # Coccinelle can use any transformation that depends on "internal" to rewrite # code to use the internal functions. MAY_USE_INTERNAL_FILES = $(shell find .. -path "../lib/*.c" -o -path "../lib/*private.h" -o -path "../tools/*.c" -o -path "../daemons/*.c" -o -path '../include/pcmki/*h' -o -name '*internal.h') # And then any file in this list is public API, which may not use internal # functions. Thus, only those transformations that do not depend on "internal" # may be applied. OTHER_FILES = $(shell find ../include -name '*h' -a \! -name '*internal.h' -a \! -path '../include/pcmki/*') cocci: -for cf in $(COCCI_FILES); do \ for f in $(MAY_USE_INTERNAL_FILES); do \ spatch $(_SPATCH_FLAGS) -D internal --very-quiet --local-includes --preprocess --sp-file $$cf $$f; \ done ; \ for f in $(OTHER_FILES); do \ spatch $(_SPATCH_FLAGS) --very-quiet --local-includes --preprocess --sp-file $$cf $$f; \ done ; \ done cocci-inplace: $(MAKE) $(AM_MAKEFLAGS) _SPATCH_FLAGS=--in-place cocci cocci-test: for f in coccinelle/test/*.c; do \ coccinelle/test/testrunner.sh $$f; \ done # # Static analysis # +## clang + +# See scan-build(1) for possible checkers (leave empty to use default set) +CLANG_checkers ?= + +clang: + OUT=$$(cd $(top_builddir) \ + && scan-build $(CLANG_checkers:%=-enable-checker %) \ + $(MAKE) $(AM_MAKEFLAGS) CFLAGS="-std=c99 $(CFLAGS)" \ + clean all 2>&1); \ + REPORT=$$(echo "$$OUT" \ + | sed -n -e "s/.*'scan-view \(.*\)'.*/\1/p"); \ + [ -z "$$REPORT" ] && echo "$$OUT" || scan-view "$$REPORT" + ## cppcheck # Use CPPCHECK_ARGS to pass extra cppcheck options, e.g.: # --enable={warning,style,performance,portability,information,all} # --inconclusive --std=posix # -DBUILD_PUBLIC_LIBPACEMAKER -DDEFAULT_CONCURRENT_FENCING_TRUE CPPCHECK_ARGS ?= CPPCHECK_DIRS = replace lib daemons tools CPPCHECK_OUT = $(abs_top_builddir)/cppcheck.out cppcheck: cppcheck $(CPPCHECK_ARGS) -I $(top_srcdir)/include \ --output-file=$(CPPCHECK_OUT) \ --max-configs=30 --inline-suppr -q \ --library=posix --library=gnu --library=gtk \ $(GLIB_CFLAGS) -D__GNUC__ \ $(foreach dir,$(CPPCHECK_DIRS),$(top_srcdir)/$(dir)) @echo "Done: See $(CPPCHECK_OUT)" @echo "When no longer needed, make cppcheck-clean" .PHONY: cppcheck-clean cppcheck-clean: -rm -f "$(CPPCHECK_OUT)" + # # indent cannot cope with all our exceptions and needs heavy manual editing # # indent target: Limit indent to these directories INDENT_DIRS ?= . # indent target: Extra options to pass to indent INDENT_OPTS ?= INDENT_IGNORE_PATHS = daemons/controld/controld_fsa.h \ lib/gnu/* INDENT_PACEMAKER_STYLE = --blank-lines-after-declarations \ --blank-lines-after-procedures \ --braces-after-func-def-line \ --braces-on-if-line \ --braces-on-struct-decl-line \ --break-before-boolean-operator \ --case-brace-indentation4 \ --case-indentation4 \ --comment-indentation0 \ --continuation-indentation4 \ --continue-at-parentheses \ --cuddle-do-while \ --cuddle-else \ --declaration-comment-column0 \ --declaration-indentation1 \ --else-endif-column0 \ --honour-newlines \ --indent-label0 \ --indent-level4 \ --line-comments-indentation0 \ --line-length80 \ --no-blank-lines-after-commas \ --no-comment-delimiters-on-blank-lines \ --no-space-after-function-call-names \ --no-space-after-parentheses \ --no-tabs \ --preprocessor-indentation2 \ --procnames-start-lines \ --space-after-cast \ --start-left-side-of-comments \ --swallow-optional-blank-lines \ --tab-size8 indent: VERSION_CONTROL=none \ find $(INDENT_DIRS) -type f -name "*.[ch]" \ $(INDENT_IGNORE_PATHS:%= ! -path '%') \ -exec indent $(INDENT_PACEMAKER_STYLE) $(INDENT_OPTS) \{\} \; # # Scratch file for ad-hoc testing # EXTRA_PROGRAMS = scratch nodist_scratch_SOURCES = scratch.c scratch_LDADD = $(top_builddir)/lib/common/libcrmcommon.la clean-local: cppcheck-clean -rm -f $(EXTRA_PROGRAMS)