Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2116838
  • 博文数量: 438
  • 博客积分: 3871
  • 博客等级: 中校
  • 技术积分: 6075
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-10 00:11
个人简介

邮箱: wangcong02345@163.com

文章分类

全部博文(438)

文章存档

2017年(15)

2016年(119)

2015年(91)

2014年(62)

2013年(56)

2012年(79)

2011年(16)

分类: LINUX

2012-03-28 17:28:52

1.在写代码之前先把Makefile弄好,然后集中精力学TCP/IP
  1. EXE=main
  2. CC=gcc                          
  3. SRC=$(wildcard *.c)              --> a 
  4. OBJ=$(SRC:.c=.o)                 --> b  
  5. DEP=$(patsubst %.c,.%.d,$(SRC))  --> c
  6. CFLAGS=-g                        --> d
  7. $(EXE):$(OBJ)                    --> e
  8.     $(CC) $^ -o $@

  9. $(DEP):.%.d:%.c                  --> f
  10.     @set -e; rm -f $@; \
  11.     $(CC) -MM $< > $@.$$$$; \
  12.     sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; \
  13.     rm -f $@.$$$$

  14. -include $(DEP)                  -->g

  15. clean:                           -->h
  16.     @rm $(EXE) $(OBJ) $(DEP) -f
解释说明
a. SRC=$(wildcard *.c) 
    SRC的内容就是一个以"*.c"结尾的文件列表
b. OBJ=$(SRC:.c=.o)
    这个等同于OBJ=$(patsubst %.c,%.o,$(SRC)),在SRC的一堆文件名中,将.c结尾的文件替换成.o
c. DEP=$(patsubst %.c,.%.d,$(SRC))
    在SRC的一堆文件名中,将.c结尾的文件替换成.d,
    注意这儿是.%.d,前面还有个点,这是为了生成隐藏文件
d. CFLAGS
    Makefile中的内含变量CFLAGS, 这个在编译时会自动用到
e. 链接
     将所有的.o连接生成目标文件
f. 生成DEP, 为什么要加入DEP呢?引用说明一下
    Makefile的自动推导功能只会推导出目标文件对源文件的依赖关系,而不会增加头文件的依赖关系!!!这导致的直接问题就是修改项目的头文件,不会导致make的自动更新!除非修改头文件后运行一次make clean,再运行make……
g. -include
     include前面的‘-’,是为了避免第一次make时由于.depend文件不存在报告错误信息
h. @rm
     rm前面加@,不输出任何信息

参考文章:
http://www.cnblogs.com/fanzhidongyzby/p/3141041.html
Makefile.txt (下载后将Makefile.txt改名为Makefile)

2. 特殊情况的改进
  1. ├── main.c            --> include了testlib目录下的testadd.c时  #include "testadd.h"
  2. ├── Makefile
  3. └── testlib
  4.     ├── Makefile
  5.     ├── testadd.c
  6.     └── testadd.h
cong@msi:/work/test/test/3testlib$ gcc -MM main.c     -->头文件的依赖关系
main.c:3:21: fatal error: testadd.h: No such file or directory
 #include "testadd.h"
                     ^
compilation terminated.
2.1 改进后的Makefile
  1. cong@msi:/work/test/test/3testlib$ cat Makefile
  2. EXE=main
  3. CC=gcc
  4. SRC=$(wildcard *.c)
  5. #OBJ=$(SRC:.c=.o)
  6. OBJ=$(patsubst %.c,%.o,$(SRC))
  7. DEP=$(patsubst %.c,.%.d,$(SRC))
  8. INCDIR=-I./testlib
  9. CFLAGS = -g -O0 $(INCDIR)
  10. LDFLAGS = -L./testlib/ -ltestadd
  11. $(EXE):$(OBJ)
  12.     make -C ./testlib
  13.     $(CC) $^ -o $@ $(LDFLAGS)

  14. $(DEP):.%.d:%.c
  15.     @set -e; rm -f $@; \
  16.     $(CC) $(INCDIR) -MM $< > $@.$$$$; \
  17.     sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; \
  18.     rm -f $@.$$$$

  19. -include $(DEP)
  20. clean:
  21.     @rm $(EXE) $(OBJ) $(DEP) -f
  22.     @make -C ./testlib clean
