pkg-config 輸出不適用於makefile?
我正在嘗試執行makefile,顯示在這個 repo中,它是一個簡單的 Wayland 客戶端。但是當我執行make時,它的輸出似乎
$(WAYLAND)
是空白的,並且由於無法找到必要的wayland-client.h標頭檔而無法編譯。bash 中 Fedora 23 上的 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的選項似乎缺少makefile
$(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"
感謝您指出對我來說可能完全顯而易見的事情。
發布的 makefile 缺少一些細節
注意:(幾乎)總是最好將編譯步驟與連結步驟分開
以下 makefile 更正了這些細節
注意:
<tab>
表示在實際makefile中使用tab鍵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 文件中的宏有兩種類型:
- 那些只使用一次評估的
:=
- 每次被引用時評估的那些
=
在規則
WAYLAND =`pkg-config wayland-client --cflags --libs`
WAYLAND
每次引用都會重新評估CFLAGS ?= -std=c11 -Wall -Werror -O3 -fvisibility=hidden
宏的格式無效。
?=
應該:=
在 a
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’ 被正確引用,
$@
如果使用 ’target’ 則不會出現按鍵錯誤$@
。images.bin: images/convert.py images/window.png images/fish.png images/convert.py cat window.bin fish.bin > images.bin
當 a
target
不是生成文件的名稱時,尤其是在較舊版本的 中make
,則目標需要以a 開頭.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