# Copyright 1996-2022 Cyberbotics Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

### Generic Makefile.include for Webots controllers, physics plugins, robot
### window libraries, remote control libraries and other libraries
### to be used with GNU make
###
### Platforms: Windows, macOS, Linux
### Languages: C, C++
###
### Authors: Olivier Michel, Yvan Bourquin, Fabien Rohrer
###          Edmund Ronald, Sergei Poskriakov
###
###-----------------------------------------------------------------------------
###
### This file is meant to be included from the Makefile files located in the
### Webots projects subdirectories. It is possible to set a number of variables
### to customize the build process, i.e., add source files, compilation flags,
### include paths, libraries, etc. These variables should be set in your local
### Makefile just before including this Makefile.include. This Makefile.include
### should never be modified.
###
### Here is a description of the variables you may set in your local Makefile:
###
### ---- C Sources ----
### if your program uses several C source files:
### C_SOURCES = my_plugin.c my_clever_algo.c my_graphics.c
###
### ---- C++ Sources ----
### if your program uses several C++ source files:
### CXX_SOURCES = my_plugin.cc my_clever_algo.cpp my_graphics.c++
###
### ---- Compilation options ----
### if special compilation flags are necessary:
### CFLAGS = -Wno-unused-result
###
### ---- Linked libraries ----
### if your program needs additional libraries:
### INCLUDE = -I"/my_library_path/include"
### LIBRARIES = -L"/path/to/my/library" -lmy_library -lmy_other_library
###
### ---- Linking options ----
### if special linking flags are needed:
### LFLAGS = -s
###
### ---- Webots included libraries ----
### if you want to use the Webots C API in your C++ controller program:
### USE_C_API = true
###
### ---- Debug mode ----
### if you want to display the gcc command line for compilation and link, as
### well as the rm command details used for cleaning:
### VERBOSE = 1
###
###-----------------------------------------------------------------------------


ifdef WEBOTS_HOME
 # Check if WEBOTS_HOME contains a trailing path separator and display a warning in this case.
 PROTECTED_WEBOTS_HOME := $(WEBOTS_HOME:/=)
 PROTECTED_WEBOTS_HOME := $(PROTECTED_WEBOTS_HOME:\=)
 ifneq ($(WEBOTS_HOME),$(PROTECTED_WEBOTS_HOME))
  WEBOTS_HOME := $(PROTECTED_WEBOTS_HOME)
  $(warning Please remove the trailing path separator from WEBOTS_HOME.)
 endif
else
 # WEBOTS_HOME is a sine qua non condition to run this Makefile.
 $(error The WEBOTS_HOME environment variable is not defined.)
endif

# WEBOTS_HOME_PATH is commonly defined in the caller Makefile
# but as it is not necessary on non-windows OS, it seems safer to reconstruct it there if required
null :=
space := $(null) $(null)
WEBOTS_HOME_PATH ?= $(subst $(space),\ ,$(strip $(subst \,/,$(WEBOTS_HOME))))

###-----------------------------------------------------------------------------
### OS determination and OS specific commands
###-----------------------------------------------------------------------------

include $(WEBOTS_HOME_PATH)/resources/Makefile.os.include

###-----------------------------------------------------------------------------
### Functions
###-----------------------------------------------------------------------------

ifeq ($(OSTYPE),darwin)

 # Retrieve the relative path of a path according to some base path.
 # cf. http://stackoverflow.com/a/3344050/2210777
 #   @param 1 Base path (e.g. "/Users/fabien/develop/webots")
 #   @param 2 Path  (e.g. "/Users/fabien/develop/webots/projects/robots/e-puck/controllers/e-puck")
 #   @return The relative path (e.g. "../../../../../")
 computeRelativePath = $(shell \
   basedir=$(1); \
   currentdir=$(2); \
   if [[ $$currentdir =~ ^$$basedir ]] ; \
   then \
     up=; \
     while ! expr $$basedir : $$currentdir >/dev/null; do \
       up=../$$up; \
       currentdir=`dirname $$currentdir`; \
     done; \
     relative=$$up`expr $$basedir : $$currentdir'/*\(.*\)'`; \
     echo $$relative; \
   else \
     echo $$currentdir; \
   fi; \
 )

