跳到主要內容

[Coding] Compiler

Something about compiling. #compiler #link #gcc

Reference

  • PTT LinuxDev, 作者: cole945 (躂躂..) 看板: LinuxDev, 標題: [心得] 用gcc 自製Library, 時間: Sun Nov 5 04:15:45 2006

Static Link

Compile 時將 library 加入程式碼,執行快但佔空間,code size 和 mem 使用都比較多
  1. Compile source codes to generate object files
    $ gcc -c file1.c file2.c file3.c
    • -c 編出 object 檔
  2. Create a static library named libmylib.a
    $ ar rcs libmylib.a file1.o file2.o file3.o
    • 把一堆 object 檔用 ar(archiver) 包裝集合起來,檔名以`.a’ 結尾
  3. Using a Static Library to generate a executable files
    $ gcc -o main main.c -L. -lmylib
    • -L: the directory of the library. 可以指定多次 -LDIR
    • -l: the name of the library (注意藍色部分是 match 的)

Dynamic Link

Compile 時不將 library 加入程式碼,執行程式的時後再將 library 載入程式碼,若有多個程式共用同一個 library,只需載一個 library 進 memory
  1. Compile source code
    $ gcc -c -fPIC file1.c file2.c file3.c
    • -fPIC 表示要編成 position-independent code,這樣不同 process 載入 shared library 時,library 的程式和資料才能放到記憶體不同位置。-fPIC 較通用於不同平台,但產生的 code 較大,而且編譯速度較慢
  2. Create a shared library named libmylib.so
    $ gcc -o libmylib.so.1.0.0 -shared -Wl,-soname,libmylib.so.1 file1.o file2.o file3.o
    • so name:用來表示是一個特定library 的名稱,像是 libmylib.so.1 。以 lib 開頭,接著是該 library 的名稱,然後是 .so,接著是版號,用來表名他的介面;如果介面改變時,就會增加版號來維護相容度
      在 mac 上我遇到 "ld: unknown option: -soname",須以 "-install_name" 取代 "-soname"
      可以用 objdump 檢查 $ objdump -p libmylib.so | grep SONAME
    • real name:是實際放有 library 程式的檔案名稱,即是 soname 後面再加上 minor 版號與 release 版號,像是libmylib.so.1.0.0。一般來說版號的改變規則是,最尾碼的 release 版號用於程式內容的修正,介面完全沒有改變。中間的minor用於有新增加介面,但相舊介面沒改變,所以與舊版本相容。最前面的version版號用於原介面有移除或改變,與舊版不相容時
    • linker name:是用於連結時的名稱,是不含版號的 so name ,如 libmylib.so。通常 linker name 與 real name 是用 ln 指到對應的 real name ,用來提供彈性與維護性
  3. Create link
    $ ln -s libmylib.so.1.0.0 libmylib.so
    $ ln -s libmylib.so.1.0.0 libmylib.so.1
  4. Using a Shared Library
    $ gcc -o main main.c -L. -lmylib
    • linker 會搜尋 libmylib.so 來進行連結,如果目錄下同時有 static 與 shared library 的話,會以 shared 為主。使用 -static 參數可以避免使用 shared 連結
    • 可以用 ldd 看編譯出的執行檔與 shared 程式庫的相依性 (mac 上改用 otool -L)
      bash-3.2$ otool -L a.out
      a.out:
              libmylib.so.1 (compatibility version 0.0.0, current version 0.0.0)
              /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.200.5)
  5. Execute
    $ ./main
    • libmylib.so.1 可以被建在其他 path,但為了能 dynamic load,該 path 即需要加入 LD_LIBRARY_PATH
      $ LD_LIBRARY_PATH=/another_path ./main
    • mac 上須改變的是 DYLD_LIBRARY_PATH
Remember to put libmylib.so into PATH, ex. /usr/lib

Dynamic Load

Compile 時不將 library 加入程式碼,執行程式時遇到函式才將 library 載入,用完後再 free 出空間,執行效果最慢。像 Windows 所用的 DLL ,在使用到時才載入,編譯連結時不需要相關的 library。動態載入庫常被用於像 plug-ins 的應用
  1. Compile source code
    $ gcc -c file1.c file2.c file3.c
  2. Create a shared library named libmylib.so
    $ gcc -o libmylib.so.1.0.0 -shared -Wl,-soname,libmylib.so.1 file1.o file2.o file3.o
    $ ln -s libmylib.so.1.0.0 libmylib.so
    $ ln -s libmylib.so.1.0.0 libmylib.so.1
  3. Using a Shared Library- Use the "dlopen" to access the shared library
    #include <dlfcn.h>
    void *dlopen(const char *filename, int flag)
    char *dlerror(void)
    void *dlsym(void *handle, const char *symbol)  取得 symbol 指定的 symbol name 在 library 被載入的記憶體位址
    int dlclose(void *handle)
  4. #include "dlfcn.h"
    #include <stdio.h>
    #include <stdlib.h>
    int main()
    {
        void *handle;
        void (*f)();
        char *error;
    
        /* open the needed object */
        handle = dlopen("./libmylib.so", RTLD_LAZY);
        if (!handle) {
            /* get diagnostic information */
            fputs(dlerror(), stderr);
            exit(1);
        }
    
        /* find the address of function and data objects */
        f = dlsym(handle, "function1");
        if ((error = dlerror())!=NULL) {
            fprintf(stderr, "%s\n", error);
            exit(1);
        }
    
        /* excute function1 */
        f();
    
        /* close a dlopen object */
        dlclose(handle);
    }
  5. Compile Since above function are implemented in the library libdl.a, we need to load this library
    $ gcc dltest.c -ldl
    • -ldl: load the library libdl.a
    • 與 dynamic link 差別就在 compile 的時候不需要去 link so

留言

這個網誌中的熱門文章

[Development] Deep Learning over Python 深度學習基於 Python 1/3

  用 Python 練習實作深度學習,主要包含 Tensorflow 以及 SVM,著重於實作範例,未深入涉及各 DL 演算法模型原理及其數學。 大綱 [Development] Deep Learning over Python  深度學習基於 Python  1/3 Basic Tools: 基於 python- numpy, matplotlib, scipy, Pandas [Development] Deep Learning over Python 深度學習基於 Python 2/3 Keras (基於 Tensorflow)  Tensorflow [Development] Deep Learning over Python 深度學習基於 Python 3/3 Support Vector Machine (SVM) 強化學習 Reinforcement Learning (RL) Reference: 本篇基於  Udemy 課程 "吳佳諺- Python 深度學習"  為架構出發衍生,其他引用資料個別在段落中標示 Basic Tools numpy import numpy as np from scipy import linalg   # linear algebra import matplotlib.pyplot as plt myarray = np.array([[1, 2, 3], [4, 5, 6]]) print('myarray:', myarray) myarray_allzero = np.zeros((3, 5), dtype = np.int16) print('myarray_allzero:', myarray_allzero) myarray_2 = np.arange(15, dtype = np.int64) print('myarray_2:', myarray_2) myarray_2 = myarray_2.reshape((3, 5)) print('myarray_2 reshape:', myarray_2) myarray: [[1 2 3...

[Development] Deep Learning over Python 深度學習基於 Python 2/3

  用 Python 練習實作深度學習,主要包含 Tensorflow 以及 SVM,著重於實作範例,未深入涉及各 DL 演算法模型原理及其數學。 大綱 [Development] Deep Learning over 深度學習基於 Python Python 1/3 Basic Tools: 基於 python- numpy, matplotlib, scipy, Pandas [ Development] Deep Learning over Python  深度學習基於 Python  2/3 Keras (基於 Tensorflow) , 使用 Sequential 模型(範例 實作 "MINST 手寫辨識") CNN (Convolutional Neural Networks) 卷積神經網路 (範例 實作 "MINST 手寫辨識") RNN (Recurrent Neural Networks) 遞歸(迴)神經網路 (範例 實作 "IMPb 評論辨識") Tensorflow 基礎應用 NN 基本作用原理 CNN (Convolutional Neural Networks) 卷積神經網路 (範例 實作 "MINST 手寫辨識") [Development] Deep Learning over Python 深度學習基於 Python 3/3 Support Vector Machine (SVM) 強化學習 Reinforcement Learning (RL) Reference: 本篇基於 Udemy 課程 "吳佳諺- Python 深度學習" 為架構出發衍生,其他引用資料個別在段落中標示 Keras Keras 是一个用 Python 编写的高级神经网络 API,它能够以  TensorFlow ,  CNTK , 或者  Theano  作为后端运行 Keras 的核心数据结构是  model ,一种组织网络层的方式。最简单的模型是  Sequential 顺序模型 ,它由多个网络层线性堆叠。对于更复杂的结构,你应该使用  Keras 函数式 API ,它允许构建任意的...

[Development] Deep Learning over Python 深度學習基於 Python 3/3

  用 Python 練習實作深度學習,主要包含 Tensorflow 以及 SVM,著重於實作範例,未深入涉及各 DL 演算法模型原理及其數學。 大綱 [Development] Deep Learning over Python 深度學習基於 Python 1/3 Basic Tools: 基於 python- numpy, matplotlib, scipy, Pandas [Development] Deep Learning over Python 深度學習基於 Python 2/3 Keras (基於 Tensorflow)  Tensorflow [Development] Deep Learning over Python 深度學習基於 Python 3/3 Support Vector Machine (SVM) 萬用分類機 Reinforcement Learning (RL) 強化學習 Reference: 本篇基於  Udemy 課程 "吳佳諺- Python 深度學習"  為架構出發衍生,其他引用資料個別在段落中標示 Support Vector Machine (SVM) 萬用分類機   SVM 就是用統計上風險最小化的方法,來產生一個分類的超平面 (hyperplane),也就是找到一個決策邊界 (decision boundary),該邊界可以讓「兩類」之間的邊界 margins 最大化。   SVM 是一個二元分類器,也就是只能做非黑即白的分類判斷。   如果資料只有二維,如在二維直線座標系中標記了許多點,若這些點概念上可以被分成兩類,我們就可以透過迴歸分析的幫助,找出一條線來最適當的把這兩類的點切分開來,這條線如果是直線,那就是一個一元一次方程式,如果是曲線那當然就是二次三次或更高。   而該怎麼找出最佳的一個切割面?SVM 的提議也很簡單,他假設如果存在一個 hyperplane,這個 hyperplane 距離所有 A/B 類節點的距離總和最長,那他就是一個最佳的分割面,這裡的距離的概念也就是 margin。簡單理解就是,處在兩個點的「最中間」位置的那條線就是這兩點的最佳切割線。  ...