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

时间:2019-02-09 10:40:46

标签: opencv ubuntu makefile

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

但是如果我在外壳上输入下面的行,它就可以工作。

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

2 个答案:

答案 0 :(得分:1)

我假设您正在使用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。它不是。 它只是字符串pkg-config opencv4 --libs --cflags的Make扩展, 就像下一行一样:

LIBS = $(OPENCV)

$(OPENCV)是Make变量OPENCV而不是shell的Make扩展。 扩展Shell命令OPENCV

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

也不能是GNU Make-function的调用 $(pkg-config ...),因为没有这样的GNU Make函数。

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

LIBS = $(OPENCV)

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

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

扩展为与以下内容相同:

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

这就是为什么链接中缺少opencv库而链接失败的原因。

使用$(shell ...) function,将shell命令的输出分配给Make变量:

OPENCV := $(shell pkg-config opencv4 --libs --cflags)

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

顺便说一句...

请注意,您的clean食谱试图删除文件core,该文件从未由Makefile创建。

并且..

请注意该食谱:

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

通常代表自动化的最无效的方法 Make编译程序的过程,因为它将重新编译所有 N 每当您更改$(SRCS)中的源文件中的1个时。在你的情况下 情况下,因为 N = 1没关系,但是当 N = 1时,没有 需要Make。期望编写 N 大的专业项目,您 可能想完成Chapter 2 An Introduction to Makefiles, 至少在GNU Make手册中。

答案 1 :(得分:0)

makefile的这一部分可能已损坏:

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

第二行似乎缺少制表符字符。

未使用它,因此make使用默认规则从.cpp文件构建可执行文件,该规则不使用LIBS变量(仅使用CFLAGS)。