2024-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オプション)はつけてはならない。デバッグシンボルが消えてしまう。
※本記事内容の無断転載を禁じます。
ご連絡は以下アドレスまでお願いします★
Wav2Lipのオープンソース版を改造して外部から呼べるAPI化する
Wav2Lipのオープンソース版で静止画の口元のみを動かして喋らせる
【iOS】アプリアイコン・ロゴ画像の作成・設定方法
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【2】
オープンソースリップシンクエンジンSadTalkerをAPI化してアプリから呼ぶ【1】
【Xcode】iPhone is not available because it is unpairedの対処法
【Let's Encrypt】Failed authorization procedure 503の対処法
【Debian】古いバージョンでapt updateしたら404 not foundでエラーになる場合
ファイアウォール内部のWindows11 PCにmacOS Sequoiaからリモートデスクトップする
Windows11+WSL2でUbuntuを使う【2】ブリッジ接続+固定IPの設定
進研ゼミチャレンジタッチをAndroid端末化する
VirtualBoxの仮想マシンをWindows起動時に自動起動し終了時に自動サスペンドする
Googleスプレッドシートを編集したら自動で更新日時を入れる
Linuxでtar.xz形式のファイルを解凍する
【C/C++】小数点以下の切り捨て・切り上げ・四捨五入
タスクスケジューラで変更を適用できません。ユーザーアカウントが不明であるか、パスワードが正しくないか、またはユーザーアカウントにタスクを変更する許可がありません。と出た
GitLabにHTTPS経由でリポジトリをクローン&読み書きを行う
Intel MacBookAir2020にWindows10→Windows11をインストールする