分享

evllib 合并静态库开发记录

 北漂之邬 2014-03-20

1.纯净项目

2.autoscan 获取简单的 ./configure.in

3.在./configure.in 添加 AC_PROG_RANLIB 用以生成静态库

4.Makefile.am 内容为:

 

复制代码
AUTOMAKE_OPTIONS=foreign
SUBDIRS=linux event fixobjpool utility database

noninst_LIBRARIES=libevllib.a
noninstdir=/usr/lib/libevllib.a

ACLOCAL_AMFLAGS=-I m4 #所有 宏添加到 m4 目录

libevllib_a_SOURCES=evllib_impl.cpp evlbuffer_impl.cpp

libevllib_a_LIBADD=utility/libevlutility.la
复制代码

 

 

5. aclocal 

6.autoheader

7.autoconf

8.automake --add-missing

error & warning reported:

configure.in: no proper invocation of AM_INIT_AUTOMAKE was found.

configure.in: You should verify that configure.in invokes AM_INIT_AUTOMAKE

需要在 configure.in 内添加 AM_INIT_AUTOMAKE:

###############################################

复制代码
AC_PREREQ(2.68)
AC_INIT([myevllib], [1.0])
AC_CONFIG_SRCDIR([evllib_impl.cpp])
AC_CONFIG_HEADER([config.h])

#check for programs.
AC_PROG_CXX
AC_PROG_CC
AC_PROG_RANLIB

#check for header files
AC_CHECK_HEADERS([stdlib.h string.h])

#check for typedefs, structures, and compiler characteries
AC_HEADER_STDBOOL
AC_TYPE_SIZE_T

#check for library functions
AC_FUNC_MALLOC
AC_CHECK_FUNCS([inet_ntoa memset select socket])

AC_CONFIG_FILES([Makefile
    database/Makefile
    event/Makefile
    fixobjpool/Makefile
    linux/Makefile
    utility/Makefile])

AC_OUTPUT
复制代码

5. aclocal 

6.autoheader

7.autoconf

8.automake --add-missing

error & warning reported:

utility/Makefile.am:3 Libtool library used but 'LIBTOOL' is undefined
utility/Makefile.am:3 The usual way to define 'LIBTOOL' is to add 'AC_PROG_LIBTOOL'

在 configure.in 上添加 AC_PROG_LIBTOOL 以生成 utility/libevlutility.la 的 libtool 库:

###############################################

 
复制代码
AC_PREREQ(2.68)
AC_INIT([myevllib], [1.0])
AC_CONFIG_SRCDIR([evllib_impl.cpp])
AC_CONFIG_HEADER([config.h])

#check for programs.
AC_PROG_CXX
AC_PROG_CC
# AC_PROG_RANLIB -----replaced with AC_PROG_LIBTOOL
AC_PROG_LIBTOOL +++++ new added #check for header files AC_CHECK_HEADERS([stdlib.h string.h]) #check for typedefs, structures, and compiler characteries AC_HEADER_STDBOOL AC_TYPE_SIZE_T #check for library functions AC_FUNC_MALLOC AC_CHECK_FUNCS([inet_ntoa memset select socket]) AC_CONFIG_FILES([Makefile database/Makefile event/Makefile fixobjpool/Makefile linux/Makefile utility/Makefile]) AC_OUTPUT
复制代码

5. aclocal 

因为使用了 LIBTOOL 输出了很多 版本兼容相关的warning 和 过程输出。

6.autoheader

7.autoconf

8.automake --add-missing

error & warning reported:

configure.in: 14 required file './ltmain.sh' not found

暂不理, 看再一次autoconf 能否生成

9.autoconf

10../configure

error & warning reported:

sed: can't read ./ltmain.sh: No sush file or directory 

但是 ltmain.sh 是什么呢? 有什么用?先得看 configure 的生成过程:

aclocal:

autoheader:

automake & libtoolize:

