大型工程的makefile编写及其维护管理

来源:互联网 发布:网络图片头像男生背影 编辑:程序博客网 时间:2024/05/01 10:03


我参考了三遍文章,记录在此,以备后查:

 

1. 跟我一起写 Makefile 

网上很容易找到,略。


2.动态链接库和静态链接库的编写

参考:http://blog.csdn.net/alex_xhl/article/details/8069517

GCC 编译使用动态链接库和静态链接库 
1 库的分类
根据链接时期的不同,库又有静态库和动态库之分。
静态库是在链接阶段被链接的,所以生成的可执行文件就不受库的影响了,即使库被删除了,程序依然可以成功运行。
有别于静态库,动态库的链接是在程序执行的时候被链接的。所以,即使程序编译完,库仍须保留在系统上,以供程序运行时调用。
2 静态库和动态库的比较
链接静态库其实从某种意义上来说也是一种粘贴复制,只不过它操作的对象是目标代码而不是源码而已。因为静态库被链接后库就直接嵌入可执行文件中了,这样就带来了两个问题。
首先就是系统空间被浪费了。这是显而易见的,想象一下,如果多个程序链接了同一个库,则每一个生成的可执行文件就都会有一个库的副本,必然会浪费系统空间。
再者,人非圣贤,即使是精心调试的库,也难免会有错。一旦发现了库中有bug,挽救起来就比较麻烦了。必须一一把链接该库的程序找出来,然后重新编译。
而动态库的出现正弥补了静态库的以上弊端。因为动态库是在程序运行时被链接的,所以磁盘上只须保留一份副本,因此节约了磁盘空间。如果发现了bug或要升级也很简单,只要用新的库把原来的替换掉就行了。
那么,是不是静态库就一无是处了呢?
答 曰:非也非也。不是有句话么:存在即是合理。静态库既然没有湮没在滔滔的历史长河中,就必然有它的用武之地。想象一下这样的情况:如果你用libpcap 库编了一个程序,要给被人运行,而他的系统上没有装pcap库,该怎么解决呢?最简单的办法就是编译该程序时把所有要链接的库都链接它们的静态库,这样, 就可以在别人的系统上直接运行该程序了。
所谓有得必有失,正因为动态库在程序运行时被链接,故程序的运行速度和链接静态库的版本相比必然会打折扣。然而瑕不掩瑜,动态库的不足相对于它带来的好处在现今硬件下简直是微不足道的,所以链接程序在链接时一般是优先链接动态库的,除非用-static参数指定链接静态库。

动态链接库
注意: little end 要加 -EL 编译选项.
1. 创建动态链接库
#include<stdio.h>  
void hello()  

printf("hello world/n");  
}  
用命令gcc -shared -fPIC hello.c -o libhello.so编译为动态库。可以看到,当前目录下多了一个文件libhello.so。
2. 再编辑一个测试文件test.c,内容如下
#include<stdio.h>  
int main()  
{  
printf("call hello()");  
hello();  
}  
编译 gcc test.c -lhello
-l 选项告诉编译器要使用hello这个库。奇怪的地方是动态库的名字是libhello.so,这里却使用hello,其实lhello即是去掉前面的lib和后面的.so.
 
但这样还不行,编译会出错。
In function `main':
test.c:(.text+0x1d): undefined reference to `hello'
collect2: ld returned 1 exit status

这是因为hello这个库在我们自己的路径中,编译器找不到。
需要使用-L选项,告诉hello库的位置
gcc test.c -lhello -L. -o test
-L .告诉编译器在当前目录中查找库文件
3. 编译成功后执行./test, 
仍然出错,说找不到库, 有两种方法:
一、可以把当前路径加入 /etc/ld.so.conf中然后运行ldconfig,或者以当前路径为参数运行ldconfig(要有root权限才行)。
二、把当前路径加入环境变量LD_LIBRARY_PATH中
 
当然,如果你觉得不会引起混乱的话,可以直接把该库拷入/lib,/usr/lib/等位置(无可避免,这样做也要有权限),这样链接器和加载器就都可以准确的找到该库了。
我们采用第二种方法:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:./
这样,再执行就成功了。
 
下面再讲讲静态链接库
仍使用刚才的hello.c和test.c。
1. gcc -c hello.c 注意这里没有使用-shared选项
2. 把目标文件归档    ar -r libhello.a hello.o
   程序 ar 配合参数 -r 创建一个新库 libhello.a 并将命令行中列出的对象文件插入。采用这种方法,如果库不存在的话,参数 -r 将创建一个新的库,而如果库存在的话,将用新的模块替换原来的模块。
