#####################################################################
# This file is part of the cpplibs suite.
#
# Copyright (C) 2001 Topi Mäenpää
# All rights reserved.
#
# This program is free software. You can redistribute and/or modify
# it under the terms of the free software licence found in the
# accompanying file "COPYING". The licence terms must always be
# redistributed with this source file. The above copyright notice
# must be reproduced in all modified and unmodified copies of this
# source file.
#
# $Revision: 1.2 $
#####################################################################

# The name of your system?
# You must have a file named base.mk file in platform/yourplatform.
SYSTEM					= $(shell uname -s)

ORBNAME					?= orbit

ifeq ($(DEBUG),yes)
  DEBUGFLAGS		= -g -DDEBUG
else
  DEBUGFLAGS		=
endif

# Include system-dependent configuration directives
include $(BASE)/platform/$(SYSTEM)/base.mk

OPTIMIZATION    = -O2
COMPILERFLAGS   = $(GNU_SOURCE) $(PTHREADFLAGS) -Wall $(DEBUGFLAGS) $(OPTIMIZATION)
INCLUDEPATH     += -I.

ifeq ($(CCSOURCES),)
  CCSOURCES     := $(wildcard *.cc *.cpp *.C})
endif
CCMODULES       = $(addsuffix .o,$(basename $(CCSOURCES)))
CCDEPENDS       = $(CCMODULES:.o=.d)

ifeq ($(CSOURCES),)
  CSOURCES      := $(wildcard *.c)
endif
CMODULES        = $(CSOURCES:.c=.o)
CDEPENDS        = $(CSOURCES:.c=.d)

ifeq ($(IDLSOURCES),)
  IDLSOURCES    := $(wildcard *.idl)
endif
ifneq ($(IDLSOURCES),)
  NEEDIDL       = yes
endif

ifeq ($(NEEDIDL),yes)
  COMPILERFLAGS += $(IDLCPPFLAGS)
  LINKERFLAGS   += $(IDLLINKFLAGS)
  # Include ORB configuration
  include $(BASE)/platform/$(SYSTEM)/orbs/$(ORBNAME).mk
endif

MODULES         = $(CCMODULES) $(CMODULES) $(IDLMODULES)
DEPENDS         = $(CCDEPENDS) $(CDEPENDS)

