#目的
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にして、コンパイルの時に使用されたのはどっちかを判明できる。
#動的ライブラリの作成及び動作確認
#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
#静的ライブラリの作成及び動作確認
#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
#各参照先
##動的ライブラリの作成を下記内容を参考
##静的ライブラリの作成を下記内容を参考