走ろうとしています。ファイルの生成、図のようにこの倉庫、これは単純なWaylandクライアントです。しかし、私が走るとき作る、出力が空のように見え、必要$(WAYLAND)
なコンテンツが見つからないためコンパイルされません。Wayland-client.hヘッドファイル。 Fedora 23のbashでcc(GCC)バージョン5.3.1。
以下はいくつかの詳細です。私の質問は、これが不可能になる私の環境にどのような問題がありますか?ファイルの生成期待どおりに動作しますか?
コンテンツファイルの生成:
WAYLAND=`pkg-config wayland-client --cflags --libs`
CFLAGS?=-std=c11 -Wall -Werror -O3 -fvisibility=hidden
hello_wayland: hello_wayland.o helpers.o helpers.h images.bin
$(CC) -o hello_wayland *.o $(WAYLAND) -lrt
images.bin: images/convert.py images/window.png images/fish.png
images/convert.py
cat window.bin fish.bin > images.bin
clean:
$(RM) *.o fish.bin window.bin hello_wayland
出力作る:
cc -std=c11 -Wall -Werror -O3 -fvisibility=hidden -c -o hello_wayland.o hello_wayland.c hello_wayland.c:6:28: 致命的なエラー: wayland-client.h: そのファイルまたはディレクトリはありません。
オプションがどうなるかをご覧くださいCC$(WAYLAND)
上記の内容で指定された出力が欠落しているようです。ファイルの生成。私が手動で行うとCCこのように:
cc -std=c11 -Wall -Werror -O3 -fvisibility=hidden -c -o hello_wayland.o hello_wayland.c \
-I/home/me/install/include -L/home/me/install/lib -lwayland-client
コンパイルに成功しました。
出力pkg-config wayland-client --cflags --libs:
-I/home/me/install/include -L/home/me/install/lib -lwayland-client
コンテンツ~/.bash_profile:
source ~/.profile
source ~/.bashrc
関連情報~/.bashrc:
export WLD=$HOME/install
export LD_LIBRARY_PATH=$WLD/lib
export PKG_CONFIG_PATH=$WLD/lib/pkgconfig/:$WLD/share/pkgconfig/
export PATH=$WLD/bin:$PATH
export ACLOCAL_PATH=$WLD/share/aclocal
export ACLOCAL="aclocal -I $ACLOCAL_PATH"
私には完全に明白だったかもしれない内容を指摘していただきありがとうございます。
答え1
公開されたメイクファイルにはいくつかの詳細がありません。
注:コンパイル段階と接続段階を分離することは(ほぼ)常に良いです。
次のmakefileはこれらの詳細を修正します。
注:<tab>
実際のmakefileでタブキーを使用することを意味します。
RM := /usr/bin/rm
LFLAGS += `pkg-config wayland-client --libs`
CFLAGS := -std=c11 -Wall -Werror -O3 -fvisibility=hidden
CFLAGS += `pkg-config wayland-client --cflags`
OBJS := hello_wayland.o helpers.o
HDRS := helpers.h
TARGET := hello_wayland
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJS) images.bin
<tab>$(CC) -o hello_wayland *.o $(LFLAGS) -lrt
%.o:%.c $(HDRS)
<tab>$(CC) $(CFLAGS)-c $< -o $@ -I.
images.bin: images/convert.py images/window.png images/fish.png
<tab>images/convert.py
<tab>cat window.bin fish.bin > images.bin
.PHONY: clean
clean:
<tab>$(RM) *.o fish.bin window.bin hello_wayland
元のmakefileに何が問題なのか尋ねます。
以下はいくつかの観察事項です。
make ファイルには 2 種類のマクロがあります。
- 使用のために一度だけ評価されます。
:=
- 参照されるたびに評価される内容
=
ルールに
WAYLAND =`pkg-config wayland-client --cflags --libs`
WAYLAND
各引用は再評価されます。
CFLAGS ?= -std=c11 -Wall -Werror -O3 -fvisibility=hidden
マクロ形式が正しくありません。 ?=
しなければならない:=
ではMakefile
一般的な使い方がありますが、make all
このmakefileにはそのターゲットがありません(最初のターゲットである必要があるため、最初にターゲットをmake
実行します)。targets
リンクステップは実際のファイル名ではなくマクロ名である必要があるためです。マクロにターゲット名が含まれています。
また、これらのマクロを使用すると、呼び出し時に生成される実行可能ファイル名を簡単に設定でき、両方のアプローチが機能しますが、make
柔軟性のためにマクロを作成することをお勧めします。
これは、再帰的な makefile や複数の異なる実行可能ファイルを作成する場合に特に当てはまります。
hello_wayland: hello_wayland.o helpers.o helpers.h images.bin
これは、特定のヘッダーファイルについて何も知らないデフォルトのレシピを使用する隠しコンパイルを持つリンクステップであるため、ヘッダーファイルが変更された場合は隠されたコンパイルは完了しません。ヘッダーファイルはhelpers.h
リンクステップではありません。
$(CC) -o hello_wayland *.o $(WAYLAND) -lrt
これはmakefileで使用してはいけませんが、makeツールと一緒に使用してください*.o
。glob
SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
「ターゲット」が正しく参照され、使用すると$@
キーストロークエラーは発生しません。$@
images.bin: images/convert.py images/window.png images/fish.png
images/convert.py
cat window.bin fish.bin > images.bin
target
aが生成されたファイルの名前ではない場合、特に以前のバージョンでは、make
ターゲットの前に次のものが必要です。.PHONY:
.PHONY: <list of target names that produce no actual output file>
clean:
$(RM) *.o fish.bin window.bin hello_wayland
makefilesで作業(例:)を使用するglob
ことはお勧めできません。代わりに、上記のよう*.o
な適切なマクロを使用してください。$(OBJS)
それでは、元のmakefileが機能しないのはなぜですか?累積的に失敗につながるものの組み合わせ。より明確な理由は次のとおりです。
1) the incorrect setting of the CFLAGS macro
2) the combining of the link operation with the compile operations
3) the missing .PHONY: statement
4) the use of the `glob` statements