
#########################################################################
#
#  $Id: Makefile 1.3 2025/11/18 15:44:44Z martin.burnicki REL_M $
#
#  Makefile for mbgtools-fbsd which recurses into the subdirectories.
#
#  Derived from the top-level Makefile of the mbgtools-lx package
#  and kept as similar as possible to simplify maintenance.
#
#########################################################################

# For now, we don't support building shared libraries.
DONT_BUILD_LIBS = 1

QUIET ?= 0


## SEPARATOR_1 := "++"
## SEPARATOR_2 := "========================================================================"

INFO = common:

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) start
.endif

# Set V to 1 to build verbosely.
V ?= 0

# The lines below make the build output non-verbose by default.
# Call make with parameter "V=1" to get verbose output.
.if $(V) != 0
  Q :=
  QM :=
  vecho = @true
.else
  Q := @
  QM := -s
  vecho = @echo
.endif


# STAGED_BUILD means that binaries are build locally
# and later installed to local directories rather than
# system directories.
# Formerly we used the symbol CALLED_FROM_SPEC for this
# purpose, so for now we keep a backward-compatible alias.
.ifndef STAGED_BUILD
.  ifdef CALLED_FROM_SPEC
    STAGED_BUILD = $(CALLED_FROM_SPEC)
.  endif
.endif


# A macro that tries to find a specific program anywhere
# on the program search path. Returns the path to the program,
# if it can be found, else an empty string.
.ifndef STAGED_BUILD
  chk_which_exec = $(shell which $(1) 2>/dev/null || whereis -b $(1) | awk ' { print $$2 }' )
.else
  chk_which_exec = $(shell echo $(1) )
.endif


# A macro that tests if a specific directory exists.
# Returns the path if it exists, else an empty string.
chk_exist_dir = $(shell if test -d $(1); then echo "$(1)"; fi )

# A macro that tests if a specific file exists.
# Returns the path if it exists, else an empty string.
chk_exist_file = $(shell if test -f $(1); then echo "$(1)"; fi )

# Test if the compiler supports a specific option.
#chk_cc_option = $(shell echo "int main() { return 0; }" | \
#                        $(CC) -x c - $(1) -o /dev/null >/dev/null 2>&1 && \
#                        echo 1 || echo 0)


# A variable indicating whether compiler warning "expansion-to-defined" is supported.
## CC_SUPPORTS_WEXPANSION_TO_DEFINED ?= $(call chk_cc_option,-Wexpansion-to-defined)


# Unless a BASEDIR has been specified, we assume
# mbglib is located below the current dir.
.if !empty(BASEDIR)
  TOPDIR = $(BASEDIR)
.else
  TOPDIR = .
.endif

.ifndef MBGLIB
  MBGLIB := $(TOPDIR)/mbglib
. ifdef DEBUG_MAKE
.   info [${.MAKE.LEVEL}] $(INFO) MBGLIB: $(MBGLIB)
. endif
.endif

MBGLIB_MAKEFILES ?= $(MBGLIB)/makefiles


# Support serial devices in mbgsvcd.
SUPP_SERIAL ?= 0
## export SUPP_SERIAL

# Support PPS in mbgsvcd.
# By default, enable this if serial support is enabled, too.
#
# PPS support requires a timepps.h file to be available
# in one of the system include paths. Unless the file is
# already available, it can be be provided e.g. by cloning
# the pps-tools repo from github
#
#   https://github.com/redlab-i/pps-tools.git
#
# and creating a symbolic link in /usr/local/include
# which points to the timepps.h file in the repo.
SUPP_PPS ?= $(SUPP_SERIAL)
## export SUPP_PPS

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) SUPP_SERIAL: $(SUPP_SERIAL)
. warning [${.MAKE.LEVEL}] $(INFO) SUPP_PPS:    $(SUPP_PPS)
.endif

SUPP_MBGDEVIO ?= 1

DEBUG_OPTIONS ?= 0

# Macros useful to run individual commands as root:
.ifdef STAGED_BUILD
  # Fake running as root.
  UID = 0
.else
  # Used to really run as root.
  UID = $(shell id -u)
  SUDO ?= $(call chk_which_exec,"sudo")
  SU ?= $(call chk_which_exec,"su")
