#! /usr/bin/perl

################################################################################
# Program: make_build
#
#    This program constructs Makefiles for model directories in
#    <include_path>/<model_dir>.
#
#    Command Syntax: make_build
#
#*******************************************************************

use lib $ENV{"TRICK_HOME"} . "/bin/pm" ;
use Cwd ;
use File::Basename ;
use trick_version ;

###############################################################################
# Process command line options 
###############################################################################

$lib_file = "";

# Check calling args.
if ( @ARGV[0] ne "") {
    if ( @ARGV[0] eq "lib" and @ARGV[1] ne "" ) {
        $lib_file = @ARGV[1];
        if ( $lib_file !~ /\.a$/ ) {
            print "USAGE: make_build lib lib_file_name.a\n";
            exit;
        }
        $lib_file =~ s/lib.*?\/// ;
        $lib_file = "lib_\${TRICK_HOST_CPU}/$lib_file";
    }
    elsif ( @ARGV[0] eq "sharedlib" and @ARGV[1] ne "" ) {
        $sharedlib_file = @ARGV[1];
        if ( $sharedlib_file !~ /\.so$/ ) {
            print "USAGE: make_build sharedlib lib_file_name.so\n";
            exit;
        }
        $sharedlib_file =~ s/lib.*?\/// ;
        $sharedlib_file = "lib_\${TRICK_HOST_CPU}/$sharedlib_file";
        $lib_file = $sharedlib_file ;
        $lib_file =~ s/\.so/\.a/ ;
    }
    else {
        print "USAGE: make_build [lib <lib_file_name>]\n";
        exit;
    }
}

# Get the full path of the current working directory
$wd = cwd();
if ($ENV{TRICK_HOME} eq "") {
    print "TRICK_HOME is not set... cannot continue\n" ;
    exit (1)
}

# If this is a /src, /include, /xml, /io_src, /catalog, or /object_*
# directory, then start make_build in the ../ directory.
if ( $wd =~ /\/include/ and $wd !~ /\/sim_services\// ) {

    $wd = dirname($wd);

} elsif (    $wd =~ /\/src/ or $wd =~ /\/xml/ or $wd =~ /\/io_src/ 
          or $wd =~ /\/catalog/ or $wd =~ /\/object_/ ) {

    $wd = dirname($wd);
}

# Let user know what's going on.
print "[36mProcessing $wd[00m\n";
print "Building Makefile...\n";

# Open the file "Makefile" 
my ($all_lines) = do { local $/; <main::DATA> };
open MAKEFILE , ">Makefile";

$date = `date` ;
chomp $date ;

my ($trick_ver, $trick_thread) = get_trick_version() ;
my ($trick_major , $trick_minor ) ;
($trick_major , $trick_minor ) = $trick_ver =~ /(\d+)\.([^\.]+)/ ;

#$trick_ver = `trick_version -f` ;
#chomp $trick_ver ;

$all_lines =~ s/DATE/$date/ ;
$all_lines =~ s/REPLACE_TRICK_MAJOR/$trick_major/g ;
$all_lines =~ s/REPLACE_TRICK_MINOR/$trick_minor/g ;
$all_lines =~ s/REPLACE_TRICK_THREAD/$trick_thread/g ;
$all_lines =~ s/LIB_FILE/$lib_file/ ;
$all_lines =~ s/SHARED_LIB_FILE/$sharedlib_file/ ;
print MAKEFILE $all_lines ;

close MAKEFILE ;

# If this directory has a '/src' directory, create a Makefile for
# /src as well.
if ( -e "$wd/src" ) {

    # Open the file "src/Makefile"
    open MAKEFILE , ">src/Makefile";

    print MAKEFILE "# Go up to parent directory and run make from there\
default:\
\tcd .. ; make\
ICG:\
\tcd .. ; make ICG\
depend:\
\tcd .. ; make depend\
io_clean:\
\tcd .. ; make io_clean\
catalog_clean:\
\tcd .. ; make catalog_clean\
clean:\
\tcd .. ; make clean\
real_clean:\
\tcd .. ; make real_clean" ;

    close MAKEFILE ;

}

print "Adding file dependencies in Makefile...\n" ;
system "make depend";
print "[32mmake_build complete[00m\n" ;

__END__
#############################################################################
#
# This make file was automatically generated by:
#    
#    /user2/lin/trick_dev/03/bin/make_build
#
# Trick ver: REPLACE_TRICK_MAJOR.REPLACE_TRICK_MINOR-REPLACE_TRICK_THREAD
#
#      Date: DATE
#
#############################################################################
#
# To get a desription of the arguments accepted by this makefile,
# type 'make help'
#
#############################################################################