ifndef NO_FAT_BINARY
FAT_BINARY = 1
endif

endif

###-----------------------------------------------------------------------------
### Paths
###-----------------------------------------------------------------------------

# compiler
ifeq ($(CC),cc)
 CC = gcc
endif

# compute the current directory, the CURDIR variable may be already set
ifndef CURDIR
 CURDIR = $(shell pwd)
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))

# compute BUILD_TYPE (either ode, controllers, physics, robot_windows, remote_controls or libraries)
SPLIT_PATH = $(subst /, ,$(dir $(CURDIR)))
BUILD_TYPE = $(word $(words $(SPLIT_PATH)),$(SPLIT_PATH))

ifdef VERBOSE
  SILENT =
else
  SILENT = @
endif

# backward compatibility
ifdef CC_SOURCES
 $(warning Please use CXX_SOURCES instead of CC_SOURCES to define the C++ sources)
endif
ifdef CPP_SOURCES
 $(warning Please use CXX_SOURCES instead of CPP_SOURCES to define the C++ sources)
endif
CXX_SOURCES += $(CC_SOURCES) $(CPP_SOURCES)

# if the source files were not explicitly defined, we try to find
# the *.c, *.cc, *.c++, or *.cpp source files.
ifeq ($(C_SOURCES),)
 ifeq ($(strip $(CXX_SOURCES)),)
  C_SOURCES = $(shell ls $(NAME).c 2> /dev/null)
  CXX_SOURCES = $(shell ls $(NAME).cpp 2> /dev/null)
  ifeq ($(CXX_SOURCES),)
   CXX_SOURCES = $(shell ls $(NAME).cc 2> /dev/null)
   ifeq ($(CXX_SOURCES),)
    CXX_SOURCES = $(shell ls $(NAME).c++ 2> /dev/null)
   endif
  endif
 endif
endif

ifneq ($(strip $(CXX_SOURCES)),)
 USE_CXX = true
endif
ifneq ($(strip $(C_SOURCES)),)
 USE_C = true
endif

# the objects files result from the C or C++ sources
SOURCES_DIRECTORIES = $(sort $(dir $(C_SOURCES) $(CXX_SOURCES)))
OBJECTS_LIST = $(patsubst %.c,%.o, $(patsubst %.cc,%.o, $(patsubst %.c++,%.o, $(patsubst %.cpp,%.o, $(notdir $(C_SOURCES) $(CXX_SOURCES))))))
OBJECTS_EMCC = $(addprefix $(BUILD_GOAL_DIR_EMCC)/,$(patsubst %.c,%.o, $(patsubst %.cc,%.o, $(patsubst %.c++,%.o, $(patsubst %.cpp,%.o, $(notdir $(C_SOURCES) $(CXX_SOURCES)))))))

# automatic flags settings
ifeq ($(BUILD_TYPE),physics)
 USE_ODE = true
 EXCLUDE_CONTROLLERS = true
endif
ifeq ($(BUILD_TYPE),controllers)
 BUILD_EXECUTABLE = true
else
 ifdef STATIC_LIBRARY
  BUILD_STATIC_LIBRARY = true
 else
  BUILD_SHARED_LIBRARY = true
 endif
endif