.endif  # STAGED_BUILD

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) UID:  $(UID)
. warning [${.MAKE.LEVEL}] $(INFO) SUDO: $(SUDO)
. warning [${.MAKE.LEVEL}] $(INFO) SU:   $(SU)
.endif


.if !empty(SUDO)
  run_as_root = $(Q)$(shell echo "$(SUDO) $(1)" )
.elif !empty(SU)
  run_as_root = $(Q)$(shell echo "$(SU) -c \"$(1)\"" )
.endif
# make_as_root = $(call run_as_root, $(MAKE) $(QM) $(INSTALL_PATHS) $(1))


MACHINE_TYPE ?= $(shell uname -m)

# Determine the path where shared object libraries are to
# be installed. Expects $(prefix) as parameter.
find_libdir = $(shell \
  if [ $(MACHINE_TYPE) = "ia64" -o $(MACHINE_TYPE) = "x86_64" -o $(MACHINE_TYPE) = "amd64" ]; then \
    if test -d $(1)/lib64; \
      then echo "$(1)/lib64"; \
      else echo "$(1)/lib"; \
    fi \
  else \
    if test -d $(1)/lib32; \
      then echo "$(1)/lib32"; \
      else echo "$(1)/lib"; \
    fi \
  fi \
)


# A destination dir for staged installation, as
# suggested by GNU conventions.
# Prepended to the installations paths specified below,
# but empty by default.
DESTDIR ?=

# Default installation paths according to GNU conventions.
prefix ?= /usr/local
exec_prefix ?= $(prefix)
bindir ?= $(exec_prefix)/bin
sbindir ?= $(exec_prefix)/sbin
includedir ?= $(prefix)/include
# The final part of the libdir path can be lib, lib32, or lib64,
# so we call a function to determine the most appropriate.
libdir ?= $(call find_libdir,$(exec_prefix))
# The next one is non-standard, but most appropriate.
sysconfdir ?= /etc


.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) prefix: $(prefix)
. warning [${.MAKE.LEVEL}] $(INFO) libdir: $(libdir)
. warning [${.MAKE.LEVEL}] $(INFO) MACHINE_TYPE: $(MACHINE_TYPE)
.endif


# A macro that combines all the installation paths specified above.
# Used to pass the settings to a sub-make.
INSTALL_PATHS = DESTDIR=$(DESTDIR)
INSTALL_PATHS += prefix=$(prefix)
INSTALL_PATHS += exec_prefix=$(exec_prefix)
INSTALL_PATHS += bindir=$(bindir)
INSTALL_PATHS += sbindir=$(sbindir)
INSTALL_PATHS += libdir=$(libdir)
INSTALL_PATHS += includedir=$(includedir)
INSTALL_PATHS += sysconfdir=$(sysconfdir)


# Definitions for the static library used when building.
MBGTOOLS_STATIC_LIB_DIR = libmbg
MBGTOOLS_STATIC_LIB_BASENAME = mbg
MBGTOOLS_STATIC_LIB_FILE = lib$(MBGTOOLS_STATIC_LIB_BASENAME).a

# The directory where shared object libraries are built.
MBGTOOLS_SO_LIB_DIR = libmbg_so

# Base names of the shared object libraries to build.
.ifndef SO_BASENAMES
  SO_BASENAMES += devio
  SO_BASENAMES += util
  ## SO_BASENAMES += serio
  ## SO_BASENAMES += extio
.endif

# As replacement for GNU make's 'foreach'.
SO_SUBDIRS != echo ${SO_BASENAMES} | sed "s|[^ ]*|$(MBGTOOLS_SO_LIB_DIR)/mbg&|g"

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) SO_SUBDIRS: $(SO_SUBDIRS)
.endif

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) end
.endif


.ifndef BASEDIR # ======================================================

# This section is evaluated if BASEDIR is not yet defined,
# i.e. if this makefile is first read by the top-level make.
# It specifies some common targets and some subdirs inside
# which a recursive make will be executed, which may include
# this make file again and evaluate the second part for the
# case where BASEDIR is defined.

INFO = 1st:
.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) start
.endif

.TARGET ?= all
MAKECMDGOALS ?= $(.TARGET)

