アプリケーション開発ポータルサイト
ServerNote.NET
ServerNote.NET厳選キャンペーン・クーポンはこちら!
カテゴリー【C/C++
【Makefile】依存関係ファイル/静的/動的ライブラリ/実行ファイルをまとめてメイク
POSTED BY
2022-07-19

ビルドの自動化はもちろん、プロジェクトの全体構成を説明するにもMakefileは欠かせない存在である。識別子の意味などいつも忘れてしまうのでメモ。

以下、自作のC++クラスライブラリlibcppのMakefileです。
libcpp GitHubはこちら

sourceMakefileGitHub Source
CXX    =  g++
CC_DBG  +=  -g -O2
#STRIP  +=  -s
#CC_OPT  +=  -D_GNU_SOURCE -D_USE_PGSQL -D_USE_MYSQL
CC_OPT  +=  -D_GNU_SOURCE -D_USE_MYSQL
CC_OPT  +=  -DLINUX -D_REENTRANT -D_FORTIFY_SOURCE=2 -fPIC -DPIC -fstack-protector-strong
CC_OPT  +=  -Wformat -Werror=format-security -Wdate-time
CC_INC  +=  -I/usr/local/include
CXXFLAGS  +=  $(CC_DBG) $(CC_OPT) $(CC_INC)
SRCS  =  LFile.cpp LSocket.cpp LPgSQL.cpp LMySQL.cpp G.cpp LCgi.cpp
OBJS  =  ${SRCS:.cpp=.o}
DESTLIB  =  /usr/local/lib
DESTINC  =  /usr/local/include

all:  .deps libcpp.a libcpp.so main.x

.deps:
  $(CXX) -M $(CXXFLAGS) $(SRCS) main.cpp > $@

libcpp.a:  $(OBJS)
  ar rv $@ $?
  ranlib $@

libcpp.so:  $(OBJS)
  $(CXX) -pthread -shared -Wl,--as-needed -Wl,-z -Wl,relro -Wl,-z -Wl,now -Wl,-soname -Wl,$@.1 -o $@.1.0 $^

# env LD_LIBRARY_PATH=`pwd` ./main.x
main.x:  main.cpp libcpp.so.1.0
  $(CXX) $(CXXFLAGS) -o $@ $^ -pthread -lm -lssl -lcrypto -lpq

clean:
  rm -f *.o *.a *.so* *.x .deps

install:  all
  install libcpp.a $(DESTLIB)
  install libcpp.so.1.0 $(DESTLIB)
  ldconfig $(DESTLIB)
  ln -f -s -r $(DESTLIB)/libcpp.so.1 $(DESTLIB)/libcpp.so
  install -m 0644 libcpp.h $(DESTINC)

-include .deps

make
で、
依存関係ファイル.deps
スタティックライブラリlibcpp.a
シェアードライブラリlibcpp.so
テスト実行ファイルmain.x
を一度にビルドします。

それぞれのターゲットだけをビルドしたい場合そのターゲット名を指定。
例)make libcpp.so
ただしlibcpp.soは.depsに依存しているため、.depsのビルドが先に行われます。

make clean
で、すべての生成ファイルを削除。

sudo make install
で、
/usr/local/lib/libcpp.a,libcpp.so、/usr/local/include/libcpp.h
と、システムにインストールされます。

インストール前にローカルでテスト実行ファイルをテストするには
env LD_LIBRARY_PATH=`pwd` ./main.x
とする。スタティックリンクライブラリをテストする場合Makefileを
main.x: main.cpp libcpp.a
と修正する。

makeでビルド後ソースファイル(LCgi.cppなど)やインクルードファイル(.depsで定義)に変更がなければ、もう一度makeとしてもビルドは行われない。ソースを変更した場合そのファイルだけがコンパイルされ、実行ファイルのビルドが行われる。

libparsonlibnkfのビルドMakefileではスタティックとシェアードでソースのコンパイルオプションを変えていたのでオブジェクトファイルも2通り定義したが、どうもシェアードのオプションでスタティック用のコンパイルをしてもリンク・実行に差し支え無さそうだったので、今回オブジェクトファイルは同じにしている(.oで統一、リコンパイルも不要)

以下、コンパイルオプション・Make識別子の説明

-O2:最適化レベル2オプション。コンパイル速度・オブジェクトサイズは大きくなる。

-fPIC:再配置可能とするオプション。シェアードライブラリビルドには必須。

$@:ターゲット名に変換される。

.deps:
  $(CXX) -M $(CXXFLAGS) $(SRCS) main.cpp > $@

では、$@ = .depsになる。

$?:依存関係リストのうちターゲットより変更時刻が新しいものだけ展開される。

libcpp.a:  $(OBJS)
  ar rv $@ $?

では、たとえばLSocket.oだけがlibcpp.aより新しいなら、$? = LSocket.oとなる。.depsにより、LSocket.oはLSocket.cppに依存しているわけだから、LSocket.cppが変更されれば上記arが行われる。

$^:依存関係リストに常に変換される。

main.x:  main.cpp libcpp.so
  $(CXX) $(CXXFLAGS) -o $@ $^ -pthread -lssl -lcrypto -lpq

では、$^ = main.cpp libcpp.so になる。

-include .deps:依存関係ファイル.depsを読み込む。読み込まないとヘッダファイルの変更などが行われても再コンパイルされない。-が重要で、これは対象ファイルが無い場合でもエラーとしない識別子。

-g -O2とするならinstallコマンドに-s(stripオプション)はつけてはならない。デバッグシンボルが消えてしまう。

最新コミックも600円分無料で読める<U-NEXT>
映画、ドラマ、アニメなど充実のラインナップ。U-NEXTは見放題作品数NO.1の動画サービスです(※GEM Partne...READ MORE
成長飲料満足度第1位!栄養豊富なのに飲みやすい!アスミールはこちら!
アスミールは、偏食や子供の成長期の栄養補給に悩む お母さんのために開発された栄養飲料です。 ◆特徴◆ ...READ MORE
日本最安値に挑戦!ソムリエスタッフ厳選の【ワインショップソムリエ】
六本木に実店舗を運営する【ワインショップソムリエ】は、 ソムリエ自らがワインの販売を行っています! フ...READ MORE
※本記事は当サイト管理人の個人的な備忘録です。本記事の参照又は付随ソースコード利用後にいかなる損害が発生しても当サイト及び管理人は一切責任を負いません。
※本記事内容の無断転載を禁じます。
【webmaster/管理人】
自営業プログラマー
ご連絡は以下アドレスまで★

☆ServerNote.NETショッピング↓
ShoppingNote
☆お仲間ブログ↓
一人社長の不動産業務日誌
【キーワード検索】