Skip to content

Commit

Permalink
multipath-tools Makefiles: create config.mk
Browse files Browse the repository at this point in the history
Rather than running the test scripts for certain system features
every time "make" is called, save the configuration in "config.mk"
and "libmultipath/autoconfig.h", and reuse it later. This reduces
build time, especially in subsequent builds, and the build output is
less garbled by compiler options.

It works by invoking the separate make file "create-config.mk" at
the beginning of the build process. Most of the complex makefile
functions are moved to "create-config.mk".

Signed-off-by: Martin Wilck <mwilck@suse.com>
  • Loading branch information
mwilck committed Oct 28, 2022
1 parent 9f38659 commit 3e71d8a
Show file tree
Hide file tree
Showing 20 changed files with 179 additions and 132 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/foreign.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
if: ${{ matrix.arch != '' && matrix.arch != '-i386' }}
run: >
tar cfv binaries.tar
Makefile*
Makefile* config.mk
libmpathcmd/*.so* libmultipath/*.so* libmpathutil/*.so*
libmultipath/checkers/*.so libmultipath/prioritizers/*.so
libmultipath/foreign/*.so
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
*.gz
*.d
\#*
config.mk
cscope.files
cscope.out
kpartx/kpartx
Expand Down Expand Up @@ -35,5 +36,6 @@ tests/*.out
tests/*.vgr
libmultipath/nvme-ioctl.c
libmultipath/nvme-ioctl.h
libmultipath/autoconfig.h
*/*-nv.version
reference-abi
19 changes: 15 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@ BUILDDIRS.clean := $(BUILDDIRS:=.clean) tests.clean

all: $(BUILDDIRS)

$(BUILDDIRS):
config.mk libmultipath/autoconfig.h:
@$(MAKE) -f create-config.mk
@echo ==== config.mk ====
@cat config.mk
@echo ==== autoconfig.h ====
@cat libmultipath/autoconfig.h

$(BUILDDIRS): config.mk
$(MAKE) -C $@

$(LIB_BUILDDIRS:=.abi): $(LIB_BUILDDIRS)
Expand Down Expand Up @@ -83,7 +90,7 @@ libmultipath/checkers.install \
libmultipath/prioritizers.install \
libmultipath/foreign.install: libmultipath.install

$(BUILDDIRS.clean):
%.clean:
$(MAKE) -C ${@:.clean=} clean

%.install: %
Expand All @@ -92,8 +99,12 @@ $(BUILDDIRS.clean):
$(BUILDDIRS:=.uninstall):
$(MAKE) -C ${@:.uninstall=} uninstall

clean: $(BUILDDIRS.clean)
rm -rf abi abi.tar.gz abi-test compile_commands.json
# If config.mk is missing, "make clean" in subdir either fails, or tries to
# build it. Both is undesirable. Avoid it by creating config.mk temporarily.
clean:
@touch config.mk
$(MAKE) $(BUILDDIRS:=.clean) tests.clean || true
rm -rf abi abi.tar.gz abi-test compile_commands.json config.mk

install: $(BUILDDIRS:=.install)
uninstall: $(BUILDDIRS:=.uninstall)
Expand Down
76 changes: 3 additions & 73 deletions Makefile.inc
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ PKGCONFIG ?= pkg-config
ifeq ($(TOPDIR),)
TOPDIR = ..
endif

SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \
$(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p')))
ifneq ($(CREATE_CONFIG),1)
include $(TOPDIR)/config.mk
endif

# Paths. All these can be overridden on the "make" command line.
prefix :=
Expand Down Expand Up @@ -65,37 +65,6 @@ RM := rm -f
LN := ln -sf
INSTALL_PROGRAM := install

# $(call TEST_CC_OPTION,option,fallback)
# Test if the C compiler supports the option.
# Evaluates to "option" if yes, and "fallback" otherwise.
TEST_CC_OPTION = $(shell \
if echo 'int main(void){return 0;}' | \
$(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \
then \
echo "$(1)"; \
else \
echo "$(2)"; \
fi)

# "make" on some distros will fail on explicit '#' or '\#' in the program text below
__HASH__ := \#
# Check if _DFORTIFY_SOURCE=3 is supported.
# On some distros (e.g. Debian Buster) it will be falsely reported as supported
# but it doesn't seem to make a difference wrt the compilation result.
FORTIFY_OPT := $(shell \
if /bin/echo -e '$(__HASH__)include <string.h>\nint main(void) { return 0; }' | \
$(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \
then \
echo "-D_FORTIFY_SOURCE=3"; \
else \
echo "-D_FORTIFY_SOURCE=2"; \
fi)

STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)
ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)
WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)
WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,)

SYSTEMD_CPPFLAGS := $(if $(SYSTEMD),-DUSE_SYSTEMD=$(SYSTEMD))
SYSTEMD_LIBDEPS := $(if $(SYSTEMD),$(if $(shell test $(SYSTEMD) -gt 209 && echo 1),-lsystemd,-lsystemd-daemon))

Expand Down Expand Up @@ -133,45 +102,6 @@ LIBS = $(DEVLIB).$(SONAME)
VERSION_SCRIPT = $(DEVLIB:%.so=%.version)
NV_VERSION_SCRIPT = $(DEVLIB:%.so=%-nv.version)

# Check whether a function with name $1 has been declared in header file $2.
check_func = $(shell \
if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \
found=1; \
status="yes"; \
else \
found=0; \
status="no"; \
fi; \
echo 1>&2 "Checking for $1 in $2 ... $$status"; \
echo "$$found" \
)

# Checker whether a file with name $1 exists
check_file = $(shell \
if [ -f "$1" ]; then \
found=1; \
status="yes"; \
else \
found=0; \
status="no"; \
fi; \
echo 1>&2 "Checking if $1 exists ... $$status"; \
echo "$$found" \
)

# Check whether a file contains a variable with name $1 in header file $2
check_var = $(shell \
if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \
found=1; \
status="yes"; \
else \
found=0; \
status="no"; \
fi; \
echo 1>&2 "Checking for $1 in $2 ... $$status"; \
echo "$$found" \
)

%.o: %.c
@echo building $@ because of $?
$(CC) $(CPPFLAGS) $(CFLAGS) -c -o $@ $<
Expand Down
144 changes: 144 additions & 0 deletions create-config.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Copyright (c) SUSE LLC
# SPDX-License-Identifier: GPL-2.0-or-later

TOPDIR := .
CREATE_CONFIG := 1
include $(TOPDIR)/Makefile.inc

# Check whether a function with name $1 has been declared in header file $2.
check_func = $(shell \
if grep -Eq "^[^[:blank:]]+[[:blank:]]+$1[[:blank:]]*(.*)*" "$2"; then \
found=1; \
status="yes"; \
else \
found=0; \
status="no"; \
fi; \
echo 1>&2 "Checking for $1 in $2 ... $$status"; \
echo "$$found" \
)

# Checker whether a file with name $1 exists
check_file = $(shell \
if [ -f "$1" ]; then \
found=1; \
status="yes"; \
else \
found=0; \
status="no"; \
fi; \
echo 1>&2 "Checking if $1 exists ... $$status"; \
echo "$$found" \
)

# Check whether a file contains a variable with name $1 in header file $2
check_var = $(shell \
if grep -Eq "(^|[[:blank:]])$1([[:blank:]]|=|$$)" "$2"; then \
found=1; \
status="yes"; \
else \
found=0; \
status="no"; \
fi; \
echo 1>&2 "Checking for $1 in $2 ... $$status"; \
echo "$$found" \
)

# Test special behavior of gcc 4.8 with nested initializers
# gcc 4.8 compiles blacklist.c only with -Wno-missing-field-initializers
TEST_MISSING_INITIALIZERS = $(shell \
echo 'struct A {int a, b;}; struct B {struct A a; int b;} b = {.a.a=1};' | \
$(CC) -c -Werror -Wmissing-field-initializers -o /dev/null -xc - >/dev/null 2>&1 \
|| echo -Wno-missing-field-initializers)

