# --------------------------------------------------
# Vala Makefile
# --------------------------------------------------
#
# This Makefile provides a starting point for building
# and testing Vala projects on Linux.
#
# There are two types of projects supported: executable
# and shared library. Basic installation/uninstallation
# support is provided as well.
#
# To build your project, first fill in some details below.
# At a minimum you need to specify a name for your
# project's target (the executable or library to be
# produced). You may also configure what packages are
# used to build it, how the files in your project's
# root are organized, and of course, whether it is an
# executable or library.
#
# There are three important subdirectories that this
# Makefile uses. The names of these can be configured
# further down, if you so desire.
#
# 	src/
# 		all *.vala source files. The `find' command
# 		is used to locate them, so feel free to create
# 		as many subdirectories here as you wish
#
# 	data/
# 		any additional data files for your project. When
# 		installed, the contents of this folder are copied
# 		directly to $(PREFIX)/share, so you should make
# 		sure that the contents mirror where you want them
# 		to be installed. For example, to create a launcher
# 		for your program, you could put the .desktop file
# 		in data/applications so that it would be installed
# 		to $(PREFIX)/share/applications.
# 		NOTE: this directory is only used for executable
# 		projects, and is set to read-only as long as the
# 		project is installed. To regain write access, you
# 		must first uninstall your project from the
# 		filesystem.
#
#	build/
#		where compiled results are placed, including
#		intermediate .c and .o files as well as the final
#		executable or library
#
# To build your project, make sure your desired source
# files are placed in src/, then run make.
#
# The following targets are supported:
#
#  	all/target: compiles the source and generates the
#		final result in build/ (default)
#  	compile: compiles vala down to its C source, but
#  		doesn't generate the final result
#  	clean: cleans all compilation results for a fresh build
#  	install: installs this program/library
#  	uninstall: uninstalls this program/library
# 		
# To install the project, run `make install' with root
# privileges. The default prefix is /usr/local, which can
# be changed by specifying a new PREFIX variable on the
# command-line, e.g. `make install PREFIX=/usr'. Likewise,
# it can be uninstalled using `make uninstall` as root,
# using the same PREFIX variable as when it was installed.
#
# WHAT THIS MAKEFILE DOES NOT DO:
#
# - dependency/version checking
# - program configuration prior to running make
# - internationalization
# - anything besides compile vala and cp/rm files
#
# Enjoy.
#



# --------------------------------------------------
# BEGIN PROJECT CONFIGURATION
# --------------------------------------------------

# Specify the project's type.
# 	EXEC = compile to an executable
# 	LIB = compile to a shared library
TYPE		:= EXEC
#TYPE		:= LIB

# The name of the final result.
# If the target is an executable, this name will be used.
# If the target is a shared library, it will be
# renamed to lib$(TARGET).so
TARGET		:= 

# A space-separated list of packages required by your
# project. Names must be compatible with pkg-config, e.g.
#    gtk+-3.0
PKGS		:= 

# Configure the project's directories.
SRC_DIR		:= $(DIRECTORY)src/
BUILD_DIR	:= $(DIRECTORY)build/
DATA_DIR	:= $(DIRECTORY)data/

# This is a hidden folder, simply used to help parallel builds
VALA_AUX	:= $(DIRECTORY).vala-aux/

# Set the vala compiler.
VALAC		:= valac

# Add any additional flags to pass to the vala compiler.
VALAFLAGS	:= 

# Set the C compiler.
CC			:= gcc

# Add any additional flags to pass to the C compiler.
CFLAGS		:= -O -Wall

# Add any additional flags to pass to the compiler during
# the linking phase.
OFLAGS		:= 

# --------------------------------------------------
# END PROJECT CONFIGURATION
# --------------------------------------------------

# Get pkg-config cflags and libs
PKG_CFLAGS 	:= $(shell pkg-config --cflags gobject-2.0 $(PKGS))
PKG_LIBS 	:= $(shell pkg-config --libs gobject-2.0 $(PKGS))

# Locate necessary files
VALA_FILES := $(shell find $(SRC_DIR) -type f -name "*.vala")
C_FILES = $(BUILD_DIR)c/$(notdir $(VALA_FILES:.vala=.c))
O_FILES = $(BUILD_DIR)o/$(notdir $(C_FILES:.c=.o))

