Makefile 链接静态库

Makefile 链接静态库,第1张

Linux的静态库是以.a结尾的,要连接静态库有两种方法,一种是在编译命令最后直接加上库路径/库名称。

例如你的库在绝对目录/lib/libtest.a下面

你就可以这样来编译

你可以用-L制定库的目录,用-l指定库的名称。(是一起用的-L -l)

例如库的名称为libtest.a 那么就用-ltest

注:-ltest要放在-o的后面,不然不会起作用。

详细可参考: https://blog.csdn.net/u011964923/article/details/73297443

在Ubutu上编译出来的.so文件,怎么添加到Android项目中去使用呢?目前:可以通过

Makefile方式和CMake方式引入预编译静动态库(静态库.a 动态库.so)到项目中去使用。就目前而言CMake是Goole推荐使用方式,但是加入接手一个老的NDK项目是MakeFile方式,看不懂就GePi了,所以这里我们还是介绍一下MakeFile方式将静动态库加入到AS中,完成NDK项目的开发。废话不多说,直接撸步骤了:

1、在src/main目录下创建一个ndkBuild文件夹

2、在此文件中创建一个Android.mk文件

3、在此文件中创建一个test.c的源文件

4、将编译好的的.so库复制到src/main目录下

如图所示目录结构:

1、编辑Android.mk文件

2、编辑grade(app)文件

3、编辑test.c文件

4、使用编译好的.so库里面的函数

本结果运行在Android 5.1 系统上

再次运行在Android8.0系统上

看以清楚知道,其实我们的APK包里面就没有libMainTest.so库,所以APP在8.0上会出现奔溃的现象。so...

1、在src/main目录下创建一个cmake文件夹

include:里面包含需要一些头文件

cmakeTest.c:需要编译的源文件

2、在app目录下创建一个文件:CmakeLists.txt

3、编辑grade(app)

4、编辑cmakeTest.c文件

4、引用编译好的libcmakeTest.so

Android 8.0.0系统:

Android 5.1.1系统:

在lib 目录下编译需要生成动态库的文件,生成动态库,并安装到系统的标准库中,供

程序调用。具体步骤如下:

(1) 编写Makefile.am 文件

AUTOMAKE_OPTIONS=foreign

lib_LTLIBRARIES=libhello.la

libhello_la_SOURCES=test.c

这里lib_LTLIBRARIES 的意思是生成的动态库,然后指定动态库依赖的源文件

test.c ,若有多个源文件用空格隔开。

(2) 在lib 目录下,用命令autoscan 产生configure.scan 文件,并改名为configure.in。 这

里需加上宏AC_PROG_LIBTOOL,表示利用libtool 来自动生成动态库

#configure.in

# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)

AC_INIT(hello,1.0, [miaoquan@nou.com.cn])

AM_INIT_AUTOMAKE

AC_CONFIG_SRCDIR([test.c])

#AC_CONFIG_HEADER([config.h])

# Checks for programs.

AC_PROG_CC

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_PROG_LIBTOOL

AC_CONFIG_FILES([Makefile])

AC_OUTPUT

(3) 执行命令aclocal、libtoolize -f -c 、autoconf、automake --add-missing、./configure、

make、make install 将动态库安装到系统的标准库中,以供调用(一般为/usr/local/lib)。

注:libtoolize 提供了一种标准的方式来将libtool 支持加入一个软件包,而GNU libtool 是

一个通用库支持脚本,将使用动态库的复杂性隐藏在统一、可移植的接口中。

4. 生成src 目录下的hello 可执行文件

(1) 编写src/Makefile.am 文件

AUTOMAKE_OPTIONS=foreign

INCLUDES= -I../include

bin_PROGRAMS=hello

hello_SOURCES=hello.c

hello_LDADD=-lhello

-ldir 指定编译时搜索库的路径。与静态库不同的是,创建动态库时不用指定库路

径,编译器自动在标准库中查找libhello.so 文件。

(2) 执行autoscan 生成configure.scan 文件,将它重命名为configure.in 并修改其内容。

# configure.in

# Process this file with autoconf to produce a configure script.

AC_PREREQ(2.59)

AC_INIT(hello,1.0, [miaoquan@nou.com.cn])