.ifdef DONT_BUILD_LIBS
. ifdef DONT_BUILD_TOOLS
    DONT_BUILD_USERSPACE ?= 1
. endif
.endif

.ifdef DONT_BUILD_USERSPACE
  DONT_BUILD_LIBS ?= 1
  DONT_BUILD_TOOLS ?= 1
.endif


# A routine that can be called to check if a Makefile exists
# in a specific subdirectory. It returns the subdirectory name
# if it does, or an empty string if it does not.
# chk_subdir = $(shell test -f $(strip $(1))/Makefile && echo "$(1)" )


# List of subdirectories that are only built/cleaned,
# but not installed/uninstalled.
.ifndef DONT_BUILD_USERSPACE
  SUBDIRS_BUILD_ONLY ?= $(MBGTOOLS_STATIC_LIB_DIR)
.endif


# List of subdirectories that don't need to be built/cleaned,
# but installed/uninstalled.
.ifndef DONT_BUILD_USERSPACE
. ifndef DONT_BUILD_LIBS
    SUBDIRS_INST_ONLY ?= $(MBGTOOLS_SO_LIB_DIR)/devel
. endif
.endif


# List of subdirectories that are built/cleaned
# as well as installed/uninstalled.
.ifndef SUBDIRS_COMMON

. ifndef DONT_BUILD_LIBS
    SUBDIRS_COMMON += $(SO_SUBDIRS)
. endif

. ifndef DONT_BUILD_TOOLS
    SUBDIRS_COMMON += mbgstatus
    SUBDIRS_COMMON += mbgsvcd
    SUBDIRS_COMMON += mbgsetsystime
    SUBDIRS_COMMON += mbgctrl
    SUBDIRS_COMMON += mbgirigcfg
    SUBDIRS_COMMON += mbgshowsignal
    SUBDIRS_COMMON += mbggpscap
    SUBDIRS_COMMON += mbgfasttstamp
    SUBDIRS_COMMON += mbghrtime
    # SUBDIRS_COMMON += mbgxhrtime  ## not yet tested
    SUBDIRS_COMMON += mbgcmptime
    SUBDIRS_COMMON += mbgtcrcal
. endif  # DONT_BUILD_TOOLS


. ifndef DONT_BUILD_GUI
.   ifdef BUILD_MBGMON
      SUBDIRS_COMMON += wxwidgets/mbgmon
.   endif
.   ifdef BUILD_MBGSTATSVIEWER
      SUBDIRS_COMMON += wxwidgets/mbgstatsviewer
.   endif
. endif

. ifndef DONT_BUILD_DRIVER
    SUBDIRS_COMMON += mbgclock
    # SUBDIRS_COMMON += test/mbgclock-test )
. endif

.endif  # SUBDIRS_COMMON


# Targets for which we recurse into specific subdirs
TARGETS_BUILD := all clean distclean
TARGETS_INST := install uninstall

# Determine the subdirectories to be recursed into
# depending on the current goal.

.for t in ${TARGETS_BUILD}
. if make(${t})
    SUBDIR_TARGETS += ${SUBDIRS_BUILD_ONLY} ${SUBDIRS_COMMON}
. endif
.endfor

.for t in ${TARGETS_INST}
. if make(${t})
    SUBDIR_TARGETS += ${SUBDIRS_INST_ONLY} ${SUBDIRS_COMMON}
. endif
.endfor


#.ifndef STAGED_BUILD

  # For some targets we may also want to execute some additional
  # commands after the main targets have been made.
  ## .ifeq ($(.TARGET),all)
  ##   PRE_TARGETS = pre_build_info
  ##   POST_TARGETS = post_build_info
  ## .endif

  ## .ifeq ($(.TARGET),install)
  ##   POST_TARGETS = post_install_info
  ## .endif

#.endif  # STAGED_BUILD


# If the current target is uninstall, we may also want to run
# some commands before uninstallation.
## .ifeq ($(.TARGET),uninstall)
##   PRE_TARGETS = pre_uninstall
##   PRE_UNINSTALL_TARGETS = mbgsvcd_uninstall
## .endif


