2023-07-18
ビルドの自動化はもちろん、プロジェクトの全体構成を説明するにもMakefileは欠かせない存在である。識別子の意味などいつも忘れてしまうのでメモ。
以下、自作のC++クラスライブラリlibcppのMakefileです。
(libcpp GitHubはこちら)
Shell | Makefile | GitHub 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としてもビルドは行われない。ソースを変更した場合そのファイルだけがコンパイルされ、実行ファイルのビルドが行われる。
libparsonやlibnkfのビルド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オプション)はつけてはならない。デバッグシンボルが消えてしまう。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Windowsのデスクトップ画面をそのまま配信するための下準備
WindowsでGPUの状態を確認するには(ASUS系監視ソフトの自動起動を停止する)
CORESERVER v1プランからさくらインターネットスタンダートプランへ引っ越しメモ
さくらインターネットでPython MecabをCGIから使う
さくらインターネットのPHPでAnalytics-G4 APIを使う
インクルードパスの調べ方
【Git】特定ファイルを除外する.gitignore
【Ubuntu/Debian】NVIDIA関係のドライバを自動アップデートさせない
【Python】Spacyを使用して文章から出発地と目的地を抜き出す
【Windows10】リモートデスクトップ間のコピー&ペーストができなくなった場合の対処法
【Apache】サーバーに同時接続可能なクライアント数を調整する
GitLabにHTTPS経由でリポジトリをクローン&読み書きを行う
Windows版Google Driveが使用中と言われアンインストールできない場合
【Linux】iconv/libiconvをソースコードからインストール
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
【PHP】Mail/mimeDecodeを使ってメールの中身を解析(準備編)
Googleファミリーリンクで子供の端末の現在地がエラーで取得できない場合