katapedia
  • README
  • doc
    • Ansible
    • Assert
    • Astah
    • Autohotkey
    • CI
    • C_Cpp
    • CentOS6x系でhttp認証に失敗する
    • Chef
    • Clipboard
    • コーディング
    • Configure
    • Console2_NYAOS
    • Debian系RedHat系の違い
    • DesignDoc目次サンプル
    • Docker
    • Doxygenコメント規約
    • Eclipse
    • Excel
    • FAQ
    • Footer
    • Git
    • GitBucket
    • GitBucketとJenkins連携
    • GitBucketとRocketChat連携
    • GitHub
    • GitLab
    • Gitで大量のファイルの中から必要ファイルのみをaddする方法
    • GitのGUI比較
    • Gitのリポジトリがでかくなったときの削減の昔のやり方
    • Gitワークフロー
    • Go
    • Googletest
    • Gradle
    • Grafana
    • Groovy
    • Haroopad
    • Haskell
    • Htmlpdfに直リンクする(ダウンロードしない)方法
    • IT業界
    • Java
    • Javascript
    • Javascriptrライブラリ・フレームワーク一覧
    • Jenkins
    • JetBrains_IDE
    • Linux
    • Linux Command
    • Linux Distribution
    • Makefile
    • Maven
    • MicrosoftProject
    • NoSQL
    • Omniauthによるアカウント統合
    • Outlook
    • PHP
    • Prometheus_Loki
    • Python
    • RDB
    • Redmine
    • RedmineDドライブへの保存
    • Redmineアップデート
    • Redmineプラグイン
    • Redmineメール通知
    • Redmine文字化け
    • Ruby
    • Rust
    • R言語
    • SVN
    • Sidebar
    • Solaris
    • Staticまとめ
    • Terraform
    • Thinkpad
    • Tmux
    • ToDoリスト
    • UML
    • Vagrant
    • Vim/Neovim
    • VirtualBox
    • Visio
    • Webアプリケーション
    • Webサーバ
    • Webブラウザ
    • Webブラウジング
    • Webページ備忘録
    • Windows
    • Word
    • Zabbix
    • Zsh
    • C#
    • dotfiles
    • html_css
    • Lua
    • sonarqube
    • terminal
    • tweetまとめ
    • xrdp
    • お預り証サンプル
    • その他Webサービス
    • その他ツール
    • よく使う英語
    • アジェンダサンプル
    • アジャイル宣言
    • アンチパターン
    • インシデント
    • エディタ・IDE
    • エンジニアリングスキル
    • オンプレミスサーバ管理
    • オープンソースライセンス
    • キックオフミーティング
    • コミットメッセージでよく使う英語
    • サーバデータ移行
    • サーバ環境構築
    • シェルスクリプト
    • セキュリティ
    • ソフトウェア開発
    • チャットツール
    • チーム構築
    • ツール調査履歴
    • テスト
    • デザイン
    • デザインパターン
    • ドキュメント
    • ネットワーク
    • ノート
    • バージョン番号
    • ビジネスモデル
    • プラクティス一覧
    • プラグイン調査
    • プログラマがやってはいけない97のこと
    • プログラミングテクニック
    • プログラム
    • プログラムエラー集
    • プロジェクトマネージメント
    • プロダクトマネージメント
    • ヘルプ文
    • ライフハック
    • リソース設計
    • リバースエンジニアリングツール
    • リリースノート
    • リリースノートサンプル1
    • リンク
    • レビュー
    • 人月の神話
    • 人間のあれこれ
    • 仕事のあれこれ
    • 会議
    • 作業報告項目サンプル
    • 例外処理
    • 勉強
    • 名言・教訓
    • 品質管理
    • 教育
    • 数学
    • 文書レビュー観点
    • 朝会
    • 未来技術
    • 林檎の木のものを持ってきた
    • 正規表現
    • 物理
    • 知識データベース
    • 紛らわしい・似たような用語
    • 経営
    • 経済
    • 自作template_class_でundefined_reference_to
    • 要求分析・要件定義
    • 見積もり
    • 設計
    • 評価
    • 認証
    • 議事録サンプル
    • 運用・保守
    • 開発インフラ
    • 開発環境
    • 開発計画
    • 関数名でよく使われる英単語
    • 関数命名規約
    • 関数型言語
    • 雑多メモ
    • 面接