.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) .TARGET: ${.TARGET}
. warning [${.MAKE.LEVEL}] $(INFO) .TARGETS: ${.TARGETS}
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_BUILD_ONLY: $(SUBDIRS_BUILD_ONLY)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_INST_ONLY: $(SUBDIRS_INST_ONLY)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_COMMON: $(SUBDIRS_COMMON)
. warning [${.MAKE.LEVEL}] $(INFO) TARGETS_BUILD: $(TARGETS_BUILD)
. warning [${.MAKE.LEVEL}] $(INFO) TARGETS_INST: $(TARGETS_INST)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIR_TARGETS: $(SUBDIR_TARGETS)
.endif


.PHONY: $(TARGETS_BUILD) $(TARGETS_INST)
$(TARGETS_BUILD) $(TARGETS_INST): $(PRE_TARGETS) $(SUBDIR_TARGETS) $(POST_TARGETS)

.PHONY: $(TARGETS_BUILD)
$(TARGETS_BUILD):
. ifdef SEPARATOR_1
	  @echo "$(SEPARATOR_1)"
. endif
	@for dir in $(SUBDIRS_BUILD_ONLY) $(SUBDIRS_COMMON); do \
	  if test -f $$dir/Makefile; then \
	    echo "Making ${.TARGET} in $$dir"; \
	    /bin/sh -c "$(MAKE) -C $$dir $(INSTALL_PATHS) ${.TARGET}"; \
	  fi \
	done


.PHONY: $(TARGETS_INST)
$(TARGETS_INST):
. ifdef SEPARATOR_1
	  @echo "$(SEPARATOR_1)"
. endif
	@for dir in $(SUBDIRS_INST_ONLY) $(SUBDIRS_COMMON); do \
	  if test -f $$dir/Makefile; then \
	    echo "Making ${.TARGET} in $$dir"; \
	    /bin/sh -c "$(MAKE) -C $$dir $(INSTALL_PATHS) ${.TARGET}"; \
	  fi \
	done


#.PHONY: probe ins rm test reload
#probe ins rm test reload:
#	$(Q)$(MAKE) $(QM) -C mbgclock $@


# .PHONY: install_svc
# install_svc: mbgsvcd_install

# .PHONY: uninstall_svc
# uninstall_svc: mbgsvcd_uninstall


# .PHONY: mbgsvcd_install mbgsvcd_uninstall
# mbgsvcd_install mbgsvcd_uninstall:
# 	$(Q)@$(MAKE) $(QM) -C mbgsvcd $@


# .PHONY: cleanreload
# cleanreload: clean all install reload

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) end
.endif

.else # ================================================================

# This section is evaluated if BASEDIR is already defined,
# i.e. if this makefile is included from a sub-level make.

INFO = 2nd

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) start, BASEDIR: $(BASEDIR)
.endif

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) MBGTOOLS_TARGET: $(MBGTOOLS_TARGET)
. warning [${.MAKE.LEVEL}] $(INFO) .TARGET: ${.TARGET}
. warning [${.MAKE.LEVEL}] $(INFO) .TARGETS: ${.TARGETS}
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_BUILD_ONLY: $(SUBDIRS_BUILD_ONLY)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_INST_ONLY: $(SUBDIRS_INST_ONLY)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_COMMON: $(SUBDIRS_COMMON)
. warning [${.MAKE.LEVEL}] $(INFO) TARGETS_BUILD: $(TARGETS_BUILD)
. warning [${.MAKE.LEVEL}] $(INFO) TARGETS_INST: $(TARGETS_INST)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIR_TARGETS: $(SUBDIR_TARGETS)
. warning [${.MAKE.LEVEL}] $(INFO) INSTALL_PATHS: $(INSTALL_PATHS)
.endif


.ifndef MBGLIB
  MBGLIB := $(BASEDIR)/mbglib
. ifdef DEBUG_MAKE
.   info [${.MAKE.LEVEL}] $(INFO) MBGLIB: $(MBGLIB)
. endif
.endif

# We could use this if we could use 'foreach':
## MBGLIB_DIRS += common
## MBGLIB_DIRS += bsd

# Without 'foreach', we use these:
MBGLIB_COMMON = ${MBGLIB}/common
MBGLIB_BSD = ${MBGLIB}/bsd

MBG_VERSION_FROM_GIT = $(shell git describe --tag --dirty 2>/dev/null)