AM_INIT_AUTOMAKE

AC_CONFIG_SRCDIR([hello.c])

#AC_CONFIG_HEADER([config.h])

# Checks for programs.

AC_PROG_CC

# Checks for header files.

# Checks for typedefs, structures, and compiler characteristics.

# Checks for library functions.

AC_CONFIG_FILES([Makefile])

AC_OUTPUT

(3) 在src 目录下编译并生成目标文件,执行命令aclocal、libtoolize -f -c 、autoconf、

automake --add-missing、./configure、make,此时你一定会觉得,成功近在咫尺了。再

执行目标文件./hello,结果却在你的意料之外:

./hello: error while loading shared libraries: libhello.so.0 : cannot open shared object file:

No such file or directory

在执行目标文件的时候,Shell 找不到共享库的位置,需要我们手工载入库路径。

5. shell 搜索动态库路径位置的两种方法

(1) 使用命令导入动态库的路径,命令如下:

export LD_LIBRARY_PATH=dir (如/usr/local/lib)

(2) 修改/etc/ld.so.conf 文件,加入搜索路径,修改后用ldconfig 命令载入修改。

将自己可能存放库文件的路径都加入到/etc/ld.so.conf 中是明智的选择 ^_^。添加

方法也极其简单,将库文件的绝对路径直接写进去就OK 了,一行一个。例如:

/usr/local/lib

/usr/lib

/lib

需要注意的是:这种搜索路径的设置方式对于程序连接时的库(包括共享库和静态

库)的定位已经足够了,但是对于使用了共享库的程序的执行还是不够的。这是 因为

为了加快程序执行时对共享库的定位速度,避免使用搜索路径查找共享库的低效率,所

以是直接读取库列表文件 /etc/ld.so.cache 从中进行搜索的。/etc/ld.so.cache 是一个非

文本的数据文件,不能直接编辑,它是根据 /etc/ld.so.conf 中设置的搜索路径由

/sbin/ldconfig 命令将这些搜索路径下的共享库文件集中在一起而生成的(ldconfig 命令

要以 root 权限执行)。因此,为了保证程序执行时对库的定位,在 /etc/ld.so.conf 中

进行了库搜索路径的设置之后,还必须要运行 /sbin/ldconfig 命令更新 /etc/ld.so.cache

文件之后才可以。ldconfig ,简单的说,它的作用就是将/etc/ld.so.conf 列出的路径下的库

文件 缓存到/etc/ld.so.cache 以供使用。因此当安装完一些库文件,(例如刚安装好glib),

或者修改ld.so.conf 增加新的库路径后,需要运行一下/sbin/ldconfig 使所有的库文件都

被缓存到ld.so.cache 中,如果没做,即使库文件明明就在/usr/lib 下的,也是不会被使

用的,结果编译过程中报错,缺少xxx 库,去查看发现明明就在那放着,搞的想大骂

computer 蠢猪一个^_^。极力推荐使用这种方法!

利用gcc 创建和使用动态库

1. 用下面的命令将mylib.c 程序创建成一个动态库:

gcc –fPIC –o mylib.o –c mylib.c

gcc –shared –o libtt.so mylib.o

-fPIC 作用于编译阶段,告诉编译器产生与位置无关代码(Position-Independent Code),

则产生的代码中,没有绝对地址,全部使用相对地址,故而代码可以被加载器加载到内存的

任意位置,都可以正确的执行。这正是共享库所要求的,共享库被加载时,在内存的位置不

是固定的。

-shared 作用于链接阶段,实际传递给链接器ld,让其添加作为共享库所需要的额外描

述信息,去除共享库所不需的信息。

也可以直接使用下面一条命令:

gcc –fPIC –shared –o libtt.so mylib.c

2. 将动态库拷贝到linux 的标准库中,usr/local/lib 或者/usr/lib 或者/lib:

cp libttt.so /usr/local/lib

3. 编译src 目录下的源程序时,指定动态库文件的目录,调用动态库中的函数

gcc –o test test.c /usr/lib/libttt.so

4. 设置shell 动态库搜索路径,运行生成的可执行文件。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11463027.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-16
下一篇2023-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存