# target
ifneq ($(C_SOURCES)$(CXX_SOURCES),)
 ifdef BUILD_EXECUTABLE
  MAIN_TARGET = $(NAME)$(EXE_EXTENSION)
  X86_64_LINKER = -target x86_64-apple-macos11
  ARM64_LINKER = -target arm64-apple-macos11
 else
  ifdef BUILD_STATIC_LIBRARY
   MAIN_TARGET ?= $(LIB_PREFIX)$(NAME)$(STATIC_LIB_EXTENSION)
  else
   MAIN_TARGET ?= $(LIB_PREFIX)$(NAME)$(SHARED_LIB_EXTENSION)
   X86_64_LINKER = -target x86_64-apple-macos11
   ARM64_LINKER = -target arm64-apple-macos11
  endif
 endif
endif
ifdef WREN
 WREN_TARGET = wrenjs.js
endif

TARGETS += $(MAIN_TARGET) $(EXTRA_TARGETS) $(WREN_TARGET)

# goal
SUPPORTED_TARGETS = all release debug profile
ifeq ($(MAKECMDGOALS),)
 GOAL = release
 GOAL_EMCC = emcc
else
 ifdef MAIN_TARGET
  ifeq ($(MAKECMDGOALS),$(MAIN_TARGET))
   GOAL_TMP = true
  endif
 endif
 ifeq ($(MAKECMDGOALS),all)
  GOAL_TMP = true
 endif

 ifdef GOAL_TMP
   GOAL = release
 else
  ifneq ($(filter $(SUPPORTED_TARGETS),$(MAKECMDGOALS)),)
   GOAL = $(MAKECMDGOALS)
  endif
 endif
endif

# build directory
BUILD_DIR = build
BUILD_GOAL_DIR = $(BUILD_DIR)/$(GOAL)
BUILD_GOAL_DIR_EMCC = $(BUILD_DIR)/$(GOAL_EMCC)

ifdef GOAL
ifdef FAT_BINARY
 $(shell mkdir $(BUILD_DIR) $(BUILD_GOAL_DIR) $(BUILD_GOAL_DIR)/x86_64 $(BUILD_GOAL_DIR)/arm64 2> /dev/null)
else
 $(shell mkdir $(BUILD_DIR) $(BUILD_GOAL_DIR) 2> /dev/null)
endif
endif

ifdef GOAL_EMCC
 $(shell mkdir $(BUILD_DIR) $(BUILD_GOAL_DIR_EMCC) 2> /dev/null)
endif

# files to remove
FILES_TO_REMOVE += $(MAIN_TARGET_COPY)
ifdef TARGET_LIB_DIR
 FILES_TO_REMOVE += $(TARGET_LIB_DIR)/$(MAIN_TARGET)
endif

WRENJS_DIR = $(WEBOTS_HOME_PATH)/resources/web/wwi
###-----------------------------------------------------------------------------
### Compilation flags
###-----------------------------------------------------------------------------

# global flags
INCLUDE += -I.
WBCFLAGS += -Wall

# goal dependent flags
ifeq ($(GOAL),debug)
 WBCFLAGS += -ggdb
endif

ifeq ($(TREAT_WARNINGS_AS_ERRORS),1)
CFLAGS += -Werror
endif

ifeq ($(GOAL),release)
 # -O3 has the advantage also to prevents a false positive trojan alert from avast and Kapersky antivirus
 WBCFLAGS += -O3 -DNDEBUG
 ifneq ($(OSTYPE),darwin)
  DYNAMIC_LINK_FLAGS += -s
 endif
endif

ifeq ($(GOAL),profile)
 WBCFLAGS += -pg
 ifneq ($(OSTYPE),darwin)
  ifndef BUILD_STATIC_LIBRARY
   LFLAGS += -pg
  endif
 endif
endif

# platform dependent flags
ifeq ($(OSTYPE),windows)
 WBCFLAGS += -mwindows -Wl,-subsystem,windows -D_GLIBCXX_USE_CXX11_ABI=1
endif

ifeq ($(OSTYPE),linux)
 DYNAMIC_LIBRARIES += -lm
endif