INCLUDE_PATHS = -I.
INCLUDE_PATHS += -I$(BASEDIR)
# foreach doesn't seem to work under *BSD :-(
# INCLUDE_PATHS += $(foreach dir,$(MBGLIB_DIRS),-I$(MBGLIB)/$(dir))
INCLUDE_PATHS += -I$(MBGLIB_COMMON)
INCLUDE_PATHS += -I$(MBGLIB_BSD)

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) end
.endif

.ifndef KMOD  #===========================================================

# Not building a kernel module, but a user space program,
# a library, or a shared object library.

INFO = 2nd usr spc

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) start
.endif


.c.o:
	$(vecho) "    $(CC)      ${.IMPSRC}"
	$(Q)$(CC) $(CPPFLAGS) $(CFLAGS) -o ${.TARGET} -c ${.IMPSRC}

.cpp.o:
	$(vecho) "    $(CC)      ${.IMPSRC}"
	$(Q)$(CC) $(CPPFLAGS) $(CXXFLAGS) -o ${.TARGET} -c ${.IMPSRC}


.if !empty(MBG_VERSION_FROM_GIT)
  CPPFLAGS += -DMBG_VERSION_FROM_GIT=$(MBG_VERSION_FROM_GIT)
.endif


CPPFLAGS += -Wall
.if !empty(CC_SUPPORTS_WEXPANSION_TO_DEFINED)
  CPPFLAGS += -Wexpansion-to-defined
.endif
## CPPFLAGS += -Wextra
## CPPFLAGS += -Winline
## CPPFLAGS += -Wno-missing-field-initializers

.if $(QUIET) != 0
  CPPFLAGS += -Wno-unused-variable
  CPPFLAGS += -Wno-unused-function
.endif

## CPPFLAGS += -DSUPP_SERIAL=$(SUPP_SERIAL)
## CPPFLAGS += -DSUPP_PPS=$(SUPP_PPS)

CPPFLAGS += -DSUPP_MBGDEVIO=$(SUPP_MBGDEVIO)
CPPFLAGS += -DDEBUG_OPTIONS=$(DEBUG_OPTIONS)


## MACHINE_TYPE = $(shell uname -m)

#.ifneq (,$(findstring sparc,$(MACHINE_TYPE)))
  # Some gcc versions on SPARC produce faulty code when doing
  # loop optimizations, which results in bus errors at run time.
  # See e.g. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78807
  # So we limit the optimization level on SPARC.
#  OPT_FLAGS = -O1
#.else
  OPT_FLAGS = -O2
#.endif


.ifdef DEBUG
  CPPFLAGS += -DDEBUG=$(DEBUG)
  CPPFLAGS += -g2
  # CPPFLAGS += $(OPT_FLAGS)
.else
  CPPFLAGS += $(OPT_FLAGS)
.endif

## CPPFLAGS += -D_USE_SOCKET_IO=1

CPPFLAGS += $(INCLUDE_PATHS)

# This is *required* for the shared object libraries, but
# we use it in general to simplify the build procedure.
CPPFLAGS += -fPIC


# Additional C++-only compiler flags.
## CXXFLAGS += -Wno-deprecated


## LDFLAGS += $(foreach dir,$(SO_SUBDIRS),-L$(BASEDIR)/$(dir) )
# foreach doesn't seem to work under *BSD :-(


# The path to the static library we use to
# simplify the build procedure.
MBGTOOLS_STATIC_LIB_PATH = $(BASEDIR)/$(MBGTOOLS_STATIC_LIB_DIR)
MBGTOOLS_STATIC_LIB_FILE_PATH = $(MBGTOOLS_STATIC_LIB_PATH)/$(MBGTOOLS_STATIC_LIB_FILE)

.ifdef MBGTOOLS_STATIC_LIB_TARGET
  CURR_TARGET = $(MBGTOOLS_STATIC_LIB_TARGET)
  USE_STATIC_LIB = 0
.endif

LDLIBS += -lutil

# We also need these version numbers for install.
SO_MAJOR_VERSION = 1
SO_MINOR_VERSION = 0

.ifdef MBGTOOLS_SO_TARGET_BASENAME

. ifndef SO_POINT_RELEASE
    SO_POINT_RELEASE = 0
