gcc

来源:互联网 发布:php删除数组元素 编辑:程序博客网 时间:2024/06/08 17:11

gcc生成静态链接库

gcc -c file1.c
gcc -c file2.c
ar crv my_library.a file1.o file2.o
注意,用gcc链接静态库的时候,-l要放在xxx.c后面
-I -l -L
系统头文件路径是:/usr/include,如果引用的头文件不在系统路径下,那么需要用-Ipath来指明头文件的目录。
静态链接库的系统路径是:/lib, /usr/lib, /usr/local/lib,引用系统路径下的库文件只要加上-lxxx即可(如果库名是libxxx.a,那么为-lxxx)。
如果保存静态库的路径不是系统路径,那么需要使用-Lpath来指明库的路径

静态库链接时搜索路径:
1) ld会去找GCC命令中的参数-L
2) 再找gcc的环境变量LIBRARY_PATH
3) 再找内定目录 /lib /usr/lib /usr/local/lib 这是当初compile gcc时写在程序内的

gcc生成动态链接库

gcc -fPIC -shared file1.c file2.c -o my_library.so
动态库如果没有保存在系统库的路径下,那么应用程序在运行时需要通过export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:path来指定动态库的路径

动态库链接时搜索路径:
1) 编译目标代码时指定的动态库搜索路径
2) 环境变量LD_LIBRARY_PATH指定的动态库搜索路径
3) 配置文件/etc/ld.so.conf中指定的动态库搜索路径
4) 默认的动态库搜索路径/lib
5) 默认的动态库搜索路径/usr/lib

有关环境变量:
LIBRARY_PATH环境变量:指定程序静态链接库文件搜索路径
LD_LIBRARY_PATH环境变量:指定程序动态链接库文件搜索路径
LIBRARY_PATH和LD_LIBRARY_PATH是在链接的时候gcc查找的库文件路径,当程序在运行时查找库文件需通过LD_LIBRARY_PATH或RUN_LIBRARY_PATH指定

强制链接时使用静态链接库

默认情况下,gcc在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话,可以在编译时加上-static选项来强制使用静态链接库。
如:gcc -L/path/lib -static -lxxx test.c -o test

gcc参数

warn选项

-Werror
make all warning into errors
-Wall(打开大部分检查,不是所有)
This enables all the warnings about constructions that some users consider questionable, and that are easy to avoid
(or modify to prevent the warning), even in conjunction with macros. This also enables some language-specific warnings
described in C++ Dialect Options and Objective-C and Objective-C++ Dialect Options.
-Wall turns on the following warning flags:

-Waddress -Warray-bounds (only with -O2) -Wc++0x-compat -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration -Wcomment -Wformat -Wmain (only for C/ObjC and unless -ffreestanding)
-Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreorder -Wreturn-type -Wsequence-point -Wsign-compare (only in C++) -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtrigraphs
-Wuninitialized -Wunknown-pragmas -Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wvolatile-register-var

-Wextra
This enables some extra warning flags that are not enabled by -Wall.
(This option used to be called -W. The older name is still supported, but
the newer name is more descriptive.)

-g

生成可执行文件中包含gdb调试信息,发生异常时会产生core文件。

-O[level]

指定优化等级,level数字越大优化程序越高,需要的编译时间也越长。默认是-O0,许多程序员喜欢用-O2,因为他在优化长度,编译时间和代码之间取得一个比较理想的平衡点。

-DMACRO

以字符串”1”定义MACRO宏
如果在源代码中使用

#ifdef MACRO

#endif

则源代码会根据gcc编译选项编译
使用方法参考:http://blog.csdn.net/luckywang1103/article/details/31821857

-DMACRO=DEFN

以字符串”DEFN”定义MACRO宏

-fPIC

-fPIC作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的任何位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不是固定的。

-shared

编译源代码为动态链接库,如gcc -fPIC -shared test.c -o libtest.so

-E -S -c -o