Powered by GitBook
On this page
  • 書き方
  • 特殊変数の取り扱い
  • イコールの違い
  • すべてのC,C++をコンパイル
  • 使い方
  • LIBSやCFLAGSなどのシンボル
  • CFLAGS,LDFLAGSのオプションがどれか調べる
  • セキュアなCFLAGS,LDFLAGS
  • 多段Make
  • べからず集
  • suffix ruleについて
  • PHONY
  • イコールの使い方
  • ヘッダファイルの依存関係を解決すること
  • FAQ
  • 参考
  • サンプル
  1. doc

Makefile

PreviousLinux DistributionNextMaven

Last updated 7 years ago

書き方

特殊変数の取り扱い

$@ : ターゲットファイル名

$% : ターゲットがアーカイブメンバだったときのターゲットメンバ名

$< : 最初の依存するファイルの名前

$? : ターゲットより新しいすべての依存するファイル名

$^ : すべての依存するファイルの名前

$+ : Makefileと同じ順番の依存するファイルの名前

$* : サフィックスを除いたターゲットの名前

イコールの違い

記号

意味

=

右辺の内容を憶えておき実際に使う時に展開される。代入には「=」を使う

:=

代入行がMakefileから読みこまれるとすぐに右辺を評価する。

?=

値がセットされていないときのみ変数に値を代入

+=

変数の最後にテキストを追加する

すべてのC,C++をコンパイル

$(patsubst %.cpp,%.o,$(wildcard .cpp)) $(patsubst %.c,%.o,$(wildcard .c))

使い方

LIBSやCFLAGSなどのシンボル

シンボル

説明

default

CC

Cコンパイルコマンド

cc

CC

Cコンパイルコマンド

cc

CXX

C++コンパイルコマンド

g++

CFLAGS

Cコンパイルオプション

無し

CXXFLAGS

C++コンパイルオプション

無し

CPPFLAGS

C++プリプロセッサ用オプション

無し

LDFLAGS

ldというリンクを呼び出すコマンドのリンクオプション

無し

INCLUDES

includeするheaderのディレクトリを指定する

無し

LIBS

利用するライブラリを指定する

無し

TARGET

生成するターゲットファイル名

無し

SRCS

ターゲットファイルを生成するために利用するソースコード

無し

OBJS

ターゲットファイルを生成するために利用するオブジェクトファイル

無し

RM

ファイル削除コマンド

rm -f

CFLAGS,LDFLAGSのオプションがどれか調べる

gccのリンカはldを呼んでいるだけなので、ldのオプションがLDFLAGSになる。

セキュアなCFLAGS,LDFLAGS

ライブラリ

CFLAGS=-fstack-protector-all -O2 -fno-strict-aliasing -D_FORTIFY_SOURCE=2

LDFLAGS=-Wl,-z,now,-z,relro

実行ファイルは追加で

CFLAGS=-fPIE

LDFLAGS=-pie

多段Make

べからず集

suffix ruleについて

suffix ruleは古い書き方で、見た目にも分かりにくい(依存関係の順番がpattern ruleと逆になっている)。GNU makeを使う限りにおいては、suffix ruleではなくpattern ruleを使う方がよいらしい。

PHONY

.PHONY: all

.PHONY: clean

は必ず書くこと。

targetがallやcleanでも誤動作しないようにするため

イコールの使い方

=は動作が直感的でないため:=を使用すること

ヘッダファイルの依存関係を解決すること

FAQ

make で同じターゲット名を定義

二重コロンでターゲットを定義すると重複を許容できる

==> 1.mk <==
all ::
echo 1

==> 2.mk <==
all ::
echo 2

==> 3.mk <==
all ::
echo 3

includeするときの ディレクトリの場所が移動できない

Makefileから別のMakefileを呼ぶ場合、カレントディレクトリから移動できない

次の変数を定義して使用すればよい。

TOP := $(dir $(lastword $(MAKEFILE_LIST)))
or
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
or
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))

コマンドラインから引数を入力されても上書きさせず、追加させる方法

override CFLAGS +=

とする

エラーで止まらないようにするには

コマンドの先頭に-をつければよい。

ヘッダーファイルの依存関係を解決する方法

にやり方が書いてある

gcc -MMDを使う方法と-include を使う方法

参考

サンプル

これがなかなかいいサンプル

