标签:
本文来源于:http://www.360doc.com/content/12/0403/08/1317564_200410720.shtml转载请注明出处
本文代码虽简单,但涉及比较复杂的各种调用关系,欲研究者需有耐心及清醒头脑。 切切!背景交待: 1、正在移植U-Boot,并对其源代码进行了一些分析,感觉它的Makefile十分强劲;
2、以前写的Makefile模板不合适多层目录;
3、研究一下多个库之间相互调用的问题。
平台及测试环境介绍:
1、fc9系统,i386平台,gcc版本4.3.2,使用Secure CRT连接linux系统,数据均由该软件复制而得;
2、工程目录名称为lib-test,其下有3个代码目录及一个头文件目录,分别是foo(foo.c及common.c文件)、bar(bar.c及common.c文件)、bt(backtrace.c文件)和configs(foo.h、bar.h及backtrace.h文件);其中bt目录为backtrace代码,它是作者的工程库的一部分。
目录路径、文件分布如下
lib-test
|-->main.c |-->example.c |-->Makefile | |-->foo.c |-->foo-->|-->common.c | |-->Makefile | | |-->bar.c |-->bar-->|-->common.c | |-->Makefile | | |-->backtrace.c |-->bt--->| | |-->Makefile | | |-->foo.h |-->configs->|-->bar.h | |-->backtrace.h |
for dir in $(SUBDIRS); /
do $(MAKE) -C $$dir all || exit 1; /
done
#ifndef FOO_H_
#define FOO_H_
void foo(int i);
int hello_foo(void);
#endif
#include <stdio.h>
void foo(int i)
{
printf("hell from %s() in file: %s, num:%d/n", __func__, __FILE__, i);
}
int hello_foo(void)
{
printf("in func: %s()/n", __func__);
bar(100);
common_foo();
printf("=========================================/n");
return 0;
}
#include <stdio.h>2、bar目录
int common_foo(void)
{
printf("this is a common function in foo/common.c/n");
return 0;
}
#ifndef BAR_H_
#define BAR_H_
void bar(int i);
int hello_bar(void);
#endif
#include <stdio.h>
void bar(int i)
{
printf("hell from %s() in file: %s, num:%d/n", __func__, __FILE__, i);
}
int hello_bar(void)
{
printf("in func: %s()/n", __func__);
foo(200);
common_bar();
printf("=========================================/n");
return 0;
}
#include <stdio.h>3、example.c
int common_bar(void)
{
printf("this is a common function in bar/common.c/n");
return 0;
}
#include <stdio.h>4、main.c
void foo1(int a)
{
int i;
i = a;
}
int fun(int a, int b, int c)
{
char buf[14];
int sum;
sum = a + b + c;
foo1(a);
return sum;
}
#include <stdio.h>(题外话:
#include <backtrace.h>
#include <foo.h>
#include <bar.h>
int main(void)
{
printf("hello from %s()/n/n", __func__);
hello_foo();
hello_bar();
print_trace(11);
}
[latelee@latelee lib-test-latelee.org]$ gcc -g -c main.c example.c --verbose -Iconfigs命令来编译时显示了gcc搜索头文件路径的过程,如下:
#include "..." search starts here:当然,实际开发中不提倡这种方法,然而在U-Boot中却是十分常见的,只是有些人不明白其中的道理罢了。
#include <...> search starts here:
configs
/usr/local/include
/usr/lib/gcc/i386-redhat-linux/4.3.2/include
/usr/include
End of search list.
# A simple Makefile for lib(libxxx.a)
# By Late Lee(http://www.latelee.org)
AR = ar
ARFLAGS = cr
LIB = libfoo.a
RM = -rm -rf
OBJS := foo.o common.o
all: $(LIB)
$(LIB): $(OBJS)
$(AR) $(ARFLAGS) $@ $(OBJS)
clean:
$(RM) $(OBJS) $(LIB) *.bak *~
.PHONY: all clean
#################################################################
# A simple Makefile
# By Late Lee(http://www.latelee.org)
#
# bugs:
# 1. 需要显式指定库位置、名称;
# 2. make 及 make clean处理得不好(对于库,要么删除再编译,要么无操作);
#################################################################
CC=gcc
CFLAGS = -Wall
DEBUG = y
ifeq ($(DEBUG), y)
CFLAGS += -g
else
CFLAGS += -O2
endif
SUBDIRS := foo bar bt
LIBS := bt/libbt.a foo/libfoo.a bar/libbar.a
LDFLAGS = $(LIBS)
RM = -rm -rf
__OBJS = main.o
__OBJS += example.o
__SRCS = $(subst .o,.c,$(__OBJS))
target = a.out
MAKE = make
#all: clean $(target)
all: $(target)
$(__OBJS): $(__SRCS)
$(CC) $(CFLAGS) -c $^ -I ./configs/
$(target): $(__OBJS)
for dir in $(SUBDIRS); /
do $(MAKE) -C $$dir all || exit 1; /
done
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
clean:
@for dir in $(SUBDIRS); do make -C $$dir clean|| exit 1; done
$(RM) $(__OBJS) $(target) *.bak *~
.PHONY: all clean
[latelee@latelee lib-test]$ make运行结果:
gcc -Wall -g -c main.c example.c -I ./configs/
example.c: In function ‘fun’:
example.c:10: warning: unused variable ‘buf’
for dir in foo bar bt ; /
do make -C $dir all || exit 1 ; /
done
make[1]: Entering directory `/home/latelee/linux-c/lib-test/foo‘
cc -c -o foo.o foo.c
cc -c -o common.o common.c
ar cr libfoo.a foo.o common.o
make[1]: Leaving directory `/home/latelee/linux-c/lib-test/foo‘
make[1]: Entering directory `/home/latelee/linux-c/lib-test/bar‘
cc -c -o bar.o bar.c
cc -c -o common.o common.c
ar cr libbar.a bar.o common.o
make[1]: Leaving directory `/home/latelee/linux-c/lib-test/bar‘
make[1]: Entering directory `/home/latelee/linux-c/lib-test/bt‘
cc -c -o backtrace.o backtrace.c
ar cr libbt.a backtrace.o
make[1]: Leaving directory `/home/latelee/linux-c/lib-test/bt‘
gcc -Wall -g main.o example.o -o a.out bt/libbt.a foo/libfoo.a bar/libbar.a
[latelee@latelee lib-test]$ ./a.out
hello from main()
in func: hello_foo()
hell from bar() in file: bar.c, num:100
this is a common function in foo/common.c
=========================================
in func: hello_bar()
hell from foo() in file: foo.c, num:200
this is a common function in bar/common.c
=========================================
Obtained 4 stack frames.
./a.out [0x8048733]
./a.out [0x80486cf]
/lib/libc.so.6(__libc_start_main+0xe5) [0x7ea6d5]
./a.out [0x8048601]
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/mu0206mu/article/details/47054643