ifneq ($(MODULEDIRS),)
  SUBSRC        = $(foreach i,c cc cpp C,$(addsuffix /*.$(i),$(MODULEDIRS)))
  SUBMODULES    = $(addsuffix .o,$(basename $(wildcard $(SUBSRC))))
endif

CC              = gcc
CXX             = g++

ifeq ($(CPPFLAGS),)
  CPPFLAGS      = $(INCLUDEPATH) $(COMPILERFLAGS)
endif

ifeq ($(LDFLAGS),)
  LDFLAGS       = $(LINKERFLAGS) $(LIBRARYPATH) $(LIBRARIES)
endif

ifeq ($origin(LDFLAGS),default) #User has not set LDFLAGS
  LDFLAGS       = $(LINKERFLAGS) $(LIBRARYPATH) $(LIBRARIES)
endif

ifeq ($(STARTFILES),no)
  LDFLAGS				+= -nostartfiles
endif

ifeq ($(suffix $(PROGRAM)),.so) #Shared libraries need special flags
	SHAREDLIB			= yes
endif

ifeq ($(SHAREDLIB),yes)
# If user has not set a version number for the library, use 1.0.0
  SO_VERSION		?= 1.0.0
  MAJOR_VERSION := $(basename $(basename $(SO_VERSION)))
  CPPFLAGS			+= -fPIC -DPIC
  SOFLAGS				:= -shared -Wl,$(SONAMEFLAG),$(PROGRAM).$(MAJOR_VERSION)
ifneq ($(PROGRAM),)
#Shared libs always have the install target
  INSTALLTARGET	= yes
  BASENAME			:= $(PROGRAM)
  PROGRAM			  := $(PROGRAM).$(SO_VERSION)
endif
endif

ifneq ($(INSTALLDIR),)
  INSTALLTARGET	= yes
else
  INSTALLDIR		= .
endif

ifeq ($(CCSOURCES),) # No C++ sources -> use C compiler
  COMPILERFLAGS += $(CFLAGS)
  LDFLAGS				+= $(CLDFLAGS)
  COMPILER			= $(CC)
else
  COMPILERFLAGS += $(CXXFLAGS)
  LDFLAGS				+= $(CXXLDFLAGS)
  COMPILER			= $(CXX)
endif

ifneq ($(MAKEMODULES),) # There are external modules that should be loaded
	include $(addprefix $(BASE)/platform/$(SYSTEM)/modules/,$(addsuffix .mk,$(MAKEMODULES)))
endif

# compile C
%.o : %.c
	$(CC) -c $(CPPFLAGS) $< -o $@
# compile C++
%.o : %.cc
	$(CXX) -c $(CPPFLAGS) $< -o $@
# crate list of dependencies for C++ sources
%.d: %.cc
	$(SHELL) -ec '$(CPP) -MM $(CPPFLAGS) $< \
								| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
								[ -s $@ ] || rm -f $@'
# crate list of dependencies for C sources
%.d: %.c
	$(SHELL) -ec '$(CPP) -MM $(CPPFLAGS) $< \
								| sed '\''s/\($*\)\.o[ :]*/\1.o $@ : /g'\'' > $@; \
								[ -s $@ ] || rm -f $@'
# make a C++ idl skeleton (omniORB-style)
%SK.cc : %.idl
	$(IDLCOMPILER) $(IDLCOMPILERFLAGS) $<
# make a C idl skeleton (orbit-style)
%-skels.c %-stubs.c %-common.c : %.idl
	$(IDLCOMPILER) $(IDLCOMPILERFLAGS) $<

ifneq ($(PROGRAM),) # Program name specified -> compile and link/archive

$(PROGRAM) : Makefile $(SUBDIRS) $(MODULES)
ifeq ($(suffix $(PROGRAM)),.a) # Create a static archive
	$(AR) $(ARFLAGS) $(PROGRAM) $(MODULES) $(SUBMODULES) $(OTHERMODULES)
else # Create a shared object file or link an executable
	$(COMPILER) $(MODULES) $(SUBMODULES) $(OTHERMODULES) $(LDFLAGS) $(SOFLAGS) -o $(PROGRAM)
endif

endif

# Compile target. Just compiles. Does not link or build a library.
.PHONY : compile
compile : Makefile $(SUBDIRS) $(MODULES);

# Install target needed
ifeq ($(INSTALLTARGET),yes)

.PHONY : install
install : $(PROGRAM)
	$(foreach i,$(SUBDIRS),$(MAKE) -C $(i) install;)
ifneq ($(INSTALLDIR),.)
	cp $(PROGRAM) $(INSTALLDIR)
endif
# Soft links for shared libraries
ifeq ($(SHAREDLIB),yes)
	-ln -s $(INSTALLDIR)/$(PROGRAM) $(INSTALLDIR)/$(BASENAME).$(MAJOR_VERSION)
	-ln -s $(INSTALLDIR)/$(BASENAME).$(MAJOR_VERSION) $(INSTALLDIR)/$(BASENAME)
endif

else # no install target needed -> try subdirs

.PHONY : install
install :
	$(foreach i,$(SUBDIRS),$(MAKE) -C $(i) install;)

endif

# IDL to C/C++
.PHONY : idl
idl : $(IDLMODULES);

# Recurse subdirectories
.PHONY : $(SUBDIRS)
$(SUBDIRS) :
	$(MAKE) -C $@

# Clean
.PHONY : clean
clean :
	-rm -f $(PROGRAM) $(MODULES) $(IDLSKELETONS) $(IDLHEADERS) $(DEPENDS) *~
	$(foreach i,$(SUBDIRS),$(MAKE) -C $(i) clean;)

-include $(DEPENDS)
