2019-12-12-c-cmake-gcc的常用编译选项

那年我21岁,我以为她也21岁

cmake

gcc使用常用选项

-o 选项 指定输出可执行程序名称

gcc main.c -o main

-Wall 开启所有的警告

如下代码

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * args) {

    int i = 0;
    printf("hello world\n");
    return 0;
}

会发出警告,提示i没有被用到

# gcc main.c -o main -Wall
main.c:5:5: warning: second argument of ‘main’ should be ‘char **’ [-Wmain]
 int main(int argc, char * args) {
     ^
main.c: In function ‘main’:
main.c:7:9: warning: unused variable ‘i’ [-Wunused-variable]
     int i = 0;
         ^

-Werror 警告变错误

将编译警告转换成错误.视警告为错误;出现任何警告即放弃编译. 编译警告很多时候会被我们忽视,在特殊场合我们还是需要重视编译警告,如果能把编译警告变长直接输出错误,那我们的重视程度会提高很多并去解决。

#include<stdio.h>

int main(void)
{
  char c;
  // Print the string
   printf("\n The Geek Stuff [%d]\n", c);
   return 0;
}

编译后将会报错

-E 生成预编译文件

 gcc -E main.c > main.i

-S 生成汇编文件

gcc -S main.c > main.s

-C 生成没有带任何链接的代码

gcc -c main.c

The command above would produce a file main.o that would contain machine level code or the compiled code.

-save-temps 生成所有文件

gcc -save-temps main.c
$ ls
a.out  main.c  main.i  main.o  main.s

-l 链接动态库

gcc -Wall main.c -o main -lCPPfile

-v 打印所有执行的命令

打印gcc执行过程中所有的步骤

$ gcc -Wall -v main.c -o main
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/i686-linux-gnu/4.6/lto-wrapper
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.6.3-1ubuntu5' --with-bugurl=file:///usr/share/doc/gcc-4.6/README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --enable-targets=all --disable-werror --with-arch-32=i686 --with-tune=generic --enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5)
...
...
...

-funsigned-char 所有的char被作为unsigned-char对待

#include<stdio.h>

int main(void)
{
  char c = -10;
  // Print the string
   printf("\n The Geek Stuff [%d]\n", c);
   return 0;
}

上面定义的 c将会被作为 unsigned-char对待

$ gcc -Wall -funsigned-char main.c -o main
$ ./main

 The Geek Stuff [246]

-fsigned-char 所有的char被作为signed-char对待

还是上面那份代码,现在的情况是这种样的:

$ gcc -Wall -fsigned-char main.c -o main
$ ./main

 The Geek Stuff [-10]

-D指定宏

#include<stdio.h>

int main(void)
{
#ifdef MY_MACRO
  printf("\n Macro defined \n");
#endif
  char c = -10;
  // Print the string
   printf("\n The Geek Stuff [%d]\n", c);
   return 0;
}

The compiler option -D can be used to define the macro MY_MACRO from command line.

$ gcc -Wall -DMY_MACRO main.c -o main
$ ./main

 Macro defined 

 The Geek Stuff [-10]

@ 指定选项文件

我们可以把所有的选项放在一个文件里面,然后使用@去引用。(Java也可以这样的。。。这样看,感觉Java应该是借鉴了gcc)

$ cat opt_file 
-Wall -omain
$ gcc main.c @opt_file
main.c: In function ‘main’:
main.c:6:11: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]

$ ls main
main

参考