3. 运行时的库
上述改法编译链接都没有问题,但是在运行时会出现如下:
  1. cong@msi:/work/test/test/3testlib$ ./main
  2. ./main: error while loading shared libraries: libtestadd.so: cannot open shared object file: No such file or directory
虽然通过export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):./testlib可以解决,
但问题是libtestlib只有这一个程序用,export LD_LIBRARY_PATH之后,所有的程序在加载时都会查找到testlib这个目录了。
这儿用到了ld的 -rpath选项,它是指定运行时的搜索路径,硬编码到可执行文件内部的搜索路径。
注意: 在gcc中使用ld链接选项时,需要在选项前面加上前缀-Wl
注意2: 加了-rpath之后, readelf -d ./main 查看,会比没加的多这一行
0x000000000000000f (RPATH)              Library rpath: [testlib:testsub]
  readelf -d   -d --dynamic           Display the dynamic section (if present)
3.1 加入运行时库的
  1. EXE=main
  2. CC=gcc
  3. SRC=$(wildcard *.c)
  4. #OBJ=$(SRC:.c=.o)
  5. OBJ=$(patsubst %.c,%.o,$(SRC))
  6. DEP=$(patsubst %.c,.%.d,$(SRC))
  7. INCDIR=-I./testlib
  8. CFLAGS = -g -O0 $(INCDIR)
  9. LDFLAGS = -L./testlib/ -ltestadd -Wl,-rpath,testlib       --> 在gcc中使用ld链接选项时,需要在选项前面加上前缀-Wl
  10. $(EXE):$(OBJ)
  11.     make -C ./testlib
  12.     $(CC) $^ -o $@ $(LDFLAGS)

  13. $(DEP):.%.d:%.c
  14.     @set -e; rm -f $@; \
  15.     $(CC) $(INCDIR) -MM $< > $@.$$$$; \
  16.     sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; \
  17.     rm -f $@.$$$$

  18. -include $(DEP)
  19. clean:
  20.     @rm $(EXE) $(OBJ) $(DEP) -f
  21.     @make -C ./testlib clean
3.2代码下载
3testlib.rar  (下载后改名为3testlib.tar.gz)

3.3 多个库的情况
  1. EXE=main
  2. CC=gcc
  3. SRC=$(wildcard *.c)
  4. OBJ=$(patsubst %.c,%.o,$(SRC))
  5. DEP=$(patsubst %.c,.%.d,$(SRC))
  6. INCDIR=-I./testlib -I./testsub
  7. CFLAGS = -g -O0 $(INCDIR)
  8. LDFLAGS = -L./testlib/ -ltestadd -L./testsub/ -ltestsub -Wl,-rpath,testlib:testsub
  9. $(EXE):$(OBJ)
  10.     make -C ./testlib
  11.     make -C ./testsub
  12.     $(CC) $^ -o $@ $(LDFLAGS)

  13. $(DEP):.%.d:%.c
  14.     @set -e; rm -f $@; \
  15.     $(CC) $(INCDIR) -MM $< > $@.$$$$; \
  16.     sed 's,/($*/)/.o[ :]*,/1.o $@ : ,g' < $@.$$$$ > $@; \
  17.     rm -f $@.$$$$

  18. -include $(DEP)
  19. clean:
  20.     @rm $(EXE) $(OBJ) $(DEP) -f
  21.     @make -C ./testlib clean
  22.     @make -C ./testsub clean
3.4 代码下载
4multlib.rar  (下载后改名为4.multlib.tar.gz)


阅读(1864) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~