苏苏的博客

简约至极

gcc编译

使用gcc编译器的一些笔记

gcc 静态编译

1.c

#include <stdio.h>

void main()
{
	printf("hello");
}

gcc -static --verbose -fno-builtin 1.c

--verbose是为了输入编译的详细信息

-fno-builtin是阻止编译器把printf变成puts

http://northstar-www.dartmouth.edu/doc/ibmcxx/en_US/doc/complink/ref/ruoptbst.htm

如果出现错误

/usr/bin/ld: cannot find -lc
collect2: 错误:ld 返回 1

可能你还需要安装glibc的静态库

yum update && yum install glibc-static -y

macOS gcc不支持静态编译,因为苹果的系统调用不稳定,只有 libSystem 的 API 保持兼容,所以静态编译的程序升级系统可能会遇到问题

优化选项

https://www.zhihu.com/question/27090458

gcc -static -O  1.c
gcc -static -O2 1.c
gcc -static -O3 1.c
gcc -static -Os 1.c

错误提示

-pedantic编译选项并不能保证被编译程序与ANSI/ISO C标准的完全兼容,它仅仅只能用来帮助Linux程序员离这个目标越来越近。或者换句话说,-pedantic选项能够帮助程序员发现一些不符合 ANSI/ISO C标准的代码,但不是全部,事实上只有ANSI/ISO C语言标准中要求进行编译器诊断的那些情况,才有可能被GCC发现并提出警告。

除了-pedantic之外,GCC还有一些其它编译选项也能够产生有用的警告信息。这些选项大多以-W开头,其中最有价值的当数-Wall了,使用它能够使GCC产生尽可能多的警告信息。

gcc -Wall test.c -o test

GCC给出的警告信息虽然从严格意义上说不能算作错误,但却很可能成为错误的栖身之所。一个优秀的Linux程序员应该尽量避免产生警告信息,使自己的代码始终保持标准、健壮的特性。所以将警告信息当成编码错误来对待,是一种值得赞扬的行为!所以,在编译程序时带上-Werror选项,那么GCC会在所有产生警告的地方停止编译,迫使程序员对自己的代码进行修改,如下:

gcc -Werror test.c -o test

调试选项

  1. -g选项,产生供gdb调试用的可执行文件:gcc -g helloworld.c

产生一个叫作a.out的可执行文件,大小明显比只用-o选项编译汇编连接后的文件大。

  1. -pg选项,产生供gprof剖析用的可执行文件:gcc -pg helloworld.c

产生一个叫作a.out的执行文件,大小明显比用-g选项后产生的文件还大。

https://www.systutorials.com/5217/how-to-statically-link-c-and-c-programs-on-linux-with-gcc/

LDFLAGS=-static ./configure --disable-plugins=auth,cgi,cheetah,dirlisting,fastcgi,liana,logger,mandril,tls --malloc-libc

编译更小的文件

gcc 使用参数 -Os -ffunction-sections -fdata-sections link 的时候使用 --gc-sections

-ffunction-sections, -fdata-sections会使compiler为每个function和data item分配独立的section。 –gc-sections会使ld删除没有被使用的section。

链接操作以section作为最小的处理单元,只要一个section中有某个符号被引用,该section就会被放入output中。

这些选项一起使用会从最终的输出文件中删除所有未被使用的function和data, 只包含用到的function和data

export CFLAGS=”-Os -ffunction-sections -fdata-sections” export LDFLAGS=”-Wl,–gc-sections”

然后 对可执行文件 strip -s

mac 交叉编译

https://blog.filippo.io/easy-windows-and-linux-cross-compilers-for-macos/