ifeq ($(OSTYPE),darwin)
 WBCFLAGS += -mmacosx-version-min=$(MACOSX_MIN_SDK_VERSION)
 DYNAMIC_LINK_FLAGS += -mmacosx-version-min=$(MACOSX_MIN_SDK_VERSION)
endif

ifdef USE_CXX
 ifdef BUILD_STATIC_LIBRARY
  LINKER = ar
 else
  LINKER = $(CXX)
 endif
 ifndef EXCLUDE_CONTROLLERS
  DYNAMIC_LIBRARIES += -L"$(WEBOTS_CONTROLLER_LIB_PATH)" -lController
  ifdef USE_C_API
   ifeq ($(OSTYPE),darwin)
    INCLUDE += -I"$(WEBOTS_HOME)/Contents/include/controller/c"
   else
    INCLUDE += -I"$(WEBOTS_HOME)/include/controller/c"
   endif
  else
   DYNAMIC_LIBRARIES += -lCppController
   ifeq ($(OSTYPE),darwin)
    INCLUDE += -I"$(WEBOTS_HOME)/Contents/include/controller/cpp"
   else
    INCLUDE += -I"$(WEBOTS_HOME)/include/controller/cpp"
   endif
  endif
  ifeq ($(OSTYPE),windows)
   DYNAMIC_LINK_FLAGS += -Wl,--enable-auto-import
  endif
 endif
 ifeq ($(OSTYPE),darwin)
  WBCFLAGS += -stdlib=libc++
  DYNAMIC_LINK_FLAGS += -stdlib=libc++
 endif
else
 ifdef BUILD_STATIC_LIBRARY
  LINKER = ar
 else
  LINKER = $(CC)
 endif
 ifndef EXCLUDE_CONTROLLERS
  ifeq ($(OSTYPE),darwin)
   INCLUDE += -I"$(WEBOTS_HOME)/Contents/include/controller/c"
  else
   INCLUDE += -I"$(WEBOTS_HOME)/include/controller/c"
  endif
  DYNAMIC_LIBRARIES += -L"$(WEBOTS_CONTROLLER_LIB_PATH)" -lController
 endif
endif

ifdef BUILD_SHARED_LIBRARY
 DYNAMIC_LINK_FLAGS += -shared
 ifeq ($(OSTYPE),linux)
  WBCFLAGS += -fPIC
 endif
 ifeq ($(OSTYPE),darwin)
  DYNAMIC_LINK_FLAGS += -dynamiclib -compatibility_version 1.0 -current_version 1.0.0
 endif
endif

ifdef BUILD_STATIC_LIBRARY
 ifeq ($(OSTYPE),linux)
  WBCFLAGS += -fPIC
 endif
 STATIC_LINK_FLAGS += rvs
endif

# Visual Studio
ifeq ($(OSTYPE),windows)
 ifdef BUILD_SHARED_LIBRARY
  ifndef USE_CXX
    ifneq ($(wildcard /C/Program\ Files\ */Microsoft\ Visual\ Studio/2017),)
      VISUAL_STUDIO_PATH?=/C/Program Files (x86)/Microsoft Visual Studio/2017
    endif
   VS_DEF_NAME = $(NAME).def
  endif
 endif
endif

ifeq ($(OSTYPE),darwin)
 ifdef WEBOTS_LIBRARY
  INSTALL_NAME ?= @rpath/Contents/lib/controller/$(MAIN_TARGET)
  LFLAGS += -Xlinker -rpath -Xlinker @loader_path/.. -install_name $(INSTALL_NAME)
 else
  CALLING_MAKEFILE_DIR := $(shell dirname "$(realpath $(firstword $(MAKEFILE_LIST)))")
  WEBOTS_RELATIVE_PATH = $(call computeRelativePath,"$(WEBOTS_HOME_PATH)","$(CALLING_MAKEFILE_DIR)")
  ifneq (,$(findstring ..,$(WEBOTS_RELATIVE_PATH)))
   DYNAMIC_LINK_FLAGS += -Xlinker -rpath -Xlinker @loader_path/$(WEBOTS_RELATIVE_PATH)
   ifdef BUILD_SHARED_LIBRARY
    INSTALL_NAME ?= @rpath$(subst $(WEBOTS_HOME_PATH),,$(CALLING_MAKEFILE_DIR))/$(MAIN_TARGET)
    DYNAMIC_LINK_FLAGS += -install_name $(INSTALL_NAME)
   endif
  endif
 endif