PROGNAME  := $(shell basename `readlink -f ..`)
PRODIR    := bin
OBJDIR    := lib
INCDIR    := include
SRCS      := $(wildcard *.c)
OBJS      := $(SRCS:%.c=%.o)
OBJSPATH  := $(addprefix $(OBJDIR)/, $(OBJS))
DEPENDS   := $(SRCS:%.c=%.d)
DEPENDSPATH   := $(addprefix $(OBJDIR)/, $(DEPENDS))

INCL      := -I$(INCDIR)/cspice/             -I$(INCDIR)/etc

LIBS      := -ansi -O2 -fPIC -DNON_UNIX_STDIO -lm cspice.a csupport.a

CC        := gcc
override CFLAGS    +=
LD        := gcc
override LDFLAGS   +=

.PHONY: all
all:$(PROGNAME)

-include $(DEPENDSPATH)

$(PROGNAME): $(OBJSPATH)
$(LD) $(LDFLAGS) $^ $(LIBS) -o $(PRODIR)/$(PROGNAME)

$(OBJDIR)/%.o: %.c
$(CC) -c $(CFLAGS) $(INCL) $< -o $@

.PHONY: clean
clean:
rm -f $(OBJSPATH)
rm -f $(DEPENDSPATH)
rm -f $(PRODIR)/$(PROGNAME)

# google test
TEST_PACKAGE  = $(PROGNAME)_test
TEST_SRC      = $(PROGNAME)_test.cc
TEST_PRODIR   = ../test/bin
TEST_OBJDIR   = ../test/lib
TEST_SUDIR    = ../test
TEST_DATADIR  = ../testdata
TEST_OBJ      = $(TEST_SRC:.cc=.o)
TEST_EXE      = $(TEST_SRC:.cc=)
TEST_EXEPATH  = $(addprefix $(TEST_PRODIR)/,$(TEST_EXE))
TEST_OBJPATH  = $(addprefix $(TEST_OBJDIR)/,$(TEST_OBJ))

GTEST_DIR     = /usr/local/gtest
GTEST_LIBS    = $(GTEST_DIR)/lib/libgtest_main.a $(GTEST_DIR)/lib/libgtest.a
GTEST_HEADERS = $(GTEST_DIR)/include
GCPPFLAGS     = -I../src -I$(GTEST_HEADERS)
GLDFLAGS      = -lpthread

MAKESHELL     = $(addsuffix ;, $(TEST_EXEPATH))

### google test ###

test: $(TEST_EXEPATH)

$(TEST_PRODIR)/%: $(TEST_OBJDIR)/%.o
g++ $(CFLAGS) -o $@ $^ $(LIBS) $(GTEST_LIBS) $(INCL) $(GLDFLAGS)

$(TEST_OBJDIR)/%.o: $(TEST_SUDIR)/%.cc

こっちもいい

TARGET ?= a.out
SRC_DIRS ?= ./src

SRCS := $(shell find $(SRC_DIRS) -name *.cpp -or -name *.c -or -name *.s)
OBJS := $(addsuffix .o,$(basename $(SRCS)))
DEPS := $(OBJS:.o=.d)

INC_DIRS := $(shell find $(SRC_DIRS) -type d)
INC_FLAGS := $(addprefix -I,$(INC_DIRS))

CPPFLAGS ?= $(INC_FLAGS) -MMD -MP

$(TARGET): $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS)

.PHONY: clean
clean:
$(RM) $(TARGET) $(OBJS) $(DEPS)

-include $(DEPS)

http://minus9d.hatenablog.com/entry/20140203/1391436293
http://www.jsk.t.u-tokyo.ac.jp/~k-okada/makefile/
http://minus9d.hatenablog.com/entry/20140204/1391527870
http://yut.hatenablog.com/entry/20120702/1341185909
http://www.asahi-net.or.jp/~wg5k-ickw/html/online/gcc-2.95.2/gcc_2.html
http://exlight.net/devel/make/child_process.html
http://d.hatena.ne.jp/wagavulin/20120405/1333629926
http://uyota.asablo.jp/blog/2010/09/04/5329742
http://stackoverflow.com/questions/18136918/how-to-get-current-directory-of-your-makefile
http://stackoverflow.com/questions/322936/common-gnu-makefile-directory-path
http://stackoverflow.com/questions/2129391/append-to-gnu-make-variables-via-command-line
http://nu-pan.hatenablog.com/entry/20121205/1354693969
http://postd.cc/7-things-you-should-know-about-make/
http://urin.github.io/posts/2013/simple-makefile-for-clang/
http://postd.cc/makefile-c-projects/