Reputation: 35
i want to compile opencv4.0 with Makefile but undefined reference error occur.
i have used to opencv in Windows and code is just simple code that only show image for test in ubuntu18.10.
but it work if i typing line below on shell.
g++ -o simple main.cpp $(pkg-config opencv4 --libs --cflags)
my Makefile is below
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
and my opencv4.pc is below.
# 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}
and error is below.
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
Upvotes: 1
Views: 693
Reputation: 61575
I assume you're using GNU Make, since you are working on Ubuntu Linux.
I also assume what you have posted as:
$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
is mis-formatted in the posting and that your Makefile really contains:
$(TARGET):$(SRCS)
(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
with the recipe command tab-indented as it must be.
In your Makefile you believe that:
OPENCV = $(pkg-config opencv4 --libs --cflags)
is a shell-expansion of the command pkg-config opencv4 --libs --cflags
that
assigns the output of the command to the Make variable OPENCV
. It is not.
It is simply a Make expansion of the string pkg-config opencv4 --libs --cflags
,
just as in the next line:
LIBS = $(OPENCV)
$(OPENCV)
is the Make expansion of the Make variable OPENCV
and not the shell
expansion of a shell command OPENCV
.
The string pkg-config opencv4 --libs --cflags
is not a Make variable that has a value (obviously).
Neither can it be an invocation of a GNU Make-function
$(pkg-config ...)
, as there is no such GNU Make function.
So $(pkg-config opencv4 --libs --cflags)
expands to nothing. Hence:
LIBS = $(OPENCV)
makes $(LIBS)
expand to nothing, and:
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
expands to the same as:
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS)
which is why the opencv libraries are missing from your linkage and the linkage fails.
To assign the output of a shell command to a Make variable, using the $(shell ...)
function:
OPENCV := $(shell pkg-config opencv4 --libs --cflags)
Then $(OPENCV)
and $(LIBS)
will acquire the correct value.
BTW...
Note that your clean
recipe attempts to delete a file, core
, that is never created by your Makefile.
And..
Be aware that the recipe:
$(TARGET):$(SRCS)
(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
represents in general the most inefficient possible way of automating a
program's build process with Make, because it will recompile all of the N
source files in $(SRCS)
whenever you change even 1 of them. In your particular
case as posted, it doesn't matter because N = 1. But when N = 1 there is no
need for Make. In anticipation of writing more professional projects where N is large, you
might like to work through Chapter 2 An Introduction to Makefiles,
at least, in the GNU Make manual.
Upvotes: 2
Reputation: 33727
This part of your makefile is likely broken:
$(TARGET):$(SRCS)
$(CC) $(CFLAGS) -o $(TARGET) $(SRCS) $(LIBS)
It looks like a leading tab character is missing on the second line.
It is not used, so make uses the default rule for building executables from .cpp
files, which does not use the LIBS
variable (only CFLAGS
).
Upvotes: 0