pkg-config 返回的结果不对

时间:2022-05-06 18:53:36
首先,我知道PKG_CONFIG_PATH可以添加搜索.pc文件的路径
其次,我知道PKG_CONFIG会从/usr/lib/pkgconfig里先搜索


问题: pkg-config --libs libavformat 返回的是 -lavformat
pkg-config --cflags libavformat 返回的居然是空行
这导致我编译ffmpeg的tutorial时出现undefined reference错误
而 pkg-config --libs opencv则返回的是
/usr/local/lib/libopencv_calib3d.so /usr/local/lib/libopencv_contrib.so /usr/local/lib/libopencv_core.so /usr/local/lib/libopencv_features2d.so /usr/local/lib/libopencv_flann.so /usr/local/lib/libopencv_gpu.so /usr/local/lib/libopencv_highgui.so /usr/local/lib/libopencv_imgproc.so /usr/local/lib/libopencv_legacy.so /usr/local/lib/libopencv_ml.so /usr/local/lib/libopencv_nonfree.so /usr/local/lib/libopencv_objdetect.so /usr/local/lib/libopencv_ocl.so /usr/local/lib/libopencv_photo.so /usr/local/lib/libopencv_stitching.so /usr/local/lib/libopencv_superres.so /usr/local/lib/libopencv_ts.a /usr/local/lib/libopencv_video.so /usr/local/lib/libopencv_videostab.so -lrt -lpthread -lm -ldl  
总结一下:  pkg-config --libs libavformat 返回的是 -lavformat也就罢了,关键是--cflags返回的是空行,这是什么情况,凭什么opencv.pc文件就返回了那么多信息呢?

附录:我用 apt-get install libavformat 安装了libavformat,libavcodec,libavdevice等等
我自己找了一下,发现apt-get install 貌似是把这些库按在了/usr/lib/i386-linux-gnu/下,该目录下有pkgconfig文件夹,放了这些库的.pc文件,贴一个出来看看
prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib/i386-linux-gnu
includedir=${prefix}/include

Name: libavcodec
Description: FFmpeg codec library
Version: 53.61.100
Requires:
Requires.private: libavutil = 51.35.100
Conflicts:
Libs: -L${libdir} -lavcodec
Libs.private: -ldl -lX11 -lXext -lXfixes -lva -lcdio_paranoia -lcdio_cdda -lcdio -ljack -lasound -lSDL -lx264 -lvpx -lvpx -lvorbisenc -lvorbis -logg -ltheoraenc -ltheoradec -logg -lspeex -lschroedinger-1.0 -lrtmp -lz -lgnutls -lpulse-simple -lpulse -lopenjpeg -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann -lmp3lame -lgsm -lfreetype -ldc1394 -lgnutls -lva -lm -pthread -lbz2 -lz
Cflags: -I${includedir}

然后贴一下opencv的.pc文件

# Package Information for pkg-config

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir_old=${prefix}/include/opencv
includedir_new=${prefix}/include

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 2.3.1
Libs: -L${libdir} -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_flann
Cflags: -I${includedir_old} -I${includedir_new}
~                                                       

6 个解决方案

#1


pkg-config --libs libavformat 返回的是 -lavformat
pkg-config --cflags libavformat 
这个没问题啊。
link 的时候才会用到 pkg-config --libs ,
pkg-config --cflags 这个是编译选项,编译时才用

#2


@二楼: 为啥 pkg-config --cflags libavformat 返回空没问题呢?为啥不返回具体的include 路径呢

澄清一下 编译ffmpeg tutorial用的makefile
# You can choose to use libswresample (This is what macports provides)
FFMPEG_RESAMPLE=-D__RESAMPLER__ -D__LIBSWRESAMPLE__
FFMPEG_PKGCONFIG_RESAMPLE=libswresample

# Or you can use libavresample which is better
#FFMPEG_RESAMPLE=-D__RESAMPLER__ -D__LIBAVRESAMPLE__
#FFMPEG_PKGCONFIG_RESAMPLE=libavresample

