# Generic Makefile for a C or C++ Webots controller
# to be used with GNU make
# will not work with Sun make
#
# Author:   Olivier.Michel@cyberbotics.com
#           Edmund Ronald <eronald@polytechnique.fr>
# Date:     October 12th, 1999.
#
# Revision: Sergei.Poskriakov@users.ch
# Date:     September 9, 2004
#
# Revision: yvan.bourquin@epfl.ch
# Purpose:  Enabling compilation from the Webots IDE
# Date:     January 13, 2005
#-----------------------------------------------------------------------------
#
# The Makefile in the controller directory is very easy to write:
#
# - for a simple controller (a single source file), just include this line:
# include ../Makefile.include
#
# - for a controller with several C source files, the Makefile should be:
# C_SOURCES = my_controller.c my_clever_algo.c my_gui.c
# include ../Makefile.include
#
# - for a controller with several C++ source files, the Makefile should be:
# CC_SOURCES = my_controller.cc my_clever_algo.cc my_gui.cc
# include ../Makefile.include
#
#  or:
# CPP_SOURCES = my_controller.cpp my_clever_algo.cpp my_gui.cpp
# include ../Makefile.include
#
#-----------------------------------------------------------------------------
#
# - if your C/C++ controller depends on source includes (bad practice but...),
#  simply prepend the following line to the Makefile so that the corresponding
#  targets get recompiled when included files are modified:
# SOURCE_INCLUDES = my_utils.h my_other_stuff.cpp
#
# - if your controller needs additional libraries,
#  simply prepend the following line to the Makefile:
# LIBRARIES=-L/path/to/my/library -lmy_library -lmy_other_library
#
# - if some special CFLAGS need to be passed, for example to find include
#  files, or set optimization level, simply prepend the following line:
# CFLAGS=-O3 -I/my_library_path/include
#
# - finally, on Windows, if you want that your controller opens up a DOS
#  console to display the printf output, simply add the following line:
# DOS_CONSOLE=1


# default commands definitions

NULL_DEVICE=/dev/null
PWD_COMMAND=pwd
RM_COMMAND=rm -f
LS_COMMAND=ls

# find out whether we are in a Windows Command Prompt

ifeq ($(OS),Windows_NT)
ifneq ($(TERM),msys)
OSTYPE=windowsprompt
endif
endif

ifndef OSTYPE
OSTYPE=$(shell uname)
endif

ifeq ($(OSTYPE),Linux)
OSTYPE=linux
endif

ifeq ($(OSTYPE),linux-gnu)
OSTYPE=linux
endif

ifeq ($(OSTYPE),)
OSTYPE=windows
endif

ifeq ($(OSTYPE),windowsprompt)

IDE_EXTENSION=.new

OSTYPE=windows

NULL_DEVICE=nul
PWD_COMMAND=cd
RM_COMMAND=del /Q
LS_COMMAND=dir /B

endif

ifeq ($(OSTYPE),msys)
OSTYPE=windows
endif

ifneq ($(findstring MINGW,$(OSTYPE)),)
OSTYPE=windows
endif

ifneq ($(findstring CYGWIN,$(OSTYPE)),)
OSTYPE=windows
endif

ifeq ($(OSTYPE),darwin)
OSTYPE=Darwin
endif

ifndef DOS_CONSOLE
WINDOWS_APP=-mwindows
endif

ifeq ($(OSTYPE),windows)
PLATFORM_CFLAG=-DWIN32 $(WINDOWS_APP)
endif

ifeq ($(OSTYPE),linux)
PLATFORM_CFLAG=-DLINUX
endif

ifeq ($(OSTYPE),Darwin)
PLATFORM_CFLAG=-DMACOS
endif

ifndef WEBOTS_HOME
#assuming we are compiling controller in the installation directory
export WEBOTS_HOME=../..
else
WEBOTS_HOME:=$(WEBOTS_HOME)
endif

# this is useful to find -lController
export LD_LIBRARY_PATH="$(WEBOTS_HOME)/lib"

# compute the current directory, the CURDIR variable may be already set
ifndef $(CURDIR)
CURDIR=$(shell $(PWD_COMMAND))
endif

# compute the name of the controller from its directory (i.e. braiten)
BAD_NAME = $(basename $(notdir $(CURDIR)))

# this is a hack to work around a problem with spaces in dir names
NAME = $(word $(words $(BAD_NAME)),$(BAD_NAME))

# if the source files were not explicitly defined, we assume that
# there is only one C or Java source file