autoconf:

看得出 ltmain.sh 和 ltconfig是在 libtoolize 时生成的, 但是 libtoolize有什么用处呢?

前面的 aclocal.m4 是 根据 用户修改的 configure.in 生成的中间 文件, 最终用于生成 configure

其实是 对 configure.in内各种 宏的 展开,以及一些其他文件、变量的加入;而对于 libtool, 他的正确使用也需要一些相关的设置, 需要自己的各种宏 ,例如

libtool.m4

ltoptions.m4

ltversion.m4

lt~obsolete.m4

ltsugar.m4

libtool 所需这些宏及其相关文件是通过 libtoolize 生成的, 估计 ltmain.sh 和 ltconfig 都是 必须的文件, 现在这些宏 应该如何导入? 其实也可以在 configure.in文件内, 一种方法在 configure.in 内仔细修改, 一种是 直接拷贝 默认的 libtool.m4 到当前目录,第三种是使用 一个特定的 包含这些宏相关文件的 目录。为了让环境清洁, 这里采用第三种独立文件夹 m4 方式。这是我们是否可以讲 libtoolize 和 aclocal 做个类比:

configure.in  ====> aclocal  ====> aclocal.m4

configure.in   ====>libtoolize  ====> libtoolize所需 m4

第一如果 在configure.in 没有显示指明 AC_CONFIG_MACRO_DIR 目录, 在进行 libtoolize 时会在 根目录下(其实是configure.in相同目录先生成相关的 文件), 否则会在 AC_CONFIG_MACRO_DIR 指定的目录生成一些文件, 于是我的configure.in修改成:

复制代码
AC_PREREQ(2.68)
AC_INIT([myevllib], [1.0])
AC_CONFIG_SRCDIR([evllib_impl.cpp])
AC_CONFIG_HEADER([config.h])
AC_CONFIG_MACRO_DIR([m4]) +++++ new added

#check for programs.
AC_PROG_CXX
AC_PROG_CC
# AC_PROG_RANLIB -----replaced with AC_PROG_LIBTOOL
AC_PROG_LIBTOOL  +++++ new added

#check for header files
AC_CHECK_HEADERS([stdlib.h string.h])

#check for typedefs, structures, and compiler characteries
AC_HEADER_STDBOOL
AC_TYPE_SIZE_T

#check for library functions
AC_FUNC_MALLOC
AC_CHECK_FUNCS([inet_ntoa memset select socket])

AC_CONFIG_FILES([Makefile
    database/Makefile
    event/Makefile
    fixobjpool/Makefile
    linux/Makefile
    utility/Makefile])

AC_OUTPUT
复制代码

但同时, 我在 Makefile.am 内也添加了 m4 目录的指定:

复制代码
AUTOMAKE_OPTIONS=foreign
SUBDIRS=linux event fixobjpool utility database

noninst_LIBRARIES=libevllib.a
noninstdir=/usr/lib/libevllib.a

ACLOCAL_AMFLAGS=-I m4 #所有 宏添加到 m4 目录 ------- here

libevllib_a_SOURCES=evllib_impl.cpp evlbuffer_impl.cpp

libevllib_a_LIBADD=utility/libevlutility.la
复制代码

 

5. aclocal 

6.autoheader

7.libtoolize --copy --force 

成功拷贝 libtool 所需的各种默认 .m4 文件到 m4 目录

8.autoconf

9.automake --add-missing

10../configure

11.make

成功生成  ./utiliby/libevlutility.la 和 ./libevllib.a

但是 nm libevllib.a 时还是 只能看到 libevlutility.la 而非具体的 o文件

 

###############################################

尝试不使用 libtool 的 convenience library .la , 而直接生成普通的 静态库 .a 

大不了使用 ar , ranlib 直接手工活的 .o 最后合并成 .a

那么 utility/Makefile.am 将如

AUTOMAKE_OPTIONS=foreign

