Learning Objective ------------------ To understand gcc source structure, and pin down the dependencies of various files using BuildBrowser tool. In particular, understand the parts that depend on the machine description files (files with the extension `.md'). A file t depends on another file s is if s is required to to create t; we call s as the source of the dependency and t as the target of the dependency. For simplicity, we exclude the header files from consideration as source files. We generically refer to C source files by `.c' files, the object files by `.o' files, the machine description files by `.md' files, and the archive files by `.a' files. We assume that the executable files do not have any extension. Warning! -------- Before you get into this assignement conduct the following check. $ python --version The output of this command would be one of the following: A python 2.6.6 B /bin/bash: python: command not found Output A above indicates that your system has Python version 2.6.6 installed on it. Output B above says that the system does not have support for Python. If you are using Ubuntu or Debian, you can install it using the following command. $ sudo apt-get install python Prologue -------- The gcc build is long winding complex process. It involves A) compiling simple `.c' files to `.o' files, B) generate `.c' files from `.md' files, C) combine multiple `.o' files into a `.a' file etc. This process involves a large source repository (nearly 70,000 files). It is very difficult to examine each line of the make output, and pick some key information, or understand the underlying structure of these sources. Consider the following make dependencies: 1 $BUILD/gcc/build/gengtype-parse.o `- $SOURCE/gcc/gengtype-parse.c This is obvious as x.o depends on x.c. In our terminology, x.o is the target and x.c is the source. 2 $BUILD/gcc/cc1 +- $BUILD/gcc/attribs.o +- $BUILD/gcc/c-aux-info.o +- $BUILD/gcc/c-convert.o . . . `- $BUILD/libiberty/libiberty.a This one is not easy; we see that the target cc1 depends on many sources which include attribs.o libiberty.a among other `.o' files. It is important to note that every source may itself be a target which depends on other sources e.g. libiberty.a depends on several `.o's and those `.o's in turn depend on the corresponding `.c' files etc. We will study and use a tool, called BuildBrowser, or just bb.py, which will be very handy in developing this understanding. BuildBrowser Program Usage -------------------------- The BuildBrowser Program, bb.py, examines output of make and generates dependancy tree(s) as the per the comand line options. The output of the command $ ./bb.py -h is as follows: --------------------------------------------------------------- Usage: ./bb.py [options] -s src_dir options -h, --help show this help message -s, --source=src_dir dir which will apprear as $SOURCE -r uses reverse mapping from dependency -> target -i enter interactive search -o, --output=filename output file name for -x and -t -t store the tree in output file -x store the XML format in a output file -x,-i and -t are mutually exclusive options default file name for -x is cc1.xml default file name for -t is cc1.txt log_filename is optional and by default it is make.log --------------------------------------------------------------- Note the following: - Providing a complete path with `-s' option is mandatory. - bb.py should be an executable file. Use the command $ chmod u+x bb.py Alternatively, use the command $ python bb.py ... We will use bb.py with `-i' option to interactively identify the sources on which a given target depends. In order to identify the targets which depend on a give source, we will use the `-r' option. Problem 1: Find out the source of the target "toplev.o". Problem 2: Find out the sources of the following three files. a insn-recog.c b insn-output.c c insn-emit.c Find out the transive dependencies by discovering the sources of the sources that you find. For convenience, ignore the `.a' files. Further, you may want to use tell bb.py to directly find the dependencies upto depth 3. Problem 3: List all `.c' files that depend on spim1.md. Procedure --------- 1 Ensure that you have the output of "make cc1" as "make.log" file. If you do not have such a file, you need to: $ make distclean $ ... configure --target=spim1 $ (The above steps as per "build-spim.txt" guidelines) $ make cc1 > make.log 2> make.err Once the above files is ready, we need not build it again and again. If you are running bb.py from some other directory, you will have to change "make.log" to it's exact path. 2 Execute bb.py on the "make.log". $ ./bb.py -i -s $SOURCE make.log You will have to answer the questions posed by bb.py. Remember this is an interactive session, you will have to enter other commands, observe the results, till you are satisfied. As a special case, if you enter "^cc1$" (without quotes, there are just 5 characters carrot-c-c-1-dollar) you will be able to see the sources on which the target cc1 depends. 3 For the targets that depend on spim1.md, we need to use the reverse mapping mode. The command will be: $ ./bb.py -r -i -s $SOURCE make.log (-r for reverse). Conclusion ---------- From the exercise above you have viewed several file names. Take any one of them, find its source, and find where all it feeds in. If you can do that this exercise does not require any other formal conclusion. Take a try, worth the effort. Additionaly this tool reveals more than what is actualy there. The generated intermediate files! This is very important lesson here. GCC has several generated files, which are very faintly trackable to the sources. The BuildBrowser serves as a handy tool for this purpose too.