. endif

  SO_TARGET_NAME = libmbg$(MBGTOOLS_SO_TARGET_BASENAME)
  SO_TARGET_LIBNAME = $(SO_TARGET_NAME).so
  SO_TARGET_SONAME = $(SO_TARGET_LIBNAME).$(SO_MAJOR_VERSION)
  CURR_TARGET = $(SO_TARGET_SONAME).$(SO_MINOR_VERSION).$(SO_POINT_RELEASE)
  USE_STATIC_LIB = 1

  OBJS += mbg$(MBGTOOLS_SO_TARGET_BASENAME).o

  CLEANFILES += $(SO_TARGET_LIBNAME)

  CPPFLAGS += -c

  LDFLAGS += -shared
  LDFLAGS += -Wl,-soname,$(SO_TARGET_SONAME)

  LDLIBS += -lc

. ifndef LIBDIR
    LIBDIR := $(shell if [ -d /usr/lib64 ]; then echo /usr/lib64; else echo /usr/lib; fi )
. endif

.endif  # MBGTOOLS_SO_TARGET_BASENAME


.ifdef MBGTOOLS_TARGET
  CURR_TARGET = $(MBGTOOLS_TARGET)
  USE_STATIC_LIB = 1

  OBJS = $(CURR_TARGET).o
.endif  # MBGTOOLS_TARGET


.ifdef USE_STATIC_LIB
. if $(USE_STATIC_LIB) != 0
    LDFLAGS += -L$(MBGTOOLS_STATIC_LIB_PATH)
    LDLIBS += -l$(MBGTOOLS_STATIC_LIB_BASENAME)

    $(CURR_TARGET): $(MBGTOOLS_STATIC_LIB_FILE_PATH)
. endif  # $(USE_STATIC_LIB) != 0
.endif  # def USE_STATIC_LIB

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) MBGTOOLS_STATIC_LIB_FILE_PATH: $(MBGTOOLS_STATIC_LIB_FILE_PATH)
. warning [${.MAKE.LEVEL}] $(INFO) USE_STATIC_LIB: $(USE_STATIC_LIB)
. warning [${.MAKE.LEVEL}] $(INFO) CURR_TARGET: $(CURR_TARGET)
.endif


.PHONY: all
all: $(CURR_TARGET)

#### VPATH += $(foreach dir,$(MBGLIB_DIRS),$(MBGLIB)/$(dir))
VPATH = $(BASEDIR)/mbglib/common:$(BASEDIR)/mbglib/bsd

## USE_THREAD_API = 1


.ifdef USE_THREAD_API

  # Check whether thread affinity is supported by the installed pthread library.
  # Newer versions of glibc/pthread (at least glibc 2.5) supports this natively.
  # Older versions of glibc/pthread (e.g. glibc 2.3) may not support this natively
  # but may provide a NPTL (New Posix Thread Library) library located under separate
  # include and lib paths. We try to detect NPTL and add those paths to the search
  # paths only if USE_NTPL has been defined e.g. on the make command line.

  # Check whether pthread_getaffinity is supported by the standard pthread.h
  USE_THREAD_AFFINITY := $(shell grep -q pthread_getaffinity /usr/include/pthread.h && echo 1)

  # If it is not, check nptl/pthread.h
. ifndef USE_THREAD_AFFINITY
.   ifdef USE_NPTL
      USE_THREAD_AFFINITY := $(shell grep -q pthread_getaffinity /usr/include/nptl/pthread.h && echo 1)
.   endif

.   ifndef USE_THREAD_AFFINITY
      # If not found either, don't support thread affinity.
      USE_THREAD_AFFINITY=0
.   else
      # If supported via nptl, add the associated search paths.
      CPPFLAGS += -I/usr/include/nptl -L/usr/lib/nptl
.   endif
. endif

  # May want to use the result for our program.
  ## CPPFLAGS += -DUSE_THREAD_AFFINITY=$(USE_THREAD_AFFINITY)

  CPPFLAGS += -DMBGDEVIO_USE_THREAD_API=1

  LDLIBS += -pthread
.endif  # USE_THREAD_API


.ifdef DEBUG_MAKE
. warning ===============================================
.endif

.ifdef INST_TO_BIN
  INST_DIR = $(DESTDIR)$(bindir)