endif


###-----------------------------------------------------------------------------
### ODE
###-----------------------------------------------------------------------------

ifdef USE_ODE
 DYNAMIC_LIBRARIES += -L"$(WEBOTS_LIB_PATH)" -lode
 ifeq ($(GOAL),profile)
  DYNAMIC_LIBRARIES += -lstdc++
 endif
 ifeq ($(OSTYPE),darwin)
  DYNAMIC_LINK_FLAGS += -flat_namespace -undefined suppress
  DYNAMIC_LIBRARIES += "$(WEBOTS_HOME)/Contents/Resources/projects/plugins/physics/physics.a"
  INCLUDE += -I"$(WEBOTS_HOME)/Contents/include/ode" -I"$(WEBOTS_HOME)/Contents/include"
 else
  DYNAMIC_LIBRARIES += "$(WEBOTS_HOME)/resources/projects/plugins/physics/physics.o"
  INCLUDE += -I"$(WEBOTS_HOME)/include/ode" -I"$(WEBOTS_HOME)/include"
 endif
endif


###-----------------------------------------------------------------------------
### Makefile setup
###-----------------------------------------------------------------------------

# clear out all suffixes for implicit rules to speed up Makefile
.SUFFIXES:
MAKEFLAGS += -r

# vpath
vpath %.d $(BUILD_DIR)
# find source files
vpath %.c $(SOURCES_DIRECTORIES)
vpath %.cc $(SOURCES_DIRECTORIES)
vpath %.c++ $(SOURCES_DIRECTORIES)
vpath %.cpp $(SOURCES_DIRECTORIES)

# phony
.PHONY : clean $(SUPPORTED_TARGETS) jar


###-----------------------------------------------------------------------------
### Rules
###-----------------------------------------------------------------------------

$(SUPPORTED_TARGETS): $(TARGETS)

# we need to be able to execute a make clean inside subdirectories targets (defined as EXTRA_TARGETS)
clean: $(EXTRA_TARGETS)

### Begin ifdef MAIN_TARGET
ifdef MAIN_TARGET

MAIN_TARGET_WINDOWS_LIB = $(MAIN_TARGET:.dll=.lib)
ifdef WEBOTS_LIBRARY
MAIN_TARGET_COPY = "$(subst $(space),\ ,$(WEBOTS_CONTROLLER_LIB_PATH))/$(MAIN_TARGET)"
MAIN_TARGET_WINDOWS64_LIB = $(WEBOTS_CONTROLLER_LIB_PATH)/$(MAIN_TARGET_WINDOWS_LIB)
else
MAIN_TARGET_COPY ?= $(MAIN_TARGET)
MAIN_TARGET_WINDOWS64_LIB = $(MAIN_TARGET:.dll=.lib)
endif
ifeq ($(OSTYPE),windows)
FILES_TO_REMOVE += $(MAIN_TARGET_WINDOWS64_LIB)
endif

###-----------------------------------------------------------------------------
### Rule for the top-level binary
###-----------------------------------------------------------------------------

ifdef BUILD_STATIC_LIBRARY
 LFLAGS += $(STATIC_LINK_FLAGS)
 ifndef VERBOSE
  AR_SUPPRESS_OUTPUT = > /dev/null 2>&1
 endif
else
 LIBRARIES += $(DYNAMIC_LIBRARIES)
 LFLAGS += $(DYNAMIC_LINK_FLAGS) -o
endif

ifdef TARGET_LIB_DIR

