一、生成规则的一些选项-M 自动生成规则,显示.c文件依赖的所有头文件
-MM 自动生成规则,显示.c文件依赖的除标准库外的头文件,输出到终端
-MMD 自动生成规则,显示.c文件依赖的除标准库外的头文件,输出到.d文件
例如Makefile里有如下规则:
byte_order.o: byte_order.c byte_order.h lala.h other.h
使用-MMD选项的话,只要在Makefile里 #include .d 文件就可以了
但如果只是这样,就会产生重复编译头文件的问题。解决方法是,"预编译"头文件
- gcc -x c++-hearder a.h #生成 a.gch
二、传入宏和取消宏-D 传入宏
-U 取消宏
- #include <stdio.h>
-
#ifdef YES
-
char* str = "Yes, this is a macro.";
-
#else
- char* str = "No, there is no macro.";
-
#endif
-
int main(void){
-
printf("%s\n", str);
-
return 0;
-
}
使用-D传入宏YES来进行编译:
- recordus@LFS test # gcc -DYES -o helloyes hello.c
-
recordus@LFS test # ./helloyes
-
Yes, this is a macro.
而不传入宏则是这样的:
- recordus@LFS test # gcc -o hellono hello.c
-
recordus@LFS test # ./hellono
-
No, there is no macro.
gcc还有与-D对应的另一个参数-U用于取消宏,比如:
- root@LFS test # gcc -DYES -UYES -o helloyesno hello.c
-
root@LFS test # ./helloyesno
-
No, there is no macro.
所以看代码时,如果有些宏死活找不到它的定义的话,不妨到Makefile里看一看。
附上Man手册中关于这两个选项的解释:
-D name
Predefine name as a macro, with definition 1.
-D name=definition
Predefine name as a macro, with definition definition. The con-
tents of definition are tokenized and processed as if they
appeared during translation phase three in a #define directive.
In particular, the definition will be truncated by embedded new-
line characters.
If you are invoking the preprocessor from a shell or shell-like
program you may need to use the shell's quoting syntax to protect
characters such as spaces that have a meaning in the shell syntax.
If you wish to define a function-like macro on the command line,
write its argument list with surrounding parentheses before the
equals sign (if any). Parentheses are meaningful to most shells,
so you will need to quote the option. With sh and csh,
-D'name(args...)=definition' works.
-D and -U options are processed in the order they are given on the
command line. All -imacros file and -include file options are
processed after all -D and -U options.
-U name
Cancel any previous definition of name, either built in or pro-
vided with a -D option.
三、库的使用
动态库是执行代码与库代码分离,代码执行过程中才去动态的寻找库文件。
优点:可以多段代码共用一个库文件,而不用多个拷贝。
缺点:因为未整合到一起,执行代码移植时,动态库也得移植,否则程序无法运行。
静态库是执行代码与库文件编译成一个文件。
优点:代码封装在一起,移植时拷贝一个文件即可运行。
缺点:因为每个执行代码都把库文件代码引进来,文件比较大,系统消耗大。
动态库的查找路径:
1、可以用 LD_LIBRARY_PATH 环境变量指定,可以放到自己的 ~/.bashrc 中只对本用户起作用
2、如果启用了 ld.so.cache 的话,系统会在 /etc/ld.so.cache 中存储所有可引用的动态链接库。
文件位置可通过 /etc/ld.so.conf 来指定,对全局所有用户都有影响;
root更改设置后,记得调用 ldconfig 来刷新一下。
3、默认的标准库路径。包括 /lib 和 /usr/lib
4、也可以在编译时指定搜索路径。gcc 的 -Wl 和 -rpath 参数。
pthread 库不是 Linux 系统默认的库,使用时要加头文件#include
编译时要加 -lpthread
gcc thread_test.c -o thread -lpthread
使用时,需在编译时加 -lm 参数。
,需在编译时加 -lrt参数
编译 mq_open ....等等的时候,要用到 -lrt (man 7 mq_overview)
可以通过ldd命令来看二进制程序调用了哪些共享库(print shared library dependencie)
- [root@local ~]# ldd /bin/ls
-
librt.so.1 => /lib/tls/librt.so.1 (0x0056b000)
-
libacl.so.1 => /lib/libacl.so.1 (0x00d70000)
-
libselinux.so.1 => /lib/libselinux.so.1 (0x00627000)
-
libc.so.6 => /lib/tls/libc.so.6 (0x006f3000)
-
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00942000)
-
/lib/ld-linux.so.2 (0x006d4000)
-
libattr.so.1 => /lib/libattr.so.1 (0x00bbc000)
-
[root@local ~]#
库 头文件 描述
---------- -------------- ----------------------------------
libGL.so 实现到OpenGL API的接口
libGLU.so 实现到OpenGL API的接口
libImlib.so 实现一套图像处理例程
libc.so 实现标准C库(不需要头文件)
libcom_err.so 实现出错处理例程的集合
libcrypt.so 实现加密函数的集合
libcurses.so 光标字符模式的屏幕操作库
libdb.so 创建和操作数据库的库
libdl.so 让程序在运行时加载和使用库代码而无须在编译时链接库
libform.so 实现字符模式应用程序的窗体处理能力
libglib.so Glib库,提供了大多数程序需要的大量基本工具函数,比如散列表等
libgthread.so 实现对Glib的线程支持
libgtk.so GIMP下的X库
libhistory.so 实现GNU readline(libreadline)包中的命令行历史机制
libjpeg.so 定义到JPEG库的接口,赋予应用程序使用JPEG图像文件的能力
libm.so 实现标准C数学库
libmenu.so 提供在字符模式屏幕上创建和使用菜单的例程
libncurses.so 使用ncurses文本模式屏幕控制系统的应用程序的基础库
libnss.so 用于名字服务切换工具的功能,提供了名字数据库比如DNS接口
libpanel.so 提供在字符模式屏幕上创建和使用面板的例程
libpbm.so 可移植的位图库,实现了使用多种格式单色位图的接口
libpgm.so 可移植的灰度图库,实现了使用多种格式灰色位图的接口
libpng.so 用于编码,解码和操作PNG格式图像文件的参考实现
libpnm.so 可移植anymap库是使用多种位图格式的基础库
libppm.so 可移植的像素图库实现了使用多种格式彩色像素图的接口
libpthread.so 实现了POSIX线程库,标准的Linux多线程库
libreadline.so GNU readline包的基础库
libresolv.so 提供使用因特网域名服务器和服务的接口
libslang.so 提供方便的脚本语言S-lang,用于嵌入其它应用程序
libtiff.so 读写TIFF格式图像文件的库
libz.so 通用压缩例程库
libvga.so Linux的底层VGA和SVGA图形库
四、__attribute__
__attribute__关键字主要是用来在函数或数据声明中设置其属性,让编译器进行优化。
语法格式:
- __attribute__ ((attribute-list))
用法:其位置约束:放于声明的尾部“;”之前,始终紧跟在 '}'之后
- struct str_struct{
-
uint8_t a;
-
uint8_t b;
-
} __attribute__ ((packed));
-
-
typedef struct _GuiPacket_Payload_t {
-
uint8_t data[GUI_MAX_DATA_SIZE];
-
uint16_t data_len;
-
-
}__attribute__ ((packed)) GuiPacket_Payload_t;
packed属性:最常用的一个属性,使用该属性可以使得变量或者结构体成员使用最小的对齐方式。
- struct my{ char ch; int a;}; sizeof(int)=4; sizeof(struct my)=8; (非紧凑模式)
-
struct my{ char ch; int a;}__attrubte__((packed)); sizeof(int)=4; sizeof(struct my)=5;
noreturn属性:告诉编译器这个函数不会返回,以便编译器在优化时去掉不必要的函数返回代码。
- extern void exit(int) __attribute__((noreturn));
-
extern void abort(void) __attribute__((noreturn));
五、其他
有时候gcc编译时,有以下告警
warning: dereferencing type-punned pointer will break strict-aliasing rules
解决方法:先将某地址强制转换为void*型,再强制转换为其他类型,即可消除这个警告。
可能是因为编译器对void*的强转不会有任何优化吧。
相关文档: @GCC编程简介.rar GCC 中文手册.rar
阅读(6837) | 评论(0) | 转发(4) |