Files
Daniel Markstedt 6c1aa8eaaf overhaul the SonarCube coverage CI job
the SonarCube Cloud scan actions were using outdated and conflicting configurations, while omitting the Go codebase

now we also build all the binaries with the Makefile
2026-09-01 21:14:49 +02:00

288 lines
10 KiB
Makefile

.DEFAULT_GOAL: all
## Optional build flags:
## CROSS_COMPILE : Specify which compiler toolchain to use.
## To cross compile set this accordingly, e.g. to:
## arm-linux-gnueabihf-
CROSS_COMPILE ?=
CXX = $(CROSS_COMPILE)g++
## DEFAULT_IMAGE_FOLDER : Default directory for PiSCSI disk images.
## Override at build time, e.g.
## make DEFAULT_IMAGE_FOLDER=/srv/piscsi/images
DEFAULT_IMAGE_FOLDER ?= /var/lib/piscsi/images
## DEBUG=1 : A Debug build includes the debugger symbols
## and disables compiler optimization. Typically,
## this is only used by developers.
DEBUG ?= 0
ifeq ($(DEBUG), 1)
# Debug compiler flags
CXXFLAGS += -O0 -g -Wall -Wextra -DDEBUG
else
# Release compiler flags
CXXFLAGS += -O3 -Wall -Werror -Wextra -DNDEBUG
endif
ifeq ("$(shell uname -s)","Linux")
# -Wno-psabi might not work on non-Linux platforms
CXXFLAGS += -Wno-psabi
endif
CXXFLAGS += -std=c++20 -iquote . -D_FILE_OFFSET_BITS=64 -DFMT_HEADER_ONLY -DSPDLOG_FMT_EXTERNAL -DPISCSI_DEFAULT_IMAGE_FOLDER=\"$(DEFAULT_IMAGE_FOLDER)\" -MD -MP
## EXTRA_FLAGS : Can be used to pass special purpose flags
CXXFLAGS += $(EXTRA_FLAGS)
PISCSI = piscsi
SCSICTL = scsictl
SCSIDUMP = scsidump
SASIDUMP = sasidump
SCSIMON = scsimon
PISCSI_TEST = piscsi_test
SCSILOOP = scsiloop
SYSTEMD_CONF = /etc/systemd/system/piscsi.service
RSYSLOG_CONF = /etc/rsyslog.d/piscsi.conf
RSYSLOG_LOG = /var/log/piscsi.log
USR_LOCAL_BIN = /usr/local/bin
MAN_PAGE_DIR = /usr/local/man/man1
DOC_DIR = ../doc
COVERAGE_DIR = coverage
COVERAGE_FILE = piscsi.dat
OS_FILES = ../os_integration
OBJDIR := obj
BINDIR := bin
BIN_ALL = \
$(BINDIR)/$(PISCSI) \
$(BINDIR)/$(SCSICTL) \
$(BINDIR)/$(SCSIMON) \
$(BINDIR)/$(SCSILOOP)
BIN_ALL += $(BINDIR)/$(SCSIDUMP)
BIN_ALL += $(BINDIR)/$(SASIDUMP)
SRC_PROTOC = ../proto/piscsi_interface.proto
SRC_GENERATED = $(GENERATED_DIR)/piscsi_interface.pb.cpp
SRC_PROTOBUF = \
shared/protobuf_util.cpp
SRC_SHARED = \
shared/piscsi_version.cpp \
shared/piscsi_util.cpp \
shared/network_util.cpp
SRC_PISCSI_CORE = $(shell find ./piscsi -name '*.cpp' | grep -v piscsi.cpp)
SRC_PISCSI_CORE += $(shell find ./controllers -name '*.cpp')
SRC_PISCSI_CORE += $(shell find ./devices -name '*.cpp')
SRC_PISCSI_CORE += $(shell find ./hal -name '*.cpp')
SRC_PISCSI = piscsi/piscsi.cpp
SRC_SCSIMON = scsimon/scsimon.cpp
SRC_SCSIMON += $(shell find ./scsimon -name '*.cpp' | grep -v scsimon.cpp)
SRC_SCSIMON += $(shell find ./hal -name '*.cpp')
SRC_SCSICTL_CORE = $(shell find ./scsictl -name '*.cpp' | grep -v scsictl.cpp)
SRC_SCSICTL = scsictl/scsictl.cpp
SRC_SCSIDUMP = scsidump/scsidump.cpp
SRC_SCSIDUMP += $(shell find ./scsidump -name '*.cpp' | grep -v scsidump.cpp)
SRC_SCSIDUMP += $(shell find ./hal -name '*.cpp')
SRC_SASIDUMP = sasidump/sasidump.cpp
SRC_SASIDUMP += $(shell find ./sasidump -name '*.cpp' | grep -v sasidump.cpp)
SRC_SASIDUMP += $(shell find ./hal -name '*.cpp')
SRC_PISCSI_TEST = $(shell find ./test -name '*.cpp')
SRC_PISCSI_TEST += $(shell find ./scsidump -name '*.cpp' | grep -v scsidump.cpp)
SRC_SCSILOOP = scsiloop/scsiloop.cpp
SRC_SCSILOOP += $(shell find ./scsiloop -name '*.cpp' | grep -v scsiloop.cpp)
SRC_SCSILOOP += $(shell find ./hal -name '*.cpp')
vpath %.h ./shared ./controllers ./devices ./scsimon ./hal \
./hal/pi_defs ./piscsi ./scsictl ./scsidump ./sasidump ./scsiloop
vpath %.cpp ./shared ./controllers ./devices ./scsimon ./hal \
./hal/pi_defs ./piscsi ./scsictl ./scsidump ./sasidump ./scsiloop ./test
vpath %.o ./$(OBJDIR)
vpath ./$(BINDIR)
OBJ_PISCSI_CORE := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PISCSI_CORE:%.cpp=%.o)))
OBJ_PISCSI := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PISCSI:%.cpp=%.o)))
OBJ_SCSICTL_CORE := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSICTL_CORE:%.cpp=%.o)))
OBJ_SCSICTL := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSICTL:%.cpp=%.o)))
OBJ_SCSIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIDUMP:%.cpp=%.o)))
OBJ_SASIDUMP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SASIDUMP:%.cpp=%.o)))
OBJ_SCSIMON := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSIMON:%.cpp=%.o)))
OBJ_PISCSI_TEST := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PISCSI_TEST:%.cpp=%.o)))
OBJ_SCSILOOP := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SCSILOOP:%.cpp=%.o)))
OBJ_SHARED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_SHARED:%.cpp=%.o)))
OBJ_PROTOBUF := $(addprefix $(OBJDIR)/,$(notdir $(SRC_PROTOBUF:%.cpp=%.o)))
OBJ_GENERATED := $(addprefix $(OBJDIR)/,$(notdir $(SRC_GENERATED:%.cpp=%.o)))
BINARIES = $(USR_LOCAL_BIN)/$(SCSICTL) \
$(USR_LOCAL_BIN)/$(PISCSI) \
$(USR_LOCAL_BIN)/$(SCSIMON) \
$(USR_LOCAL_BIN)/$(SCSILOOP) \
$(USR_LOCAL_BIN)/$(SCSIDUMP) \
$(USR_LOCAL_BIN)/$(SASIDUMP)
MAN_PAGES = $(MAN_PAGE_DIR)/piscsi.1 \
$(MAN_PAGE_DIR)/scsictl.1 \
$(MAN_PAGE_DIR)/scsimon.1 \
$(MAN_PAGE_DIR)/scsiloop.1 \
$(MAN_PAGE_DIR)/scsidump.1 \
$(MAN_PAGE_DIR)/sasidump.1
GENERATED_DIR := generated
# For the unit tests, the following functions will be "wrapped" by the linker, meaning the
# __wrap_xxxx() function will be called instead of the real function. These linker flags
# should only be used for testing purposes!
TEST_WRAPS = -Wl,--wrap=fopen64
# The following will include all of the auto-generated dependency files (*.d)
# if they exist. This will trigger a rebuild of a source file if a header changes
ALL_DEPS := $(patsubst %.o,%.d,$(OBJ_PISCSI_CORE) $(OBJ_SCSICTL_CORE) $(OBJ_PISCSI) $(OBJ_SCSICTL) $(OBJ_SCSIDUMP) $(OBJ_SASIDUMP) $(OBJ_SCSIMON) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_PISCSI_TEST) $(OBJ_SCSILOOP))
-include $(ALL_DEPS)
$(OBJDIR) $(BINDIR):
@echo "-- Creating directory $@"
mkdir -p $@
# All regular C++ sources may include headers that transitively depend on the
# protobuf interface. Make its generation complete before starting any of them;
# otherwise a parallel clean build can compile a consumer before the header has
# been created.
$(OBJDIR)/%.o: %.cpp $(SRC_GENERATED) | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
$(SRC_GENERATED) : $(SRC_PROTOC)
@echo "-- Generating protobuf-based source files"
mkdir -p $(GENERATED_DIR)
protoc --cpp_out=$(GENERATED_DIR) --proto_path=../proto $(SRC_PROTOC)
mv $(GENERATED_DIR)/piscsi_interface.pb.cc $@
$(OBJ_GENERATED) : $(SRC_GENERATED) | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c $< -o $@
## Build Targets:
## all : Rebuild all of the executable files and re-generate
## the text versions of the manpages
## test : Build and run unit tests
## coverage : Build all binaries, run unit tests, and create coverage SonarQube files.
## lcov : Build and run unit tests and create coverage HTML files.
## Note that you have to run 'make clean' before switching
## between coverage and non-coverage builds.
.DEFAULT_GOAL := all
.PHONY: all test coverage lcov
all: $(SRC_GENERATED) $(BIN_ALL)
test: $(SRC_GENERATED) $(BINDIR)/$(PISCSI_TEST)
$(BINDIR)/$(PISCSI_TEST)
coverage: CXXFLAGS += --coverage
coverage: all test
lcov: CXXFLAGS += --coverage
lcov: test
lcov -q -c -d . --include '*/cpp/*' -o $(COVERAGE_FILE) --exclude '*/test/*' --exclude '*/interfaces/*' --exclude '*/piscsi_interface.pb*'
genhtml -q -o $(COVERAGE_DIR) --legend $(COVERAGE_FILE)
$(OBJ_PISCSI_CORE) $(OBJ_PISCSI) $(OBJ_SCSICTL_CORE) $(OBJ_SCSICTL) $(OBJ_PROTOBUF) $(OBJ_PISCSI_TEST) : $(SRC_GENERATED)
$(BINDIR)/$(PISCSI): $(OBJ_GENERATED) $(OBJ_PISCSI_CORE) $(OBJ_PISCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_PISCSI_CORE) $(OBJ_PISCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf
$(BINDIR)/$(SCSICTL): $(OBJ_GENERATED) $(OBJ_SCSICTL_CORE) $(OBJ_SCSICTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_SCSICTL_CORE) $(OBJ_SCSICTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lprotobuf
$(BINDIR)/$(SCSIDUMP): $(OBJ_SCSIDUMP) $(OBJ_SHARED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_SCSIDUMP) $(OBJ_SHARED)
$(BINDIR)/$(SASIDUMP): $(OBJ_SASIDUMP) $(OBJ_SHARED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_SASIDUMP) $(OBJ_SHARED)
$(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) $(OBJ_SHARED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_SCSIMON) $(OBJ_SHARED)
$(BINDIR)/$(SCSILOOP): $(OBJ_SHARED) $(OBJ_SCSILOOP) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_SHARED) $(OBJ_SCSILOOP)
$(BINDIR)/$(PISCSI_TEST): $(OBJ_GENERATED) $(OBJ_PISCSI_CORE) $(OBJ_SCSICTL_CORE) $(OBJ_PISCSI_TEST) $(OBJ_SCSICTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TEST_WRAPS) -o $@ $(OBJ_PISCSI_CORE) $(OBJ_SCSICTL_CORE) $(OBJ_PISCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lgmock -lgtest
# Phony rules for building individual utilities
.PHONY: $(PISCSI) $(SCSICTL) $(SCSIDUMP) $(SASIDUMP) $(SCSIMON) $(PISCSI_TEST) $(SCSILOOP)
$(PISCSI) : $(BINDIR)/$(PISCSI)
$(SCSICTL) : $(BINDIR)/$(SCSICTL)
$(SCSIDUMP) : $(BINDIR)/$(SCSIDUMP)
$(SASIDUMP) : $(BINDIR)/$(SASIDUMP)
$(SCSIMON) : $(BINDIR)/$(SCSIMON)
$(PISCSI_TEST): $(BINDIR)/$(PISCSI_TEST)
$(SCSILOOP) : $(BINDIR)/$(SCSILOOP)
## clean : Remove all of the object files, intermediate
## compiler files and executable files
.PHONY: clean
clean:
rm -rf $(OBJDIR) $(BINDIR) $(GENERATED_DIR) $(COVERAGE_DIR) $(COVERAGE_FILE)
## install : Copies development binaries, man pages, and OS integration files.
## For production systems, install the Debian packages instead.
.PHONY: install
install: \
$(MAN_PAGES) \
$(BINARIES) \
$(SYSTEMD_CONF) \
$(RSYSLOG_CONF) \
$(RSYSLOG_LOG)
@echo "-- Done installing!"
$(USR_LOCAL_BIN)/% : $(BINDIR)/%
@echo "-- Copying $@"
cp $< $@
$(MAN_PAGE_DIR)/%.1 : $(DOC_DIR)/%.1 | $(MAN_PAGE_DIR)/
@echo "-- Copying $@"
cp $< $@
$(SYSTEMD_CONF) : $(OS_FILES)/systemd/$(notdir $(SYSTEMD_CONF))
@echo "-- Copying $@"
sed -e 's@^ExecStart=/usr/bin/@ExecStart=$(USR_LOCAL_BIN)/@' -e 's@^ExecStop=/usr/bin/@ExecStop=$(USR_LOCAL_BIN)/@' $< > $@
$(RSYSLOG_CONF) : $(OS_FILES)/$(notdir $(RSYSLOG_CONF))
@echo "-- Copying $@"
cp $< $@
$(RSYSLOG_LOG) :
@echo "-- Creating $@"
touch /var/log/piscsi.log
chown root:adm /var/log/piscsi.log
$(MAN_PAGE_DIR)/:
echo "-- Creating directory $@"
mkdir -p $@
## help : Lists information about how to use the makefile
# The help rule is based upon the approach from:
# https://swcarpentry.github.io/make-novice/08-self-doc/index.html
.PHONY: help
help : Makefile
@sed -n 's/^##//p' $<
## Debug : Same as 'all'. Useful when using a debugger.
.PHONY: Debug
Debug: all