使用Makefile编译时对opencv函数的未定义引用

使用Makefile编译时对opencv函数的未定义引用,opencv,ubuntu,makefile,Opencv,Ubuntu,Makefile,我想用Makefile编译opencv4.0,但出现未定义的引用错误。 我曾经在Windows中使用opencv,代码只是简单的代码,仅在ubuntu18.10中显示用于测试的图像 但若我在shell上键入下面的行,它就会工作 g++ -o simple main.cpp $(pkg-config opencv4 --libs --cflags) 我的Makefile在下面 CC = g++

我想用Makefile编译opencv4.0,但出现未定义的引用错误。
我曾经在Windows中使用opencv,代码只是简单的代码,仅在ubuntu18.10中显示用于测试的图像

但若我在shell上键入下面的行,它就会工作

g++ -o simple main.cpp $(pkg-config opencv4 --libs --cflags)
我的Makefile在下面

CC = g++                                                                                             
CFLAGS = -W -Wall
SRCS = main.cpp
TARGET = simple

OPENCV = $(pkg-config opencv4 --libs --cflags)
LIBS = $(OPENCV)

$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)

clean:
    rm -f $(OBJECTS) $(TARGET) core
下面是我的opencv4.pc

# Package Information for pkg-config                                                                 

prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include/opencv4

Name: OpenCV
Description: Open Source Computer Vision Library
Version: 4.0.0
Libs: -L${exec_prefix}/lib -lopencv_gapi -lopencv_stitching -lopencv_aruco -lopencv_bgsegm -lopencv_b
Libs.private: -ldl -lm -lpthread -lrt -L/usr/lib/x86_64-linux-gnu -lGL -lGLU
Cflags: -I${includedir}

错误如下

g++ -W -Wall -o simple main.cpp 
/usr/bin/ld: /tmp/cciHsvhP.o: in function `main':
main.cpp:(.text+0x70): undefined reference to `cv::imread(cv::String const&, int)'
/usr/bin/ld: main.cpp:(.text+0xc4): undefined reference to `cv::imshow(cv::String const&, cv::_InputArray const&)'
....
collect2: error: ld returned 1 exit status
make: *** [Makefile:11: simple] Error 1

生成文件的这一部分可能已损坏:

$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
第二行似乎缺少前导制表符


它没有使用,所以make使用默认规则从
.cpp
文件中构建可执行文件,该规则不使用
LIBS
变量(仅
CFLAGS
)。

我假设您使用的是GNU make,因为您使用的是Ubuntu Linux

我还假设您发布的内容为:

$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
发布中的格式错误,并且您的Makefile确实包含:

$(TARGET):$(SRCS)
    (CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
配方命令选项卡必须缩进

在Makefile中,您相信:

OPENCV = $(pkg-config opencv4 --libs --cflags)
是命令
pkg config opencv4--libs--cflags
的shell扩展 将命令的输出分配给Make变量
OPENCV
。事实并非如此。 它只是字符串的Make扩展
pkg config opencv4--libs--cflags
, 正如在下一行:

LIBS = $(OPENCV)
$(OPENCV)
是Make变量的Make扩展
OPENCV
,而不是shell shell命令的扩展
OPENCV

字符串
pkg config opencv4--libs--cflags
不是一个有值的Make变量(显然)

这也不能是一种对
$(pkg config…
),因为没有这样的GNU Make函数

因此,
$(pkg config opencv4--libs--cflags)
扩展为零。因此:

使
$(LIBS)
扩展为零,并且:

$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
扩展为与以下内容相同:

$(CC) $(CFLAGS) -o $(TARGET) $(SRCS)
这就是为什么链接中缺少opencv库,链接失败的原因

要将shell命令的输出指定给Make变量,请使用:

然后
$(OPENCV)
$(LIBS)
将获得正确的值

顺便说一句…

请注意,您的
clean
配方尝试删除一个文件
core
,该文件从未由您的Makefile创建过

和..

请注意配方:

$(TARGET):$(SRCS)
    (CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
一般来说,它代表了自动化 程序的生成过程使用Make,因为它将重新编译所有N 只要您更改其中的一个源文件,就可以使用
$(SRCS)
中的源文件。特别是你 如前所述,这并不重要,因为N=1。但当N=1时,则不存在 需要制造。为了编写N较大的专业项目,您需要 我想通过,
至少,在GNU制作手册中。

?您的Makefile无法工作,因为它生成的命令与您在shell中运行
g++
时的命令不同-OpenCV开关都丢失了。@MarkSetchell这意味着OpenCV开关都丢失了什么?如果您查看后面的行,您说*“下面是错误”,您将看到,所执行的命令并不包括您已经说过并知道需要的所有库。这也是Florian在回答中告诉你的。我可以编译简单的“.cpp”文件,但我想编译包含“opencv”api的“.cpp”文件,我引用了[]中的Makefile。你确定你复制了它吗?在你的问题中,缺少一个制表符。
OPENCV := $(shell pkg-config opencv4 --libs --cflags)
$(TARGET):$(SRCS)
    (CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)