I hope you're all fine.
I'm learning opencv (c++) currently and I'm trying to compile a "main.cpp" with a class called "Algorithms"(.h and .cpp) and for some reason I get an error like this one when trying :
g++ `pkg-config --cflags opencv4` `pkg-config --libs opencv4` src/Algorithms.cpp -o obj/Algorihtms.o -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
make: *** [makefile:15: obj/Algorithms.o] Error 1
Here is my makefile:
CFLAGS = `pkg-config --cflags opencv4`
LIBS = `pkg-config --libs opencv4`
B = bin
O = obj
S = src
FLAGS = -c -Wall
all: $(O) $(B) $(B)/main
$(B)/main: $(O)/Algorithms.o
g++ $(FLAGS) -ggdb $(S)/main.cpp -o $(O)/main.o
$(O)/Algorithms.o:
g++ $(CFLAGS) $(LIBS) $(S)/Algorithms.cpp -o $(O)/Algorihtms.o -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs
$(O):
mkdir $(O)
$(B):
mkdir $(B)
clean: $(O) $(B)
rm -rf $(O)
rm -rf $(B)
(Opencv is installed and I know that if I compile "main.cpp" alone it works, but I can't get "main.cpp" and the class "Algorithm" to compile simultaneously.)
Thanks a lot.
If you do not want to link to an executable, you need to make GCC aware. The default is to compile and link. Use option -c:
$(O)/Algorithms.o:
g++ -c $(CFLAGS) $(LIBS) $(S)/Algorithms.cpp -o $(O)/Algorihtms.o -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs
From the manpage:
When you invoke GCC, it normally does preprocessing, compilation, assembly and linking. The
"overall options" allow you to stop this process at an intermediate stage. For example, the -c
option says not to run the linker. Then the output consists of object files output by the
assembler.
However in your case, as mentioned in my comment, the question is why you need an intermediate object file at all.
Answering to my own question.
I don't know why I didn't figure that out immediately in my makefile.
Whatever, here is a working makefile that does the job :
CFLAGS = `pkg-config --cflags opencv4`
LIBS = `pkg-config --libs opencv4`
B = bin
O = obj
S = src
FLAGS = -c -Wall
all: $(O) $(B) $(B)/main
$(B)/main: $(O)/Algorithms.o
g++ $(CFLAGS) $(LIBS) $(S)/main.cpp -o $(B)/main $(O)/*.o -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_imgcodecs
$(O)/Algorithms.o:
g++ $(FLAGS) $(CFLAGS) $(LIBS) $(S)/Algorithms.cpp -o $(O)/Algorithms.o
$(O):
mkdir $(O)
$(B):
mkdir $(B)
clean: $(O) $(B)
rm -rf $(O)
rm -rf $(B)
I'm sure this makefile is not the most efficient and it can be improved in many ways.
Related
.
Novice to makefile. I am trying out the Gstreamer library. Need to issue a command to the CLI as
'gcc basic-tutorial-1.c -o basic-tutorial-1 `pkg-config --cflags --libs gstreamer-1.0`
I am trying to write a make file to simplify things
And my makefile is as follows
CC = gcc
CFLAGS = `pkg-config --cflags gstreamer-1.0`
LDFLAGS = `pkg-config --libs gstreamer-1.0`
CLIBS = `pkg-config --libs gstreamer-1.0`
SOURCE = basic-tutorial-1.c
TARGET = demo
video : $(TARGET).o
$(CC) $(LDFLAGS) -o $(TARGET).o
$(TARGET).o : $(SOURCE)
$(CC) $(CFLAGS) -c $(SOURCE)
clean:
rm -f $(TARGET) $(OBJECTS)
It gives me an error message
make: Entering directory '/home/test/VSCode/C++/Gstreamer'
gcc `pkg-config --cflags gstreamer-1.0` -c basic-tutorial-1.c
gcc `pkg-config --libs gstreamer-1.0` -o demo.o
/usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:14: recipe for target 'video' failed
make: *** [video] Error 1
make: Leaving directory '/home/test/VSCode/C++/Gstreamer'
What should i do next?
Thanks
Check if you have the main() function in the source files being compiled
For GNU make,
CFLAGS = `pkg-config --cflags gstreamer-1.0`
is wrong, and you should code:
CFLAGS = $(shell pkg-config --cflags gstreamer-1.0) -Wall -Wextra -g
Read the documentation of GNU make and try make -p
This recipe is incomplete:
video : $(TARGET).o
$(CC) $(LDFLAGS) -o $(TARGET).o
What are you compiling? If $(TARGET).o is a dependency, why is it listed as the output of $(CC)? Not sure what you really want here, but perhaps:
$(CC) $(TARGET).o -o video $(LDFLAGS)
Currently, i am been working on how to link an existing library with OpenCV using Makefile. I am still new to Makefile. I had googled on the Internet but mostly the answer is on CMake. Even there is an answer, the output of the result contain errors. Please have a look on my Makefile, am i doing anything wrong?
Makefile
###############################################################
#
# Purpose: Makefile for "head_tracking"
# Author.: robotis
# Version: 0.1
# License: GPL
#
###############################################################
TARGET = head_tracking
INCLUDE_DIRS = -I../../../include -I../../../../Framework/include
CXX = g++
CXXFLAGS += -O2 -DLINUX -Wall $(INCLUDE_DIRS)
#CXXFLAGS += -O2 -DDEBUG -DLINUX -Wall $(INCLUDE_DIRS)
LFLAGS += -lpthread -ljpeg -lrt
CPPFLAGS = $(shell pkg-config --cflags opencv2) #The one i added
LDLIBS = $(shell pkg-config --libs opencv2) #The one i addded
OBJECTS = main.o
all: $(TARGET)
clean:
rm -f *.a *.o $(TARGET) core *~ *.so *.lo
libclean:
make -C ../../../build clean
distclean: clean libclean
darwin.a:
make -C ../../../build
$(TARGET): darwin.a $(OBJECTS)
$(CXX) $(CFLAGS) $(OBJECTS) ../../../lib/darwin.a -o $(TARGET) $(LFLAGS)
chmod 755 $(TARGET)
# useful to make a backup "make tgz"
tgz: clean
mkdir -p backups
tar czvf ./backups/head_tracking_`date +"%Y_%m_%d_%H.%M.%S"`.tgz --exclude backups *
Error Image: Undefined Refrenced
Okay i finally solve my linking error. I can now compile openCV with my Robotis-Op library. This is the new Makefile.
###############################################################
#
# Purpose: Makefile for "head_tracking"
# Author.: robotis
# Version: 0.1
# License: GPL
#
###############################################################
TARGET = head_tracking
INCLUDE_DIRS = -I../../../include -I../../../../Framework/include -I/usr/local/include/opencv2
CXX = g++
CXXFLAGS += -O2 -DLINUX -Wall $(INCLUDE_DIRS) `pkg-config --cflags opencv`
#CXXFLAGS += -O2 -DDEBUG -DLINUX -Wall $(INCLUDE_DIRS)
LFLAGS += -lpthread -ljpeg -lrt
LDFLAGS = `pkg-config --libs opencv`
#CPPFLAGS = $(shell pkg-config --cflags opencv2)
#LDLIBS = $(shell pkg-config --libs opencv2)
OBJECTS = main.o
all: $(TARGET)
clean:
rm -f *.a *.o $(TARGET) core *~ *.so *.lo
libclean:
make -C ../../../build clean
distclean: clean libclean
darwin.a:
make -C ../../../build
$(TARGET): darwin.a $(OBJECTS)
$(CXX) $(CFLAGS) $(OBJECTS) ../../../lib/darwin.a -o $(TARGET) $(LFLAGS) $(LDFLAGS)
chmod 755 $(TARGET)
# useful to make a backup "make tgz"
tgz: clean
mkdir -p backups
tar czvf ./backups/head_tracking_`date +"%Y_%m_%d_%H.%M.%S"`.tgz --exclude back
ups *
You are having the linking errors,
You need to link with the following flags:
-lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_ocl -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab
OpenCV Undefined symbols for architecture x86_64: error
I have a project, which uses opencv library. Today I have upgraded my Mac OS X Lion to Mavericks and now I am wondering why it does not compile anymore because of the following error:
c++ -O2 -g -Wall -fmessage-length=0 -c -o Hello.o Hello.cpp
Hello.cpp:2:10: fatal error: 'opencv/cv.h' file not found
#include "opencv/cv.h"
^
1 error generated.
make: *** [Hello.o] Error 1
Here's the code of Hello.cpp:
#include <iostream>
#include "opencv/cv.h"
using namespace std;
int main(){
return 0;
}
Here's my makefile:
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
OBJS = Hello.o
LIBS = -lopencv_core -lopencv_imgproc -lopencv_calib3d -lopencv_video -lopencv_features2d -lopencv_ml -lopencv_highgui -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_gpu
INCPATH = -I/usr/local/Cellar/opencv/2.4.6.1/include
LIBPATH = -L/usr/local/Cellar/opencv/2.4.6.1/lib
TARGET = Hello
$(TARGET): $(OBJS)
g++ $(INCPATH) $(LIBPATH) -o $(TARGET) $(OBJS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(OBJS) $(TARGET)
I have to say that I can compile my project using terminal by typing:
g++ `pkg-config --cflags opencv` Hello.cpp -o Hello
and to be sure, this is what I get by running pkg-config --cflags opencv on terminal:
-I/usr/local/Cellar/opencv/2.4.6.1/include/opencv
I doubt this makefile ever worked, unless somehow the new version of MacOSX has moved those headers out of the standard location into a different location.
You are using the default built-in rules, as Paul R says, but you are not using the default make variables that go with those rules. I would write my makefile like this:
CXX = g++
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
CPPFLAGS = -I/usr/local/Cellar/opencv/2.4.6.1/include
OBJS = Hello.o
LDFLAGS = -L/usr/local/Cellar/opencv/2.4.6.1/lib
LDLIBS = -lopencv_core -lopencv_imgproc -lopencv_calib3d -lopencv_video \
-lopencv_features2d -lopencv_ml -lopencv_highgui -lopencv_objdetect \
-lopencv_contrib -lopencv_legacy -lopencv_gpu
TARGET = Hello
.PHONY: all
all: $(TARGET)
$(TARGET): $(OBJS)
$(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $#
.PHONY: clean
clean:
rm -f $(OBJS) $(TARGET)
You makefile does not have an explicit rule for building Hello.o so it is using a default rule. There are various ways to handle this but I would just change it to:
CXXFLAGS = -O2 -g -Wall -fmessage-length=0
SRCS = Hello.cpp
LIBS = -lopencv_core -lopencv_imgproc -lopencv_calib3d -lopencv_video -lopencv_features2d -lopencv_ml -lopencv_highgui -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_gpu
INCPATH = -I/usr/local/Cellar/opencv/2.4.6.1/include
LIBPATH = -L/usr/local/Cellar/opencv/2.4.6.1/lib
TARGET = Hello
$(TARGET): $(SRCS)
g++ $(CXXFLAGS) $(INCPATH) $(LIBPATH) -o $(TARGET) $(SRCS) $(LIBS)
all: $(TARGET)
clean:
rm -f $(TARGET)
Dear i got the same error, please have a look here:
C++ linking error after upgrading to Mac OS X 10.9 / Xcode 5.0.1
very quick solution: add -stdlib=libstdc++ to the linking command.
I recently inherited some OpenCV code. I installed openCV on my mac, built in in XCode, and then compiled and successfully ran my first openCV "hello world"-ish program.
Now I'm trying to run the code I was given, but I get errors that lead me to believe it's an issue with the original code being run on a 32-bit Windows system and mine being on a 64-bit Mac.
When I run the Makefile by entering "make"
CC = g++
CFLAGS =
LDFLAGS = -I/usr/local/include/opencv -lm -lopencv_core -lopencv_highgui -lopencv_video
ALL = vision
all: $(ALL)
vision: vision.o
$(CC) $(LDFLAGS) -o $# $^
vision.o: vision.cpp
$(CC) $(LDFLAGS) -c $<
.PHONY: clean
clean:
rm -rf *.o core* $(ALL)
I get the following output…
g++ -I/usr/local/include/opencv -lm -lopencv_core -lopencv_highgui -lopencv_video -o vision vision.o
Undefined symbols for architecture x86_64:
"cv::equalizeHist(cv::Mat const&, cv::Mat&)", referenced from:
_main in vision.o
"cv::threshold(cv::Mat const&, cv::Mat&, double, double, int)", referenced from:
_main in vision.o
ld: symbol(s) not found for architecture x86_64
collect2: ld returned 1 exit status
make: *** [vision] Error 1
I'm confused; does this mean my install of OpenCV is wrong, the code (those methods specifically) needs to be changed, or something else entirely?
Note: When I comment out the problem methods from the vision.cpp code, everything compiles just fine.
Add opencv_imgprocto your LDFLAGS:
LDFLAGS = -I/usr/local/include/opencv -lm -lopencv_core -lopencv_highgui -lopencv_video -lopencv_imgproc
Here is a working example:
CXX = g++
SOURCES = aaa.cpp bbb.cpp
OBJS = $(SOURCES:.cpp=.o)
CXXFLAGS = -I. -I/opt/local/include \
-std=c++11 -stdlib=libc++ \
-g3 -Wall -O0
# -std=c++0x -arch x86_64 -stdlib=libc++ \
LDFLAGS = -L/opt/local/lib -L/usr/lib $(pkg-config --libs --cflags opencv) -lm -ljpeg
LDFLAGS = -L/opt/local/lib -L/usr/lib -I/opt/local/include/opencv -I/opt/local/include -L/opt/local/lib -lopencv_calib3d -lopencv_contrib -lopencv_core -lopencv_features2d -lopencv_flann -lopencv_gpu -lopencv_highgui -lopencv_imgproc -lopencv_legacy -lopencv_ml -lopencv_nonfree -lopencv_objdetect -lopencv_photo -lopencv_stitching -lopencv_superres -lopencv_ts -lopencv_video -lopencv_videostab -lm -ljpeg
.o:
$(CXX) $(CXXFLAGS) -o $# -c $^
all: $(OBJS)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o out $(OBJS)
clean:
rm -rf *.o
You can also have the computer guess you the libraries automatically:
CFLAGS = `pkg-config --cflags opencv`
LDFLAGS = `pkg-config --libs opencv` -lm
So I'm having trouble compiling my application which is using yaml-cpp
I'm including "yaml.h" in my source files (just like the examples in the yaml-cpp wiki) but when I try compiling the application I get the following error:
g++ -c -o entityresourcemanager.o entityresourcemanager.cpp
entityresourcemanager.cpp:2:18: error: yaml.h: No such file or directory
make: *** [entityresourcemanager.o] Error 1
my makefile looks like this:
CC = g++
CFLAGS = -Wall
APPNAME = game
UNAME = uname
OBJECTS := $(patsubst %.cpp,%.o,$(wildcard *.cpp))
mac: $(OBJECTS)
$(CC) `pkg-config --cflags --libs sdl` `pkg-config --cflags --libs yaml-cpp` $(CFLAGS) -o $(APPNAME) $(OBJECTS)
pkg-config --cflags --libs yaml-cpp returns:
-I/usr/local/include/yaml-cpp -L/usr/local/lib -lyaml-cpp
and yaml.h is indeed located in /usr/local/include/yaml-cpp
Any idea what I could do?
Thanks
Your default target is "mac" and you have rule how to build it. It depends on object files and you do not have any rules how to build those, so make is using its implicit rules. Those rules do just that:
g++ -c -o entityresourcemanager.o entityresourcemanager.cpp
As you can see there is no -I/usr/local/... part here.
The easiest way to fix that is to change CPPFLAGS and LDFLAGS value globally:
YAML_CFLAGS := $(shell pkg-config --cflags yaml-cpp)
YAML_LDFLAGS := $(shell pkg-config --libs yaml-cpp)
SDL_CFLAGS := $(shell pkg-config --cflags sdl)
SDL_LDFLAGS := $(shell pkg-config --libs sdl)
CPPFLAGS += $(YAML_CFLAGS) $(SDL_CFLAGS)
LDFLAGS += $(YAML_LDFLAGS) $(SDL_LDFLAGS)
mac: $(OBJECTS)
$(CXX) -o $(APPNAME) $(OBJECTS) $(LDFLAGS)
CPPFLAGS value is used by implicit rules that build object files from cpp files, so now compiler should find yaml headers.
Edit:
LDFLAGS probably should go after OBJECTS
Don't you mismatch your include directory?
-I/usr/local/include
instead of
-I/usr/local/include/yaml-cpp