GCC -M,-MM,-MMD,-MF,-MT

时间:2020-12-14 02:29:23

GCC的命令参数有很多,下面主要介绍几个M相关的:

-M

生成文件关联的信息。包含目标文件所依赖的所有源代码,下面是测试log:

jack@jxes-VirtualBox:~/samba_share/tmp$ vim test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -M test.c
test.o: test.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/i386-linux-gnu/sys/cdefs.h \
 /usr/include/i386-linux-gnu/bits/wordsize.h \
 /usr/include/i386-linux-gnu/gnu/stubs.h \
 /usr/include/i386-linux-gnu/gnu/stubs-32.h \
 /usr/lib/gcc/i686-linux-gnu/5/include/stddef.h \
 /usr/include/i386-linux-gnu/bits/types.h \
 /usr/include/i386-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/i686-linux-gnu/5/include/stdarg.h \
 /usr/include/i386-linux-gnu/bits/stdio_lim.h \
 /usr/include/i386-linux-gnu/bits/sys_errlist.h

-MM

和上面的那个一样,但是它将忽略由#include造成的依赖关系。

jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MM test.c
test.o: test.c

-MMD

和-MM相同,但是输出将导入到.d的文件里面:

jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MMD test.c -o test
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 24
drwxrwxr-x 2 jack jack 4096 717 10:42 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rwxrwxr-x 1 jack jack 7344 717 10:42 test*
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
-rw-rw-r-- 1 jack jack   13 717 10:42 test.d //test.d为导出文件
jack@jxes-VirtualBox:~/samba_share/tmp$ rm test.d
jack@jxes-VirtualBox:~/samba_share/tmp$ rm test
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 12
drwxrwxr-x 2 jack jack 4096 717 10:42 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MMD test.c//注意这里的定法,即使没有指明目标-o,编译器也会自动生成a.out,这与前面-M,-MM有所不同。
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 24
drwxrwxr-x 2 jack jack 4096 717 10:42 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rwxrwxr-x 1 jack jack 7344 717 10:42 a.out*
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
-rw-rw-r-- 1 jack jack   15 717 10:42 test.d
jack@jxes-VirtualBox:~/samba_share/tmp$ ./a.out 
100
jack@jxes-VirtualBox:~/samba_share/tmp$ 

test.d文件里的内容与-MM是类似的,只是导出到文件里而已:

jack@jxes-VirtualBox:~/samba_share/tmp$ cat test.d
test.o: test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ 

-MD

与-MMD类似,只是导出的内容有所不一样,内容与-M是一样的。具体可以看log:

jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MD test.c -o test
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 24
drwxrwxr-x 2 jack jack 4096 717 10:48 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rwxrwxr-x 1 jack jack 7344 717 10:48 test*
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
-rw-rw-r-- 1 jack jack  624 717 10:48 test.d
jack@jxes-VirtualBox:~/samba_share/tmp$ cat test.d
**test: test.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/i386-linux-gnu/sys/cdefs.h \
 /usr/include/i386-linux-gnu/bits/wordsize.h \
 /usr/include/i386-linux-gnu/gnu/stubs.h \
 /usr/include/i386-linux-gnu/gnu/stubs-32.h \
 /usr/lib/gcc/i686-linux-gnu/5/include/stddef.h \
 /usr/include/i386-linux-gnu/bits/types.h \
 /usr/include/i386-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/i686-linux-gnu/5/include/stdarg.h \
 /usr/include/i386-linux-gnu/bits/stdio_lim.h \
 /usr/include/i386-linux-gnu/bits/sys_errlist.h**