# Set stamp and deps information
# This part is needed in order to avoid re-building everything each time
BASENAMES = $(notdir $(basename $(VALA_FILES)))
VALA_FASTVAPI_FILES = $(foreach f, $(BASENAMES), $(VALA_AUX)$(f).vapi)
VALA_FASTVAPI_STAMPS = $(foreach f, $(BASENAMES), $(VALA_AUX)$(f).vapi.stamp)
VALA_DEPS = $(foreach f, $(BASENAMES), $(VALA_AUX)$(f).dep)

# Default installation prefix
PREFIX = /usr/local

LIB_TARGET_DIR = $(PREFIX)/lib

# Set some executable-vs-library specific variables
ifeq ($(TYPE), LIB)
TARGET := lib$(TARGET).so
CFLAGS := $(CFLAGS) -fPIC
OFLAGS := $(OFLAGS) -shared
BUILDMSG := Generating shared library...

# Check for a 64-bit library
ifeq ($(shell uname -m), x86_64)
$(LIB_TARGET_DIR) = $(LIB_TARGET_DIR)64
endif

else
BUILDMSG := Generating executable...
endif


.PRECIOUS: $(VALA_AUX)%.vapi.stamp $(VALA_AUX)%.dep

all: target

$(VALA_FASTVAPI_FILES): ;

$(VALA_FASTVAPI_STAMPS): $(VALA_FILES) | $(VALA_AUX)
	@echo '  GEN    '$(@:.stamp=); $(VALAC) --fast-vapi=$(@:.stamp=) $< && touch $@

$(VALA_DEPS): $(VALA_FILES) | $(VALA_FASTVAPI_STAMPS)
	@echo '  VALAC  '$(notdir $<); $(VALAC) -C --deps=$@ -b $(SRC_DIR) -d $(BUILD_DIR)c $(VALAFLAGS) $(addprefix --use-fast-vapi=,$(subst $(VALA_AUX)$(notdir $(basename $@)).vapi,, $(VALA_FASTVAPI_FILES))) $(addprefix --pkg=,$(PKGS)) $<

$(VALA_AUX):
	@mkdir -p $(VALA_AUX)

$(C_FILES) : | $(VALA_DEPS) ;

$(O_FILES): $(C_FILES)
	@echo '  CC     '$(notdir $<); mkdir -p $(BUILD_DIR)o; $(CC) -c $(CFLAGS) $(PKG_CFLAGS) -o $@ $<

target: $(O_FILES)
	@echo '  $(BUILDMSG)'; $(CC) -o $(BUILD_DIR)$(TARGET) $(OFLAGS) $(O_FILES) $(PKG_LIBS)
	@echo '  Done.'

compile: $(VALA_DEPS)

clean:
	@echo '  Cleaning up...'; $(RM) -r $(BUILD_DIR) $(VALA_AUX)
	@echo '  Done.'

install: install-$(TYPE)

uninstall: uninstall-$(TYPE)

install-EXEC:
	@echo '  Installing to $(PREFIX)...' && cp $(BUILD_DIR)$(TARGET) $(PREFIX)/bin && cp -r $(DATA_DIR)* $(PREFIX)/share
	@echo '  Setting data files to read-only...' && (cd $(DATA_DIR) && find . -exec chmod -w {} \;)
	@echo '  Done.'

install-LIB:
	@echo '  Installing $(TARGET) to $(LIB_TARGET_DIR)...'; cp $(BUILD_DIR)$(TARGET) $(LIB_TARGET_DIR) && /sbin/ldconfig $(LIB_TARGET_DIR)
	@echo '  Done.'

uninstall-EXEC:
	@echo '  Removing...'; $(RM) $(PREFIX)/bin/$(TARGET) && (cd $(DATA_DIR) && find . -type f -exec $(RM) $(PREFIX)/share/{} \;)
	@echo '  Re-enabling editing of data files...' && (cd $(DATA_DIR) && find . -exec chmod +w {} \;)
	@echo '  Done.'

uninstall-LIB:
	@echo '  Removing...'; $(RM) $(LIB_TARGET_DIR)/$(TARGET) && /sbin/ldconfig $(LIB_TARGET_DIR)
	@echo '  Done.'

.PHONY: all clean target install install-EXEC install-LIB uninstall uninstall-EXEC uninstall-LIB

include $(wildcard $(VALA_AUX)/*.dep)

