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
Related
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.
environment
ubuntu 18.04 (a virtual environment created by vagrant)
gcc5.5.0
I'm trying to build my own little OS.
I'm writing the kernel in C++/NASM.
I'm going to compile each of the several C++ files that make up the kernel and then link them together to create an executable file. (This is because the entry point of my own kernel is not "main", so I dare not link at the same time as compiling)
Error
The compilation of each C++ file will run without any problems and each object file will be created.
However, I get the following error in linking the object files.
But I understand that a ".a" file is a static object, not a dynamic object, so I can not understand why I'm getting this error.
I'd appreciate it if you could let me know.
ld: attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libc++abi.a'
Here's the full text of the log
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/hoge.o -c src/hoge.cpp
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/huga.o -c src/huga.cpp
mkdir -p ./obj
g++ -O2 -g -MMD -Wall -I./include -o obj/piyo.o -c src/piyo.cpp
mkdir -p ./obj
nasm -f elf64 -o obj/assm.o src/assm.asm
ld --entry <ENTRY_POINT> --static -o ./ELF/kernel.elf ./obj/hoge.o ./obj/huga.o ./obj/piyo.o ./obj/assm.o -lc -lc++ -lc++abi -L/usr/lib/x86_64-linux-gnu
ld: attempted static link of dynamic object `/usr/lib/x86_64-linux-gnu/libc++abi.a'
Makefile:12: recipe for target 'ELF/kernel.elf' failed
make: *** [ELF/kernel.elf] Error 1
Makefile
COMPILER = g++
CFLAGS = -O2 -g -MMD -Wall
INCLUDE = -I./include
TARGET = ./ELF/kernel.elf
SRCDIR = ./src
SOURCES := $(shell find $(SRCDIR) -name *.cpp -or -name *.c -or -name *.asm)
OBJDIR = ./obj
OBJECTS = $(OBJDIR)/hoge.o $(OBJDIR)/huga.o $(OBJDIR)/piyo.o $(OBJDIR)/assm.o
DEPENDS = $(OBJECTS:.o=.d)
LDFLAGS = --entry <ENTRY_POINT> --static
$(TARGET): $(OBJECTS)
ld $(LDFLAGS) -o $(TARGET) $(OBJECTS) -lc -lc++ -lc++abi -L/usr/lib/x86_64-linux-gnu
$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
-mkdir -p $(OBJDIR)
$(COMPILER) $(CFLAGS) $(INCLUDE) -o $# -c $<
$(OBJDIR)/%.o: $(SRCDIR)/%.asm
-mkdir -p $(OBJDIR)
nasm -f elf64 -o $# $<
all: clean $(TARGET)
clean:
rm -rf $(OBJECTS) $(DEPENDS) $(TARGET)
-include $(DEPENDS)
I seem to be going from one problem to the next ever since I decided to organize my code into subdirectories. The problems are naturally arising from the Makefile. So here's what I've currently got:
UNAME := $(shell uname)
# Directories
SOURCEDIR = src/
BUILDDIR = build/
# Compiler options
CC = clang++
DEBUG = -g
CFLAGS = -std=c++11 -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
# Files
SRC = $(wildcard $(SOURCEDIR)*.cpp) $(wildcard $(SOURCEDIR)**/*.cpp)
OBJS = $(SRC:$(SOURCEDIR)%.cpp=$(BUILDDIR)%.o)
ifeq ($(UNAME), Darwin)
LIBS = -lglfw3 -framework OpenGL -lglew -framework IOKit -framework CoreFoundation -framework ApplicationServices -framework Foundation -framework AppKit
BUILDDIR = ./build/osx/
endif
ifeq ($(UNAME), Linux)
LIBS = -lglfw -lGL -lGLEW
BUILDDIR = ./build/linux/
endif
# Build target
TARGET = test
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LFLAGS) $? -o $(TARGET) $(LIBS)
$(OBJS): $(BUILDDIR)%.o : $(SOURCEDIR)%.cpp
#mkdir -p $(dir $#)
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf $(BUILDDIR)*.o $(BUILDDIR)**/*.o $(TARGET)
I was really glad when it actually compiled everything! Except when I made a change to a file, and tried to make it again, it spat this at me:
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [test] Error 1
Thing is, when I make it once more, it works just fine. The problem seems to be with resolving dependencies? And for that, I need to specify a VPATH? Well, that's the closest I've gotten, except trying to specify a VPATH hasn't made a difference. I'm probably specifying it incorrectly, or then I'm taking the wrong approach to this.
I'm pretty inexperienced when it comes to Makefiles, so I'd really appreciate some guidance!
Thanks to Etan Reisner for the solution. The problem was with the difference between $? and $^. Here's the fixed version:
UNAME := $(shell uname)
# Directories
SOURCEDIR = src/
BUILDDIR = build/
# Compiler options
CC = clang++
DEBUG = -g
CFLAGS = -std=c++11 -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
# Files
SRC = $(wildcard $(SOURCEDIR)*.cpp) $(wildcard $(SOURCEDIR)*/*.cpp)
OBJS = $(SRC:$(SOURCEDIR)%.cpp=$(BUILDDIR)%.o)
ifeq ($(UNAME), Darwin)
LIBS = -lglfw3 -framework OpenGL -lglew -framework IOKit -framework CoreFoundation -framework ApplicationServices -framework Foundation -framework AppKit
BUILDDIR = ./build/osx/
endif
ifeq ($(UNAME), Linux)
LIBS = -lglfw -lGL -lGLEW
BUILDDIR = ./build/linux/
endif
# Build target
TARGET = test
all: $(TARGET)
$(TARGET): $(OBJS)
$(CC) $(LFLAGS) $^ -o $(TARGET) $(LIBS)
$(OBJS): $(BUILDDIR)%.o : $(SOURCEDIR)%.cpp
#mkdir -p $(dir $#)
$(CC) $(CFLAGS) $< -o $#
clean:
rm -rf $(BUILDDIR)*.o $(BUILDDIR)*/*.o $(TARGET)
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