3. 在程序中链接静态库
 gcc test.c -lhello -L. -static -o hello.static 
或者   gcc test.c libhello.a -L. -o hello.static
生成的hello.static就不再依赖libhello.a了
 
两个有用的命令

file程序是用来判断文件类型的,在file命令下,所有文件都会原形毕露的。
顺便说一个技巧。有时在 windows下用浏览器下载tar.gz或tar.bz2文件,后缀名会变成奇怪的tar.tar,到Linux有些新手就不知怎么解压了。但 Linux下的文件类型并不受文件后缀名的影响,所以我们可以先用命令file xxx.tar.tar看一下文件类型,然后用tar加适当的参数解压。
 
另外,还可以借助程序ldd实用程序来判断。
ldd是用来打印目标程序(由命令行参数指定)所链接的所有动态库的信息的,如果目标程序没有链接动态库,则打印“not a dynamic executable”,ldd的用法请参考manpage

3.UNIX ar Examples: How To Create, View, Extract, Modify C Archive Files (*.a)

http://www.thegeekstuff.com/2010/08/ar-command-examples/

ar is an archive tool used to combine objects to create an archive file with .a extension, also known as library.

In this article, let us discuss about how to create an user defined static library in C programming using the “ar” utility. The examples shows how to create, extract, and modify the archives using Linux ar command.

To demonstrate the static library creation, let us create two C programs — addition.c and multiplication.c

Using gcc, the object code for these programs are obtained, and the static library libarith.a is created from these two objects.

1. Create Two Sample C Programs

Create addition.c program as shown below.

int addition(int a,int b){int result;result = a + b;return result;}

Create multiplication.c program as shown below.

int multiplication(int a, int b){int result;result = a * b;return result;}

A while back we discussed about fundamental of writing C program using C hello world example.

2. Compile the Programs and Get Object Codes

Use -c option to compile both the c program. Using option -c will create the corresponding .o files.

$ gcc -c addition.c$ gcc -c multiplication.c

Now, the current working directory contains both the .c and .o files as shown below.

$ lsaddition.c   multiplication.c   addition.o   multiplication.o

3. Create the C Program Static Library using ar utility

Now create the static library “libarith.a” with the addition object file and multiplication object file as follows,

$ ar cr libarith.a addition.o multiplication.o

4. Write C program to Use the Library libarith.a

The library file libarith.a is now ready to usage. Following example indicates how to write a sample C program with the header file to use the libarith.a static library.

Create header.h :

#include <stdio.h>int addition(int a,int b);int multiplication(int a,int b);

Create example.c :

#include "header.h"int main(){int result;result = addition(1,2);printf("addition result is : %d\n",result);result = multiplication(3,2);printf("multiplication result is :  %d\n",result);}

Note: How to Debug C Program using gdb in 5 Simple Steps provides step-by-step instruction on debugging your C code.

Compile example.c :

$ gcc -Wall example.c -L/home/guest/ -larith -o example

The option -L instructs the compiler to look in the /home/guest directory for library files. From this directory, the compiler takes the libarith library file, compiles it with example.c program.

Another method to Compile example.c :

$ gcc -Wall example.c libarith.a -o example

Execute example executable :

$ ./exampleaddition result is : 3multiplication result is : 6

5. View Object Files in an Archive Using ar Command, option t

To list the object files available in the libarith.a:

$ ar t libarith.aaddition.omultiplication.o

The options in ar command are similar to the tar command.

6. Extract Object Files from an Archive Using ar Command, option x

You can extract the object files available in an archive as follows.

$ mkdir object$ cp libarith.a object/$ cd object$ ar x libarith.a$ ls *.oaddition.omultiplication.o

7. Add an Object File into the Existing Archive Using ar, option r

Let assume that you have create another object file called subtraction.o

The following command extends the libarith.a library file, by inserting subtraction.o object as shown below.

$ ar r libarith.a subtraction.o $ ar t libarith.aaddition.omultiplication.osubtraction.o

While inserting a .o file, it it already exists in the archive, it would be replaced. Without checking for replacements the objects can be added to end of the archive by using -q option.

8. Delete a Specific Archive Member Using ar, option d

In order to delete a specific archive member from the library file, do the following.

$ ar d libarith.a addition.o$ ar t libarith.amultiplication.osubtraction.o

原创粉丝点击