GNU Make Print Commands Before Executing

- - | Comments

複雜的大型程式有時很難搞清楚它們是怎麼被build出來的, 如果我們能看到GNU Make在執行Makefile時做了些什麼, 那麼狀況就會變得很清楚.

另外, 像是Android.mk, 最終負責執行它的內容的程式, 其實也是GNU Make, 所以如果我們能看到GNU Make執行了哪些command, 那我們就可以知道在build Android時, Android到底用了哪些特別的compiler flag.

我改了一版GNU Make來取得make執行了哪些command的資訊, build code的方法如下:

Terminal
1
2
3
4
bramante@matrix:~$ git clone https://github.com/Bramante/debugging-tools.git
bramante@matrix:~$ cd debugging-tools/make-3.81/
bramante@matrix:~/debugging-tools/make-3.81$ ./configure
bramante@matrix:~/debugging-tools/make-3.81$ make

我改動的code其實就只有下面這幾行:

Terminal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
bramante@matrix:~/debugging-tools/make-3.81$ git log job.c
commit 127676f45707a6bef7361c146b9b106d4302393a
Author: bramante <bramante@matrix.(none)>
Date:   Thu Oct 8 00:04:48 2015 +0800

    +: Making make print commands before executing.

commit d6ded34ecab13b1569186fd4b879fdee98b49f65
Author: bramante <bramante@matrix.(none)>
Date:   Wed Oct 7 09:38:08 2015 +0800

    +: make-3.81
bramante@matrix:~/debugging-tools/make-3.81$ git diff d6ded34ecab13b1569186fd4b879fdee98b49f65 job.c
diff --git a/make-3.81/job.c b/make-3.81/job.c
old mode 100644
new mode 100755
index a81cd81..a912b36
--- a/make-3.81/job.c
+++ b/make-3.81/job.c
@@ -2073,6 +2073,32 @@ exec_command (char **argv, char **envp)

 # else

+  char* makeLogFileName = getenv("MAKE_LOG_FILE_NAME");
+  if( makeLogFileName )
+    {
+     int i ;
+     FILE * fh = NULL ;
+     fh = fopen( makeLogFileName, "a" );
+     if(fh)
+       {
+        fprintf(fh,"[*][argv] ");
+        for(i=0;argv[i]!=NULL;i++)
+           {
+            fprintf(fh,"%s ",argv[i]);
+           }
+        fprintf(fh,"\n");
+        fprintf(fh,"[*][envp] ");
+        for(i=0;envp[i]!=NULL;i++)
+           {
+            fprintf(fh,"%s ",envp[i]);
+           }
+        fprintf(fh,"\n");
+        fflush(fh);
+        fsync(fileno(fh));
+        fclose(fh);
+       }
+   }
+
   /* Run the program.  */
   environ = envp;
   execvp (argv[0], argv);
bramante@matrix:~/debugging-tools/make-3.81$

替換掉原本系統裡的GNU Make, 並設定log file的名稱:

Terminal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
bramante@matrix:~/debugging-tools/make-3.81$ which make
/usr/bin/make
bramante@matrix:~/debugging-tools/make-3.81$ ll make
-rwxrwxr-x 1 bramante bramante 610769 Oct  8 17:10 make*
bramante@matrix:~/debugging-tools/make-3.81$ cp ./make ../
bramante@matrix:~/debugging-tools/make-3.81$ cd ..
bramante@matrix:~/debugging-tools$ ll
total 616
drwxr-xr-x  4 bramante bramante   4096 Oct  8 18:20 ./
drwxr-xr-x 19 bramante bramante   4096 Oct  8 17:09 ../
drwxrwxr-x  8 bramante bramante   4096 Oct  8 17:09 .git/
-rwxrwxr-x  1 bramante bramante 610769 Oct  8 18:20 make*
drwxrwxr-x 10 bramante bramante   4096 Oct  8 17:10 make-3.81/
bramante@matrix:~/debugging-tools$ pwd
/home/bramante/debugging-tools
bramante@matrix:~/debugging-tools$ export PATH="/home/bramante/debugging-tools:$PATH"
bramante@matrix:~/debugging-tools$ which make
/home/bramante/debugging-tools/make
bramante@matrix:~/debugging-tools$ export MAKE_LOG_FILE_NAME="make_log.txt"

重build GNU Make 3.81來取得make執行了哪些command的資訊:

Terminal
1
2
3
4
5
6
bramante@matrix:~/debugging-tools$ cd -
/home/bramante/debugging-tools/make-3.81
bramante@matrix:~/debugging-tools/make-3.81$ make clean ; make
bramante@matrix:~/debugging-tools/make-3.81$ ll make_log.txt
-rw-rw-r-- 1 bramante bramante 99665 Oct  8 18:27 make_log.txt
bramante@matrix:~/debugging-tools/make-3.81$

從log file可以看出make執行過哪些command:

Terminal
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
bramante@matrix:~/debugging-tools/make-3.81$ grep "\[argv]" make_log.txt
[*][argv] /bin/sh -c if test ! -f config.h; then \
[*][argv] make all-recursive
[*][argv] /bin/sh -c failcom='exit 1'; \
[*][argv] /bin/sh -c if test ! -f config.h; then \
[*][argv] /bin/sh -c failcom='exit 1'; \
[*][argv] /bin/sh -c test -z "make" || rm -f make
[*][argv] /bin/sh -c test -z "loadavg" || rm -f loadavg
[*][argv] rm -f ansi2knr
[*][argv] /bin/sh -c rm -f *.o
[*][argv] /bin/sh -c test "" = "" || rm -f *_.c
[*][argv] /bin/sh -c if test ! -f config.h; then \
[*][argv] make all-recursive
[*][argv] /bin/sh -c failcom='exit 1'; \
[*][argv] /bin/sh -c if test ! -f config.h; then \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT ar.o -MD -MP -MF ".deps/ar.Tpo" -c -o ar.o ar.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT arscan.o -MD -MP -MF ".deps/arscan.Tpo" -c -o arscan.o arscan.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT commands.o -MD -MP -MF ".deps/commands.Tpo" -c -o commands.o commands.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT default.o -MD -MP -MF ".deps/default.Tpo" -c -o default.o default.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT dir.o -MD -MP -MF ".deps/dir.Tpo" -c -o dir.o dir.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT expand.o -MD -MP -MF ".deps/expand.Tpo" -c -o expand.o expand.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT file.o -MD -MP -MF ".deps/file.Tpo" -c -o file.o file.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT function.o -MD -MP -MF ".deps/function.Tpo" -c -o function.o function.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT getopt.o -MD -MP -MF ".deps/getopt.Tpo" -c -o getopt.o getopt.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT getopt1.o -MD -MP -MF ".deps/getopt1.Tpo" -c -o getopt1.o getopt1.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT implicit.o -MD -MP -MF ".deps/implicit.Tpo" -c -o implicit.o implicit.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT job.o -MD -MP -MF ".deps/job.Tpo" -c -o job.o job.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT main.o -MD -MP -MF ".deps/main.Tpo" -c -o main.o main.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT misc.o -MD -MP -MF ".deps/misc.Tpo" -c -o misc.o misc.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT read.o -MD -MP -MF ".deps/read.Tpo" -c -o read.o read.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT remake.o -MD -MP -MF ".deps/remake.Tpo" -c -o remake.o remake.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT remote-stub.o -MD -MP -MF ".deps/remote-stub.Tpo" -c -o remote-stub.o remote-stub.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT rule.o -MD -MP -MF ".deps/rule.Tpo" -c -o rule.o rule.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT signame.o -MD -MP -MF ".deps/signame.Tpo" -c -o signame.o signame.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT strcache.o -MD -MP -MF ".deps/strcache.Tpo" -c -o strcache.o strcache.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT variable.o -MD -MP -MF ".deps/variable.Tpo" -c -o variable.o variable.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT version.o -MD -MP -MF ".deps/version.Tpo" -c -o version.o version.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT vpath.o -MD -MP -MF ".deps/vpath.Tpo" -c -o vpath.o vpath.c; \
[*][argv] /bin/sh -c if gcc -DLOCALEDIR=\"/usr/local/share/locale\" -DLIBDIR=\"/usr/local/lib\" -DINCLUDEDIR=\"/usr/local/include\" -DHAVE_CONFIG_H -I. -I. -I.      -g -O2 -MT hash.o -MD -MP -MF ".deps/hash.Tpo" -c -o hash.o hash.c; \
[*][argv] rm -f make
[*][argv] gcc -g -O2 -o make ar.o arscan.o commands.o default.o dir.o expand.o file.o function.o getopt.o getopt1.o implicit.o job.o main.o misc.o read.o remake.o remote-stub.o rule.o signame.o strcache.o variable.o version.o vpath.o hash.o -lrt
bramante@matrix:~/debugging-tools/make-3.81$

Comments