CC:=gcc
INCLUDES:=$(shell pkg-config --cflags libavformat libavcodec libswscale libavutil $(FFMPEG_PKGCONFIG_RESAMPLE) sdl)
CFLAGS:=-Wall -ggdb $(FFMPEG_RESAMPLE) -std=c99
LDFLAGS:=$(shell pkg-config --libs libavformat libavcodec libswscale libavutil $(FFMPEG_PKGCONFIG_RESAMPLE) sdl) -lm
EXE:=tutorial01.out tutorial02.out tutorial03.out tutorial04.out\
        tutorial05.out tutorial06.out tutorial07.out

#
# This is here to prevent Make from deleting secondary files.
#
.SECONDARY:
        

#
# $< is the first dependency in the dependency list
# $@ is the target name
#
all: dirs $(addprefix bin/, $(EXE)) tags

dirs:
        mkdir -p obj
        mkdir -p bin

tags: *.c
        ctags *.c

bin/%.out: obj/%.o
        $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@

obj/%.o : %.c
"Makefile" 49L, 1184C                                 

#3


如果头文件放在非常用位置,那么 pkg-config --cflags 需要返回 头文件所在的位置,否则编译时可能找不到头文件,
但如果放在如 /usr/include 里面的,是否返回 -I/usr/include 关系不大,编译器默认就在这个目录找头文件。

#4


说得有理,但是如果是这样的话,为啥MAke完了出的错误是undefined reference to `av_register_all' 呢?

我在.bashrc里已经export LD_LIBRARY_PATH=/usr/local/lib/:/usr/lib/i386-linux-gnu/而且source过了


#5


undefined reference to 这个是 link 的时候找不到符号,
缺少类库,或是指向的类库版本不对。

#6


类库肯定是有的,为什么说版本不对呢?ld链接的时候是怎么知道版本的?还有哪些信息告诉ld要链接哪个版本呢?

在:/usr/lib/i386-linux-gnu$ 下有这些库

-rw-r--r--   1 root root  9012580  4月 26 18:20 libavcodec.a
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavcodec.so -> libavcodec.so.53.61.100
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavcodec.so.53 -> libavcodec.so.53.61.100
-rw-r--r--   1 root root  7704964  4月 26 18:20 libavcodec.so.53.61.100
-rw-r--r--   1 root root    98252  4月 26 18:20 libavdevice.a
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavdevice.so -> libavdevice.so.53.4.100
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavdevice.so.53 -> libavdevice.so.53.4.100
-rw-r--r--   1 root root    76676  4月 26 18:20 libavdevice.so.53.4.100
lrwxrwxrwx   2 root root       23  4月 26 18:20 libavfilter.so -> libavfilter.so.2.61.100
lrwxrwxrwx   2 root root       23  4月 26 18:20 libavfilter.so.2 -> libavfilter.so.2.61.100
-rw-r--r--   1 root root   576352  4月 26 18:20 libavfilter.so.2.61.100
-rw-r--r--   1 root root  1811014  4月 26 18:20 libavformat.a
lrwxrwxrwx   1 root root       24  4月 26 18:20 libavformat.so -> libavformat.so.53.32.100
lrwxrwxrwx   1 root root       24  4月 26 18:20 libavformat.so.53 -> libavformat.so.53.32.100
-rw-r--r--   1 root root  1237192  4月 26 18:20 libavformat.so.53.32.100
-rw-r--r--   1 root root   173622  4月 26 18:20 libavutil.a
lrwxrwxrwx   1 root root       22  4月 26 18:20 libavutil.so -> libavutil.so.51.35.100
lrwxrwxrwx   1 root root       22  4月 26 18:20 libavutil.so.51 -> libavutil.so.51.35.100
-rw-r--r--   1 root root   136568  4月 26 18:20 libavutil.so.51.35.100

#1


pkg-config --libs libavformat 返回的是 -lavformat
pkg-config --cflags libavformat 
这个没问题啊。
link 的时候才会用到 pkg-config --libs ,
pkg-config --cflags 这个是编译选项,编译时才用

#2


@二楼: 为啥 pkg-config --cflags libavformat 返回空没问题呢?为啥不返回具体的include 路径呢

澄清一下 编译ffmpeg tutorial用的makefile
# You can choose to use libswresample (This is what macports provides)
FFMPEG_RESAMPLE=-D__RESAMPLER__ -D__LIBSWRESAMPLE__
FFMPEG_PKGCONFIG_RESAMPLE=libswresample

# Or you can use libavresample which is better
#FFMPEG_RESAMPLE=-D__RESAMPLER__ -D__LIBAVRESAMPLE__
#FFMPEG_PKGCONFIG_RESAMPLE=libavresample

CC:=gcc
INCLUDES:=$(shell pkg-config --cflags libavformat libavcodec libswscale libavutil $(FFMPEG_PKGCONFIG_RESAMPLE) sdl)
CFLAGS:=-Wall -ggdb $(FFMPEG_RESAMPLE) -std=c99
LDFLAGS:=$(shell pkg-config --libs libavformat libavcodec libswscale libavutil $(FFMPEG_PKGCONFIG_RESAMPLE) sdl) -lm
EXE:=tutorial01.out tutorial02.out tutorial03.out tutorial04.out\
        tutorial05.out tutorial06.out tutorial07.out

#
# This is here to prevent Make from deleting secondary files.
#
.SECONDARY:
        

#
# $< is the first dependency in the dependency list
# $@ is the target name
#
all: dirs $(addprefix bin/, $(EXE)) tags

dirs:
        mkdir -p obj
        mkdir -p bin

tags: *.c
        ctags *.c

bin/%.out: obj/%.o
        $(CC) $(CFLAGS) $< $(LDFLAGS) -o $@

obj/%.o : %.c
"Makefile" 49L, 1184C                                 

#3


如果头文件放在非常用位置,那么 pkg-config --cflags 需要返回 头文件所在的位置,否则编译时可能找不到头文件,
但如果放在如 /usr/include 里面的,是否返回 -I/usr/include 关系不大,编译器默认就在这个目录找头文件。

#4


说得有理,但是如果是这样的话,为啥MAke完了出的错误是undefined reference to `av_register_all' 呢?