.elifdef INST_TO_SBIN
  INST_DIR = $(DESTDIR)$(sbindir)
.elifdef INST_TO_LIB
  INST_DIR = $(DESTDIR)$(libdir)
.elifdef INST_TO_INCLUDE
  INST_DIR = $(DESTDIR)$(includedir)/mbglib
.else
  INST_DIR = "---"
.endif

.ifdef DEBUG_MAKE
. warning ===============================================
.endif


.ifdef DEBUG_MAKE
. warning ---------------------------------------------------
. warning [${.MAKE.LEVEL}] $(INFO) INST_TO_BIN: $(INST_TO_BIN)
. warning [${.MAKE.LEVEL}] $(INFO) INST_TO_SBIN: $(INST_TO_SBIN)
. warning [${.MAKE.LEVEL}] $(INFO) INST_DIR: $(INST_DIR)
. warning ---------------------------------------------------
.endif

.ifdef DO_GUI_INSTALLATION
  EXT_INSTALL += gui_install
  EXT_UNINSTALL += gui_uninstall
.endif


$(MBGTOOLS_STATIC_LIB_FILE_PATH):
	/bin/sh -c "cd $(MBGTOOLS_STATIC_LIB_PATH) && $(MAKE) $(MBGTOOLS_STATIC_LIB_FILE)"

# Options for the archiver to build a static library
ARFLAGS := rcs
.if $(V) != 0
  # In verbose mode we also make the archiver verbose.
  ARFLAGS := $(ARFLAGS)v
.endif

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) MBGTOOLS_TARGET: $(MBGTOOLS_TARGET)
. warning [${.MAKE.LEVEL}] $(INFO) .TARGET: ${.TARGET}
. warning [${.MAKE.LEVEL}] $(INFO) .TARGETS: ${.TARGETS}
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_BUILD_ONLY: $(SUBDIRS_BUILD_ONLY)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_INST_ONLY: $(SUBDIRS_INST_ONLY)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIRS_COMMON: $(SUBDIRS_COMMON)
. warning [${.MAKE.LEVEL}] $(INFO) TARGETS_BUILD: $(TARGETS_BUILD)
. warning [${.MAKE.LEVEL}] $(INFO) TARGETS_INST: $(TARGETS_INST)
. warning [${.MAKE.LEVEL}] $(INFO) SUBDIR_TARGETS: $(SUBDIR_TARGETS)
. warning [${.MAKE.LEVEL}] $(INFO) CPPFLAGS: $(CPPFLAGS)
. warning [${.MAKE.LEVEL}] $(INFO) EXTRA_CFLAGS: $(EXTRA_CFLAGS)
.endif


$(CURR_TARGET): $(OBJS)
.ifdef MBGTOOLS_STATIC_LIB_TARGET
	$(vecho) "    $(AR)       $@"
	$(Q)$(AR) $(ARFLAGS) $@ $(OBJS)
.else
	$(vecho) "    Linking $@"
	$(Q)$(CC) -o $@ $(LDFLAGS) $(OBJS) $(LDLIBS)

. ifdef SO_TARGET_LIBNAME
	ln -sf $(CURR_TARGET) $(SO_TARGET_LIBNAME)
. endif
.endif  # MBGTOOLS_STATIC_LIB_TARGET


.PHONY: install
install: $(EXT_INSTALL)
.ifdef XXX #.ifneq ($(UID),0)
	$(call make_as_root, $@)
.else  # UID
. ifdef INCLUDE_FILES  # include files
	  mkdir -p $(INST_DIR)
	  for incfile in $(INCLUDE_FILES); do \
	      install -m 644 $(BASEDIR)/mbglib/common/$$incfile $(INST_DIR)/; \
	  done;
	  for basename in $(SO_BASENAMES); do \
	      pushd $(DESTDIR)$(libdir); \
	      ln -sf libmbg$$basename.so.$(SO_MAJOR_VERSION) libmbg$$basename.so; \
	      popd; \
	  done;
. else  # usual installation
.   ifdef STAGED_BUILD
	      mkdir -p $(INST_DIR)
.   endif
	  install -s $(MBGTOOLS_TARGET) $(INST_DIR)

.   ifndef STAGED_BUILD
.     ifdef INST_TO_LIB
	          /sbin/ldconfig
