Ta.Da Ta.Da - 2 months ago 9
C++ Question

GNU make issue: "No rule to make target `pjsip.h', needed by `main.o'"

I have been working to write my first makefile and after following some tutorials and reading some links on stackoverflow I managed to write the file, what I am doing is


  • using .a files from the pjsip api, notice the variables PJSIP, PJLIB_UTIL and PJLIB

  • define the path to the .h file using the -I option, see the variables PJSIP_HDR, PJLIB_HDR and PJLIB_U_HDR



I get the following error:

make: ***No rule to make target `pjsip.h', needed by `main.o'. Stop.


It believe that it is usefull to mention that I have only 4 #includes in my .cpp file

#include <iostream>
#include <pjsip.h>
#include <pjlib-util.h>
#include <pjlib.h>


The goal is to have a file called main which I can excute, I am using Ubuntu 14.04 . Here is my makefile

CC = g++
DEBUG = -g
CFLAGS = -Wall -c $(DEBUG)
LFLAGS = -Wall $(DEBUG)
PJSIP = -L/home/ubuntu/pjsip/trunk/pjsip/lib -llibpjsip-simple-x86_64-unknown-linux-gnu.a -llibpjsip-ua-x86_64-unknown-linux-gnu.a -llibpjsip-x86_64-unknown-linux-gnu.a -llibpjsua2-x86_64-unknown-linux-gnu.a -llibpjsua-x86_64-unknown-linux-gnu.a
PJLIB = -L/home/ubuntu/pjsip/trunk/pjlib/lib -llibpj-x86_64-unknown-linux-gnu.a
PJLIB_UTIL = -L/home/ubuntu/pjsip/trunk/pjlib-utils/lib -llibpjlib-util-x86_64-unknown-linux-gnu.a
PJSIP_HDR = -I/home/ubuntu/pjsip/trunk/pjsip/include/
PJLIB_HDR = -I/home/ubuntu/pjsip/trunk/pjlib/include/
PJLIB_U_HDR = -I/home/ubuntu/pjsip/trunk/pjlib-utils/include

main: main.o
$(CC) $(LFLAGS) main.o -o main

main.o: main.cpp pjsip.h pjlib.h pjlib-utils.h
$(CC) $(CFLAGS) $(PJSIP_HDR) $(PJLIB_HDR) $(PJLIB_U_HDR) main.cpp $(PJSIP) $(PJLIB) $(PJLIB_UTIL)

clean:
\rm -f *.o


Any extra comments that might help me improve my makefile are welcomed

Thanks in advance

Answer

The problem is that you specify the pjsjp.h as dependency (i.e., after the ":" in the line for main.o target); but make doesn't know how to find the include file pjsip.h - it doesn't interpret the -I ... options, these are only for the g++ command.

You could try to specify an absolute path, something like this:

PJLIB_HEADER_DIR=/home/ubuntu/pjsip/trunk/pjlib/include
main.o: main.cpp $(HEADER_DIR)/pjlib.h ...

(...and similar for other headers) By the way, the "-I" option only accepts directories (see the g++ documentation on directory search), thus the definition of PJSIP_HDR with the header file name in it makes no sense, it should just be:

PJSIP_HDR = -I/home/ubuntu/pjsip/trunk/pjsip/include/

You probably added the header name because of the error?

The second, easier option is to simply remove those external dependencies. Just write

main.o: main.cpp

that is, leave out all the library header files. Dependecies are there to tell make to rebuild stuff if a dependency has changed. I assume those pjsip.h, pjlib.h, ... come from an external library which you are not changing often? Then making it a dependency in make isn't really necessary.

By the way, these days make files are hardly written by hand; they are typically generated by tools such as cmake.