1. 静态函数库

这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

2. 动态函数库

这类库的名字一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。 
linux系统有几个重要的目录存放相应的函数库,如/lib /usr/lib。

编译静态库和动态库 :

无论是静态库还是动态库 ,都是由.o文件组成。因此我们可以先编译出.o文件 。
下面提供两个小程序 :
  1. sum.h
  2.  
  3. #ifndef SUM_H_
  4. #define SUM_H_
  5.  
  6. int add (int ,int ) ;
  7.  
  8. #endif

  1. sum.cpp
  2.  
  3. #include <iostream>
  4. #include "auth.h"
  5.  
  6. int add (int x ,int y )
  7. {
  8. int sum = x + y ;
  9. return sum ;
  10. }
  1. #include "sum.h"
  2. #include<iostream>
  3. int main()
  4. {
  5. int k = add(8,10);
  6. std::cout<<"k= "<< k<<std::endl;
  7. return 0 ;
  8. }

linux32位系统下 :

首先编译.o文件:

g++ -c sum.cpp    ------>生成.o文件
  
编译.so 文件 :
g++ -shared -fPIC -o libsum.so sum.o       ------>生成libsum.so文件

编译.a 文件 :
ar rcs libsum.a sum.o   - ----> 生成libsum.a 文件 

编译测试文件并测试 :
g++ -c test.cpp 
g++ -o test test.o -lauth -L./ 
ok,测试结果显示k = 18 ;

