#                                                     -*-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 'uspace' 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 ;)

BUILDSYS = @BUILD_SYS@

KERNELDIR := @KERNELDIR@
CC := @CC@
RTAI = @RTAI@
RTFLAGS = $(filter-out -ffast-math,@RTFLAGS@ @EXT_RTFLAGS@) -fno-fast-math $(call cc-option,-mieee-fp) -fno-unsafe-math-optimizations
RTFLAGS := -Os -g -I. -I@RTDIR@/include $(RTFLAGS) -DRTAPI -D_GNU_SOURCE -Drealtime
ifneq ($(KERNELRELEASE),)
ifeq ($(RTARCH):$(RTAI):$(filter $(RTFLAGS),-msse),x86_64:3:)
EXTRA_CFLAGS += -msse
endif
endif
EXTRA_CFLAGS += -fno-builtin-sin -fno-builtin-cos -fno-builtin-sincos
EMC2_HOME=@EMC2_HOME@
RUN_IN_PLACE=@RUN_IN_PLACE@
ifeq ($(RUN_IN_PLACE),yes)
EXTRA_CFLAGS := $(RTFLAGS) -D__MODULE__ -I$(EMC2_HOME)/include
RTLIBDIR := @EMC2_HOME@/rtlib
LIBDIR := @EMC2_HOME@/lib
else
prefix := @prefix@
EXTRA_CFLAGS := $(RTFLAGS) -D__MODULE__ -I@includedir@/linuxcnc
RTLIBDIR := @EMC2_RTLIB_DIR@
LIBDIR := @libdir@
endif
EXTRA_CFLAGS += -Wframe-larger-than=2560

ifeq ($(BUILDSYS),kbuild)
modules:
	$(MAKE) KBUILD_EXTRA_SYMBOLS=$(RTLIBDIR)/Module.symvers -C $(KERNELDIR) SUBDIRS=`pwd` CC=$(CC) V=0 modules

clean:
	rm *.ko *.mod.c *.o

install:
	cp $(patsubst %.o,%.ko,$(obj-m)) $(DESTDIR)$(RTLIBDIR)/
endif

ifeq ($(BUILDSYS),uspace)
EXTRA_CFLAGS += -DSIM -fPIC
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 $@
	$(Q)ld -d -r -o $*.tmp $^
	$(Q)objcopy -j .rtapi_export -O binary $*.tmp $*.sym
	$(Q)(echo '{ global : '; tr -s '\0' < $*.sym | xargs -r0 printf '%s;\n' | grep .; echo 'local : * ; };') > $*.ver
	$(Q)$(CC) -shared -Bsymbolic $(LDFLAGS) -Wl,--version-script,$*.ver -o $@ $^ -lm
endif

ifeq ($(BUILDSYS),normal)
$(error Makefile.modinc is only suitable for 'kbuild' kernels and 'uspace' systems)
endif