$(MAIN_TARGET): $(TARGET_LIB_DIR)/$(MAIN_TARGET)
ifdef VS_DEF_NAME
	@# Generate the .lib libraries to facilitate the integration with Visual Studio
	@# if the .def file is existing.
	@if [ -f $(VS_DEF_NAME) ]; then \
		if [ -d "$(VISUAL_STUDIO_PATH)" ]; then \
			PATH="$(VISUAL_STUDIO_PATH)/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64":$PATH lib /machine:X64 /def:$(VS_DEF_NAME) /out:out.lib > /dev/null; \
			mv out.lib $(MAIN_TARGET_WINDOWS64_LIB); \
			rm -f *.exp; \
		else \
			echo "'VISUAL_STUDIO_PATH' environmental variable not set or Microsoft Visual Studio not installed, skipping $(NAME).lib"; \
		fi \
	fi
endif

else

$(MAIN_TARGET): $(BUILD_GOAL_DIR)/$(MAIN_TARGET)
	@# Even when compiled from Webots with possibly the previous version of the binary
	@# being executed, it is safe to delete it and copy the new version as a replacement.
	@# This new version will be executed only when the process restarts.
	@# Note: this binary may be an executable (e.g., a controller) or shared library (e.g., a physics plug-in).
	@rm -f $(MAIN_TARGET) > /dev/null 2>&1 && echo "# copying to" $(MAIN_TARGET_COPY) && cp $(BUILD_GOAL_DIR)/$(MAIN_TARGET) $(MAIN_TARGET_COPY) > /dev/null 2>&1
ifdef VS_DEF_NAME
	@# Generate the .lib libraries to facilitate the integration with Visual Studio
	@# if the .def file is existing.
	@if [ -f $(VS_DEF_NAME) ]; then \
		if [ -d "$(VISUAL_STUDIO_PATH)" ]; then \
			PATH="$(VISUAL_STUDIO_PATH)/BuildTools/VC/Tools/MSVC/14.16.27023/bin/Hostx64/x64":$PATH lib /machine:X64 /def:$(VS_DEF_NAME) /out:out.lib > /dev/null; \
			mv out.lib $(MAIN_TARGET_WINDOWS64_LIB); \
			rm -f *.exp; \
		else \
			echo "'VISUAL_STUDIO_PATH' environmental variable not set or Microsoft Visual Studio not installed, skipping $(NAME).lib"; \
		fi \
	fi
endif

endif

###-----------------------------------------------------------------------------
### Rule to make the executable file from C/C++ objects
###-----------------------------------------------------------------------------

ifdef FAT_BINARY
X86_64_OBJECTS = $(addprefix $(BUILD_GOAL_DIR)/x86_64/, $(OBJECTS_LIST))
ARM64_OBJECTS = $(addprefix $(BUILD_GOAL_DIR)/arm64/, $(OBJECTS_LIST))

$(BUILD_GOAL_DIR)/$(MAIN_TARGET): $(BUILD_GOAL_DIR)/x86_64/$(MAIN_TARGET) $(BUILD_GOAL_DIR)/arm64/$(MAIN_TARGET)
	@echo "# creating fat" $(notdir $@)
	$(SILENT)lipo -create -output $@ $(BUILD_GOAL_DIR)/x86_64/$(MAIN_TARGET) $(BUILD_GOAL_DIR)/arm64/$(MAIN_TARGET)
	$(SILENT)codesign -s - $@

$(TARGET_LIB_DIR)/$(MAIN_TARGET): $(BUILD_GOAL_DIR)/x86_64/$(MAIN_TARGET) $(BUILD_GOAL_DIR)/arm64/$(MAIN_TARGET)
	@echo "# creating fat" $(notdir $@)
	$(SILENT)lipo -create -output $@ $(BUILD_GOAL_DIR)/x86_64/$(MAIN_TARGET) $(BUILD_GOAL_DIR)/arm64/$(MAIN_TARGET)
	$(SILENT)codesign -s - $@