#############################################################################
##                         DIRECTORY DEFINITIONS                           ##
#############################################################################

ifeq ($(wildcard src),src)
SRC_DIR := src/
CD_CMD := cd src ;
UP_DIR := ../
else
SRC_DIR :=
CD_CMD :=
UP_DIR :=
endif

PWD = $(shell pwd)

IO_SRC_DIR = io_src/
OBJ_DIR = lib_${TRICK_HOST_CPU}
LIB = LIB_FILE
SHARED_LIB = SHARED_LIB_FILE

ifndef TRICK_CC
 TRICK_CC = cc
endif

ifndef TRICK_CPPC
 TRICK_CPPC = c++
endif

ifndef TRICK_FC
 TRICK_FC = f90
endif

TRICK_CFLAGS += -I${TRICK_HOME}/trick_source -I../include -fPIC
ifdef TRICK_CXXFLAGS
    TRICK_CXXFLAGS += -DTRICK_VER=REPLACE_TRICK_MAJOR -DTRICK_MINOR=REPLACE_TRICK_MINOR -I${TRICK_HOME}/trick_source -I../include -fPIC
else
    TRICK_CXXFLAGS = ${TRICK_CFLAGS} -DTRICK_VER=REPLACE_TRICK_MAJOR -DTRICK_MINOR=REPLACE_TRICK_MINOR -I${TRICK_HOME}/trick_source -I../include -fPIC
endif
TRICK_FTNFLAGS += -I${TRICK_HOME}/trick_source -I../include

ifeq ($(TRICK_HOST_TYPE), Linux)
 MAKEDEP_CPP_INC = -Iinclude -I/usr/include/g++-3
 TRICK_CFLAGS += -I/usr/X11R6/include
endif

ifeq ($(TRICK_HOST_TYPE), QNX)
 MAKEDEP_CPP_INC = -Iinclude
 TRICK_EXEC_LINK_LIBS += -lm -lsocket
endif

ifeq ($(TRICK_HOST_TYPE), LynxOS)
 TRICK_CFLAGS += -mthreads
 TRICK_CXXFLAGS += -mthreads
endif

ifeq ($(TRICK_HOST_TYPE), Darwin)
 MAKEDEP_CPP_INC = -Iinclude -I/usr/include/gcc/darwin/3.1/g++-v3 \
  -I/usr/include/gcc/darwin/3.1/g++-v3/ppc-darwin \
  -I/usr/include/gcc/darwin/default/g++-v3/backward \
  -I/usr/include/gcc/darwin/3.1
 TRICK_RANLIB = /usr/bin/ranlib
 TRICK_CFLAGS += -I/usr/X11R6/include -I/usr/local/include
endif

ifeq ($(TRICK_HOST_TYPE), SunOS_5.6_plus)
 # These are specific to our gcc 2.95 installation in /opt/sfw
 MAKEDEP_CPP_INC = -Iinclude -I/opt/sfw/include/g++-3 \
  -I/opt/sfw/sparc-sun-solaris2.8/include \
  -I/opt/sfw/lib/gcc-lib/sparc-sun-solaris2.8/2.95.3/include
endif

ifeq ($(TRICK_HOST_TYPE), IRIX_6.x)
 MAKEDEP_CPP_INC = -Iinclude -I/usr/include/CC
endif

ifeq ($(TRICK_HOST_TYPE), Interix)
 TRICK_CFLAGS += -D_ALL_SOURCE
 TRICK_CXXFLAGS += -D_ALL_SOURCE
 TRICK_EXEC_LINK_LIBS += -lm
endif


#############################################################################
##                          UTILITY DEFINITIONS                            ##
#############################################################################
SHELL = /bin/sh
AWK   = awk
SED   = sed
LEX   = /usr/bin/flex
YACC  = /usr/bin/bison
PERL  = /usr/bin/perl
CD    = cd
MV    = mv
RM    = rm

#
# Make information
#
MAKEFILE = $(PWD)/Makefile
DEPFILE = $(PWD)/Makefile_deps
DEPTEMPFILE = Makefile_temp_depends

#############################################################################
##                        FILE NAME DEFINITIONS                            ##
#############################################################################

L_SRC = $(wildcard $(SRC_DIR)*.l)
L_OUT = $(subst .l,.clex,$(L_SRC))

Y_SRC = $(wildcard $(SRC_DIR)*.y)
Y_OUT = $(subst .y,.c,$(Y_SRC))
Y_OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(subst .y,.o,$(Y_SRC))))

C_SRC = $(wildcard $(SRC_DIR)*.c)
C_OBJS = $(filter-out $(Y_OBJS), $(addprefix $(OBJ_DIR)/,$(notdir $(subst .c,.o,$(C_SRC)))))

CPP_C_SRC = $(wildcard $(SRC_DIR)*.C) 
CPP_CC_SRC = $(wildcard $(SRC_DIR)*.cc) 
CPP_CPP_SRC = $(wildcard $(SRC_DIR)*.cpp) 
CPP_CXX_SRC = $(wildcard $(SRC_DIR)*.cxx) 
CPP_CPLUS_SRC = $(wildcard $(SRC_DIR)*.c++) 
CPP_SRC = $(CPP_C_SRC) $(CPP_CC_SRC) $(CPP_CPP_SRC) $(CPP_CXX_SRC) $(CPP_CPLUS_SRC) 
CPP_C_OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(subst .C,.o,$(CPP_C_SRC))))
CPP_CC_OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(subst .cc,.o,$(CPP_CC_SRC))))
CPP_CPP_OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(subst .cpp,.o,$(CPP_CPP_SRC))))
CPP_CXX_OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(subst .cxx,.o,$(CPP_CXX_SRC))))
CPP_CPLUS_OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(subst .c++,.o,$(CPP_CPLUS_SRC))))
CPP_OBJS = $(CPP_C_OBJS) $(CPP_CC_OBJS) $(CPP_CPP_OBJS) $(CPP_CXX_OBJS) $(CPP_CPLUS_OBJS) 

F_SRC = $(wildcard $(SRC_DIR)*.f)
F_OBJS = $(addprefix $(OBJ_DIR)/,$(notdir $(subst .f,.o,$(F_SRC))))

IO_C_SRC = $(wildcard $(IO_SRC_DIR)*.c)
IO_C_OBJS =$(subst io_src,$(OBJ_DIR),$(subst .c,.o,$(IO_C_SRC)))

IO_CPP_SRC = $(wildcard $(IO_SRC_DIR)*.cpp)
IO_CPP_OBJS =$(subst io_src,$(OBJ_DIR),$(subst .cpp,.o,$(IO_CPP_SRC)))

IO_SRC = $(IO_C_SRC) $(IO_CPP_SRC)
IO_OBJS = $(IO_C_OBJS) $(IO_CPP_OBJS)

OBJECT_FILES = $(IO_OBJS) $(Y_OBJS) $(C_OBJS) $(CPP_OBJS) $(F_OBJS)

#############################################################################
##                            MODEL TARGETS                                ##
#############################################################################

ifneq ($(LIB),"")
default: objects $(LIB) $(SHARED_LIB)
else
default: objects
endif

trick: objects

object_dir: $(OBJ_DIR)

objects: y_objects c_objects cpp_objects f_objects h_objects
	@ echo "[32m$(CURDIR) object files up to date[00m"

c_objects: $(OBJ_DIR) $(C_OBJS)

cpp_objects: $(OBJ_DIR) $(CPP_OBJS)

f_objects: $(OBJ_DIR) $(F_OBJS)

h_objects: $(OBJ_DIR) $(IO_OBJS)

y_objects: $(OBJ_DIR) $(L_OUT) $(Y_OUT) $(Y_OBJS)

$(LIB) : $(OBJECT_FILES)
	ar cr $(LIB) $?
	@ if [ "${TRICK_RANLIB}" != "" ] ; then \
	     echo ${TRICK_RANLIB} $(LIB) ; \
	     ${TRICK_RANLIB} $(LIB) ; \
	  fi

$(SHARED_LIB) : $(OBJECT_FILES)
	gcc -shared -o $(SHARED_LIB) $(OBJECT_FILES) 

$(OBJ_DIR):
	@ mkdir -p $(OBJ_DIR)
	@ echo "Created $(OBJ_DIR)"

#
# IO_OBJS
#

$(IO_C_OBJS): $(OBJ_DIR)/%.o : $(IO_SRC_DIR)%.c
	$(TRICK_CC) $(TRICK_CFLAGS) -c $< -o $@

$(IO_CPP_OBJS): $(OBJ_DIR)/%.o : $(IO_SRC_DIR)%.cpp
	$(TRICK_CPPC) $(TRICK_CXXFLAGS) -c $< -o $@

#
#
# C_OBJS
#

$(C_OBJS): $(OBJ_DIR)/%.o : $(SRC_DIR)%.c
	$(CD_CMD) $(TRICK_CC) $(TRICK_CFLAGS) -c ${<F} -o $(UP_DIR)$@

#
# CPP_OBJS
#

