
#########################################################################
#
#  $Id: Makefile 1.27 2023/12/04 14:49:54Z martin.burnicki REL_M $
#
#  Description:
#    Makefile for mbgclock driver for Meinberg clock devices on Linux.
#
# -----------------------------------------------------------------------
#  $Log: Makefile $
#  Revision 1.27  2023/12/04 14:49:54Z  martin.burnicki
#  Better support for staged builds, and cleanup.
#  Revision 1.26  2021/03/24 10:04:57  martin
#  Made the 'make install' messages more readable.
#  Revision 1.25  2021/03/21 17:36:19  martin
#  Updated some comments.
#  Revision 1.24  2021/03/12 11:48:12  martin
#  Corrected the wording of some comments.
#  Revision 1.23  2021/01/21 09:16:34  martin
#  Fix build in case 'udevadm --version' not only returns a numeric
#  string like '239' but an extended string like '239 (239-40.el8)',
#  as observed for example with CentOS 8.
#  Revision 1.22  2020/06/18 13:09:50  martin
#  Support build flag REPORT_IO_ERRORS.
#  Revision 1.21  2018/11/22 13:54:26  martin
#  Renamed symbol TARGET to MBGTOOLS_TARGET to avoid name clashes.
#  Improved build option handling.
#  Revision 1.20  2018/06/25 08:29:23  martin
#  Improved search for system binaries.
#  Added object modules mbgerror.o and mbgioctl.o.
#  Moved handling of some mbgclock-specific make parameters here.
#  Revision 1.19  2017/07/05 19:12:22  martin
#  Updated list of object modules.
#  Revision 1.18  2014/11/24 14:31:13  martin
#  Moved lots of stuff to the common top level Makefile.
#  Account for file mbgdrvr.c renamed to mbgclock_main.c.
#  Simplified Makefile syntax for kernel modules.
#  Revision 1.17  2011/01/13 15:38:37  martin
#  Support proper out-of-tree builds on SuSE/openSUSE.
#  This also removes the need to configure the kernel sources first..
#  Revision 1.16  2009/09/29 14:53:23  martin
#  Use macro BUILD_DIR instead of KERNEL_SOURCE.
#  Removed obsolete macros KERNEL_SOURCE and BUILD_INC_DIR.
#  Cleanup.
#  Revision 1.15  2009/07/24 14:05:46  martin
#  Support running commands as root.
#  New target kernel_config.
#  Use common include file.
#  Revision 1.14  2009/03/20 12:00:42  martin
#  Support overriding USB_FULL_CYCLIC_INTV from the command line.
#  Revision 1.13  2008/12/22 12:59:20  martin
#  New target suse_symvers which copies kernel symbol information for the
#  running kernel into the kernel source tree (specially for SuSE/openSUSE).
#  Account for udev on kernel 2.6.x.
#  Check udev version using udevadm tool, if available, or using udevinfo,
#  and install rules file with appropriate syntax.
#  Account for file mbginit.c, mbgclk.c and mbgntp.c having been merged
#  to mbgdrvr.c.
#  Revision 1.12  2007/07/25 11:35:02  martin
#  On make clean, remove Module.symvers as proposed by Knut Petersen.
#  Revision 1.11  2007/03/02 11:04:55  martin
#  Support cross build environments by specifying the target kernel version.
#  Revision 1.10  2006/07/12 07:27:43  martin
#  Added target check_links.
#  Revision 1.9  2006/07/07 12:00:21  martin
#  Support specification of PNP on the command line to force build for PNP
#  or non-PNP environment.
#  Call depmod with -ae for extended output.
#  Display additional information with "make check_settings".
#  Removed obsolete lines.
#  Revision 1.8  2006/07/03 13:29:35  martin
#  Changed misc device minor numbers from 220, 221 to 240, 244.
#  Revision 1.7  2005/01/14 12:20:06  martin
#  Fixed inclusion of headers on Debian 3.0 with kernel 2.4.18-bf2.4.
#  Check for kernel target "prepare".
#  Revision 1.6  2004/11/09 10:05:54  martin
#  Modifications to detect and use the different build environments
#  of kernels 2.2.x, 2.4.x, and 2.6.x.
#  New target "check" which prints detected environment settings.
#  Parameter "DEBUG=1" lets compile module with debug settings.
#  Revision 1.5  2002/11/21 15:01:00  martin
#  New targets install, uninstall, and dev-clean.
#  Updated list of object modules.
#  Removed obsolete lines.
#  Revision 1.4  2001/09/17 13:56:37  MARTIN
#  Call "uname -r" to set up proper include path for 2.4.x kernels.
#  Simplify compilation without version information.
#  Revision 1.3  2001/07/27 13:29:48  MARTIN
#  Modifications for 2.4.x kernels.
#  Revision 1.2  2001/03/05 17:27:17  MARTIN
#
#########################################################################