$(BUILD_GOAL_DIR)/x86_64/$(MAIN_TARGET): $(X86_64_OBJECTS) $(LINK_DEPENDENCIES)
	@echo "# linking" $(notdir $@) "(x86_64)"
	$(SILENT)$(LINKER) $(X86_64_LINKER) $(LFLAGS) $@ $(X86_64_OBJECTS) $(LIBRARIES) $(AR_SUPPRESS_OUTPUT)

$(BUILD_GOAL_DIR)/arm64/$(MAIN_TARGET): $(ARM64_OBJECTS) $(LINK_DEPENDENCIES)
	@echo "# linking" $(notdir $@) "(arm64)"
	$(SILENT)$(LINKER) $(ARM64_LINKER) $(LFLAGS) $@ $(ARM64_OBJECTS) $(LIBRARIES) $(AR_SUPPRESS_OUTPUT)

else

OBJECTS = $(addprefix $(BUILD_GOAL_DIR)/, $(OBJECTS_LIST))
$(BUILD_GOAL_DIR)/$(MAIN_TARGET): $(OBJECTS) $(LINK_DEPENDENCIES)
	@echo "# linking" $(notdir $@)
	$(SILENT)$(LINKER) $(LFLAGS) $@ $(OBJECTS) $(LIBRARIES) $(AR_SUPPRESS_OUTPUT)

$(TARGET_LIB_DIR)/$(MAIN_TARGET): $(OBJECTS) $(LINK_DEPENDENCIES)
	@echo "# linking" $(notdir $@)
	$(SILENT)$(LINKER) $(LFLAGS) $@ $(OBJECTS) $(LIBRARIES) $(AR_SUPPRESS_OUTPUT)

endif

endif

### End ifdef MAIN_TARGET

ifdef WREN
$(WREN_TARGET): $(OBJECTS_EMCC)
	$(SILENT) emcc -O3 -s WASM=1 -s EXIT_RUNTIME=1 -s USE_WEBGL2=1 -s FULL_ES3=1 -s ALLOW_MEMORY_GROWTH=1 --preload-file ../../resources/wren/shaders@../../resources/wren/shaders $(OBJECTS_EMCC) -s EXPORTED_FUNCTIONS='[$(shell cat functions_to_export.txt)]' -s 'EXPORTED_RUNTIME_METHODS=["ccall", "getValue"]' -o wrenjs.js
	$(SILENT) cp wrenjs.js wrenjs.wasm wrenjs.data $(WRENJS_DIR)/ > /dev/null 2>&1
endif

###-----------------------------------------------------------------------------
### Rules to make automatic dependencies adapted from the GNU make info file
###-----------------------------------------------------------------------------
$(BUILD_GOAL_DIR)/%.d:%.c
	@echo "# updating" $(notdir $@)
	$(SILENT)$(CC) $(INCLUDE) $(WBCFLAGS) $(CFLAGS) -MM $< -MT $(addprefix $(BUILD_GOAL_DIR)/,$(notdir $(<:.c=.o))) > $@