然而 在linux64位的系统中,这个问题就出来了 。
如果依然按照上面的命令进行编译 ,会出现以下错误 :
      /usr/bin/ld: sum.o: relocation R_X86_64_32 against `a local symbol' can not be used when making a shared object; recompile with -fPIC
auth.o: could not read symbols: Bad value。
碰到这个错误 ,你可以去检查下,对应的文件在编译的时候是不是用了-fPIC这个参数哦 。

 -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。

在生成.o文件的时候 加上参数 -fPIC ,这个错误就可以搞定了 ,在编译动态库时,必须指定这个参数 ,主要是因为代码的重定向的问题 。如果没有这个参数 ,编译的代码加载的时候不能够重定向。
 g++ -fPIC -c sum.cpp 

那么,如果我希望指定执行文件链接静态库怎么办呢 ??
默认情况下,如果在某个目录下.so 和.a 同时存在的时 ,gcc会优先选择.so 。
我们一般通过 -I引入包含文件 ,-L引入库目录 ,-l指定依赖的库文件。当在静态库和动态库同时存在时,gcc选择.so ,如果你在能够将.
so和.a分开的情况下 ,使用-lname (name为lib的名字)来指定库文件(无论静态库还是动态库都可以),如果静态库和动态库在同一目录下 ,可以使用 path/libname.a  来指定依赖的库文件 。
Linux下约定所有库都以前缀lib开始静态库以.a结尾,动态库以.so结尾。再编译程式时,无需带上前缀和后缀

在编译过程中,-L指定的路径是编译路径 ,而在运行时需要动态的搜索库文件 ,这两个路径不是一个概念 。因此经常会出现这样的问题 :

”明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过“-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你 要作的就是通过修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题 了。










linux下编译.so 和.a 可能出现的问题 ?的更多相关文章

  1. 05 linux下编译Memcached

    一: linux下编译Memcached(1)先在linux上安装gcc,cmake,autoconf,libtool工具,以后会使用到. 安装命令为:yum install gcc make aut ...

  2. linux下编译gcc6.2.0

    linux下编译gcc6.2.0 在archlinx的下gcc已经更新到6.2.1了,win10的WSL下还是gcc4.8.官方源没有比较新的版本,于是自己编译使用. GCC6的几个新特性 GCC 6 ...

  3. LINUX下编译安装PHP各种报错大集合

    本文为大家整理汇总了一些linux下编译安装php各种报错大集合 ,感兴趣的同学参考下. nginx1.6.2-mysql5.5.32二进制,php安装报错解决: 123456 [root@clien ...

  4. linux下编译安装vim7.4并安装clang_complete插件

    linux下编译安装vim7.4并安装clang_complete插件 因为debian里软件仓库中下载安装的vim是不支持python写的插件的(可以打开vim,在命令模式先输入:py测试一下),导 ...

  5. linux下编译出现空间不足解决办法

    linux下编译出现空间不足解决办法 编译内核出现问题: AS      .tmp_kallsyms1.o .tmp_kallsyms1.S:2: fatal error: when writing ...

  6. linux下编译安装curl

    linux下编译安装curl 1.下载curl git clone https://github.com/curl/curl.git 2.在curl目录下生成configure文件 ./buldcon ...

  7. 如何在Kali Linux下编译Windows Exploit

    前言 微软的Windows在企业或是个人应用领域占据着最大的市场份额,在渗透测试过程中你会经常遇到很多Windows的工作站和服务器.另一方面,大多数渗透测试人员主要使用基于Linux的发行版渗透测试 ...

  8. 如何用javac 和java 编译运行整个Java工程 (转载)【转】在Linux下编译与执行Java程序

    如何用javac 和java 编译运行整个Java工程 (转载)  http://blog.csdn.net/huagong_adu/article/details/6929817 [转]在Linux ...

  9. linux下编译qt5.6.0静态库——configure配置

    linux下编译qt5.6.0静态库 linux下编译qt5.6.0静态库 configure生成makefile 安装选项 Configure选项 第三方库: 附加选项: QNX/Blackberr ...

随机推荐

  1. javascript 学习随笔7

    <head> <title>标题页-学无忧(www.xue51.com)</title> <script language="JavaScript& ...

  2. 转: 模块化开发框架seajs简介

    JavaScript模块化开发库之SeaJSSeaJS由国内的牛人lifesinger开发.目前版本是1.1.1,源码不到1500行,压缩后才4k,质量极高.这篇会讲述SeaJS的一些基本用法,不会面 ...

  3. vs2010 调试 调用堆栈 窗口

    msdn 如何使用call stack窗口: http://msdn.microsoft.com/zh-cn/library/a3694ts5(v=vs.90).aspx 使用“调用堆栈”窗口可以查看 ...

  4. VC++中的头文件包含问题

    在一些大的工程中,可能会包含几十个基础类,免不了之间会互相引用(不满足继承关系,而是组合关系).也就是需要互相声明.好了,这时候会带来一些混乱.如果处理得不好,会搞得一团糟,根据我的经验,简单谈谈自已 ...

  5. mac .bash_profile环境变量汇总

    export CATALINA_HOME=/Applications/MyApplications/apache-tomcat-7.0.54 export PATH=$PATH:$CATALINA_H ...

  6. 【Hibernate】set排序

    使用hibernate进行一对多操作的时候,普遍使用HashSet进行操作.但是HashSet是无序集合,对此可以使用TreeSet进行排序. 1.将HashSet改为TreeSet private ...

  7. iOS开发进阶之 UIWebView

    刚接触IOS开发1年多,现在对于混合式移动端开发越来越流行,因为开发成本上.速度上都比传统的APP开发要好,混合式开发是传统模式与PC网页端相结合的模式.那么提到了 APP的混合模式开发,在Andro ...

  8. PHP MYSQL数据字典

    <?php /** * 生成mysql数据字典 */ header ( "Content-type: text/html; charset=utf-8" ); // 配置数据 ...

  9. USACO The Tamworth Two 模拟

    一道模拟题不过要担心的是牛或者人在转弯的时候,另一方如果能走,那么要走,不能停留. 还是蛮简单的. 调试输出的话可以看到具体追击过程 Source Code: /* ID: wushuai2 PROG ...

  10. Raphael Js矢量库API简介:

    Raphael Js矢量库API简介:Raphael Javascript 是一个 Javascript的矢量库. 2010年6月15日,著名的JavaScript库ExtJS与触摸屏代码库项目jQT ...