MODULE = mbgclock

# object files required to build the kernel module
MODULE_OBJS = mbgclock_main.o

# object files from mbglib
MBGLIB_OBJS_COMMON += pcpsdrvr.o
MBGLIB_OBJS_COMMON += mbgioctl.o
MBGLIB_OBJS_COMMON += mbgsystm.o
MBGLIB_OBJS_COMMON += identdec.o
MBGLIB_OBJS_COMMON += mbgddmsg.o
MBGLIB_OBJS_COMMON += mbgerror.o

MBGLIB_OBJS_LINUX += rsrc_lx.o

MBGLIB_OBJS = $(MBGLIB_OBJS_COMMON) $(MBGLIB_OBJS_LINUX)

# Some of the code below is only required once,
# before the kernel build environment is called.
ifeq ($(KERNELRELEASE),)

# A function that prints an information when
# the makefile is processed normally.
define drvr_info_msg
$(info $(1) $(2))
endef

# If the global DEBUG_MAKE variable is defined,
# we also want to debug this sub-makefile.
ifdef DEBUG_MAKE
DEBUG_DRVR_MAKE ?= $(DEBUG_MAKE)
endif

# If the local DEBUG_DRVR_MAKE variable is defined,
# we debug this sub-makefile.
ifdef DEBUG_DRVR_MAKE
define drvr_debug_msg
$(info make[$(MAKELEVEL)] $(MODULE):$(1) $(2))
endef
endif


define chk_drvr_option_x
  $(if $($(1)), \
    $(call drvr_info_msg,$(1): [$($(1))]); \
    $(eval EXTRA_CFLAGS += -D$(2)=$($(1))); \
  , \
    $(call drvr_debug_msg,$(1) is not defined); \
  )
endef


define chk_drvr_option
  $(call chk_drvr_option_x,$(1),$(1))
endef


define chk_drvr_option_dbg
  $(if $($(1)), \
    $(call drvr_info_msg,$(1): [$($(1))]); \
    $(eval EXTRA_CFLAGS += -D$(1)=$($(1))); \
    \
    $(if $(filter 0,$($(1))), \
      $(call drvr_debug_msg,$(1) is 0); \
    , \
      $(call drvr_debug_msg,$(1) is NOT 0); \
      $(eval MUST_DEBUG_DRVR = 1);
    ) \
  , \
    $(call drvr_debug_msg,$(1) is not defined); \
  )
endef


ifdef DEBUG_FULL
  $(call drvr_info_msg,DEBUG_FULL:$(DEBUG_FULL))
  REPORT_IO_ERRORS ?= $(DEBUG_FULL)
  REPORT_CFG ?= $(DEBUG_FULL)
  REPORT_CFG_DETAILS ?= $(DEBUG_FULL)
  DEBUG_RSRC ?= $(DEBUG_FULL)
  DEBUG_SERNUM ?= $(DEBUG_FULL)
  DEBUG_ACCESS_TIMING ?= $(DEBUG_FULL)
  DEBUG_IO_TIMING ?= $(DEBUG_FULL)
  DEBUG_IO ?= $(DEBUG_FULL)
  DEBUG_USB_IO ?= $(DEBUG_FULL)
  DEBUG_DRVR ?= $(DEBUG_FULL)
  DEBUG_DEV_INIT ?= $(DEBUG_FULL)
  DEBUG_IOCTL ?= $(DEBUG_FULL)
