linux底下的makefile框架拓扑结构分析
Make file
由于把系统所的东西都整合在一起编译,有些要编译的项目可能记不住,这时必须写个makefile的help命令,用来导出可以编译的项目.
这时可以执行make help命令
[czw@localhost project]$ make help
make diagnose u can get information
how to build a project
step1:make com2com
step2:make com2comclean
handapp
gpsapp
wtdapp
logapp
evdoapp
mainapp
rootfs_img
busybox
com2com
libnl6k
libnl6ksys
home_img
update
pppd
tinylogin
在调试makefile的过程中,可能需要对一些路径或者变量的值的预期进行验证,这时可以执行make
diagnose命令,会把你想知道的路径打印出来
示例如下:
[czw@localhost project]$ make diagnose
PROJECT_BUSYBOX=
PROJECT_LINUX=/home/czw/project/kernel/linux
PROJECT_UBOOT=/home/czw/project/uboot
PROJECT_LIBDES=/home/czw/project/src/libdes
WORKSPACE=/home/czw/project
CROSS=/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-
如何编译一个应用,举个例子:
当然在编译应用之前,最好先确认使用的工具链是哪个.
[czw@localhost project]$ env
PATH=/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin:/usr/local/bin:/bin:/usr/bin:/home/czw/bin
好了,看到了工具链正是可以用来编译海思平台的,
PATH=/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin
附注:export PATH=
PATH=/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin:$PATH
(这条命令可以用来设置当前工具链的)
示例:编译mainapp这个应用,编译完后会把编译结果放在scripts目录底下(cp
/home/czw/project/src/MainApp/MainApp /home/czw/project/scripts
)
[root@localhost project]# make mainapp
cd /home/czw/project/src/MainApp;make
make[1]: Entering directory `/home/czw/project/src/MainApp'
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Main.o
-I/home/czw/project/NL6KLIB/include NL_Main.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Alarm.o
-I/home/czw/project/NL6KLIB/include NL_Alarm.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_DynamicMenu.o
-I/home/czw/project/NL6KLIB/include NL_DynamicMenu.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_GPS.o
-I/home/czw/project/NL6KLIB/include NL_GPS.c
In file included from NL_GPS.c:35:
/home/czw/project/NL6KLIB/include/libzlib.h:30:7: warning: no
newline at end of file
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Menu.o
-I/home/czw/project/NL6KLIB/include NL_Menu.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Misc.o
-I/home/czw/project/NL6KLIB/include NL_Misc.c
In file included from NL_Misc.c:18:
/home/czw/project/NL6KLIB/include/libzlib.h:30:7: warning: no
newline at end of file
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Net.o
-I/home/czw/project/NL6KLIB/include NL_Net.c
NL_Net.c: In function `NL_Net_WL_SHM':
NL_Net.c:619: warning: use of cast expressions as lvalues is
deprecated
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Recieve.o
-I/home/czw/project/NL6KLIB/include NL_Recieve.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Send.o
-I/home/czw/project/NL6KLIB/include NL_Send.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Set.o
-I/home/czw/project/NL6KLIB/include NL_Set.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Update.o
-I/home/czw/project/NL6KLIB/include NL_Update.c
In file included from NL_Update.c:17:
/home/czw/project/NL6KLIB/include/libzlib.h:30:7: warning: no
newline at end of file
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Camera.o
-I/home/czw/project/NL6KLIB/include NL_Camera.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Ext_Dev.o
-I/home/czw/project/NL6KLIB/include NL_Ext_Dev.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/NL_Tts.o
-I/home/czw/project/NL6KLIB/include NL_Tts.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/Msg_Handle.o
-I/home/czw/project/NL6KLIB/include Msg_Handle.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/Msg_CRC.o
-I/home/czw/project/NL6KLIB/include Msg_CRC.c
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -c -o obj/Msg_Parser.o
-I/home/czw/project/NL6KLIB/include Msg_Parser.c
In file included from Msg_Parser.c:23:
/home/czw/project/NL6KLIB/include/libzlib.h:30:7: warning: no
newline at end of file
/opt/hisi-linux/x86-arm/gcc-3.4.3-uClibc-0.9.28/usr/bin/arm-hismall-linux-gcc
-D__ARM_CPU__ -L/home/czw/project/NL6KLIB -o MainApp obj/NL_Main.o
obj/NL_Alarm.o obj/NL_DynamicMenu.o obj/NL_GPS.o obj/NL_Menu.o
obj/NL_Misc.o obj/NL_Net.o obj/NL_Recieve.o obj/NL_Send.o
obj/NL_Set.o obj/NL_Update.o obj/NL_Camera.o obj/NL_Ext_Dev.o
obj/NL_Tts.o obj/Msg_Handle.o obj/Msg_CRC.o obj/Msg_Parser.o -lNL6K
-lNL6Ksys -lpthread -ldes -lzlib -lrsa -lencryption -lm
make[1]: Leaving directory `/home/czw/project/src/MainApp'
cp /home/czw/project/src/MainApp/MainApp
/home/czw/project/scripts
示例:如何来清除一个应用的编译结果呢?
[root@localhost project]# make mainappclean
cd /home/czw/project/src/MainApp;make clean
make[1]: Entering directory `/home/czw/project/src/MainApp'
rm -f MainApp
rm -rf obj
make[1]: Leaving directory `/home/czw/project/src/MainApp'
好了现在来看一个应用是如何被编译的细节东西了?
1:介绍这个之前要看一个如以一下图
2:要弄懂架构的组织方式
3:每个人在服务器都是有一个工作目录,位置在(home/czw /home/wangx /home/wmh等等)
4:在/home/czw 目录底下创建一个目录用来作为海思平台的开发目录:名字起为workspace
当然也可以是其它名字,最好能统一为workspace。
4:个人目录的组织拓扑结构:从172.16.6.98/svn/project/trunk目录底下check
out一份属于自己访问权限内的目录结构到/home/czw/worksapce ( 以czw用户为例)
好了来看从svn服务器获取代码后的目录结构,
/home/czw/workspace---
|src
|scripts
|third-part
|makefile
|build
|doc
|rootfs
|kernel----------|busybox
| |uboot
| |linux
|
|
现在可以来探讨主makefile了
#cd /home/czw/workspace
#获取当前的工作目录,作为海思平台的开发目录附注(其实这个目录可以是任意的不要以为只界定在/home/czw/workspace,也可以是/home****/workspace等)
export WORKSPACE=$(PWD)-------海思平台的工作目录
#编译项目所在的目录
export
PROJECT_MAINAPP=$(WORKSPACE)/src/MainApp-------用来指定要编译的应用所在的目录
SCRIPT=$(WORKSPACE)/scripts-----用来存放编译结果的
mainapp:
cd $(PROJECT_MAINAPP);make //进入应用的目录,进行编译
cp $(PROJECT_MAINAPP)/MainApp $(SCRIPT) //把编译结果拷贝到script目录底下
想引进的一套机制,该机制应该功能比较灵活强大,适合于大型应用组织架构的编译。该机制不但可以解决应用编译的问题,而且还能解决动态库的生成,静态库的生成,这些机制已经做实验验证过.
举个例子:
对动态库的测试:
/home/czw/workspace---
|src---------------------------------|so---------------(so为动态库的生成)
| |testso----------(testso为对动态库进行测试的应用)
|scripts
|third-part
|makefile
|build-----|commonact.mak
-------|-env.mak
#进入主makefile所在的目录,动态库的生成
#make soclean
#make so------------------生成libczw.so
把libczw.so拷贝到NL6KLIB目录底下
#进入主makefile所在的目录,对动态库进行测试
#make testsoclean
#make testso----------生成可执行文件testso.exe
在海思终端上对动态库和测试程序进行测试
把libczw.so 拷贝到/usr/lib目录底下
把testso.exe拷贝到终端的任何目录底下
运行testso.exe
/tmp $ ./testso.exe
out one
out two
out three
out four
说明动态库和测试程序都正常.
那把libczw.so删除掉呢会怎么样呢?
/tmp $ ./testso.exe
./testso.exe: can't load library
'/home/czw/project/NL6KLIB//libczw.so'
那把libczw.so拷贝到/newland/lib/libczw.so目录底下呢
/tmp $ ./testso.exe
./testso.exe: can't load library
'/home/czw/project/NL6KLIB//libczw.so'
如何解决把应用自己产生的动态库放在自己的目录上呢也就是在/newland/lib
执行export LD_LIBRARY_PATH=/newland/lib:$LD_LIBRARY_PATH
运行testso.exe
/tmp $ ./testso.exe
out one
out two
out three
out four
好了,执行到这边,对动态库的生成,以及在终端文件系统上如何组织有了自己的解决方案.
#进入主makefile所在的目录,静态库的生成
#make soclean
#make so STATIC_LIB=1 ------------------生成libczw.a 注意编译时要传一宏STATIC_LIB=1,不传宏时默认是动态库
把libczw.a拷贝到NL6KLIB目录底下
删除掉/newland/lib/libczw.so
/tmp $ ./testso.exe
out one
out two
out three
out four
从执行效果看,知道库的代码已经链接到程序testso.exe
致此, 该makefile应该从整体上解决了应用的编译,动态库的编译,静态库的编译的问题.再回顾一下makefile的用法
[czw@localhost project]$ make help
make diagnose u can get information
how to build a project
step1:make com2com
step2:make com2comclean
handapp
gpsapp
wtdapp
logapp
evdoapp
mainapp
rootfs_img
busybox
com2com
libnl6k
libnl6ksys
home_img
update
pppd
tinylogin
由帮助中得知各个要编译的应用的名字
[czw@localhost project]$ make handapp ----------------------编译手柄应用
[czw@localhost project]$ make
handappclean-----------------清除手柄应用编译出来的中间文件
[czw@localhost project]$ make
mainapp------------------------编译主应用
[czw@localhost project]$ make
mainapp-----------------------清除主应用编译出来的中间文件
具体的各个makefile的写法都有相应的模板,可移植性比较好.
海思平台的makefile设计的架构如下:
/home/czw/workspace--|
|makefile---------------------------------------总的makefile
|build----------------------|env.mak----------定义一些命令,工具链
|commonact.mak----定义一些模式规则
|src-------|handapp----代码
Makefile--------各个应用底下的Makefile
|gpsapp------代码
Makefile--------各个应用底下的Makefile
|so------------代码
makefile--------各个库底下的Makefile
编译时,总的makefile,通过命令会进入到应用底下(src目录下)的各个应用模块去编译.而且编译规则的共性已被抽象成两个文件env.mak
commonact.mak
应用底下的makefile本身可以写得很简单,抽象出来如下1:定义依赖 2:定义源文件列表 3:定义头文件搜索路径
4:定义库文件搜索路径,这些东西可以定制成模板,具有普遍的通用性,也就是说,可移植性好。
这样子整体框架就出来了