静态库与动态库

来源:互联网 发布:编程原本 pdf 下载 编辑:程序博客网 时间:2024/05/17 22:59

动态库与静态库

目录

动态库与静态库...1

1.     动态库与静态库概述...1

1.1       动态库与静态库的区别:...1

1.2       运行时的动态库对内存的影响:...1

1.3       对内存的消耗因进程个数而异:...1

2.     Shell 脚本语法...1

3.     静态库的制作与makefile语法...3

3.1       部分语法注释...3

3.2       静态库的生成:  ---<机芯库的makefile>.3

3.3       核心语句分析:...4

3.4       机芯接入库制作源码...5

4.     动态库的制作...7

4.1       动态库制作核心语句分析...7

4.2       动态库制作源码...8

 

 

1.     动态库与静态库概述

1.1      动态库与静态库的区别:

1.      静态连接库就是把(lib)文件中用到的函数代码直接链接进目标程序,程序运行的时候不再需要其它的库文件;

2.      动态链接就是把调用的函数所在文件模块(DLL)和调用函数在文件中的位置等信息链接进目标程序,程序运行的时候再从DLL中寻找相应函数代码,因此需要相应DLL文件的支持。 

 

1.2      运行时的动态库对内存的影响:

 

1. 静态链接后的davinci加载完后,我们把davinci删除,也就是需要使用的内存只是一份。

2. 动态库的运行时加载。实际需要的内存是两份。必须保存一份在内存中,不能删除。

运行时再有操作系统加载一份。

 

1.3      对内存的消耗因进程个数而异:

 

1. 当我们的代码只有一个进程时,使用动态库运行比直接静态库,浪费一份动态库的内存的。

 

2. 有两个进程时动态库运行跟静态链接要的内存一样。

3.      只有大于3个进程才能体现出动态库在内存使用上的节省。

 

 

 

2.     Shell脚本语法

$@:表示所有脚本参数的内容,表示方法:”1””2” ”3”

$#:表示返回所有脚本参数的个数

$*:表示所有脚本参数的内容,表示方法”1 2 3”

文件表达式

if [ -f file ]    如果文件存在

if [ -d ...   ]    如果目录存在

if [ -s file  ]    如果文件存在且非空

if [ -r file  ]    如果文件存在且可读

if [ -w file  ]    如果文件存在且可写

if [ -x file  ]    如果文件存在且可执行   

 

整数变量表达式

if [ int1 -eq int2 ]    如果int1等于int2  

if [ int1 -ne int2 ]    如果不等于   

if [ int1 -ge int2 ]       如果>=

if [ int1 -gt int2 ]       如果>

if [ int1 -le int2 ]       如果<=

if [ int1 -lt int2 ]       如果<

   

 

字符串变量表达式

If  [$a = $b ]                如果string1等于string2

                               字符串允许使用赋值号做等号

if  [$string1 !=  $string2 ]  如果string1不等于string2      

if  [-n $string  ]            如果string 非空(0),返回0(true) 

if  [-z $string  ]            如果string 为空

if  [$sting ]                 如果string 非空,返回0 (-n类似)   

 

 

特殊字符:

file=/dir1/dir2/dir3/my.file.txt

我們可以用 ${ } 分別替換獲得不同的值:

${file#*/}:拿掉第一條 /及其左邊的字串:dir1/dir2/dir3/my.file.txt

${file##*/}:拿掉最後一條 /及其左邊的字串:my.file.txt

${file#*.}:拿掉第一個 .及其左邊的字串:file.txt

${file##*.}:拿掉最後一個 .及其左邊的字串:txt

${file%/*}:拿掉最後條 /及其右邊的字串:/dir1/dir2/dir3

${file%%/*}:拿掉第一條 /及其右邊的字串:(空值)

${file%.*}:拿掉最後一個 .及其右邊的字串:/dir1/dir2/dir3/my.file

${file%%.*}:拿掉第一個 .及其右邊的字串:/dir1/dir2/dir3/my

 

 

 

 

 

 

 

 

 

 

3.     静态库的制作与makefile语法

3.1      部分语法注释

1.      C_SRCS   = $(filter %.c, $(SOURCES))

语法:$(filter <pattern...>,<text> )

名称:过滤函数——filter

功能:以<pattern>模式过滤<text>字符串中的单词,保留符合模式<pattern>的单词。可

以有多个模式。

返回:返回符合模式<pattern>的字串。

2.      C_OBJS   = $(C_SRCS:%.c=%.o)

语法:$(patsubst %.c,%.o,x.c.c bar.c)

把字串“x.c.cbar.c”符合模式[%.c]的单词替换成[%.o],返回结果是“x.c.obar.o

$(var:<pattern>=<replacement> )”

相当于

$(patsubst <pattern>,<replacement>,$(var))”,

3.

Make –c :指定目录

Make –f:通过 -f选项将其它文件看作Makefile

Make –j:-j参数可以使make进行并行编译

 

$(shell xxx): 调用shell指令××

 

4.-include:

如果指示符“include”指定的文件不是以斜线开始(绝对路径,如/usr/src/Makefile...),而且当前目录下也不存在此文件;make将根据文件名试图在以下几个目录下查找:首先,查找使用命令行选项“-I”或者“--include-dir”指定的目录,如果找到指定的文件,则使用这个文件;否则继续依此搜索以下几个目录(如果其存在):“/usr/gnu/include”、“/usr/local/include”和“/usr/include”。

当在这些目录下都没有找到“include”指定的文件时,make将会提示一个包含文件未找到的告警提示,但是不会立刻退出。而是继续处理Makefile的后续内容。当完成读取整个Makefile后,make将试图使用规则来创建通过指示符“include”指定的但未找到的文件,当不能创建它时(没有创建这个文件的规则),make将提示致命错误并退出。会输出类似如下错误提示:

 

5.CFLAGSLDFLAGS:

configure时我们经常会遇到明明已经指令了目录但有时就是链接不了的情况,解决方法及原因如下(引用自http://www.cnblogs.com/taskiller/archive/2012/12/14/2817650.html)

 

 

CFLAGS:指定头文件(.h文件)的路径,如:CFLAGS=-I/usr/include-I/path/include。同样地,安装一个包时会在安装路径下建立一个include目录,当安装过程中出现问题时,试着把以前安装的包的include目录加入到该变量中来。

 

LDFLAGSgcc等编译器会用到的一些优化参数,也可以在里面指定库文件的位置。用法:LDFLAGS=-L/usr/lib -L/path/to/your/lib。每安装一个包都几乎一定的会在安装目录里建立一个lib目录。如果明明安装了某个包,而安装另一个包时,它愣是说找不到,可以抒那个包的lib路径加入的LDFALGS中试一下。

 

LIBS:告诉链接器要链接哪些库文件,如LIBS= -lpthread -liconv

 

简单地说,LDFLAGS是告诉链接器从哪里寻找库文件,而LIBS是告诉链接器要链接哪些库文件。不过使用时链接阶段这两个参数都会加上,所以你即使将这两个的值互换,也没有问题。

 

有时候LDFLAGS指定-L虽然能让链接器找到库进行链接,但是运行时链接器却找不到这个库,如果要让软件运行时库文件的路径也得到扩展,那么我们需要增加这两个库给"-Wl,R"

 

LDFLAGS = -L/var/xxx/lib -L/opt/mysql/lib-Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib

 

如果在执行./configure以前设置环境变量export LDFLAGS="-L/var/xxx/lib -L/opt/mysql/lib-Wl,R/var/xxx/lib -Wl,R/opt/mysql/lib",注意设置环境变量等号两边不可以有空格,而且要加上引号(shell的用法)。那么执行configure以后,Makefile将会设置这个选项,链接时会有这个参数,编译出来的可执行程序的库文件搜索路径就得到扩展了。

6. –D -I

-D gcc编译的时候提供了预定义功能,参数是-D,

-I 过对编译器指定参数-I<PATH>来指定头文件所在目录

 

3.2      静态库的生成:  ---<机芯库的makefile>

 

AR = $(KBUILD_VERBOSE)$(TOOL_PREFIX)ar  //@arm-hik_v7a-linux-uclibcgnueabi-ranlib

注释:

$(KBUILD_VERBOSE): @

$(TOOL_PREFIX): arm-hik_v7a-linux-uclibcgnueabi-ranlib

 

C_SRCS  = $(filter %.c, $(SOURCES))   //指定源C文件

CPP_SRCS = $(filter %.cpp,$(SOURCES))  //指定源CPP文件

C_OBJS  = $(C_SRCS:%.c=%.o)       //.c更名为.o

CPP_OBJS = $(CPP_SRCS:%.cpp=%.o)   //.cpp更名为.o

 

@$(AR) -rc $@ $(C_OBJS) $(CPP_OBJS)

注释:核心语句

 

 

 

 

3.3      核心语句分析:

 

.PHONY: all

all: $(RETAILTARGET)  // release/dm8127/libcamera.a,库的目标名

$(RETAILTARGET) : $(C_OBJS) $(CPP_OBJS)//依赖关系,makefile典型语法

         @echo"current platform is $(PLAT_FORM)"  //执行语句要tab键错位

         @mkdir-p $(RELEASE_DIR)  //-p可以自动创建目标目录路径中尚不存在的上级目录

         @$(AR)-rc $@ $(C_OBJS) $(CPP_OBJS)

         @$(RANLIB)$@

/* $@表示规则的当前目标文件名

 

ranlib作用:之前我们将编译完成的.o文件直接加入到了库的末尾,却并没有更新库的有效符号表。连接程序进行连接时,在静态库的符号索引表中无法定位刚才加入的.o文件中定义的函数或者变量。这就需要在完成库成员追加以后让加入的所有.o文件中定义的函数(变量)有效,完成这个工作需要使用另外一个工具“ranlib”来对静态库的符号索引表进行更新。

@放在行首,表示不打印此行。默认在编译的过程中,会把此行的展开效果字符串打印出来。

$@:目标文件名,release/dm8127/libcamera.a

*/

 

         cp  $(RETAILTARGET) $(OUTPUT_DIR_A)/ -f

         cp  $(INTERFACE_DIR)/camera_lib_interface.h  $(ROOTDIR)/app/include/ -f

 

 

%.o:%.c

         @echo"Compling   $@"

         $(CC)$(CFLAGS) -c $^ -o $@ //$@表示目标,$^表示依赖列表

 

%.o:%.cpp

         $(CC)$(CFLAGS) -c $^ -o $@

 

clean :

         find./ -name "libcamera.a" | xargs rm –f

/* xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具。它把一个数据流分割为一些足够小的块,以方便过滤器和命令进行处理。通常情况下,xargs从管道或者stdin中读取数据,但是它也能够从文件的输出中读取数据。xargs的默认命令是echo,这意味着通过管道传递给xargs的输入将会包含换行和空白,不过通过xargs的处理,换行和空白将被空格取代。

 */

         find./ -name "*.o" | xargs rm -f

 

 

3.4      机芯接入库制作源码

# cross compile tools

#TOOL_PREFIX=arm-wrs-linux-gnueabi-armv6jel_vfp-uclibc_small-

 

ROOTDIR = ../..

include $(ROOTDIR)/Rules.make

 

TARGET = libcamera.a

DEF= -Wall -O2 -Werror

INCLUDE_DIR=./include

INTERFACE_DIR=./interface

RELEASE_DIR=release/

OUTPUT_DIR_H=../../../include/camera_lib

OUTPUT_DIR_A=$(IPC_LIB_DIR)

 

 

#8127ƽ̨ʹԃ

ifeq ($(PLAT_FORM), dm8127)

         DEF+= -DCAM_DM8127 -DDM8127

         RELEASE_DIR=release/dm8127

endif

 

 

INCLUDE :=-I$(INCLUDE_DIR)/Arch-davinciHD 

 

#ADD INCLUDE FOR CCDPARAM

DEF += -DFOR9000 -DNET_EMAIL

INCLUDE += -I$(ROOT_DIR)/include \

                      -I$(INTERFACE_DIR) \

                      -I$(ROOT_DIR)/app/include \

                      -I$(ROOT_DIR)/app/include/modules_wrapper \

                      -I$(DADSP_INC_DIR) \

                      -I../../openssl-1.0.0a/include \

                      -I$(PLATFORM_INC_DIR) \

                      -I$(INCLUDE_DIR)

 

 

SOURCES :=

 

-include $(shell pwd)/SOURCES

 

 

 

KBUILD_VERBOSE = @

ifdef V

 ifeq ("$(origin V)", "command line")

   KBUILD_VERBOSE = #SPACE

 endif

endif

 

CC=$(KBUILD_VERBOSE)$(TOOL_PREFIX)gcc

AR = $(KBUILD_VERBOSE)$(TOOL_PREFIX)ar

RANLIB =$(KBUILD_VERBOSE)$(TOOL_PREFIX)ranlib

 

DEF +=

 

C_SRCS  = $(filter %.c, $(SOURCES))

CPP_SRCS = $(filter %.cpp,$(SOURCES))

 

C_OBJS  = $(C_SRCS:%.c=%.o)

CPP_OBJS = $(CPP_SRCS:%.cpp=%.o)

 

CFLAGS = $(INCLUDE) $(DEF)

 

RETAILTARGET=$(RELEASE_DIR)/$(TARGET)

        

 

        

.PHONY: all

all: $(RETAILTARGET)

$(RETAILTARGET) : $(C_OBJS) $(CPP_OBJS)

 

         echo$(RETAILTARGET)

         echo$(RELEASE_DIR)

#echo $(CFLAGS)

         echo$@

         echo1111

        

         @echo"current platform is $(PLAT_FORM)"

         @mkdir-p $(RELEASE_DIR)

         @$(AR)-rc $@ $(C_OBJS) $(CPP_OBJS)

         @$(RANLIB)$@

        

         echo$(RANLIB)

         echo      

         @echo$(OUTPUT_DIR_A)

         @echo$(INTERFACE_DIR)

         @echo$(ROOTDIR)

        

        

         cp  $(RETAILTARGET) $(OUTPUT_DIR_A)/ -f

         cp  $(INTERFACE_DIR)/camera_lib_interface.h  $(ROOTDIR)/app/include/ -f

 

 

%.o:%.c

         @echo"Compling   $@"

         $(CC)$(CFLAGS) -c $^ -o $@

        

%.o:%.cpp

         $(CC)$(CFLAGS) -c $^ -o $@

 

clean :

         find./ -name "libcamera.a" | xargs rm -f

         find./ -name "*.o" | xargs rm –f

 

4.     动态库的制作

4.1      动态库制作核心语句分析

.PHONY: all

/*PHONY 目标并非实际的文件名:只是在显式请求时执行命令的名字。有两种理由需要使用PHONY目标:避免和同名文件冲突,改善性能。如果编写一个规则,并不产生目标文件,则其命令在每次make该目标时都执行*/

all: $(RETAILTARGET)

$(RETAILTARGET) : $(C_OBJS)

         @echo"cc"

         @mkdir-p $(RELEASE_DIR)

         $(CC)-shared $(CFLAGS) -o $@ $(C_OBJS) //生成动态库

         cp$(RETAILTARGET) $(OUTPUT_DIR)

         cp$(LIB_INTERFACE_HEADER) $(OUTPUT_DIR)

 

%.o:%.c

         @echoCC $@

         $(CC)$(CFLAGS) -c $^ -o $@

 

clean :

         find./ -name $(TARGET) | xargs rm -fv

         find./ -name "*.o" | xargs rm -fv

         rm-fv $(OUTPUT_DIR)/*

         rm./rules_make_lib

 

 

-Wall 是打开警告开关,-O代表默认优化,可选:-O0不优化,-O1低级优化,-O2中级优化,-O3高级优化,-Os代码空间优化。-g是生成调试信息,生成的可执行文件具有和源代码关联的可调试的信息。

 

4.2      动态库制作源码

 

# cross compile tools

#TOOL_PREFIX=arm-wrs-linux-gnueabi-armv6jel_vfp-uclibc_small-

TOOL_PREFIX=arm-linux-gnueabihf-

TARGET = libispfrontz.so

DEF = -Wall -O2

INCLUDE_DIR=./include

 

RELEASE_DIR=./release

LD_DIR=./libs

OUTPUT_DIR=./output

LIB_INTERFACE_HEADER=./include/isp_set_frontz_interface.h

 

INCLUDE += -I$(INCLUDE_DIR)

INCLUDE += -I$(INCLUDE_DIR1)

INCLUDE += -I$(INCLUDE_DIR2)

SOURCES :=

 

-include $(shell pwd)/SOURCES

include ./rules_make_lib

 

#CC=gcc

#CC=$(TOOL_PREFIX)gcc

 

 

KBUILD_VERBOSE = @

ifdef V

 ifeq ("$(origin V)", "command line")

   KBUILD_VERBOSE = #SPACE

 endif

endif

 

CC=$(KBUILD_VERBOSE)$(TOOL_PREFIX)gcc

 

#DEF += -DARMLIB

DEF += -fPIC

 

C_SRCS  = $(filter %.c, $(SOURCES))

C_OBJS  = $(C_SRCS:%.c=%.o)

 

CFLAGS = $(INCLUDE) $(DEF)

 

RETAILTARGET=$(RELEASE_DIR)/$(TARGET)

 

.PHONY: all

all: $(RETAILTARGET)

$(RETAILTARGET) : $(C_OBJS)

         @echo"cc"

         @mkdir-p $(RELEASE_DIR)

         $(CC)-shared $(CFLAGS) -o $@ $(C_OBJS)

         cp$(RETAILTARGET) $(OUTPUT_DIR)

         cp$(LIB_INTERFACE_HEADER) $(OUTPUT_DIR)

 

%.o:%.c

         @echoCC $@

         $(CC)$(CFLAGS) -c $^ -o $@

 

clean :

         find./ -name $(TARGET) | xargs rm -fv

         find./ -name "*.o" | xargs rm -fv

         rm-fv $(OUTPUT_DIR)/*

         rm./rules_make_lib

0 0