pkg-config出力はmakefileで機能しませんか?

pkg-config出力はmakefileで機能しませんか?

走ろうとしています。ファイルの生成、図のようにこの倉庫、これは単純な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ツールと一緒に使用してください*.oglob

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

targetaが生成されたファイルの名前ではない場合、特に以前のバージョンでは、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

関連情報