从clapack-cmake看动态库和静态库的编译

1.      下载最新的clapack-cmake包

2.      解压 tar –zxf 压缩包

3.      下载cmake linux i386版本,依个人而异(本人虚拟机Ubuntu 14 32bit)

4.      目标平台powerpc 交叉工具链eldk,ppc_6xx

5.      执行cmake-gui配置(关键步骤)

第一步:

从clapack-cmake看动态库和静态库的编译_第1张图片


第二步:

点击configure,选择unix_makefile,选择配置交叉工具链选项,如下图

 

第三步:

 从clapack-cmake看动态库和静态库的编译_第2张图片

第四步:

 从clapack-cmake看动态库和静态库的编译_第3张图片

第五步:

点击configure 完成后点击 generate(NOTE:一般没什么问题,如果有问题请google;另外,warning一般没事,主要是error)

选择CMAKE的选项菜单,添加编译选项的值,需要配置的有这么几个值

CMAKE_C_FLAGS 配置成-fPIC –DNON_UNIX_STDIO


-fPIC选项链接成动态库有用

原因具体如下,参考clapack的源码下f2c目录下的makfile

# Unix makefile: see README.

# For C++, first "make hadd".

# If your compiler does not recognize ANSI C, add

#       -DKR_headers

# to the CFLAGS = line below.

# On Sun and other BSD systems that do not provide an ANSI sprintf, add

#       -DUSE_STRLEN

# to the CFLAGS = line below.

# On Linux systems, add

#       -DNON_UNIX_STDIO

# to the CFLAGS = line below.  For libf2c.so under Linux, also add

#       -fPIC

# to the CFLAGS = line below.

CMAKE_EXE_LINKER_FLAGS 配置成-lm

 从clapack-cmake看动态库和静态库的编译_第4张图片

CMAKE_SHARED_LINKER_FLAGS 配置成-shared(此标志在链接成共享库时有效)

 

第六步:

所有填完以后点击generate

应该有一个完整的Makefile了,Makefile的目录就在之前选择的“where to build the binaries”

 

第七步:

到指定的目录下,执行make

1)  发现有个错误,形如:

错误的原因是,代码用交叉工具链生成了一个arithchk,然后执行,意图得到一个头文件叫arith.h,但是实际这是有问题的。因为,根本不能运行。需要将其拷贝到目标板运行,将输出到arith.h文件,手动生成一个.h文件即可。

从clapack-cmake看动态库和静态库的编译_第5张图片

我这边的头文件内容如下:

#define IEEE_MC68k

#define Arith_Kind_ASL 2

#define Double_Align

#define NO_LONG_LONG

#define QNaN0 0x7ff80000

#define QNaN1 0x0

将此文件拷贝到 F2CLIBS/libf2c/即可,此路径是相对于目前执行make的当前目录而言。

拷贝以后,再次执行make即可。一马平川,应该会非常顺利!

从clapack-cmake看动态库和静态库的编译_第6张图片

2)  拷贝真正的链接库

在当前目录执行 find . –name *.a 即可看到当前目录及其子目录下的静态库,将其拷贝出来即可。

到此为止,静态库的方法制作完毕,可以直接调用。

 


第八步

动态库的制作

这时候修改这么4个文件:(本人下载的版本是3.2.1)

clapack-3.2.1-CMAKE/BLAS/SRC/CMakeLists.txt

139 18:add_library(blas SHARED ${ALLOBJ})

clapack-3.2.1-CMAKE/SRC/CMakeLists.txt

378 20:add_library(lapack SHARED ${ALLOBJ} ${ALLXOBJ})

clapack-3.2.1-CMAKE/F2CLIBS/libf2c/CMakeLists.txt

61 17:add_library(f2c SHARED ${OFILES} ${CMAKE_CURRENT_BINARY_DIR}/arith.h)

clapack-3.2.1-CMAKE/TESTING/MATGEN/CMakeLists.txt

  68 20:add_library(tmglib SHARED ${ALLOBJ} )

即,添加了几个SHARED的关键字

这句话的意思是:

add_library的作用是指示CMake生成一个库,根据参数SHARED还是STATIC来决定生成动态库还是静态库


第九步

修改完后,重新再cmake-gui里点击generate,

然后,再到指定的目录执行make(可能还有错误上次一样的错误,处理即可!)

 

第十步

链接库的使用

1)  静态库的使用

静态库的使用就在makefile里引用即可

2)  动态库的使用

上述编译的动态库,其实还不能用。使用的时候有这么几个问题;

动态库之间的依赖问题

对生成的4个动态库进行readelf会发现,相互之间有依赖关系,并且库的引用是引用的相对路径。带来的问题是,根本找不到依赖库,怎么办呢?

重新做库,别无他法!

做库的方法,即将所用到的库复制到链接的目录下,手动执行link.txt的内容,手动指定链接库的目录为当前目录,和链接库的名字。编译的时候,注意所有的OBJ文件还在子目录里也有

3)  编译应用程序

结果发现,还是不能用,提示错误。f2c.so中的MAIN__是“ undefined reference to'MAIN__'

到源码中会发现,确实f2c中有个main.c,其中确实引用了MAIN__,确实MAIN__没定义

需要思考的是!库咱们只需要用其中的function api,根本不需要main的入口。解决办法,即把做f2c动态库的时候,将main.c.obj删除,然后编译还是不行!分析代码就会知道,还需要把getarg_.c.obj 和iargc_.c.obj删除。

将重新做好的libf2c.so拷贝出来,执行例程引用库,编译OK!


6.      需要思考的

为什么同样是库,包含同样的obj,结果还是不一样呢?

这一点需要说明下动态库和静态库的区别

静态链接库是在程序连接的时候将静态库中的数据代码,插入到源程序当中去,这样有个缺点就是程序会过于庞大;而在应用动态链接库的程序,链接器需要检查动态链接库,确保其包括生成的可执行文件所需的所有符号,这是编译器并不将代码插入到执行文件当中,而是在程序运行的时候,告诉系统的动态加载程序动态链接库的位置,然后动态的装载与动态的卸载

关键点,主要就是红字部分;展开来说,动态静态各有优缺点,静态库使用时会把公用的函数自己保存一份,结果就是可能好多个app引用,好多个函数副本。但是,如果库很大,你只用了其中几个函数,这实话片子资源紧张,静态库是优势的;如果动态库,恰好相反。

并且,参考上面遇到的错误,还有一点。当库里某个api没有定义时,引用库时会提示未定义,而静态却没有问题。为什么呢?

首先把静态和动态的文件file下看下区别

从clapack-cmake看动态库和静态库的编译_第7张图片

很明显,动态库链接在链接库时会坚持所有的符号,确保是有效的。

但是,静态库只是一个类似文件夹的作用,只是把所有的obj打包在一起。用哪个,我最终链接哪个obj,其他的我不关心。

 

 

qdzhaox 20160614

[email protected]

[email protected]

 

 

 

你可能感兴趣的:(CLAPACK,libtmglib,liblapack,libblas,libf2c)