jack@jxes-VirtualBox:~/samba_share/tmp$ rm test
jack@jxes-VirtualBox:~/samba_share/tmp$ rm test.d
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MD test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 24
drwxrwxr-x 2 jack jack 4096 717 10:48 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rwxrwxr-x 1 jack jack 7344 717 10:48 a.out*
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
-rw-rw-r-- 1 jack jack  626 717 10:48 test.d
jack@jxes-VirtualBox:~/samba_share/tmp$ cat test.d
test.o: test.c /usr/include/stdc-predef.h /usr/include/stdio.h \
 /usr/include/features.h /usr/include/i386-linux-gnu/sys/cdefs.h \
 /usr/include/i386-linux-gnu/bits/wordsize.h \
 /usr/include/i386-linux-gnu/gnu/stubs.h \
 /usr/include/i386-linux-gnu/gnu/stubs-32.h \
 /usr/lib/gcc/i686-linux-gnu/5/include/stddef.h \
 /usr/include/i386-linux-gnu/bits/types.h \
 /usr/include/i386-linux-gnu/bits/typesizes.h /usr/include/libio.h \
 /usr/include/_G_config.h /usr/include/wchar.h \
 /usr/lib/gcc/i686-linux-gnu/5/include/stdarg.h \
 /usr/include/i386-linux-gnu/bits/stdio_lim.h \
 /usr/include/i386-linux-gnu/bits/sys_errlist.h
jack@jxes-VirtualBox:~/samba_share/tmp$ 

-MF

man帮助里
指一个文件用于存放生成文件的关联信息,这些信息与-M或-MM是一样的,所以要与-M或-MM一些使用,否则会报错,看下面log:

jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MF test.c -o test
gcc: fatal error: no input files
compilation terminated.
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MF"test.d" test.c -o test
cc1: error: to generate dependencies you must specify either -M or -MM
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc -MM -MF"test.d" test.c -o test
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 16
drwxrwxr-x 2 jack jack 4096 717 10:53 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rw-rw-r-- 1 jack jack    0 717 10:53 test
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
-rw-rw-r-- 1 jack jack   15 717 10:53 test.d
jack@jxes-VirtualBox:~/samba_share/tmp$ cat test.d
test.o: test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ 

注意:单独使用-M或-MM时,生成的目标文件没有可执行属性:

-rw-rw-r-- 1 jack jack    0 717 10:53 test

注意:
-MF与-MMD或-MD混用,会覆盖-MD或-MMD的特性,简单说,它们功能是等效的,下面是man帮助里的介绍:

       -MF file
           When used with -M or -MM, specifies a file to write the dependencies to.  If no -MF switch is given the
           preprocessor sends the rules to the same place it would have sent preprocessed output.

           When used with the driver options -MD or -MMD, -MF overrides the default dependency output file.

-MT

指定目标文件名

jack@jxes-VirtualBox:~/samba_share/tmp$ gcc test.c -MT"test.o"
cc1: error: to generate dependencies you must specify either -M or -MM
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc test.c -MT"test.o" -MM
test.o: test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 12
drwxrwxr-x 2 jack jack 4096 717 10:58 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc test.c -MT"test.d" -MT"test.o" -MM
test.d test.o: test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 12
drwxrwxr-x 2 jack jack 4096 717 10:58 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ gcc test.c -MF"test.d" -MT"test.d" -MT"test.o" -MM
jack@jxes-VirtualBox:~/samba_share/tmp$ ll
total 16
drwxrwxr-x 2 jack jack 4096 717 11:00 ./
drwxr-xr-x 6 jack jack 4096 717 10:38 ../
-rw-rw-r-- 1 jack jack   87 717 10:39 test.c
-rw-rw-r-- 1 jack jack   22 717 11:00 test.d
jack@jxes-VirtualBox:~/samba_share/tmp$ cat test.d
test.d test.o: test.c
jack@jxes-VirtualBox:~/samba_share/tmp$ 

总结

-M,-MM,-MMD,-MF,-MT这几个用法,主要是用来生成关联信息,以及指定输出文件名,所以本人一般习惯用-MMD这一个,其他几个很少会用。另外加上-D,编译器会自动生成.d的的文件保存关联信息,同时最终生成的目标文件也不会没有可执行属性。