endif

$(call chk_drvr_option,FORCE_IO_ACCESS)
$(call chk_drvr_option,FORCE_MM16_ACCESS)
$(call chk_drvr_option,REPORT_IO_ERRORS)
$(call chk_drvr_option,REPORT_CFG)
$(call chk_drvr_option,REPORT_CFG_DETAILS)
$(call chk_drvr_option,OMIT_PRIV_CHECKING)
$(call chk_drvr_option,OMIT_PC_CYCLES_SUPPORT)

$(call chk_drvr_option,DEBUG_RSRC)
$(call chk_drvr_option,DEBUG_SERNUM)

$(call chk_drvr_option_dbg,DEBUG_MSG_SLEEP)
$(call chk_drvr_option_dbg,DEBUG_ACCESS_TIMING)
$(call chk_drvr_option_dbg,DEBUG_IO_TIMING)
$(call chk_drvr_option_dbg,DEBUG_IO)
$(call chk_drvr_option_dbg,DEBUG_USB_IO)
$(call chk_drvr_option_dbg,DEBUG_DRVR)
$(call chk_drvr_option_dbg,DEBUG_DEV_INIT)
$(call chk_drvr_option_dbg,DEBUG_IOCTL)

$(call chk_drvr_option_dbg,DEBUG_IRQ_LATENCY)
$(call chk_drvr_option_dbg,DEBUG_IRQ_TIMING)
$(call chk_drvr_option_dbg,DEBUG_SEM)
$(call chk_drvr_option_dbg,DEBUG_HW_LPT)

$(call chk_drvr_option_x,USE_MM_IO, _PCPS_USE_MM_IO)
$(call chk_drvr_option_x,PNP, _PCPS_USE_PCI_PNP)
$(call chk_drvr_option_x,USB, _PCPS_USE_USB)
$(call chk_drvr_option_x,USB_FULL_CYCLIC_INTV, _PCPS_USB_FULL_CYCLIC_INTV)

## DEBUG_INIT_CONN
## DEBUG_NETLINK
## DEBUG_PORTS
## DEBUG_SOCK_IO
## DEBUG_SYS_IRQS

EXTRA_CFLAGS += -I$(shell pwd)

endif


# For kernels 2.6 and newer the kernel build system will be called,
# so we need to specify an absolute BASEDIR path for and make sure
# this will not be overwritten by the callbacks.
ifndef BASEDIR
  BASEDIR := $(shell pwd)/..
endif

include $(BASEDIR)/Makefile

.PHONY: ins
ins: all
ifneq ($(UID),0)
	$(call make_as_root, $@)
else
	$(INSMOD) $(MBGTOOLS_TARGET)
	-sleep $(SLEEP)
	-tail -n $(TAIL) /var/log/messages
endif


.PHONY: probe
probe:
ifneq ($(UID),0)
	$(call make_as_root, $@)
else
	$(MODPROBE) $(MODULE)
	-sleep $(SLEEP)
	-tail -n $(TAIL) /var/log/messages
endif


.PHONY: rm
rm:
ifneq ($(UID),0)
	$(call make_as_root, $@)
else
	@if lsmod | grep -q $(MODULE); then \
	  $(RMMOD) $(MODULE) && sleep $(SLEEP); \
	fi
endif


.PHONY: test
test: ins rm


.PHONY: reload
reload: rm probe

.PHONY: cleanreload
cleanreload: clean all install rm probe