$(BUILD_GOAL_DIR)/%.d:%.cc
	@echo "# updating" $(notdir $@)
	$(SILENT)$(CXX) $(INCLUDE) $(WBCFLAGS) $(CFLAGS -MM $< -MT $(addprefix $(BUILD_GOAL_DIR)/,$(notdir $(<:.cc=.o))) > $@

$(BUILD_GOAL_DIR)/%.d:%.c++
	@echo "# updating" $(notdir $@)
	$(SILENT)$(CXX) $(INCLUDE) $(WBCFLAGS) $(CFLAGS) -MM $< -MT $(addprefix $(BUILD_GOAL_DIR)/,$(notdir $(<:.c++=.o))) > $@

$(BUILD_GOAL_DIR)/%.d:%.cpp
	@echo "# updating" $(notdir $@)
	$(SILENT)$(CXX) $(INCLUDE) $(WBCFLAGS) $(CFLAGS) -MM $< -MT $(addprefix $(BUILD_GOAL_DIR)/,$(notdir $(<:.cpp=.o))) > $@

# dependencies
ifdef GOAL
 DEPENDENCIES = $(addprefix $(BUILD_GOAL_DIR)/,$(notdir $(C_SOURCES:.c=.d) $(CXX_SOURCES:.cpp=.d)))
 ifneq ($(DEPENDENCIES),)
  -include $(DEPENDENCIES)
 endif
endif

###-----------------------------------------------------------------------------
### Generic rules to make the object files
###-----------------------------------------------------------------------------
$(BUILD_GOAL_DIR)/%.o:%.c
	@echo "# compiling" $(notdir $<)
	$(SILENT)$(CC) -c $(WBCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR)/x86_64/%.o:%.c
	@echo "# compiling" $(notdir $<) "(x86_64)"
	$(SILENT)$(CC) -c -target x86_64-apple-macos11 $(WBCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR)/arm64/%.o:%.c
	@echo "# compiling" $(notdir $<) "(arm64)"
	$(SILENT)$(CC) -c -target arm64-apple-macos11 $(WBCFLAGS) $(CFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR)/%.o:%.cc
	@echo "# compiling" $(notdir $<)
	$(SILENT)$(CXX) -c $(WBCFLAGS) $(CFLAGS) $(CXXFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR)/%.o:%.c++
	@echo "# compiling" $(notdir $<)
	$(SILENT)$(CXX) -c $(WBCFLAGS) $(CFLAGS) $(CXXFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR)/%.o:%.cpp
	@echo "# compiling" $(notdir $<)
	$(SILENT)$(CXX) -c $(WBCFLAGS) $(CFLAGS) $(CXXFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR)/x86_64/%.o:%.cpp
	@echo "# compiling" $(notdir $<) "(x86_64)"
	$(SILENT)$(CXX) -c -target x86_64-apple-macos11 $(WBCFLAGS) $(CFLAGS) $(CXXFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR)/arm64/%.o:%.cpp
	@echo "# compiling" $(notdir $<) "(arm64)"
	$(SILENT)$(CXX) -c -target arm64-apple-macos11 $(WBCFLAGS) $(CFLAGS) $(CXXFLAGS) $(INCLUDE) $< -o $@

$(BUILD_GOAL_DIR_EMCC)/%.o:%.cpp
	@echo "# compiling with emcc " $(notdir $<)
	$(SILENT)emcc -O3 -c $(WBCFLAGS) $(CFLAGS) $(CXXFLAGS) $(INCLUDE) $< -o $(@)

###-----------------------------------------------------------------------------
### How to clean up the directory
###-----------------------------------------------------------------------------
clean:
	$(SILENT)rm -fr $(FILES_TO_REMOVE) $(BUILD_DIR) > /dev/null 2>&1 || :
	$(SILENT)rm -d $(EMPTY_DIRECTORIES_TO_REMOVE) > /dev/null 2>&1 || :
  ifdef WREN
	 $(SILENT)rm $(WEBOTS_HOME_PATH)/src/wren/wrenjs.js $(WEBOTS_HOME_PATH)/src/wren/wrenjs.data $(WEBOTS_HOME_PATH)/src/wren/wrenjs.wasm  $(WEBOTS_HOME_PATH)/src/wren/functions_to_export.txt > /dev/null 2>&1 || :
	 $(SILENT)rm $(WRENJS_DIR)/wrenjs.js $(WRENJS_DIR)/wrenjs.data $(WRENJS_DIR)/wrenjs.wasm > /dev/null 2>&1 || :
  endif
  $(SILENT)rm -r $(WRENJS_DIR)/images/post_processing > /dev/null 2>&1 || :
