一、gcc -l参数和-L参数用法含义
1、-l 的用法
-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名,那么库名跟真正的库文件名有什么关系呢?就拿数学库来说,他的库名是m,他的库文件名是libm.so,很容易看出,把库文件名的头lib和尾.so去掉就是库名了(即gcc -lm)
2、-L 的用法
当我们自已要用到一个第三方提供的库名字libtest.so,那么我们只要把libtest.so拷贝到/usr/lib里,编译时加上-ltest参数,我们就能用上libtest.so库了(当然要用libtest.so库里的函数,我们还需要与libtest.so配套的头文件)
放在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接了,但如果库文件没放在这三个目录里,而是放在其他目录里,这时我们只用-l参数的话,链接还是会出错,出错信息大概是:“/usr/bin/ld: cannot find -lxxx”,也就是链接程序ld在那3个目录里找不到libxxx.so,这时另外一个参数-L就派上用场了,比如常用的X11的库,它在/usr/X11R6/lib目录下,我们编译时就要用-L/usr/X11R6/lib -lX11参数,-L参数跟着的是库文件所在的目录名。再比如我们把libtest.so放在/aaa/bbb/ccc目录下,那链接参数就是-L/aaa/bbb/ccc -ltest(若库文件就在当前编译目录下,则链接参数就是-L.)
二、动态库软链接
1、硬链接(hard link)
命令ln sourse dest可以为文件source创建一个名为dest的硬链接。两个文件指向同一块数据块,所以对任意文件修改都会反映到其它所有被链接的文件上。如果source被删除了,dest仍然有效,可以被使用。
2、软链接(symbolic link)
命令ln -s source dest可以为文件source创建一个名为dest的软链接。软链接类似于Windows上的快捷方式。一旦source不存在了,那么dest的文件也会失效。
大部分libxxxx.so只是一个链接,以RH9为例,比如libm.so它链接到/lib/libm.so.x,/lib/libm.so.6又链接到/lib/libm-2.3.2.so,
如果没有这样的链接,还是会出错,因为ld只会找libxxxx.so,所以如果你要用到xxxx库,而只有libxxxx.so.x或者libxxxx-x.x.x.so,做一个链接就可以了ln -s libxxxx-x.x.x.so libxxxx.so
三、动态库查找路径LD_LIBRARY_PATH
使用动态库的应用程序在运行前需要设置动态库查找路径,设置方法为export LD_LIBRARY_PATH=LD_LIBRARY_PATH:/XXX
四、-include和-I参数
-include用来包含头文件,但一般情况下包含头文件都在源码里用#include xxxxxx实现,-include参数很少用。-I参数是用来指定头文件目录,/usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/include里我们就要用-I参数指定了,比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude参数了,如果不加你会得到一个"xxxx.h: No such file or directory"的错误。-I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定。
五、makefile中调用其它makefile
有时Makefile中需要先调用库文件的makefile生成.a或.so,再生成最终文件,调用方法如下
1、make其它目录(./test)下的Makefile
$(MAKE) -C ./test/
2、make clean
make -C ./test/ clean
六、Makefile编写
TARGET = librunoob.so
all:$(TARGET)
CC = gcc
CXX = g++-4.8
STRIP = strip
ARMCC = arm-linux-gcc
ARMSTRIP = arm-linux-strip
#where to install
INSTDIR = bin
#where are include files kept
INCLUDE = -I./
#CFLAGS = -g -Wall –lstdc++
CFLAGS = -g -Wall
CXXFLAGS = -g -Wall -std=c++11
LDFLAGS = -L./
RANLIB = ranlib
SOURCES = runoob_main.cpp runoob_base_func.cpp
C_SRCS = $(filter %.c, $(SOURCES))
CPP_SRCS = $(filter %.cpp, $(SOURCES))
C_OBJS = $(C_SRCS:%.c=release/%.o)
CPP_OBJS = $(CPP_SRCS:%.cpp=release/%.o)
$(C_OBJS):release/%.o:%.c
@mkdir -p release
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -shared -fPIC -c $^ -o $@
$(CPP_OBJS):release/%.o:%.cpp
@mkdir -p release
@mkdir -p $(dir $@)
$(CXX) $(CXXFLAGS) -shared -fPIC -c $^ -o $@
$(TARGET):$(C_OBJS) $(CPP_OBJS)
$(CXX) -shared -fPIC -o $@ $^
#$(AR) r $@ $^
#$(RANLIB) $@
mkdir -p $(INSTDIR)/debug
cp $@ $(INSTDIR)/debug
mkdir -p $(INSTDIR)/release
#$(STRIP) $@
cp $@ $(INSTDIR)/release
clean:
@echo "cleanning project.."
-rm -rf release
-rm -rf $(INSTDIR)
-rm -rf $(TARGET)
@echo "clean completed"