$(CPP_C_OBJS): $(OBJ_DIR)/%.o : $(SRC_DIR)%.C
	$(CD_CMD) $(TRICK_CPPC) $(TRICK_CFLAGS) -c ${<F} -o $(UP_DIR)$@

$(CPP_CC_OBJS): $(OBJ_DIR)/%.o : $(SRC_DIR)%.cc
	$(CD_CMD) $(TRICK_CPPC) $(TRICK_CXXFLAGS) -c ${<F} -o $(UP_DIR)$@

$(CPP_CPP_OBJS): $(OBJ_DIR)/%.o : $(SRC_DIR)%.cpp
	$(CD_CMD) $(TRICK_CPPC) $(TRICK_CXXFLAGS) -c ${<F} -o $(UP_DIR)$@

$(CPP_CXX_OBJS): $(OBJ_DIR)/%.o : $(SRC_DIR)%.cxx
	$(CD_CMD) $(TRICK_CPPC) $(TRICK_CXXFLAGS) -c ${<F} -o $(UP_DIR)$@

$(CPP_CPLUS_OBJS): $(OBJ_DIR)/%.o : $(SRC_DIR)%.c++
	$(CD_CMD) $(TRICK_CPPC) $(TRICK_CXXFLAGS) -c ${<F} -o $(UP_DIR)$@

#
# LEX/YACC SOURCE
#

$(L_OUT) : $(SRC_DIR)%.clex : $(SRC_DIR)%.l
	$(CD_CMD) $(LEX) -o${@F} ${<F}

$(Y_OUT) : $(SRC_DIR)%.c : $(SRC_DIR)%.y
	$(CD_CMD) $(YACC) -o${@F} ${<F}

$(Y_OBJS) : $(OBJ_DIR)/%.o : $(SRC_DIR)%.c $(SRC_DIR)%.clex
	$(CD_CMD) $(TRICK_CC) $(TRICK_CFLAGS) -c ${<F} -o $(UP_DIR)$@

#
#
# F_OBJS
#

$(F_OBJS): $(OBJ_DIR)/%.o : $(SRC_DIR)%.f
	$(CD_CMD) $(TRICK_FC) $(FTN_PRE_DEFS) $(TRICK_FTNFLAGS) $(FTN_POST_DEFS) -c ${<F} -o $(UP_DIR)$@

#
# ICG Target
#

ICG: io_clean $(OBJ_DIR) $(IO_OBJS)
	@ echo "IO files are up to date!"

#############################################################################
##                         MAINTENANCE TARGETS                             ##
#############################################################################

depend:
	@ $(TRICK_CC) -MM $(TRICK_CXXFLAGS) $(MAKEDEP_CPP_INC) $(C_SRC) >> $(DEPTEMPFILE)
	@ $(PERL) ${TRICK_HOME}/bin/depend_cp $(DEPTEMPFILE) > $(DEPFILE)
	@ $(RM) $(DEPTEMPFILE)
	@ echo "Created dependency file $(DEPFILE)"

io_clean: 
	$(RM) -rf io_src

real_clean: clean io_clean catalog_clean
	$(RM) -rf xml *~ *.bak core
	@ echo "Directory is really clean!"

clean: 
ifeq ($(notdir $(LIB)),libtrick.a)  
	$(RM) -rf $(OBJ_DIR) $(L_OUT) $(Y_OUT)
else
	$(RM) -rf $(LIB) $(OBJ_DIR) $(L_OUT) $(Y_OUT)
endif
	@ echo "Object files successfully removed"

catalog_clean : 
	@ echo y | catalog -dp $(CURDIR)
	@ echo "Catalog purged"

catalog : catalog_clean $(IO_SRC)
	MIS
	@ echo "$(CURDIR) Catalog rebuilt"

help :
	@ echo -e "\n\
Source Directory Make Options:\n\
    make               - Compiles are source files\n\
\n\
    make ICG           - Deletes the io_src directory and runs ICG\n\
                         on all pertinent *.h files\n\
\n\
    make catalog       - Deletes the local catalog and builds a new one\n\
\n\
    make depend        - Adds file dependencies to Makefile\n\
\n\
    make io_clean      - Deletes the local io_src directory\n\
\n\
    make catalog_clean - Deletes the local catalog directory\n\
\n\
    make clean         - Deletes the object code directory\n\
\n\
    make real_clean    - Deletes xml/, io_src/,\n\
                         and lib_${TRICK_HOST_CPU}/ directories\n"

ifeq ($(wildcard makefile_overrides),makefile_overrides)
include makefile_overrides
endif

-include Makefile_deps

