1

I have the following makefile (for c++)

LDLIBS=$(shell root-config --libs)
INCLUDE= -I/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/include            \
         -I/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/include/darwin     \


foo: foo.o
        $(CXX) -shared -fPIC $(LDLIBS) $(INCLUDE) -o foo.o foo.cpp

foo.cpp has the following includes

#include <jvmti.h>

If I run the "g++ -shared -fPIC -I..." command manually, it'll produce the foo.o as expected.

But when I run make, I'll get this error

$ make                                                                                                                                 
c++    -c -o foo.o foo.cpp                                                                                                 
lib_track_npe.cpp:1:10: fatal error: 'jvmti.h' file not found                                                                                  
#include <jvmti.h>                                                                                                                             
         ^                                                                                                                                     
1 error generated.                                                                                                                             
make: *** [foo.o] Error 1  

Could someone please tell me what I did wrong in the makefile?

Thanks

One Two Three
  • 22,327
  • 24
  • 73
  • 114
  • can you post the command: `pwd` when you type it just after entering `g++ ... ` manually? – Amadeus Oct 18 '16 at 01:27
  • pwd is the current directory (where foo.cpp) is located. Please not that in my `-I`, I specified an absolute path. Hence, it shouldn't matter where I call it – One Two Three Oct 18 '16 at 01:30
  • Yes it should. Manually you pass -I.. which means that the parent directory is in search path – Amadeus Oct 18 '16 at 01:31
  • Ooh, actually that `...` (ie., ellipsis ) was meant as "etc" ;) – One Two Three Oct 18 '16 at 01:44
  • Oh I got it. So, in your original makefile, I guess you just declared wrongly your rule. I guess it should be: `foo.o : foo.cpp` – Amadeus Oct 18 '16 at 01:48

1 Answers1

4

The implicit make rule for building .o targets from .cpp sources does not use the INCLUDE variable. INCLUDE is not a standard variable used by default make rules. Your Makefile is dependent on the default make rules in order to build .o targets from .cpp sources.

The correct make variable for specifying preprocessor options is CPPFLAGS:

CPPFLAGS= -I/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/include            \
         -I/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/include/darwin     \

Additionally, your explicit make rule for linking foo from foo.o specifies all these -I optionals. Unfortunately, that accomplishes absolutely nothing, whatsoever. -I is used only when compiling .cpp sources. The -I option is not used at all, when linking, and is effectively ignored when linking. You should simply remove the $(INCLUDE) from your link command, without even replacing it with $(CPPFLAGS). It only causes confusion.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148
  • Oooh, I see. I, as a makefile novice, thought I could "declare" any variable (which is called INCLUDE in this case) and reference it! – One Two Three Oct 18 '16 at 01:34
  • 1
    You can declare and reference any variable you wish. But if you need to rely on default rules, declaring only the variables that are actually used by the default rules is going to accomplish anything useful. The default rule used here does not use `INCLUDE`. You can declare it, and use it however you wish, but the default rule will not use it. – Sam Varshavchik Oct 18 '16 at 01:35
  • Hmm, so how do I make it use it? – One Two Three Oct 18 '16 at 01:38
  • Define your own rule for building `.cpp` from `.o`, which can use whatever you want it to use. Just like you defined the rule to link foo from foo.o. In fact, existing frameworks based on make, such as GNU automake, will generate their own custom build rules, overriding make's default rules. – Sam Varshavchik Oct 18 '16 at 01:39