22

I am learning OpenCV using Learning OpenCV book.

One problem I am facing while compiling the code is that I have to write a long command to compile and get the executable.

This is the command I am using

g++ `pkg-config –cflags opencv` file_name.cpp -o output_file `pkg-config –libs opencv`

I am no Make expert but I think I can eliminate writing that long command using make. Before that I should explain my work flow. I have created a directory called opencv in my home directory (~/opencv/). I am reading the book section by section and coding the examples or exercises into new cpp source code files in that directory. So I don't know the names of the files before hand.

Now what I want make to do is,

Suppose I have coded a new file named facedetect.cpp in my opencv directory, and if I call make like this

make facedetect

then I want make to execute the following command for me

g++ `pkg-config --cflags opencv` facedetect.cpp -o facedetect `pkg-config --libs opencv`

so that whenever I make a new file named abc.cpp, I will execute make abc so that I can run

$ ./abc

at my command line to test my abc.cpp

Please give that make file so that I can save the frustration of typing that long command each time.

PS: I have Googled for help on this and found this on using CMake but I could not understand what that does. Kindly also explain how can I use CMake for the same task.

Pranit Bauva
  • 152
  • 9
jumpdiffusion
  • 704
  • 1
  • 7
  • 22

3 Answers3

27

You can create a file called Makefile in you working directory like this:

CFLAGS = `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`

% : %.cpp
        g++ $(CFLAGS) $(LIBS) -o $@ $<

then you can use this file for all your single-file programms. Just call make with the basename of the file you want to compile. For facedetect.cpp that would be

make facedetect

Here some more details:

The general format of a makefile is like this:

target : dependecy1 dependenc2 ...
    command that generates the target

So for your example you could write:

facedetect : facedetect.cpp
    g++  $(CFLAGS) $(LIBS) -o facedetect facedetect.cpp

For each new example you can now create a new target. But you can also make it more general:

% : %.cpp
    g++  $(CFLAGS) $(LIBS) -o $@ $<

Here % matches any nonempty substring. The automatic variables $@ and $< substitute the names of the target file and the source file. For more information you can consult the make documentation.

sietschie
  • 7,425
  • 3
  • 33
  • 54
  • 9
    It looks like only `g++ $(CFLAGS) -o $@ $< $(LIBS)` will work. But I think that is a opencv thing. Thanks for the Makefile. Can u explain what does that mean or give any good resource to learn about Make – jumpdiffusion Mar 26 '12 at 14:57
  • Good resources about make: [make manual](http://www.gnu.org/software/make/manual/make.html). It's not as scary and hard to understand as it looks. – morynicz Mar 27 '12 at 07:30
  • 3
    Thanks Siva Prasad Varma, it was indeed the **order** of the arguments. `$(LIBS)` **must go at the end of the compilation command**, or OpenCV examples themselves will not compile! – Cosimo Jan 09 '13 at 13:49
  • 1
    You can just use `LDLIBS = \`pkg-config --libs opencv\`` without explicitly writing the build command. – nn0p Oct 06 '15 at 06:05
  • 1
    stackoverflow.com/questions/33530363/order-in-makefile also about the order. – mrgloom Nov 04 '15 at 20:02
6

GNU Make is pretty smart and the Makefile you need for this doesn't need to be as verbose as in the other answers given so far. Here is a simple Makefile which you can use to compile the OpenCV examples:

CPPFLAGS = $(shell pkg-config --cflags opencv)
LDLIBS = $(shell pkg-config --libs opencv)

That's it. The Makefile can be this short thanks to Make's implicit rules.

Then run make as usual:

make facedetect

This assumes there is a facedetect.c or facedetect.cpp in the same directory.

I recommend the following (free!) book if you want to learn Make: http://oreilly.com/catalog/make3/book/index.csp

Serrano
  • 1,457
  • 20
  • 17
  • today, you can simply install cmake(if not already installed => sudo apt-get install cmake); open a terminal; navigate to opencv folder; cmake .; make; note the "."(dot) after cmake, now, wait for everything to be built –  Oct 03 '14 at 12:17
  • 1
    @ComputerSaysNo: I think you misunderstood the question. He's not trying to compile OpenCV, but source files that he wrote himself from exercises in a book (which use the OpenCV libraries). – Serrano Oct 04 '14 at 15:42
  • ahhh, yes, misunderstood badly, I'm sorry –  Oct 04 '14 at 15:49
0

Create a file named makefile in your working directory that contains the following:

CFLAGS = $SHELL(pkg-config --cflags opencv)
LIBS = $SHELL(pkg-config --libs opencv)

facedetect : facedetect.cpp
    g++ $(CFLAGS) $(LIBS) -o $@ $<

Then when you want to compile you just type:

$ make

(To answer your PS - note that CMake is very different from make - for now you should probaby just use make.)

Paul R
  • 208,748
  • 37
  • 389
  • 560