# Makefile for Thrift compiler. This Makefile assumes that you are running on
# some form of *NIX operating system with the following tools and packages
# installed:
#
#   g++
#   flex
#   bison
#   libfl
# 
# Author:
#   Mark Slee <mcslee@facebook.com>

# Default build rule
target:	thrift

# Tools
CC    = g++
LD    = g++
LEX   = flex
YACC  = bison
MKDIR = mkdir

# Source directory
SRC_DIR = src/

# Object file directory
OBJ_DIR = obj/

# Generated source dir
GEN_DIR = $(SRC_DIR)

# Output directory
BIN_DIR = bin/

# Source files
SRC_FILES = main.cc \
            generate/t_generator.cc \
            generate/t_py_generator.cc \
            generate/t_java_generator.cc \
            generate/t_php_generator.cc \
            generate/t_cpp_generator.cc

# Autogenerated files
GEN_FILES = thrift.tab.hh \
            thrift.tab.cc \
            lex.yy.cc

# Object files
OBJ_FILES = ${SRC_FILES:.cc=.o}

# Generated object files
GOB_FILES = thrift.tab.o \
            lex.yy.o

# Apply directory prefixes
SRCS = ${addprefix $(SRC_DIR), $(SRC_FILES)}
GENS = ${addprefix $(GEN_DIR), $(GEN_FILES)}
OBJS = ${addprefix $(OBJ_DIR), $(OBJ_FILES)}
GOBS = ${addprefix $(OBJ_DIR), $(GOB_FILES)}

# Compile with strict warnings
CFL = -g -Wall -I$(SRC_DIR) -I$(OBJ_DIR)

# Flex library
LIBS = -lfl

# Build directories
obj_dirs: $(BIN_DIR) $(OBJ_DIR)parse $(OBJ_DIR)generate
$(BIN_DIR):
	$(MKDIR) -p $(BIN_DIR)
$(OBJ_DIR)parse:
	$(MKDIR) -p $(OBJ_DIR)parse
$(OBJ_DIR)generate:
	$(MKDIR) -p $(OBJ_DIR)generate

# Scanner generation
$(GEN_DIR)lex.yy.cc: $(SRC_DIR)thrift.l
	$(LEX) -o$@ $(SRC_DIR)thrift.l
$(OBJ_DIR)lex.yy.o: $(GEN_DIR)lex.yy.cc
	$(CC) $(CFL) -c -o $@ $(GEN_DIR)lex.yy.cc

# Parser generation
$(GEN_DIR)thrift.tab.hh: $(GEN_DIR)thrift.tab.cc
$(GEN_DIR)thrift.tab.cc: $(SRC_DIR)thrift.y
	$(YACC) -d -o$(GEN_DIR)thrift.tab.cc $(SRC_DIR)thrift.y
$(OBJ_DIR)thrift.tab.o: $(GEN_DIR)thrift.tab.cc
	$(CC) $(CFL) -c -o $@ $(GEN_DIR)thrift.tab.cc

# C++ compilation
$(OBJS): $(SRCS)
	$(CC) $(CFL) -c -o $@ ${subst $(OBJ_DIR),$(SRC_DIR),$*.cc}

# Main build rule
thrift:	obj_dirs $(OBJS) $(GOBS)
	$(LD) $(CFL) -o $(BIN_DIR)thrift $(OBJS) $(GOBS) $(LIBS)

# Install
install: thrift
	sudo install bin/thrift /usr/local/bin/thrift

# Remove auto-gen'd files and binaries
clean:
	rm -fr \
	$(OBJ_DIR) \
	$(GENS) \
	$(BIN_DIR)thrift.exe \
	$(BIN_DIR)thrift

