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:没有这样的文件或目录

请注意选项如何抄送上面似乎缺少$(WAYLAND)指定的输出生成文件。如果我手动执行抄送像这样:

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 缺少一些细节

注意:(几乎)总是最好将编译步骤与链接步骤分开

以下 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)

“目标”被正确引用,并且如果使用,$@则不会出现击键错误。$@

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

当 atarget不是生成的文件的名称时,特别是在旧版本的 中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

相关内容