我在.bashrc里已经export LD_LIBRARY_PATH=/usr/local/lib/:/usr/lib/i386-linux-gnu/而且source过了


#5


undefined reference to 这个是 link 的时候找不到符号,
缺少类库,或是指向的类库版本不对。

#6


类库肯定是有的,为什么说版本不对呢?ld链接的时候是怎么知道版本的?还有哪些信息告诉ld要链接哪个版本呢?

在:/usr/lib/i386-linux-gnu$ 下有这些库

-rw-r--r--   1 root root  9012580  4月 26 18:20 libavcodec.a
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavcodec.so -> libavcodec.so.53.61.100
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavcodec.so.53 -> libavcodec.so.53.61.100
-rw-r--r--   1 root root  7704964  4月 26 18:20 libavcodec.so.53.61.100
-rw-r--r--   1 root root    98252  4月 26 18:20 libavdevice.a
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavdevice.so -> libavdevice.so.53.4.100
lrwxrwxrwx   1 root root       23  4月 26 18:20 libavdevice.so.53 -> libavdevice.so.53.4.100
-rw-r--r--   1 root root    76676  4月 26 18:20 libavdevice.so.53.4.100
lrwxrwxrwx   2 root root       23  4月 26 18:20 libavfilter.so -> libavfilter.so.2.61.100
lrwxrwxrwx   2 root root       23  4月 26 18:20 libavfilter.so.2 -> libavfilter.so.2.61.100
-rw-r--r--   1 root root   576352  4月 26 18:20 libavfilter.so.2.61.100
-rw-r--r--   1 root root  1811014  4月 26 18:20 libavformat.a
lrwxrwxrwx   1 root root       24  4月 26 18:20 libavformat.so -> libavformat.so.53.32.100
lrwxrwxrwx   1 root root       24  4月 26 18:20 libavformat.so.53 -> libavformat.so.53.32.100
-rw-r--r--   1 root root  1237192  4月 26 18:20 libavformat.so.53.32.100
-rw-r--r--   1 root root   173622  4月 26 18:20 libavutil.a
lrwxrwxrwx   1 root root       22  4月 26 18:20 libavutil.so -> libavutil.so.51.35.100
lrwxrwxrwx   1 root root       22  4月 26 18:20 libavutil.so.51 -> libavutil.so.51.35.100
-rw-r--r--   1 root root   136568  4月 26 18:20 libavutil.so.51.35.100