Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1749384
  • 博文数量: 143
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1462
  • 用 户 组: 普通用户
  • 注册时间: 2016-08-23 11:14
文章分类

全部博文(143)

文章存档

2022年(3)

2021年(13)

2020年(21)

2019年(8)

2018年(28)

2017年(7)

2016年(63)

我的朋友

分类: 嵌入式

2016-10-18 17:25:59

1 func1.c func1.h func2.c func2.h 被 main.c 和 debug.c 共同调用的makefile如何写?

点击(此处)折叠或打开

  1. CROSS_COMPILE = arm-none-linux-gnueabi-
  2. CC = $(CROSS_COMPILE)gcc
  3. RM = rm

  4. EXES = main debug
  5. SRCS = func1.c func2.c
  6. OBJS = $(SRCS:.c=.o)

  7. all:$(EXES)

  8. main:main.o $(OBJS)
  9.     $(CC) -o $@ $^

  10. debug:debug.o $(OBJS)
  11.     $(CC) -o $@ $^

  12. clean:
  13.     $(RM) -rf *.o $(EXES)

  14. %.o:%.c
  15.     $(CC) -o $@ -c $<
顺便提醒一下Makefile常识:当Makefile中有多个目标(target)时,若执行make指令时不指定执行哪一个target,则系统默认只执行第一个target。
1.1 $@ $^ $< 分别代表什么意思?
$@  表示目标文件
$^  表示所有的依赖文件
$<  表示第一个依赖文件
1.2 常用的makefile写法中
SRCS = func1.c func2.c
OBJS = $(SRCS:.c=.o)

OBJS = func1.o func2.o
SRCS = $(OBJS:.o=.c)
表示什么意思?
前者被makefile解释为:
SRCS = func1.c func2.c
OBJS = func1.o func2.o
后者被makefile解释为:
OBJS = func1.o func2.o
SRCS = func1.c func2.c
这下明白了吧。
2 若把func1.c func1.h func2.c func2.h作为动态链接库comm呢?

点击(此处)折叠或打开

  1. CROSS_COMPILE = arm-none-linux-gnueabi-
  2. CC = $(CROSS_COMPILE)gcc
  3. RM = rm
  4. LD = ld

  5. EXES = main debug
  6. SRCS = func1.c func2.c
  7. OBJS = $(SRCS:.c=.o)
  8. LIBS = libcomm.so

  9. all:$(LIBS) $(EXES)

  10. main: main.o
  11.     $(CC) -o $@ $^ -L./ -lcomm

  12. debug: debug.o
  13.     $(CC) -o $@ $^ -L./ -lcomm

  14. $(LIBS):$(OBJS)
  15.     $(CC) -shared -o $@ $^

  16. clean:
  17.     $(RM) -rf *.o $(EXES) $(LIBS)

  18. main.o:main.c
  19.     $(CC) -o $@ -c $^

  20. debug.o:debug.c
  21.     $(CC) -o $@ -c $^

  22. $(OBJS):%.o:%.c
  23.     $(CC) -fPIC -o $@ -c $<

2.1 必须先调用$(LIBS)规则生成libcomm.so。否则,报错:找不到libcomm.so。
2.2 必须要使用“makefile静态模式”。否则,报错:
gcc -o func1.o -c func1.c func2.c
gcc: 致命错误: 当有多个文件时不能在已指定 -c 或 -S 的情况下指定 -o 编译中断。
  注意若把静态模式,即上面的
$(OBJS):%.o:%.c
$(CC) -fPIC -o $@ -c $<
改为
$(OBJS):%.o:%.c
$(CC) -fPIC -o $@ -c $^
效果是一样的。
但是,改写为
$(OBJS):$(SRCS)
$(CC) -fPIC -o $@ -c $^
或者
$(OBJS):$(SRCS)
$(CC) -fPIC -o $@ -c $<
都是不行的。
  这是因为:静态模式表示依次对$(OBJS)下的.c编译为.o。是依次,不是一次,所以$<改为$^效果是一样的。
2.3 执行前必须将生成的libcomm.so拷贝到/usr/lib/下。否则,报错:./main: error while loading shared libraries: libcomm.so: cannot open shared object file: No such file or directory。
  其实,“找不到所依赖的动态链接库文件”是个非常常见的问题,解决方法有很多种,参考我的另一篇博文:export。具体用什么方法,视情况而定,如上拷贝比较方便,但有时无root权限,就只能用export LD_LIBRARY_PATH的方法了。
  事实上,执行main或debug前,使用ldd main或ldd debug就可以测试是否正确动态链接,而不一定必须通过执行来发现找不到动态链接库文件。
3 小结
  %.o:%.c 和 makefile静态模式:$(OBJS):%.o:%.c 对于编译大量.c文件非常高效率。执行起来类似于for循环一样,需要注意的是理解其commands中使用的是$<,而非$^,虽然使用$<或$^的执行过程相同。
3.1 %.o:%.c常用的几种写法:
%.o:%.c
$(CC) -o $@ -c $<

%.o:%.c
$(CC) -o $@ $<
  利用Makefile缺省规则的写法:
.c.o:
$(CC) -o $@ -c $<

.c.o:
$(CC) -o $@ $<

.c.o: 
$(CC) -c $< 
  注意其中的.c.o,其实是和%o:%c等价,是一个旧格式。
3.2 makefile静态模式:$(OBJS):%.o:%.c常用的几种写法:
$(OBJS):%.o:%.c
$(CC) -o $@ -c $<

$(OBJS):%.o:%.c
$(CC) -o $@ $<
阅读(1830) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~