Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

Linux環境にてC++で静的ライブラリ、動的ライブラリを作成する方法に関して

Linux環境で静的ライブラリを作成して運用する機会があったのですが、、
恥ずかしながら今まで静的ライブラリを自作したことがなく、少し困ってしまったので備忘録で残したいと思います。。

今まで実行ファイルは何度も作成しており、静的ライブラリをリンクさせたことはあったのですが、
いざ作成するとなると、、困ってしまった感じです。恥ずかしい。。



■環境

今回手順を記載するのはLinuxとなります。
※題名の通り。

■静的ライブラリ作成手順

早速、静的ライブラリの作成手順を記載します。

ライブラリとして用意するファイルですが、
ファイル名:Calc.cppとし、コードを、

#include <stdio.h>

int Add(int a, int b){
	return a+b;
}

int Sub(int a,int b){
	return a-b;
}

としました。
よくある計算コードですね。

静的ライブラリを作成するためにはオブジェクトファイルが必要になるため、

g++ -c Calc.cpp

でオブジェクトファイルを生成します。

その後、

ar rc Calclib.a Calc.o

のように、arコマンドを用いることで
Calclib.a
のように、静的ライブラリが生成できます。

ライブラリ使用時ですが、こちらはいつも通り、

#include <stdio.h>
int Add(int a, int b);
int Sub(int a,int b);

int main(){
    printf("AddFunc:%d \n", Add(1,2));
    printf("SubFunc:%d \n", Sub(3,1));

    return 0;
}

といったコードを作成の上、

g++ -o calcMain main.cpp Calclib.a

といったようにコンパイルを実行すれば、静的リンクが行われた実行ファイルが作成できます。

こちらの実行ファイルを実行すれば、

AddFunc:3
SubFunc:2

といったように計算結果が返ってくることが確認できます。

Makefileで静的ライブラリを作成

次にMakefileで静的ライブラリを生成するためのコードをご紹介します。
コードはこちら。

NAME	=	Calclib.a
SRCS	=	Calc.cpp
OBJS	=	$(SRCS:.cpp=.o)
CC		=	g++

$(NAME) : $(OBJS)
	ar rc $(NAME) $(OBJS)

all: $(NAME)

.c.o:
	$(CC) -c $< -o $@

clean:
	rm -f $(OBJS) $(NAME)

NAMEに静的ライブラリ名を記載し、SRCSにソースファイル名を記載。
そして、

$(NAME) : $(OBJS)
	ar rc $(NAME) $(OBJS)

にて、ソースファイルをオブジェクトファイルに変換の上、
arコマンドにより、静的ライブラリを作成する。
先ほどのコマンドでの一連の流れを実行しています。

オブジェクトファイル生成は、

.c.o:
	$(CC) -c $< -o $@

にて定義しています。

こちらのMakefileを作成後、

make

を実行すると先ほどのコマンド時と同様にCalclib.aが生成されます。

すでに生成済みの場合、makeコマンド実行しても変化しないので、

make clean

でオブジェクトファイルや静的ライブラリを一旦削除してから試してみてください。

■動的ライブラリ作成手順

補足として動的ライブラリの作成手順に関しても載せておきます。
動的ライブラリの場合には、オブジェクトファイルに対してarコマンドではなく、

g++ -shared -o Calclib.so Calc.o

と-sharedオプションを付与してg++を実行すれば生成できます。

動的リンクは、
>||[
g++ ./Calclib.so
|

とすればOKです。
※動的ライブラリを指定する場合、パスを指定してあげないとうまく読み込んでくれないので注意。

lddコマンドで動的リンクされているか確認することが出来ます。
私の環境ですと、

ldd ./calcMain2

./Calclib.so アドレス

と表示されました。

■動的ライブラリ生成に対するMakefile

静的ライブラリと同様にMakefileを作成していきます。
といっても静的ライブラリの時のMakefileとほぼ同じです。
コードはこちら。

NAME	=	Calclib.so
SRCS	=	Calc.cpp
OBJS	=	$(SRCS:.cpp=.o)
CC		=	g++
CFLAGS	=	-shared

$(NAME) : $(OBJS)
	$(CC) $(CFLAGS) -o $(NAME) $(OBJS)

all: $(NAME)

.c.o:
	$(CC) -c $< -o $@

clean:
	rm -f $(OBJS) $(NAME)

静的ライブラリと異なる点ですが、
・NAMEをCalclib.soとしたこと
・オプション用にCFLAGSを定義したこと
・下記の通り、コードを変更した点

$(NAME) : $(OBJS)
	$(CC) $(CFLAGS) -o $(NAME) $(OBJS)

になります。
こちらは、先ほどコマンドで実行したコードを変数で示して、
オブジェクトファイル生成から動的ライブラリ生成までを記載しているのみです。
後は同じですので割愛します。

■最後に

今回は静的ライブラリや動的ライブラリの生成方法について簡単にまとめました。
初歩のことでも実際にやってみないと分からないことってあるんだな。と感じました。。
色々挑戦していきたいと思います!!