# Makefile.in # this is the Makefile for Elsa, the Elkhound-based C++ Parser #temporary: iptree iptparse cipart smin # main target: a C++ parser all: cc.ast.gen.h tlexer ccparse quicktest # work in progress.. #iptree smin cipart # directories of other software SMBASE := @SMBASE@ AST := @AST@ ELKHOUND := @ELKHOUND@ # stuff inside those other directories LIBSMBASE := $(SMBASE)/libsmbase.a LIBAST := $(AST)/libast.a LIBELKHOUND := $(ELKHOUND)/libelkhound.a # external tools PERL := @PERL@ MYFLEX := $(PERL) $(SMBASE)/run-flex.pl -nobackup -copies # list of files to clean in 'clean' (etc.) targets # (these get added to below) TOCLEAN = TOTOOLCLEAN = TODISTCLEAN = # re-create the Makefile if Makefile.in has changed TODISTCLEAN += Makefile Makefile: Makefile.in config.status ./config.status # reconfigure if the configure script has changed config.status: configure.pl $(SMBASE)/sm_config.pm ./config.status -reconfigure # dependencies upon automatically-generated files extradep.mk: $(PERL) $(ELKHOUND)/find-extra-deps *.d >$@ -include extradep.mk # modules to compile with coverage info; I do not build them # all with coverage info because it takes about 25% longer to # compile for each module with coverage info GCOV_MODS := @GCOV_MODS@ TOCLEAN += *.bb *.bbg *.da # --------------------- extension modules ---------------------- # base modules LEXER_MODS := cc.lex TOK_MODS := cc_tokens.tok CC_AST_MODS := cc.ast CC_GR_MODS := cc.gr EXT_OBJS := # type checker CC_AST_MODS += cc_tcheck.ast # pretty printer CC_AST_MODS += cc_print.ast # control flow graph CC_AST_MODS += cfg.ast # elaboration pass CC_AST_MODS += cc_elaborate.ast # optional: GNU language extension USE_GNU := @USE_GNU@ ifeq ($(USE_GNU),1) LEXER_MODS += gnu.lex TOK_MODS += gnu_ext.tok CC_AST_MODS += gnu.ast CC_GR_MODS += gnu.gr EXT_OBJS += gnu.o endif # optional: K&R language extension USE_KANDR := @USE_KANDR@ ifeq ($(USE_KANDR),1) CC_AST_MODS += kandr.ast CC_GR_MODS += kandr.gr EXT_OBJS += kandr.o endif # ----------------------- compiler configuration ------------------- # C++ preprocessor, compiler and linker CXX := g++ # flags for the C++ compiler (and preprocessor) CCFLAGS := @CCFLAGS@ -DXML -Woverloaded-virtual -I$(SMBASE) -I$(AST) -I$(ELKHOUND) # how to enable coverage GCOV_OPTS := -fprofile-arcs -ftest-coverage # flags for the linker libraries := $(LIBELKHOUND) $(LIBAST) $(LIBSMBASE) LDFLAGS := @LDFLAGS@ $(libraries) # compile .cc in this directory to a .o TOCLEAN += *.o *.d %.o: %.cc $(CXX) -c -o $@ $< $(if $(findstring $*,$(GCOV_MODS)),$(GCOV_OPTS) )$(CCFLAGS) @$(PERL) $(SMBASE)/depend.pl -o $@ $< $(CCFLAGS) >$*.d # compile a special module; -O0 will override any earlier setting notopt.o: notopt.cc $(CXX) -c -o $@ $< $(CCFLAGS) -O0 @$(PERL) $(SMBASE)/depend.pl -o $@ $< $(CCFLAGS) -O0 >$*.d # ------------------------ tlexer ------------------- LEXER_OBJS := \ cc_lang.o \ baselexer.o \ lexer.o \ lexer.yy.o \ cc_tokens.o -include $(LEXER_OBJS:.o=.d) -include tlexer.d # program to test the lexer alone TOCLEAN += tlexer tlexer: tlexer.o $(LEXER_OBJS) $(libraries) $(CXX) -o $@ tlexer.o $(LEXER_OBJS) $(LDFLAGS) # ------------------------- ccparse --------------------- # combine base lexer description and extensions TOCLEAN += lexer.lex lexer.lex: $(LEXER_MODS) merge-lexer-exts.pl rm -f $@ $(PERL) merge-lexer-exts.pl $(LEXER_MODS) >$@ chmod a-w $@ # run flex on the lexer description TOCLEAN += lexer.yy.cc lexer.yy.cc: lexer.lex lexer.h $(MYFLEX) -o$@ lexer.lex TOCLEAN += astxml_lexer.lex astxml_lexer.lex: astxml_lexer0_top.lex astxml_lexer1_mid.gen.lex astxml_lexer1_type.lex astxml_lexer2_bottom.lex rm -f $@ cat $^ > $@ chmod a-w $@ # typesystem xml lexer files generated by astxml_type_tok.pl XML_TYPE_LEXER := XML_TYPE_LEXER += astxml_lexer1_type.cc XML_TYPE_LEXER += astxml_lexer1_type.lex XML_TYPE_LEXER += astxml_tokens1_type.h TOCLEAN += $(XML_TYPE_LEXER) $(XML_TYPE_LEXER): astxml_type_tok.pl rm -f $@ $(PERL) ./$< # ast xml lexer/parser files generated by astgen XML_PARSER_GEN := XML_PARSER_GEN += astxml_lexer1_mid.gen.cc XML_PARSER_GEN += astxml_lexer1_mid.gen.lex XML_PARSER_GEN += astxml_tokens1_mid.gen.h XML_PARSER_GEN += astxml_parse1_0decl.gen.cc XML_PARSER_GEN += astxml_parse1_1defn.gen.cc XML_PARSER_GEN += astxml_parse1_2ctrc.gen.cc XML_PARSER_GEN += astxml_parse1_3regc.gen.cc # Note that astxml_lexer.cc actually #include-s # astxml_lexer1_mid.gen.cc and astxml_lexer1_type.cc astxml_lexer.o: astxml_lexer1_mid.gen.cc astxml_lexer1_type.cc # and main_astxmlparse.cc includes all four astxml_parse1*.gen.cc # files main_astxmlparse.o: $(XML_PARSER_GEN) TOCLEAN += $(XML_PARSER_GEN) $(XML_PARSER_GEN): $(CC_AST_MODS) $(AST)/astgen rm -f $(XML_PARSER_GEN) $(AST)/astgen -tr no_ast.gen,xmlParser $(CC_AST_MODS) chmod a-w $(XML_PARSER_GEN) ASTXML_LEXER_OBJS := \ astxml_lexer.o \ astxml_lexer.yy.o -include $(ASTXML_LEXER_OBJS:.o=.d) # run flex on the lexer description for ast xml parser TOCLEAN += astxml_lexer.yy.cc astxml_lexer.yy.cc: astxml_lexer.lex astxml_lexer.h $(MYFLEX) -o$@ astxml_lexer.lex # when building the ast xml lexer, delete the methods that would # otherwise conflict with methods in lexer.yy.cc; they have identical # implementations astxml_lexer.yy.o: astxml_lexer.yy.cc $(CXX) -c -o $@ $< -DNO_YYFLEXLEXER_METHODS $(CCFLAGS) @$(PERL) $(SMBASE)/depend.pl -o $@ $< -DNO_YYFLEXLEXER_METHODS $(CCFLAGS) >$*.d # generate token lists TOK_FILES := cc_tokens.h cc_tokens.cc cc_tokens.ids TOCLEAN += $(TOK_FILES) $(TOK_FILES): $(TOK_MODS) make-token-files rm -f $(TOK_FILES) $(PERL) ./make-token-files $(TOK_MODS) chmod a-w $(TOK_FILES) astxml_lexer.o: astxml_tokens.h TOCLEAN += astxml_tokens.h astxml_tokens.h: astxml_tokens0_top.h astxml_tokens1_mid.gen.h astxml_tokens1_type.h astxml_tokens2_bottom.h rm -f $@ cat $^ > $@ chmod a-w $@ # # generate token lists for parsing ast xml # TOCLEAN += astxml_tokens.ids # astxml_tokens.ids: astxml_tokens.h # rm -f $@ # $(ELKHOUND)/make-tok ASTXMLTokenType $@ # chmod a-w $@ # run astgen to generate the AST implementation TOCLEAN += cc.ast.gen.h cc.ast.gen.cc cc.ast.gen.h cc.ast.gen.cc: $(CC_AST_MODS) $(AST)/astgen $(AST)/astgen -occ.ast.gen $(CC_AST_MODS) # run elkhound to generate the parser TOCLEAN += cc.gr.gen.h cc.gr.gen.cc cc.gr.gen.out cc.gr.gen.h cc.gr.gen.cc: $(CC_GR_MODS) cc_tokens.ids $(ELKHOUND)/elkhound $(ELKHOUND)/elkhound -v -tr lrtable -o cc.gr.gen $(CC_GR_MODS) # list of modules needed for the parser; ideally they're in an order # that finds serious compilation problems earliest (it's ok to # rearrange as different parts of the code are in flux) CCPARSE_OBJS := \ mtype.o \ integrity.o \ astvisit.o \ template.o \ notopt.o \ cc_env.o \ cc_tcheck.o \ const_eval.o \ implint.o \ serialno.o \ cc_scope.o \ cc_elaborate.o \ ast_build.o \ $(LEXER_OBJS) \ $(ASTXML_LEXER_OBJS) \ $(EXT_OBJS) \ builtinops.o \ cfg.o \ sprint.o \ mangle.o \ cc_err.o \ cc_type.o \ cc_type_xml.o \ stdconv.o \ implconv.o \ overload.o \ typelistiter.o \ cc.ast.gen.o \ cc.gr.gen.o \ parssppt.o \ cc_flags.o \ cc_print.o \ cc_ast_aux.o \ variable.o \ lookupset.o \ xml.o \ main_astxmlparse.o \ ccparse.o -include $(CCPARSE_OBJS:.o=.d) main.d # parser binary TOCLEAN += ccparse ccparse: $(CCPARSE_OBJS) main.o $(libraries) $(CXX) -o $@ $(CCPARSE_OBJS) main.o $(LDFLAGS) # run the binary; the 'quicktest' file is so we don't run it if # 'ccparse' hasn't recently changed TOCLEAN += quicktest quicktest: ccparse ./ccparse in/t0001.cc @touch quicktest @echo BUILD FINISHED # -------------------- semgrep -------------------- TOCLEAN += semgrep semgrep: $(CCPARSE_OBJS) semgrep.o $(libraries) $(CXX) -o $@ $(CCPARSE_OBJS) semgrep.o $(LDFLAGS) # --------------------- iptree -------------------- TOCLEAN += iptree iptree: iptree.cc $(LIBSMBASE) $(CXX) -o $@ $(CCFLAGS) -DTEST_IPTREE iptree.cc $(LDFLAGS) # -------------------- iptparse ------------------- TOCLEAN += iptparse iptparse: iptparse.cc iptree.o iptparse.yy.o $(LIBSMBASE) $(CXX) -o $@ $(CCFLAGS) -DTEST_IPTPARSE iptparse.cc iptree.o iptparse.yy.o $(LDFLAGS) # ---------------------- smin --------------------- # lexer for interval partition tree specs TOCLEAN += iptparse.yy.cc iptparse.yy.cc: iptparse.lex flex -o$@ iptparse.lex iptparse.yy.o: iptparse.h SMIN_OBJS := \ iptparse.o \ iptparse.yy.o \ iptree.o \ smin.o -include $(SMIN_OBJS:.o=.d) TOCLEAN += smin smin: $(SMIN_OBJS) $(LIBSMBASE) $(CXX) -o $@ $(SMIN_OBJS) $(LDFLAGS) # --------------------- cipart -------------------- TOCLEAN += cipart.yy.cc cipart.yy.cc: cipart.lex flex -o$@ cipart.lex -include cipart.yy.d cipart: cipart.yy.o $(LIBSMBASE) $(CXX) -o $@ cipart.yy.o $(LDFLAGS) # ---------------------- misc --------------------- # rule to decompress one of the big examples TODISTCLEAN += in/big/*.i in/big/%.i: in/big/gz/%.i.gz gunzip -c <$^ >$@ # comment out line directives $(PERL) -i -lpe 's|^\W*(#.*)$$|//$$1|' $@ # this line is illegal C++ and for now we just comment it out $(PERL) -i -lpe 's|^(\W*)(char ip_opts\[40\];)\W*$$|$$1//$$2|' $@ # change "((void *)0)" to "0" to compensate for a bad NULL macro somewhere... $(PERL) -i -lpe 's|\(\(void \*\)0\)|0|' $@ # define bad_alloc, don't just declare it $(PERL) -i -lpe 's|class bad_alloc;|class bad_alloc {};|' $@ # decompress all of them which haven't already been decompressed .PHONY: in/big in/big: $(patsubst in/big/gz/%.i.gz,in/big/%.i,$(wildcard in/big/gz/*.gz)) @echo made $@ # ------------------ documentation ------------------ gendoc: mkdir gendoc gendoc/configure.txt: configure ./configure --help >$@ .PHONY: gendoc/dependencies.dot gendoc/dependencies.dot: $(PERL) $(SMBASE)/scan-depends.pl -r \ -Xcc_env.h=1 -Xcc_type.h=1 -Xcc_flags.h=1 -Xcc_ast.h=1 -Xvariable.h=1 \ -Xcc_print.h -Xsprint.h -Xcc_type_xml.h -Xmain_astxmlparse.h \ -Xgeneric_aux.h -Xcc_ast_aux.h -Xcc_lang.h=1 \ main.cc cc_tcheck.cc >$@ gendoc/3.4.5.dot: ccparse in/std/3.4.5.cc ./ccparse -tr printHierarchies in/std/3.4.5.cc | \ $(PERL) ./chop_out "--- E ---" "--- F ---" >$@ # because of the above dependency on ccparse, if someone does 'make doc' # without first building Elsa, they get an error about libsmbase.a; so # this is an attempt to deal with that more gracefully $(SMBASE)/libsmbase.a: @echo "You have to build smbase, ast and elkhound first." @exit 2 # check to see if they have dot .PHONY: dot dot: @if ! which dot >/dev/null; then \ echo "You don't have the 'dot' tool. It is part of graphviz, available at:"; \ echo "http://www.research.att.com/sw/tools/graphviz/"; \ exit 2; \ fi # use 'dot' to lay out the graph %.ps: %.dot dot dot -Tps <$*.dot >$@ # use 'convert' to make a PNG image with resolution not to exceed # 1200 in X or 1000 in Y ('convert' will preserve aspect ratio); this # also antialiases, so it looks very nice (it's hard to reproduce # this using 'gs' alone) %.png: %.ps convert -geometry 1200x1000 $^ $@ # 3.4.5 is smaller gendoc/3.4.5.png: gendoc/3.4.5.ps convert -geometry 300x400 $^ $@ .PHONY: doc doc: gendoc gendoc/configure.txt gendoc/dependencies.png gendoc/3.4.5.png @echo "built documentation" #TOCLEAN += TAGS #TAGS: # @ETAGS@ *.cc *.h # -------------------- count source lines ------------------- # dsw: This should give the right answer even after a "make all", # since we filter the generated files. # # sm: I haven't carefully inspected the set of files counted, # and it appears to not count cc_tokens.tok (which it should). # I don't care about fixing right now it though. GENREGEX := '\.gen\.\|lexer\.yy\|cc_tokens' .PHONY: count-loc count-loc: @echo @echo "Count of lines of source code in this directory by file type." @echo "C++, C, and headers:" # @ls *.cc *.c *.h | grep -v $(GENREGEX) | xargs wc -l | grep total @ls *.cc *.h | grep -v $(GENREGEX) | xargs wc -l | grep total @echo "tok, lex, gr, and ast:" # @ls *_ext.tok *_ext.lex *.gr *.ast | grep -v $(GENREGEX) | xargs wc -l | grep total @ls *_ext.tok *.gr *.ast | grep -v $(GENREGEX) | xargs wc -l | grep total @echo "sum of those:" # @ls *.cc *.c *.h *_ext.tok *_ext.lex *.gr *.ast @ls *.cc *.h *_ext.tok *.gr *.ast \ | grep -v $(GENREGEX) | xargs wc -l | grep total @echo @echo "Makefiles:" @ls Makefile.in *.mk | xargs wc -l | grep total # -------------------- clean, etc. ------------------- clean: rm -f $(TOCLEAN) cd outdir && ls | grep -v CVS | xargs rm -f distclean: clean rm -f $(TODISTCLEAN) rm -f config.status config.summary rm -rf gendoc toolclean: clean rm -f $(TOTOOLCLEAN) check: semgrep all MAKE=$(MAKE) ./regrtest @echo "" @echo "Regression tests passed." # run the xml commutative diagram tests .PHONY: checkxml checkxml: $(MAKE) -f checkxml.mk