.     endif  # INST_TO_LIB
.   endif  # STAGED_BUILD
. endif  # !INCLUDE_FILES
.endif  # UID


.PHONY: uninstall
uninstall: $(EXT_UNINSTALL)
.ifdef INCLUDE_FILES #remove include files and
	$(Q)rm -rf $(INST_DIR)
. ifndef STAGED_BUILD #remove symbolic links
	    for basename in $(SO_BASENAMES); do \
	        $(Q)rm -f $(libdir)/libmbg$$basename.so; \
	    done;
. endif  # STAGED_BUILD
.else  # !INCLUDE_FILES
. ifdef XXX #.ifneq ($(UID),0)
	  $(call make_as_root, $@)
. else  # UID
	  $(Q)rm -f $(INST_DIR)/$(MBGTOOLS_TARGET)
.   ifndef STAGED_BUILD
.     ifdef INST_TO_LIB
	          /sbin/ldconfig
.     endif  # INST_TO_LIB
.   endif  # STAGED_BUILD
. endif  # UID
.endif  # INCLUDE_FILES


.PHONY: gui_install
gui_install:
.ifdef XXX #.ifneq ($(UID),0)
	$(call make_as_root, $@)
.else  # UID
	mkdir -p $(DESTDIR)$(prefix)/share/$(MBGTOOLS_TARGET)
	cp $(MBGTOOLS_TARGET).png $(DESTDIR)$(prefix)/share/$(MBGTOOLS_TARGET)/$(MBGTOOLS_TARGET).png
	mkdir -p $(DESTDIR)$(prefix)/share/applications
	cp $(MBGTOOLS_TARGET).desktop $(DESTDIR)$(prefix)/share/applications/$(MBGTOOLS_TARGET).desktop
.endif  # UID


.PHONY: gui_uninstall
gui_uninstall:
.ifdef XXX #.ifneq ($(UID),0)
	$(call make_as_root, $@)
.else  # UID
	$(Q)rm -rf $(DESTDIR)$(prefix)/share/$(MBGTOOLS_TARGET)
	$(Q)rm -f $(DESTDIR)$(prefix)/share/applications/$(MBGTOOLS_TARGET).desktop
.endif  # UID


CLEANFILES += *.o
CLEANFILES += *~
CLEANFILES += core
CLEANFILES += $(CURR_TARGET)

.PHONY: clean
clean:
.ifdef CLEANFILES
	$(Q)rm -f $(CLEANFILES)
.endif
.ifdef CLEANDIRS
	$(Q)rm -rf $(CLEANDIRS)
.endif

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) usr spc end
.endif

.else  # ===== Building a kernel module =============================================

INFO = 2nd krn spc

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) start
.endif

# Conditionals for any kernel driver.

.ifdef MBG_PRI_64_PREFIX_L
  CPPFLAGS += -DMBG_PRI_64_PREFIX_L
.else
.ifdef MBG_PRI_64_PREFIX_LL
    CPPFLAGS += -DMBG_PRI_64_PREFIX_LL
.endif
.endif


# Handle global debug options that are useful
# for any kernel module.
# Driver-specific debug options are handled
# in the appropriate sub-makefile.

.ifdef DEBUG_MSG_SLEEP
  CPPFLAGS += -DDEBUG_MSG_SLEEP=$(DEBUG_MSG_SLEEP)
  MUST_DEBUG_DRVR = 1
.endif

.ifdef MUST_DEBUG_DRVR
. ifndef DEBUG
    DEBUG = 1
. endif
.endif

.ifdef DEBUG
  CPPFLAGS += -DDEBUG=$(DEBUG)
.endif


# Driver files to be removed on clean.

CLEANFILES = *~
CLEANFILES += machine
CLEANFILES += *.o
CLEANFILES += .depend.*.o
CLEANFILES += @

.include <bsd.kmod.mk>

.PHONY: uninstall
uninstall:
	rm -f /boot/modules/mbgclock.ko

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) end
.endif

.endif  # ===== Building a kernel module ============================================

.ifdef DEBUG_MAKE
. warning [${.MAKE.LEVEL}] $(INFO) bottom
.endif
# common targets:

.PHONY: distclean
distclean: clean

.endif
