C++---初識《通過g++ / makefile 編譯和調用動態庫so文件》(ubuntu)


C++---初識《通過g++ / makefile  編譯和調用動態庫so文件》(ubuntu)

------------------------目錄-----------------------------

一、通過makefile  編譯和調用動態庫so文件

二、通過makefile  編譯和調用動態庫so文件

 

-------------------------正文----------------------------

一、通過makefile  編譯和調用動態庫so文件

 1、動態庫的編譯
  舉例,這里有一個頭文件:test.h,三個.c文件:test_a.c、test_b.c、test_c.c,這幾個文件編譯成一個動態庫:libtest.so。

文件test.h:

#include   "stdio.h"
void test_a();
void test_b();
void test_c();
文件test_a.c:

#include "test.h"
void test_a()
{
  printf("this is in test_a...\n");
}
文件test_b.c:

#include "test.h"
void test_b()
{
  printf("this is in test_b...\n");
}
文件test_c.c:

#include "test.h"
void test_c()
{
    printf("this is in test_c...\n");
}

將這幾個文件編譯成一個動態庫:libtest.so
 $ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so


2、動態庫的鏈接
  在1、中,已經成功生成了一個自己的動態鏈接庫libtest.so,下面通過一個程序來調用這個庫里的函數。程序的源文件為:test.c。

test.c:

#include "test.h"

int main()
{
  test_a();
  test_b();
  test_c();
  return 0;
}

將test.c與動態庫libtest.so鏈接生成執行文件test:
 $   gcc test.c -L. -ltest -o test

測試是否動態連接,如果列出libtest.so,那么應該是連接正常了:
 $   ldd test

執行:
 $  ./test        #可以看到它是如何調用動態庫中的函數的。

遇到問題:
u@u1604:~/C_learn/makefile_so$ gcc test_a.c test_b.c test_c.c -fPIC -shared -o libtest.so u@u1604:~/C_learn/makefile_so$ gcc test.c -L. -ltest -o test u@u1604:~/C_learn/makefile_so$ ldd test linux-vdso.so.1 => (0x00007ffc096bf000) libtest.so => not found libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2e43587000) /lib64/ld-linux-x86-64.so.2 (0x00007f2e43951000)

解決方式一:
u@u1604:~/C_learn/makefile_so$ sudo cp libtest.so /lib # libtest.so復制到/usr/lib下 # 刪除命令 : sudo rm /lib/libtest.so
[sudo] u 的密碼:
u@u1604:~/C_learn/makefile_so$ gcc test.c -L. -ltest -o test
u@u1604:~/C_learn/makefile_so$ ldd test
    linux-vdso.so.1 =>  (0x00007ffd96947000)
    libtest.so => /lib/libtest.so (0x00007f07a2820000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f07a2456000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f07a2a22000)

成功:
u@u1604:~/C_learn/makefile_so$ ./test
this is in test_a...
this is in test_b...
this is in test_c..

 


二、通過makefile  編譯和調用動態庫so文件

 

文件../hello/hello.c

#include "hello.h"

void hello()
{
    printf("Hello .....\n");
}
文件../hello/hello.h

#ifndef _HEAD_H
#define _HEAD_H
#include <stdio.h>

void hello();

#endif
文件../hello/Makefile

CC = gcc OBJS = $(wildcard *.c) TARGET = libhello.so all:   $(CC) $(OBJS) -fPIC -shared -o $(TARGET)   sudo mv ./$(TARGET) /lib
clean:   rm $(SRCS) $(headfile)

【解釋】主要命令: gcc -hello.c -fPIC -shared -o libhello.so,
這里生成的libhello.so並不是在系統 /lib目錄下的,所以將.so文件移動到系統/lib里去
文件 test.c

#include "test.h"

#include <sys/types.h>  
#include <sys/wait.h>

int main()
{
    hello();
    return 0;

}
文件 test.h

#ifndef _HEAD_H
#define _HEAD_H
#include <stdio.h>

#endif
文件 makefile

CC = gcc OBJS = $(wildcard *.c) TARGET = test all: cd ./hello; make $(CC) $(OBJS) -L/lib -lhello -o $(TARGET) clean: rm -rf *o $(TARGET) cd ./hello; make clean

【解釋】注意這里的makefile,既make此目錄下的,還要進去子目錄hello里去make,
所以首先進去子目錄cd ./hello;make,然后要連接libhello.so,
主要是 gcc test.c -L/lib -lhello -o test,記得要清除.o 和.so文件
結果
u@u1604:~/C_learn/makefile_so$ make cd ./hello; make make[1]: Entering directory '/home/u/C_learn/makefile_so/hello' gcc hello.c -fPIC -shared -o libhello.so sudo mv ./libhello.so /lib [sudo] u 的密碼: make[1]: Leaving directory '/home/u/C_learn/makefile_so/hello' gcc test.c -L/lib -lhello -o test test.c: In function ‘main’: test.c:8:5: warning: implicit declaration of function ‘hello’ [-Wimplicit-function-declaration] hello(); ^ u@u1604:~/C_learn/makefile_so$ ./test Hello .....

 

問題:

如果在打印出現的信息中,發現有一行: libtest.so => not found
則表明鏈接程序找不到我們的libtest.so文件哦,為什么呢?因為鏈接程序只尋找固定目錄,例如/lib目錄。
如果我們的當前目錄是諸如/home/u/a/b/c這種目錄,那么人家是不會主動了解到的。
怎么辦?辦法一:把libtest.so拷貝到鏈接程序的搜索路徑目錄下。 辦法二:設置環境變量LD_LIBRARY_PATH,增加當前路徑到該變量中。
看看現在LD_LIBRARY_PATH有什么內容吧?
1、執行 echo $LD_LIBRARY_PATH 就打印出來。 2、配置環境變量的方法簡單點就是: LD_LIBRARY_PATH=LD_LIBRARY_PATH:"/root/nana/so" export LD_LIBRARY_PATH 3、好了,再次執行ldd就有新發現了。 4、執行./***, OK,輸出正常。

  " 辦法二:設置環境變量LD_LIBRARY_PATH,增加當前路徑到該變量中。 "嘗試設置環境路徑了,可能沒對,幾經折騰還沒編譯通過。回頭編譯通過,再來記錄。

  今天收獲了,g++  ---->   makefile  ----->  cmake  linux下學習C++編譯的三層境界的思維,前者是后者思維的基礎,后者是前者進一步提升編程效率的優化。學會三者,是在linux下學習c++必會的技能,后面再學習如何寫makelist.txt。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM