# -*-makefile-gmake-*-
# Makefile.modinc includes rules for building HAL realtime modules outside
# the LinuxCNC source tree.  It has three useful targets:
#
# modules
#   Actually build the modules
#
# clean
#   Cleans up files made by 'modules'
#
# install
#   Installs the modules

# An example Makefile using Makefile.modinc to build one kernel module from a
# single source file would read:
# 
# obj-m += example.o
# include .../Makefile.modinc

# An example Makefile using Makefile.modinc to build one kernel module from
# several source files would read:
# 
# obj-m += complex.o
# complex-objs := complex1.o complex2.o complex_main.o
# include .../Makefile.modinc

# Currently this Makefile is only suitable for 'kbuild' and 'sim' systems, but
# there is no technical reason it cannot be extended to pre-kbuild systems.

# When there is a single module and it consists of a single source file, an
# easier way to build modules is to invoke 'comp':
#  comp --compile example.c
# or
#  comp --install example.c

ifeq ("$(origin V)", "command line")
  BUILD_VERBOSE = $(V)
endif
ifndef BUILD_VERBOSE
  BUILD_VERBOSE = 0
endif

ifeq ($(BUILD_VERBOSE),1)
  Q =
else
  Q = @
endif

ifeq "$(findstring s,$(MAKEFLAGS))" ""
ECHO=@echo
VECHO=echo
else
ECHO=@true
VECHO=true
endif


cc-option = $(shell if $(CC) $(CFLAGS) $(1) -S -o /dev/null -xc /dev/null \
             > /dev/null 2>&1; then echo "$(1)"; else echo "$(2)"; fi ;)

# Used in RTLIB_DIR path
KERNEL_VERS = $(shell uname -r)

# FIXME:  need better way to find correct KERNELDIR
KERNELDIR = /lib/modules/$(KERNEL_VERS)/build

RUN_IN_PLACE=@RUN_IN_PLACE@

# Use same settings as everybody else
ifeq ($(RUN_IN_PLACE),yes)
include @EMC2_HOME@/src/Makefile.inc
else
include @EMC2_HOME@/share/linuxcnc/Makefile.inc
endif

EXTRA_CFLAGS := $(RTFLAGS) $(EXTRA_RTFLAGS) \
	-D__MODULE__ \
	$(call cc-option,-mieee-fp) \
	$(KERNEL_MATH_CFLAGS)

ifeq ($(RUN_IN_PLACE),yes)
EXTRA_CFLAGS += -I$(EMC2_HOME)/include
RTLIBDIR := $(EMC2_HOME)/rtlib/$(RTDIR_EXT)
LIBDIR := $(EMC2_HOME)/lib
else
EXTRA_CFLAGS += -I$(includedir)/linuxcnc
RTLIBDIR := $(EMC2_RTLIB_DIR)
LIBDIR := $(libdir)
endif

EXTRA_CFLAGS +=  -fPIC -g -funwind-tables
allmodules = $(patsubst %.o,%.so,$(obj-m))
modules: $(allmodules)

install: modules
	cp $(allmodules) $(DESTDIR)$(RTLIBDIR)/

getobjs = $(if $(filter undefined, $(origin $(1)-objs)), $(1).o, $($(1)-objs))
getsrcs = $(patsubst %.o,%.c,$(call getobjs,$(1)))

maks := $(patsubst %.o,.%.modinc,$(obj-m))
$(foreach mod,$(patsubst %.o,%,$(obj-m)),\
	$(eval $(mod).so: $(call getobjs,$(mod))))
%.o: %.c
	$(ECHO) Compiling realtime $<
	$(Q)$(CC) -o $@ $(EXTRA_CFLAGS) -c $<

.PHONY: %.so
%.so:
	$(ECHO) Linking $(notdir $@)
	$(Q)$(LD) -d -r -o $*.tmp $^
	$(Q)objcopy -j .rtapi_export -O binary $*.tmp $*.exported

	$(Q)(echo '{ global : '; tr -s '\0' <$*.exported | xargs -r0 printf '%s;\n' | grep .; echo 'local : * ; };') > $*.ver
	$(Q)$(CC) -shared -Bsymbolic $(LDFLAGS) -Wl,--version-script,$*.ver -o $@ $^ $(EXTRA_LDFLAGS)
	$(Q)ld -d -r -o $*.tmp $^