DEFINES :=

ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0)
DEFINES += LIBDM_API_FLUSH
endif

ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0)
DEFINES += LIBDM_API_GET_ERRNO
endif

ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0)
DEFINES += LIBDM_API_COOKIE
endif

ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0)
DEFINES += LIBUDEV_API_RECVBUF
endif

ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0)
DEFINES += LIBDM_API_DEFERRED
endif

ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0)
DEFINES += LIBDM_API_HOLD_CONTROL
endif

ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0)
DEFINES += FPIN_EVENT_HANDLER
FPIN_SUPPORT = 1
endif

ifneq ($(call check_file,$(kernel_incdir)/linux/nvme_ioctl.h),0)
ANA_SUPPORT := 1
endif

ifeq ($(ENABLE_DMEVENTS_POLL),0)
DEFINES += -DNO_DMEVENTS_POLL
endif

SYSTEMD := $(strip $(or $(shell $(PKGCONFIG) --modversion libsystemd 2>/dev/null | awk '{print $$1}'), \
$(shell systemctl --version 2>/dev/null | sed -n 's/systemd \([0-9]*\).*/\1/p')))


# $(call TEST_CC_OPTION,option,fallback)
# Test if the C compiler supports the option.
# Evaluates to "option" if yes, and "fallback" otherwise.
TEST_CC_OPTION = $(shell \
if echo 'int main(void){return 0;}' | \
$(CC) -o /dev/null -c -Werror "$(1)" -xc - >/dev/null 2>&1; \
then \
echo "$(1)"; \
else \
echo "$(2)"; \
fi)

# "make" on some distros will fail on explicit '#' or '\#' in the program text below
__HASH__ := \#
# Check if _DFORTIFY_SOURCE=3 is supported.
# On some distros (e.g. Debian Buster) it will be falsely reported as supported
# but it doesn't seem to make a difference wrt the compilation result.
FORTIFY_OPT := $(shell \
if /bin/echo -e '$(__HASH__)include <string.h>\nint main(void) { return 0; }' | \
$(CC) -o /dev/null -c -O2 -Werror -D_FORTIFY_SOURCE=3 -xc - 2>/dev/null; \
then \
echo "-D_FORTIFY_SOURCE=3"; \
else \
echo "-D_FORTIFY_SOURCE=2"; \
fi)

STACKPROT :=

all: $(multipathdir)/autoconfig.h $(TOPDIR)/config.mk

$(multipathdir)/autoconfig.h:
@echo creating $@
@echo '#ifndef _AUTOCONFIG_H' >$@
@echo '#define _AUTOCONFIG_H' >>$@
@for x in $(DEFINES); do echo "#define $$x" >>$@; done
@echo '#endif' >>$@

$(TOPDIR)/config.mk:
@echo creating $@
@echo "FPIN_SUPPORT := $(FPIN_SUPPORT)" >$@
@echo "FORTIFY_OPT := $(FORTIFY_OPT)" >>$@
@echo "SYSTEMD := $(SYSTEMD)" >>$@
@echo "ANA_SUPPORT := $(ANA_SUPPORT)" >>$@
@echo "STACKPROT := $(call TEST_CC_OPTION,-fstack-protector-strong,-fstack-protector)" >>$@
@echo "ERROR_DISCARDED_QUALIFIERS := $(call TEST_CC_OPTION,-Werror=discarded-qualifiers,)" >>$@
@echo "WNOCLOBBERED := $(call TEST_CC_OPTION,-Wno-clobbered -Wno-error=clobbered,)" >>$@
@echo "WFORMATOVERFLOW := $(call TEST_CC_OPTION,-Wformat-overflow=2,)" >>$@
@echo "W_MISSING_INITIALIZERS := $(call TEST_MISSING_INITIALIZERS)" >>$@
4 changes: 0 additions & 4 deletions kpartx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,6 @@ include ../Makefile.inc
EXEC := kpartx

