linux library

 

 1 #include <iostream>
 2 #include <mylib.h>
 3 using namespace std;
 4 int main()
 5 {
 6 while(1)
 7 {
 8   cout_t(5);
 9 }
10   return 0;
11 
12 }
main.cpp
#ifndef MYLIB_H_
#define MYLIB_H_
extern "C" void cout_t(int x);
#endif
mylib.h
#include <iostream>
#include "mylib.h"
using namespace std;
void cout_t(int x)
{
    int y = x + 10;
    cout<<"resut is :"<<y<<endl;
}
mylib.cpp

 

 

编译过程

//-fPIC Position-Independent Code

gcc -c -Wall -fPIC mylib.cpp //单独编译动态库于其他路径(和main不再同一文件夹内)要加-c

gcc -Wall -shared -o libmylib.so mylib.o // 有链接过程

nm -D ./libmylib.so

gcc  -Wall -I/mnt/Working/DEVELOPMENT/C++/Linux_lib_study/lib -L/mnt/Working/DEVELOPMENT/C++/Linux_lib_study/lib -lmylib -o main main.cpp -lstdc++ //编译main 链接mylib

如果出现:

undefined reference to `std::ios_base::Init::Init()'

或者

error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or d

则:

export LD_LIBRARY_PATH=/mnt/Working/DEVELOPMENT/C++/Linux_lib_study/lib

 

GCC采用搜索目录的办法来查找所需要的文件,-I选项可以向GCC的头文件搜索路径中添加新的目录。比如把mylib.h和mylib.cpp单独放一个lib文件夹。

为了让GCC能够顺利地找到它们(头文件),

-I /mnt/Working/DEVELOPMENT/C++/Linux_lib_study/lib

同样,如果使用了不在标准位置的库文件,那么可以通过-L选项向GCC的库文件搜索路径中添加新的目录,为了让GCC能够顺利地找到它( 库文件),

-L/mnt/Working/DEVELOPMENT/C++/Linux_lib_study/lib

 

然而使用CMake

project(TEST)

set(MYLIB_DIR "/mnt/Working/DEVELOPMENT/C++/Linux_lib_study/lib")
add_library(mylib SHARED ${MYLIB_DIR}/mylib.cpp)
ADD_EXECUTABLE(main main.cpp)
link_directories({CMAKE_BINARY_DIR}/)
TARGET_LINK_LIBRARIES(main ${MYLIB_DIR}/mylib)

一撸到底

一:静态库

1.ar

 ar命令可以用来创建、修改库,也可以从库中提出单个模块。库是一单独的文件,里面包含了按照特定的结构组织起来的其它的一些文件(称做此库文件的member)。原始文件的内容、模式、时间戳、属主、组等属性都保留在库文件中。

ar [-]{dmpqrtx}[abcfilNoPsSuvV] [membername] [count] archive files...

ar rv libtest.a hello.o hello1.o

生成一个库,库名字是test,链接时可以用-ltest链接。该库中存放了两个模块hello.o和hello1.o。选项前可以有‘-'字符。

二.共享库

第一个程序调用的时候,库的副本会被加载到内存中,所以会花费相对较长的时间,其他程序调用统一个库的时候只是复制库的副本(每个程序都会有自己的全局和静态变量)。

每个程序都有自己的副本,所以数据不会混乱,但是如果一个程序的不同进程或者线程调用呢?会不会使数据串了?

 

 -fPIC 制定编译器应该生成位置独立的代码,这会改变编译器生成执行特定操作的代码的方式,包括访问全局变量、静态和外部变量。访问字符串常量以及获取函数地址。这些变更使得代码可以再运行是被放置再任意一个虚拟地址处。

用以下命令来检查是否使用了 -fPIC:

[alpha@alpha lib]$ nm mylib.o | grep _GLOBAL_OFFSET_TABLE_
                 U _GLOBAL_OFFSET_TABLE_

[alpha@alpha lib]$ readelf -s mylib.o | grep _GLOBAL_OFFSET_TABLE_
    14: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _GLOBAL_OFFSET_TABLE_

下面两个命令有输出,就表示有模块没使用-fPIC

[alpha@alpha lib]$ objdump --all-headers libmylib.so | grep TEXTEL
[alpha@alpha lib]$ readelf -d libmylib.so | grep TEXTREL

 

转载于:https://www.cnblogs.com/CGAlpha/p/7443562.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值