web-dev-qa-db-ja.com

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

単純なWaylandクライアントである this repo に示すmakefileを実行しようとしています。しかし、makeを実行すると、$(WAYLAND)の出力が空白になり、実行できないためにコンパイルに失敗するようです。必要なwayland-client.hヘッダーファイルを見つけるため。 bashのFedora23上のcc(GCC)バージョン5.3.1。

以下はいくつかの詳細です。私の質問は、このmakefileが意図したとおりに機能するのを妨げている環境でどのような間違いを犯しているのかということです。

makefileの内容:

_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
_

makeの出力:

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)の出力が欠落しているように見えることに注意してください。 makefile。このように手動で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"
_

おそらく私には完全に明白なはずの何かを指摘してくれてありがとう。

2
ybakos

投稿されたメイクファイルに詳細がありません

注:(ほとんどの場合)コンパイルステップをリンクステップから分離するのが常に最善です。

次のメイクファイルはそれらの詳細を修正します

注:_<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つのタイプがあります。

  • _:=_を使用して1回だけ評価されたもの
  • 参照されるたびに評価されるもの_=_

ルールで

_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
_

_*.o_はglob操作であり、makefileでは使用しないでください。代わりにmake機能を使用してください。

_SRC := $(wildcard *.c)
OBJ := $(SRC:.c=.o)
_

'target'は_$@_によって適切に参照され、_$@_が使用されている場合はキーパンチエラーは発生しません。

_images.bin: images/convert.py images/window.png images/fish.png
    images/convert.py
    cat window.bin fish.bin > images.bin
_

targetが生成されたファイルの名前ではない場合、特に古いバージョンのmakeでは、ターゲットの前に_.PHONY:_を付ける必要があります。

_.PHONY: <list of target names that produce no actual output file>

clean:
    $(RM) *.o fish.bin window.bin hello_wayland
_

Makefileで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
_
2
user3629249