Stefan Reinauer | f8ee180 | 2008-01-18 15:08:58 +0000 | [diff] [blame] | 1 | # Coreboot codebase analysis tool |
Josiah England | 35befb7 | 2006-07-20 15:35:04 +0000 | [diff] [blame] | 2 | # |
| 3 | # This makefile collects source usage information for all working targets. |
| 4 | # |
| 5 | # Written 7/2006 by Josiah England <josiah@lanl.gov> |
| 6 | # |
| 7 | # This file is subject to the terms and conditions of the GNU General |
| 8 | # Public License. See the file COPYING in the main directory of this |
| 9 | # archive for more details. |
| 10 | |
| 11 | TOP := $(shell cd ../.. && pwd) |
| 12 | BUILD_BASE := $(TOP)/targets |
| 13 | |
| 14 | IGNORE_ERRORS := 2>/dev/null # Comment out this line for some ugly verbosity |
| 15 | IGNORE_VENDORS := emulation momentum embeddedplanet motorola totalimpact |
| 16 | IGNORE_C := static.c# romcc.c |
| 17 | |
| 18 | quote = "#" |
| 19 | |
| 20 | VENDORS := $(shell ls -l $(TOP)/targets | grep ^d | grep -Eo [[:alnum:]_-]+$$$(foreach ignored, $(IGNORE_VENDORS), | grep -v $(ignored))) |
| 21 | #<VENDOR>_BOARDS assignments |
| 22 | $(foreach VENDOR, $(VENDORS), $(eval $(VENDOR)_BOARDS := $(shell ls $(TOP)/targets/$(VENDOR)))) |
| 23 | TARGETS := $(foreach VENDOR, $(VENDORS), $(addprefix $(VENDOR)/, $($(VENDOR)_BOARDS))) |
| 24 | |
| 25 | # The following delayed-evalutate variables are only to be used in rule commands. |
| 26 | MAINBOARD = $(TOP)/src/mainboard/$(shell grep ^mainboard $(dir $*)/Config.lb|grep -Eo [-[:alnum:]_/]+[[:space:]]?$$) |
| 27 | IMAGE_DIR = $(firstword $(shell grep -Eo ^romimage[[:space:]]+\"[[:alnum:]_-/]+ $(dir $*)/Config.lb|sed -r s/romimage[[:space:]]+\"//)) |
| 28 | |
| 29 | # Evaluate one assignment to variable "$1" from file "$2" |
| 30 | load_var = $(eval $(shell grep -E ^[[:space:]]*$1[[:space:]]*:*= $2 $(IGNORE_ERRORS))) |
| 31 | |
| 32 | .PHONY: clean analysis |
| 33 | |
| 34 | analysis: analysis.dat |
| 35 | gnuplot -persist '$<' |
| 36 | |
| 37 | # Generate gnuplot data file |
| 38 | analysis.dat: analysis.txt |
| 39 | @ echo Writing gnuplot data file \($@\). |
| 40 | @ echo -e > $@ "# gnuplot dataset auto-generated $(shell date)" \ |
Stefan Reinauer | f8ee180 | 2008-01-18 15:08:58 +0000 | [diff] [blame] | 41 | "\nset title \"Coreboot Codebase Analysis\"" \ |
Josiah England | 35befb7 | 2006-07-20 15:35:04 +0000 | [diff] [blame] | 42 | "\nset style data boxes" \ |
| 43 | "\nset style fill solid .5" \ |
| 44 | $(foreach target, $(TARGETS), "\n"set label \"$(target)\" at $(words $(labels))$(eval labels += $(target)),-145 rotate front) \ |
| 45 | "\nplot [-.5:] '-' t 'Source:' , '-' t 'Nested C:' , '-' t 'Headers:' , '-' t 'romcc Sources:' , '-' t 'romcc Headers:'" |
| 46 | @ grep -F "C files" $< | grep -Eo [[:digit:]]+ >> $@ |
| 47 | @ echo e >> $@ |
| 48 | @ grep -F "Nested C" $< | grep -Eo [[:digit:]]+ >> $@ |
| 49 | @ echo e >> $@ |
| 50 | @ grep -F "Headers" $< | grep -Eo [[:digit:]]+ | sed -r s/\([[:digit:]]+\)/'-'\\1/>> $@ |
| 51 | @ echo e >> $@ |
| 52 | @ grep -F "romcc C" $< | grep -Eo [[:digit:]]+ >> $@ |
| 53 | @ echo e >> $@ |
| 54 | @ grep -F "romcc H" $< | grep -Eo [[:digit:]]+ | sed -r s/\([[:digit:]]+\)/'-'\\1/>> $@ |
| 55 | @ echo e >> $@ |
| 56 | |
| 57 | analysis.txt: $(foreach target, $(TARGETS), $(BUILD_BASE)/$(target)/$(shell grep ^target $(BUILD_BASE)/$(target)/Config.lb | grep -Eo [[:alnum:]_-]+[[:space:]]?$$)/analysis/info) |
| 58 | @ echo -e "\n\n"Compiling individual target analysis info into $@. |
| 59 | cat $? | tee -a $@ |
| 60 | |
| 61 | # Prevent automatic deletion of intermediate files |
| 62 | .SECONDARY: $(prepend $(foreach target, $(TARGETS), $(BUILD_BASE)/$(target)/$(shell grep ^target $(BUILD_BASE)/$(target)/Config.lb | grep -Eo [[:alnum:]_-]+$$)), /analysis, /analysis/c_files, /analysis/h_files, /analysis/info, /Makefile) |
| 63 | |
| 64 | # FIXME: This rule is necessary even if the Makefile already exists. |
| 65 | %/Makefile: |
| 66 | @ echo \*\*\* Building target: $(notdir $*) \*\*\* |
| 67 | -@ cd $(TOP)/targets && ./buildtarget $(dir $*) 1>>build.log 2>>builderrors.log |
| 68 | @ echo -e >> $*/$(IMAGE_DIR)/Makefile "depend:\n\t"'@ makedepend -v -f- -- $$(CPPFLAGS) -- $$(SOURCES)' |
| 69 | |
| 70 | %/analysis/c_files: %/Makefile |
| 71 | @ echo Analysis directory is $*/analysis |
| 72 | -@ mkdir $*/analysis $(IGNORE_ERRORS) |
| 73 | @ echo -n Finding C source files... |
| 74 | @ grep -Eo \\$$+[\(][A-Z_]+[\)][/-_[:alnum:]]+'\.c\>' $*/$(IMAGE_DIR)/Makefile | grep -v $(IGNORE_C) | sort -u > $@ |
| 75 | @ echo " "Done. |
| 76 | |
| 77 | # Grep for .c files #included within others (only one level deep). |
| 78 | # sed commands provide full pathname for included .c files, assuming two things: |
| 79 | # 1. If include statement has no directory component, the file is in same dir. |
| 80 | # 2. If included file has a directory component, it's base is from $(TOP)/src/. |
| 81 | %/analysis/nested_c_files: %/analysis/c_files |
| 82 | @ echo -n Finding nested .c includes... |
| 83 | $(eval c_files := $(shell cat $<)) |
| 84 | @ grep -Eo '\#'include[[:space:]\"]+[/-_[:alnum:]]+'\.c' $(c_files) | sed s/\#include[[:space:]]// > $@.tmp |
| 85 | @ sed -r s/\([/-_[:alnum:]]+\\/\)\([-_[:alnum:]]+'.c'\):\"\([-_[:alnum:]]+'.c'$$\)/\\1\\2:' '\\1\\3/ $@.tmp | \ |
| 86 | sed -r s/\([/-_[:alnum:]]+\\/\)\([-_[:alnum:]]+'.c'\):\"\([/-_[:alnum:]]+'.c'$$\)/\\1\\2:' '\$$\(TOP\)\\/src\\/\\3/ > $@ |
| 87 | @ rm $@.tmp |
| 88 | @ echo " "Done. |
| 89 | |
| 90 | %/analysis/h_files: %/analysis/c_files %/analysis/nested_c_files |
| 91 | @ echo -n Finding all included headers... |
| 92 | $(call load_var,TARGET_DIR, $*/Makefile.settings) |
| 93 | @ $(MAKE) -C $(TARGET_DIR)/$(IMAGE_DIR) depend $(IGNORE_ERRORS) | grep -v makedepend | grep -Eo [/-_[:alnum:]]+'\.h' | sort -u > $@ && \ |
| 94 | $(MAKE) -C $(TARGET_DIR)/$(IMAGE_DIR) "SOURCES := $(shell grep [/-_[:alnum:]]+'.c' $(word 2, $?))" depend $(IGNORE_ERRORS) | grep -v makedepend | grep -Eo [/-_[:alnum:]]+'\.h' | sort -u >> $@ |
| 95 | @ echo " "Done. |
| 96 | |
| 97 | #%/auto.inc: |
| 98 | |
| 99 | # Determine which sources use romcc by their inclusion in auto.inc #FIXME better |
| 100 | %/analysis/romcc_files: %/analysis/c_files %/analysis/nested_c_files |
| 101 | $(call load_var,TARGET_DIR, $*/Makefile.settings) |
| 102 | @ $(if $(findstring cache_as_ram, $(shell cat $<)), \ |
| 103 | echo none, \ |
| 104 | echo -n \* Uses romcc - making auto.inc... && \ |
| 105 | $(MAKE) -iC $(TARGET_DIR)/$(IMAGE_DIR) auto.inc $(IGNORE_ERRORS) 1>/dev/null && \ |
| 106 | echo " "to find sources that use romcc. && \ |
| 107 | grep -Eo [/-_[:alnum:]]+'\.c' $(TARGET_DIR)/$(IMAGE_DIR)/auto.inc | sort -u) \ |
| 108 | > $@ |
| 109 | |
| 110 | # Full pathnames of found files are gathered from nested_c_files and c_files. |
| 111 | %/analysis/romcc_sources: %/analysis/c_files %/analysis/nested_c_files %/analysis/romcc_files |
| 112 | @ echo -e $(foreach file, $(shell cat $(dir $@)/romcc_files), "\n"'$(firstword $(shell grep -Eho [/-_\$$\(\)[:alnum:]]+/'$(file)' $(dir $@)/nested_c_files $(dir $@)/c_files))') >$@ |
| 113 | |
| 114 | %/analysis/romcc_headers: %/analysis/romcc_sources |
| 115 | @ echo -n Finding headers used by any romcc source... |
| 116 | $(eval romcc_sources = $(shell cat $(dir $@)/romcc_sources)) |
| 117 | $(call load_var,TARGET_DIR, $*/Makefile.settings) |
| 118 | @ $(MAKE) -C $(TARGET_DIR)/$(IMAGE_DIR) "SOURCES := $(romcc_sources)" depend $(IGNORE_ERRORS) | grep -v makedepend | grep -Eo [/-_[:alnum:]]+'\.'h | sort -u > $@ |
| 119 | @ echo " "Done. |
| 120 | |
| 121 | $(BUILD_BASE)/%/analysis/info: $(BUILD_BASE)/%/analysis/h_files $(BUILD_BASE)/%/analysis/romcc_headers |
| 122 | @ echo -e Target: $(subst /, , $(dir $*)) \ |
| 123 | "\n"Uses $(if $(findstring cache_as_ram, $(shell grep -F '.c' $(dir $@)/c_files)),CAR,romcc) \ |
| 124 | "\n"C files: $(shell grep -Eo [-_[:alnum:]]+'\.c' $(dir $@)/c_files $(dir $@)/nested_c_files $(dir $@)/romcc_sources | sort -u | grep -Fc '.c') \ |
| 125 | "\n"Nested C: $(shell grep -Eo [-_[:alnum:]]+'\.c' $(dir $@)/nested_c_files | sort -u | grep -Fc '.c') \ |
| 126 | "\n"Headers: $(shell grep -Eo [-_[:alnum:]]+'\.h' $(dir $@)/h_files $(dir $@)/romcc_headers | sort -u | grep -Fc '.h') \ |
| 127 | "\n"romcc C: $(shell grep -Ec [-_[:alnum:]]+'\.c' $(dir $@)/romcc_sources) \ |
| 128 | "\n"romcc H: $(shell grep -Ec [-_[:alnum:]]+'\.h' $(dir $@)/romcc_headers) \ |
| 129 | "\n">> $@ |
| 130 | |
| 131 | clean-builds: |
| 132 | rm -rf $(foreach target, $(TARGETS), $(BUILD_BASE)/$(target)/$(shell grep ^target $(BUILD_BASE)/$(target)/Config.lb | grep -Eo [[:alnum:]_-]+[[:space:]]?$$)) |
| 133 | |
| 134 | clean: |
| 135 | rm -rf $(foreach target, $(TARGETS), $(BUILD_BASE)/$(target)/$(shell grep ^target $(BUILD_BASE)/$(target)/Config.lb | grep -Eo [[:alnum:]_-]+[[:space:]]?$$)/analysis) analysis.txt analysis.dat |