ifndef C_SOURCES
C_SOURCES   =$(shell $(LS_COMMAND) $(NAME).c 2> $(NULL_DEVICE))
endif
ifndef CPP_SOURCES
CPP_SOURCES =$(shell $(LS_COMMAND) $(NAME).cpp 2> $(NULL_DEVICE))
endif
ifndef CC_SOURCES
CC_SOURCES  =$(shell $(LS_COMMAND) $(NAME).cc 2> $(NULL_DEVICE))
endif
ifndef JAVA_SOURCES
JAVA_SOURCES=$(shell $(LS_COMMAND) $(NAME).java 2> $(NULL_DEVICE))
endif
ifndef SOURCE_INCLUDES
SOURCE_INCLUDES=
endif

INCLUDE=-I"$(WEBOTS_HOME)/include"

ifeq ($(OSTYPE),windows)
EXE_EXTENSION=.exe
else
EXE_EXTENSION=
endif

# the objects files result from the C or C++ sources
C_OBJECTS   = $(C_SOURCES:.c=.o)
CPP_OBJECTS = $(CPP_SOURCES:.cpp=.o)
CC_OBJECTS  = $(CC_SOURCES:.cc=.o)
RC_OBJECTS  = $(RC_SOURCES:.rc=.o)

# set the class files resulting from the java sources
CLASSES     = $(JAVA_SOURCES:.java=.class)

# set the controller library needed
CTR_LIB=Controller

# set CC to your favorit C or C++ compiler
ifneq ($(C_SOURCES),)
CC=gcc
else
ifneq ($(CPP_SOURCES),)
CC=g++
else
ifneq ($(CC_SOURCES),)
CC=g++
else
CC=unknown_compiler
endif
endif
endif

ifeq ($(OSTYPE),windows)
PLATFORM_LIBS=-lmingw32 $(WINDOWS_APP)
else
PLATFORM_LIBS=
endif

LIBRARY=-L"$(WEBOTS_HOME)/lib" -l$(CTR_LIB) $(PLATFORM_LIBS) $(LIBRARIES)

ifneq ($(WEBOTS_DEMO_CODE),)
CC_OPTS_DEMO=-DWEBOTS_DEMO_CODE=$(WEBOTS_DEMO_CODE)
endif

# set the C compiler options
CC_OPTS=-c $(INCLUDE) $(CC_OPTS_DEMO) -Wall $(CFLAGS) $(CFLAGS_WIN) $(PLATFORM_CFLAG)

# set JAVAC to your favorit Java compiler
JAVAC=javac

# set the Java compiler options

ifeq ($(OSTYPE),windows)
JAVAC_OPTS=-classpath "$(WEBOTS_HOME)/lib/Controller.jar;."
else
JAVAC_OPTS=-classpath "$(WEBOTS_HOME)/lib/Controller.jar":.
endif

ifneq ($(JAVA_SOURCES),)
TARGET=$(CLASSES)
$(NAME).jar: $(CLASSES)
	jar cf $@ $<
else
TARGET=$(NAME)$(EXE_EXTENSION)$(IDE_EXTENSION)
endif


all: $(TARGET)


# rules to make the executable file from C/C++ objects
$(NAME)$(EXE_EXTENSION)$(IDE_EXTENSION): $(C_OBJECTS) $(CC_OBJECTS) $(CPP_OBJECTS) $(RC_OBJECTS)
	$(CC) -o $(NAME)$(EXE_EXTENSION)$(IDE_EXTENSION) $(C_OBJECTS) $(CC_OBJECTS) $(CPP_OBJECTS) $(RC_OBJECTS) $(LIBRARY)
	$(EXTRA_FINAL_CMD)

# rule to make the .class files
%.class:%.java
	$(JAVAC) $(JAVAC_OPTS) $<

# rule to make automatic dependencies
# adapted from the GNU make info file
%.d:%.c
	$(CC) $(INCLUDE) -MM $< -MT "$(@:.d=.o) $@ " > $@

-include $(C_SOURCES:.c=.d) $(CC_SOURCES:.cc=.d) $(CPP_SOURCES:.cpp=.d)

# generic rule to make the object files
%.o:%.c $(SOURCE_INCLUDES)
	$(CC) $(CC_OPTS) $< -o $@

%.o:%.cpp $(SOURCE_INCLUDES)
	$(CC) $(CC_OPTS) $< -o $@

%.o:%.cc $(SOURCE_INCLUDES)
	$(CC) $(CC_OPTS) $< -o $@

%.o:%.rc
	windres -i $< -o $@ --include-dir ../../../../software/wxWindows/include --define __WIN32__ --define __WIN95__ --define __GNUWIN32__

# how to clean up the directory
clean:
	@-$(RM_COMMAND) *.o *.class *.jar *.d *~ $(NAME)$(EXE_EXTENSION)$(IDE_EXTENSION) core 2> $(NULL_DEVICE)

# show the ostype recognized by the Makefile
ostype:
	@echo OSTYPE=$(OSTYPE)
        
test:
	@echo TEST=$(TEST)