noninst_LIBRARIES=libevlutility.a
noninstdir=$(EVLLIB_SRC_TOP_DIR)/utility/
libevlutility.a_SOURCES=variant.cpp readConfig.cpp

根目录 $(EVLLIB_SRC_TOP_DIR)的Makefile.am 将如:

复制代码
AUTOMAKE_OPTIONS=foreign
SUBDIRS=linux event fixobjpool utility database

noninst_LIBRARIES=libevllib.a
# noninstdir=/usr/lib/libevllib.a  -------------- modifyed
noninstdir=$(EVLLIB_SRC_TOP_DIR)

ACLOCAL_AMFLAGS=-I m4 #所有 宏添加到 m4 目录 ------- here

libevllib_a_SOURCES=evllib_impl.cpp evlbuffer_impl.cpp

libevllib_a_LIBADD=./utility/libevlutility.a
复制代码

 

5. aclocal 

6.autoheader

7.libtoolize --copy --force 

成功拷贝 libtool 所需的各种默认 .m4 文件到 m4 目录

8.autoconf

9.automake --add-missing

10../configure

11.make

这样能够生成 出最终的 libevllib.a

并且其内部包含了如何下文件:

evllib_impl.o
evlbuff_impl.o

libevlutility.a

将其他所需的源合并后, 将如:

复制代码
evllib_impl.o
evlbuff_impl.o

libevlutility.a
libdatabase.a
libfixobjpool.a
libevllinux.a
复制代码

###############################################

为了将上传输的 所有 .o 和 .a 文件合并到 单一的一个 静态库 libevllib.a (注意这里的 libevllib.a 名字是相同的), 在根目录下 添加了一个 目录 ./targetDir/ 用以处理ar 的解包 和 合并静态库; 在添加一个自动脚本 ./artest 用以在 targetDir 内完成全部工作:

复制代码
#!/bin/bash

# 从根目录 移动 libevllib.a 到 工作目录 targetDir, 此时只有一个 静态库 libevllib.a 哟 echo moving libevllib.a into targetDir mv ./libevllib.a ./targetDir/
# 进入 工作目录 targetDir echo entering targetDir... cd targetDir
# 接下来是一个循环,使用 ar -x 解压出 各种 静态库文件.a 的内容后, 还需要对新文件进行.a 查找并解压,
# 因为 可能 一个 .a 文件内包含有其他的 .a 文件, 就如本例的 libevllib.a
echo loop finding and exploding orignal static files...
#fineshed 是全部 .a 被解压成功标记 finished=0; until [[ $finished == 1 ]]; do
  #查找所有.a 文件 filelist=`ls | grep '.a\>' ` if [ "$filelist" != "" ]; then echo files found: $filelist
     #逐个解压 .a 文件, 并 移除 for file in $filelist do echo expanding $file ar -x $file echo deleting $file rm -f $file done else finished=1 echo all orignal static file dealed. fi done;
#将全部解压出来的 .o 文件 合并成一个静态库 文件 libevllib.a echo generating target file libevllib.a ... ar rcs libevllib.a *.o
#一些移动操作 echo coping libevllib.a to /usr/lib/ cp ./libevllib.a /usr/lib/ echo leaving targetDir... cd ../ echo done.
复制代码

最后 $./artest 

即可生成所需文件

 

文章参考:

C1.aclocal : http://www./autobook/autobook/autobook_277.html#SEC277

C2.autoheader: http://www./autobook/autobook/autobook_278.html#SEC278

C3.automake & libtoolize :http://www./autobook/autobook/autobook_279.html#SEC279

C4.autoconf : http://www./autobook/autobook/autobook_280.html#SEC280

Invoking libtoolize : http://www./software/libtool/manual/html_node/Invoking-libtoolize.html

GNU的ar,ranlib和nm: http://blog.sina.com.cn/s/blog_4fcd1ea30100uu3m.html

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多