-E 仅预处理 gcc -E test.c -o test.i
-S 仅预处理和编译 gcc -S test.c -o test.s
-c 预处理、编译和汇编 gcc -c test1.c test2.c生成各自的目标文件test1.o test2.o
-o output_filename 生成指定文件,如果没有指定,生成a.out

-Lpath -Ipath -l

如果代码中只使用c的标准库(libc.a libc.so),不需要指定选项
如果使用了非标准库,且该库文件及库的头文件位于默认目录,需要使用-lxxx,例如使用了libm.a或libm.so,需要指定-lm
如果使用了非标准库,且该库文件及库的头文件不在默认目录,需要使用-Ipath指定库的头文件所在目录,-Lpath指定库文件所在位置,-lxxx指定使用的库


gcc编译属性

unused
它用于函数和变量,表示该函数或变量可能不使用,可以在编译时防止编译器产生“变量未使用”这样的警告信息

pack
不进行对齐

align
使用指定的字节数对齐

force
# define force __attribute((force))
表示所定义的变量类型是可以做强制类型转换的,在进行Sparse分析的时候,是不用报告警信息的。


预编译

预编译又称预处理,主要做些代码替换的工作。
尽管在目前绝大多数编译器都包含了预处理程序,但通常认为它们是独立于编译器的。预处理过程读入源代码,检查包含预处理指令的语句和宏定义,并对源代码进行相应的转换。预处理过程还会删除程序中的注释和多余的空白字符。
预处理指令是以#号开头的代码行。#号必须是该行除了任何空白字符外的第一个字符。#后是指令关键字,在关键字和#号之间允许存在任意个数的空白字符。下面是部分预处理指令:

#             空指令,无任何效果#include      包含一个源代码文件#define       定义宏#undef        取消已定义的宏#if           如果给定条件为真,则编译下面代码#ifdef        如果宏已经定义,则编译下面代码#ifndef       如果宏没有定义,则编译下面代码#elif         如果前面的#if给定条件不为真,当前条件为真,则编译下面代码,相当于#elseif#endif        结束一个#if……#else条件编译块#error        停止编译并显示错误信息

文件包含

‘#include’预处理指令的作用是在指令处展开被包含的文件。包含可以是多重的,也就是说一个被包含的文件中还可以包含其他文件。
在程序中包含头文件有两种格式:

#include <my.h>#include "my.h"

为了避免那些只包含一次的头文件被包含多次,可以在头文件中用编译条件来进行控制

#ifndef MY_H#define MY_H...#endif

宏最常见的用法是定义代表某个值的全局符号。宏的第二种用法是定义带参数的宏,这样的宏可以象函数一样被调用,但它是在调用语句处展开宏,并用调用时的实际参数来代替定义中的形式参数。
#define指令
#运算符
‘#’运算符把跟在其后的参数转换成一个字符串。有时把这种用法的#称为字符串化运算符。例如:

#define PASTE(n) "adhfkj"#nmain(){    printf("%s\n",PASTE(15));}

输出应该是adhfkj15

##运算符
‘##’运算符用于把参数连接到一起。预处理程序把出现在##两侧的参数合并成一个符号

#define NUM(a,b,c) a##b##c#define STR(a,b,c) a##b##cmain(){    printf("%d\n",NUM(1,2,3));    printf("%s\n",STR("aa","bb","cc"));}

最后程序的输出为:
123
aabbcc\


条件编译指令

条件编译指令将决定那些代码被编译,而哪些是不被编译的。可以根据表达式的值或者某个特定的宏是否被定义来确定编译条件
#if
#endif
#ifdef和#ifndef
#else
#elif


其他一些标准指令

#error指令将使编译器显示一条错误信息,然后停止编译。
#line指令可以改变编译器用来指出警告和错误信息的文件号和行号。
#pragma指令没有正式的定义。编译器可以自定义其用途。典型的用法是禁止或允许某些烦人的警告信息

0 0
原创粉丝点击