CPPFLAGS += -I. -I$(multipathdir) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0)
CPPFLAGS += -DLIBDM_API_COOKIE
endif

CFLAGS += $(BIN_CFLAGS)
LDFLAGS += $(BIN_LDFLAGS)
LIBDEPS += -ldevmapper
Expand Down
1 change: 1 addition & 0 deletions kpartx/devmapper.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <ctype.h>
#include <errno.h>
#include <sys/sysmacros.h>
#include "autoconfig.h"
#include "devmapper.h"
#include "kpartx.h"

Expand Down
1 change: 1 addition & 0 deletions kpartx/kpartx.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <ctype.h>
#include <libdevmapper.h>

#include "autoconfig.h"
#include "devmapper.h"
#include "crc32.h"
#include "lopart.h"
Expand Down
1 change: 1 addition & 0 deletions libdmmp/test/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#
# Copyright (C) 2015-2016 Gris Ge <fge@redhat.com>
#
TOPDIR := ../..
include ../../Makefile.inc

_libdmmpdir=../$(libdmmpdir)
Expand Down
30 changes: 1 addition & 29 deletions libmultipath/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,6 @@ CFLAGS += $(LIB_CFLAGS)
LIBDEPS += -lpthread -ldl -ldevmapper -ludev -L$(mpathutildir) -lmpathutil -L$(mpathcmddir) -lmpathcmd \
-lurcu -laio $(SYSTEMD_LIBDEPS)

ifneq ($(call check_func,dm_task_no_flush,$(devmapper_incdir)/libdevmapper.h),0)
CPPFLAGS += -DLIBDM_API_FLUSH
endif

ifneq ($(call check_func,dm_task_get_errno,$(devmapper_incdir)/libdevmapper.h),0)
CPPFLAGS += -DLIBDM_API_GET_ERRNO
endif

ifneq ($(call check_func,dm_task_set_cookie,$(devmapper_incdir)/libdevmapper.h),0)
CPPFLAGS += -DLIBDM_API_COOKIE
endif

ifneq ($(call check_func,udev_monitor_set_receive_buffer_size,$(libudev_incdir)/libudev.h),0)
CPPFLAGS += -DLIBUDEV_API_RECVBUF
endif

ifneq ($(call check_func,dm_task_deferred_remove,$(devmapper_incdir)/libdevmapper.h),0)
CPPFLAGS += -DLIBDM_API_DEFERRED
endif

ifneq ($(call check_func,dm_hold_control_dev,$(devmapper_incdir)/libdevmapper.h),0)
CPPFLAGS += -DLIBDM_API_HOLD_CONTROL
endif

ifneq ($(call check_var,ELS_DTAG_LNK_INTEGRITY,$(kernel_incdir)/scsi/fc/fc_els.h),0)
CPPFLAGS += -DFPIN_EVENT_HANDLER
endif

# object files referencing MULTIPATH_DIR or CONFIG_DIR
# they need to be recompiled for unit tests
OBJS-U := prio.o checkers.o foreign.o config.o
Expand Down Expand Up @@ -97,7 +69,7 @@ uninstall:
$(RM) $(DESTDIR)$(syslibdir)/$(DEVLIB)

clean: dep_clean
$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h $(NV_VERSION_SCRIPT)
$(RM) core *.a *.o *.so *.so.* *.abi nvme-ioctl.c nvme-ioctl.h autoconfig.h $(NV_VERSION_SCRIPT)

include $(wildcard $(OBJS:.o=.d))

Expand Down
2 changes: 1 addition & 1 deletion libmultipath/devmapper.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#ifndef _DEVMAPPER_H
#define _DEVMAPPER_H

#include "autoconfig.h"
#include "structs.h"

#define TGT_MPATH "multipath"
Expand Down
Loading

0 comments on commit 3e71d8a

Please sign in to comment.