# DESCRIPTION: Perl ExtUtils: Type 'perl Makefile.PL' to create a Makefile for this package
#
# Copyright 2000-2014 by Wilson Snyder.  This program is free software;
# you can redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License Version 2.0.

use ExtUtils::MakeMaker;
use Config;

sub MY::postamble {
    my $out;
    #print Config::myconfig();
    if ($Config{osname} !~ /cygwin/i && $Config{archname} !~ /cygwin/i
	&& $Config{osname} !~ /darwin/i && $Config{archname} !~ /darwin/i) {
	# Cygwin: Don't change LD, it breaks
	# Sun: Requires g++ LD
	# Linux: Either way
	$out .= "LD = g++\n";
    }
    # Note OPTIMIZE is passed from upper makefile, so this code needed there too.
    my $optimize = $Config{optimize};  $optimize =~ s/(^| )-O2( |$)/\1-O\2/g;
    $out .= "OPTIMIZE = $optimize\n";
    if ($Config{osname} =~ /cygwin/i || $Config{archname} =~ /cygwin/i) {
	# Cygwin ExtUtils::MakeMaker ignores our LIBS declaration and says
	# "No library found for -lstdc++".  Force it.
	$out .= "LDLOADLIBS += -lstdc++\n";
	# Cygwin: High optimization causes g++ "out of memory"
	$out .= "OPTIMIZE += -O\n";
    }
    if ($Config{osname} =~ /darwin/i || $Config{archname} =~ /darwin/i) {
	# MakeMaker wants to create bundles on MacOSX rather than dylibs. We override DLEXT and LDDLFLAGS generated by MakeMaker in this case
	$out .= "DLEXT = dylib\n";
	if ($^V eq '5.12.4') {
	    $out .= sprintf("LDDLFLAGS = -dynamiclib -lstdc++ -L/System/Library/Perl/5.12/%s/CORE -lperl -L/usr/local/lib\n",$Config{archname});
	} else {
	    $out .= sprintf("LDDLFLAGS = -dynamiclib -lstdc++ -L/System/Library/Perl/%vd/%s/CORE -lperl -lgcc_eh -L/usr/local/lib\n",$^V,$Config{archname});
	}
    }
    # The ../Makefile.PL will override these if make is called from there!
    $out .= "CCFLAGS  += -Wall -Wno-unused -Werror\n" if $ENV{VERILATOR_AUTHOR_SITE};
    $out .= "CCFLAGS  += $ENV{VERILOGPERL_CCFLAGS}\n" if defined $ENV{VERILOGPERL_CCFLAGS};
    $out .= "OPTIMIZE += -Wno-unused\n" if $ENV{VERILATOR_AUTHOR_SITE};  # Makefile has another -Wall
    $out .= "OPTIMIZE += $ENV{VERILOGPERL_CCFLAGS}\n" if defined $ENV{VERILOGPERL_CCFLAGS};
    $out .= "CCFLAGS += -I\$(PPSRC)\n";
    my $cmt = $ENV{VERILOGPERL_FLEX_DEBUG} ? "" : "#";
    $out .= "${cmt}CFLAGS += -DFLEX_DEBUG\n";
    $out .= "LEXFLAGS += -d\n";
    $out .= '
CC = $(OBJCACHE) g++
LEX = flex
YACC = bison
PPSRC = ../Preproc
FLEXFIX = $(PPSRC)/flexfix
TOOLHASH = $(PPSRC)/toolhash
XSUBPPFIX = $(PPSRC)/xsubppfix

VPATH += . $(PPSRC)

VHEADERS = VParseLex.h VParseGrammar.h VParse.h VFileLine.h VParseBison.h \
	VSymTable.h VAst.h Parser_callbackgen.cpp

VParseLex.o:		VParseLex.cpp     $(VHEADERS)
VParseGrammar.o:	VParseGrammar.cpp $(VHEADERS)
VParseBison.o:		VParseBison.cpp   $(VHEADERS)
VParse.o:		VParse.cpp        $(VHEADERS)
VFileLine.o:	        VFileLine.cpp     $(VHEADERS)
VAst.o:		        VAst.cpp	  $(VHEADERS)
VSymTable.o:	        VSymTable.cpp     $(VHEADERS)

VFileLine.o: $(PPSRC)/VFileLine.cpp
	$(CCCMD) $(CCCDLFLAGS) "-I$(PERL_INC)" $(PASTHRU_DEFINE) $(DEFINE) $<

VParseLex_pretmp.cpp: VParseLex.l
	-$(LEX) --version
	$(PERL) $(TOOLHASH) --verbose --in $< --out $@ --cmd $(LEX) $(LEXFLAGS) -o$@ $<

VParseLex.cpp: $(FLEXFIX) VParseLex_pretmp.cpp
	$(PERL) $(FLEXFIX) VParseLex < VParseLex_pretmp.cpp > $@

VParseBison.h: VParseBison.cpp

VParseBison.cpp:	VParseBison.y bisonpre
	-$(RM_RF) VParseBison.c VParseBison.cpp
	-${YACC} --version | head -1
	@echo "Note: toolhash ignores VParseBison.output; remove gen/ if you want to debug the grammar"
	@echo "Note: If the next command fails, you probably need to install Bison 1.875 or newer"
	$(PERL) $(TOOLHASH) --verbose --name bisonpre --vercmd bison --skip-cmd 1 \
		--in VParseBison.y bisonpre \
		--out VParseBison.c VParseBison.h \
		--cmd $(PERL) bisonpre --yacc ${YACC} --debug --verbose --d -p VParseBison -k VParseBison.y -o VParseBison.c
	mv VParseBison.c VParseBison.cpp

Parser_callbackgen.cpp: callbackgen
	$(PERL) callbackgen

Parser_cleaned.c: Parser.c $(VHEADERS)
	$(PERL) $(XSUBPPFIX) < Parser.c > Parser_cleaned.c

clean::
	-$(RM_RF) test *.d *.o *.output *.pre.* *_pretmp.*
	-$(RM_RF) VParseLex*.cpp VParseBison.h VParseBison.cpp Parser_cleaned.c
	-$(RM_RF) Parser_callbackgen.cpp
';
    return $out;
}

# Grr; some flags cause warnings in g++
(my $ccflags = $Config{ccflags}) =~ s/ *-Wdeclaration-after-statement//;

WriteMakefile(
              NAME => "Verilog::Parser",
	      LIBS => '-lstdc++',
	      VERSION_FROM  => 'Parser.pm',
	      XSOPT => '-C++',
	      CCFLAGS	=> $ccflags,
	      OBJECT   => 'VFileLine.o VParseLex.o VParse.o VParseBison.o VSymTable.o VAst.o ',
	      MYEXTLIB => 'Parser_cleaned.o',
	      );
