18
14

More than 3 years have passed since last update.

C言語で静的・動的ライブラリを作成・使用する方法

Last updated at Posted at 2020-03-23

目的

Linuxで.a(静的)と.so(動的)の2種類ライブラリを作成できるが、コンパイルする時に同じような方法で使用される。
即ち、異なるライブラリのlibA.aとlibA.soが存在しても、コンパイルのコマンドではライブラリの拡張子が省略され、gcc xxx -lAのようになるため、どっちが使用されるかは曖昧になる。

libA.aとlibA.soが共存する場合の動作確認をしたく、メモする。

先に結論

gcc -o main main.c -L. -lA
のように、ライブラリlibA(-lAで指定)が指定されている場合、libA.so(動的)はlibA.a(静的)より優先的にリンクされる。

追記
gcc -o main main.c -L. -static -lA
のように、「-static」を指定すれば、libA.a(静的)はリンクされる。

追記2
gcc -o main main.c -L. -static-libgcc -Wl,-Bdynamic,-lc,-Bstatic,-lA
のように、gccの「-Wl」オプションで「-Bdynamic」(動的)や「-Bstatic」(静的)を指定すれば、ライブラリを選択することは可能。
@yumetodoさん本当にありがとうございました!)

サンプルコード

下記記事のコードを使用する。
また、静的ライブラリでnumを5にして、動的ライブラリでnumを10にして、コンパイルの時に使用されたのはどっちかを判明できる。

C言語グローバル変数の宣言

動的ライブラリの作成及び動作確認

A.c
#include<stdio.h>
#include"A.h"

 void A(){
     num = 10;   //動的ライブラリでnumを10にする
     printf("inside A, num = %d\n", num);
 }
#Aの共有(動的)ライブラリを作成
[pirlo@centos8 02]$ gcc -shared -o libA.so -c A.c
・・・
#メイン処理をコンパイルして実行ファイルを作成
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
#ファイル一覧
[pirlo@centos8 02]$ ls
A.c  A.h  B.c  B.h  libA.so  libB.so  main  main.c
実行結果
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10

静的ライブラリの作成及び動作確認

A.c
#include<stdio.h>
#include"A.h"

 void A(){
     num = 5;   //静的ライブラリのここだけは違う
     printf("inside A, num = %d\n", num);
 }
#Aの静的ライブラリを作成
[pirlo@centos8 02]$ gcc -c A.c B.c   #オブジェクト「.o」ファイルが作成される
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  main.c
[pirlo@centos8 02]$ ar rcs libA.a A.o   #オブジェクトファイルから静的ライブラリを作成
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  main.c
・・・Bの関連処理を略・・・
#メイン処理をコンパイルして実行ファイルを作成(コマンドは動的の時と完全一致)
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
#ファイル一覧
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  libB.a  main  main.c
実行結果
[pirlo@centos8 02]$ ./main 
inside A, num = 5
inside B, num = 5

動的・静的ライブラリが共存する場合で再度確認

#ファイル一覧
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  libA.so  libB.a  libB.so  main.c
#同じコンパイルコマンドで実行ファイルを再作成
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
実行結果
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10

まとめ

動的・静的ライブラリが共存する場合、動的ライブラリが優先的に参照される。

追記
「-static」オプションを追加すれば、静的ライブラリは参照される。

実行結果
[pirlo@centos8 02]$ ls
A.c  A.h  A.o  B.c  B.h  B.o  libA.a  libA.so  libB.a  libB.so  main.c
#「-static」オプション無し
[pirlo@centos8 02]$ gcc -o main main.c -L. -lA -lB
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10
#「-static」オプション有り
[pirlo@centos8 02]$ gcc -o main main.c -L. -static -lA -lB
[pirlo@centos8 02]$ ./main 
inside A, num = 5
inside B, num = 5

追記2
gccの「-Wl」オプションで「-Bdynamic」(動的)や「-Bstatic」(静的)を指定すれば、ライブラリを選択することは可能。

実行結果
#AとBの静的ライブラリを使用
[pirlo@centos8 02]$ gcc -o main main.c -L. -static-libgcc -Wl,-Bdynamic,-lc,-Bstatic,-lA,-lB
[pirlo@centos8 02]$ ./main 
inside A, num = 5
inside B, num = 5
#すべての動的ライブラリを使用
[pirlo@centos8 02]$ gcc -o main main.c -L. -static-libgcc -Wl,-Bdynamic,-lc,-lA -lB
[pirlo@centos8 02]$ ./main 
inside A, num = 10
inside B, num = 10

各参照先

動的ライブラリの作成を下記内容を参考

17.3. GCC での動的ライブラリーの作成

静的ライブラリの作成を下記内容を参考

17.4. GCC および ar での静的ライブラリーの作成

18
14
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
14