MakeFile: error: <jni.h>: No such file or directory - c

I am trying to call java from c, and I have made the following MakeFile:
include ../../Makefile.defs
auto_gen=
NAME=libproto.so
CC=gcc
CFLAGS= -g -Wall -fPIC
LIBS= -L'$(LD_LIBRARY_PATH)' -ljvm -I"/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64/include/" -I"/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64/include/linux" -I"/usr/local/lib64/kamailio/"
include ../../Makefile.modules
SOURCE=jni_wrapper.c ProtoType.c
OBJECTS=$(SOURCE:.c=.o)
all: $(SOURCE) $(NAME)
%.o: %.c
$(CC) $(CFLAGS) -c $(LIBS) $<
clean:
rm -f $(EXEC); rm -f *~; rm -f .*.swp; rm -f .*.swo; rm -f *.o
java:
javac ProtoType.java
jar cf ProtoType.jar ProtoType.class
javap -s -p ProtoType > sigs.txt
cat sigs.txt
When I compile with make I get an error like this:
error: <jni.h>: No such file or directory
I looked through many stackoverflow pages with a similar problem but they all have same solution which I already had implemented. They said you need to link the library path to jni.h.
As you can see in my MakeFile this is being done:
LIBS= -L'$(LD_LIBRARY_PATH)' -ljvm -I"/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64/include/" -I"/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64/include/linux" -I"/usr/local/lib64/kamailio/"
I triple checked the directories and the permissions and everything is fine.
Any Suggestions?

You need to add the end of your LIBS definition to the CFLAGS
CFLAGS= -g -Wall -fPIC -I"/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64/include/" -I"/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.91.x86_64/include/linux" -I"/usr/local/lib64/kamailio/"
LIBS= -L'$(LD_LIBRARY_PATH)' -ljvm
The -I include directories are used by the compiler not the linker. It's the compiler that can't find your .h file.
You may also want to change the targets as follows
%.o: %.c
$(CC) $(CFLAGS) -c $<
$(NAME): $(OBJECTS)
$(CC) $(OBJECTS) -o $# $(LIBS)
This will build you .so file.

Related

C library, makefile header dependencies

Let' say I have library project with a few folders:
build: where .o files go
lib: where the compiled static and dynamic libraries go
src: where the .c source files go
include: where the headers are placed
The problem is, everytime I change a header file and make doesn't perceive this (which is obvious why if you look at my Makefile) and says everything is up to date. I have manage to solve this with another project which wasn't a library, but with this one everytime I try something I end up with an error when the target is getting built. Here is the Makefile:
CC=gcc
CFLAGS=-g -O2 -Wall -Iinclude -rdynamic -DNDEBUG $(OPTFLAGS)
LDFLAGS=$(OPTLIBS)
SOURCES=$(wildcard src/*.c)
OBJECTS=$(patsubst src/%.c,build/%.o,$(SOURCES))
TARGET=lib/libdatastruct.a
SO_TARGET=$(patsubst %.a,%.so,$(TARGET))
# The Target lib
all: $(TARGET) $(SO_TARGET)
dev: CFLAGS=-g -Wall -Iinclude -Wall -Wextra $(OPTFLAGS)
dev: all
$(TARGET): CFLAGS += -fPIC
$(TARGET): build $(OBJECTS)
ar rcs $# $(OBJECTS)
ranlib $#
$(SO_TARGET): $(TARGET) $(OBJECTS)
$(CC) -shared -o $# $(OBJECTS)
build/%.o: src/%.c
$(CC) $(CFLAGS) -o $# -c $<
build:
#mkdir -p lib
#mkdir -p build
clean:
rm -rf lib build
I was able to solve this myself. Changed this:
build/%.o: src/%.c
$(CC) $(CFLAGS) -o $# -c $<
To this:
build/%.o: src/%.c
$(CC) $(CFLAGS) -MMD -o $# -c $<
include $(DEPS)
$(DEPS): ;
And added:
DEPS=$(patsubst %.o,%.d,$(OBJECTS))
After:
OBJECTS=$(patsubst src/%.c,build/%.o,$(SOURCES))
Generate a list of headers:
HEADERS := $(wildcard src/*.h)
and since you don't have any dependency files, simply ensure that all object files depend on all header files:
$(OBJECTS): $(HEADERS)
If any header is modified every object file is rebuild since any source file may include (and depend) on any header file.
If you don't want to rebuild everything after a header is changed, you can manually add specific dependencies, so that only the needed files are rebuilt. For example:
src/file.c: src/file.h
src/main.c: src/main.h src/file.h
Those dependencies can also be made automatically.

makefile exit with no reason when compile .pc and .c at the same time. very strange

I am using pro*c in AIX,I want make my .pc file compile to a .so libary. And link it. This is my directory:
ls
connect.pc func.c get_log.pc main.c makefile sql_err.pc
This is my makefile:
#Makefile
CC = cc -g -brtl
CFLAGS = -g -c
ESQL = proc
RM = rm -f
MYHOME = /home/xxx
OBJ = main.o func.o
LIBOBJ = get_log.o connect.o sql_err.o
DBINC = -I$(ORACLE_HOME)/precomp/public
DBLIB = -L$(ORACLE_HOME)/lib -lclntsh
INCLUDE = -I$(MYHOME)/include
.SUFFIXES: .pc .c .o
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
clean:
rm -f *.o *.lis
when I make I get this:
.......
cc -g -brtl -o sql_err.o -g -c sql_err.c -I/home/xxx/include -I/oracle/product/10.2.0/precomp/public -L/oracle/product/10.2.0/lib -lclntsh
rm -f sql_err.c
rm -f sql_err.lis
cc -g -brtl -qmkshrobj -o libmydb.so get_log.o connect.o sql_err.o -L/oracle/product/10.2.0/lib -lclntsh
mv libmydb.so /home/xxxlib
when it done mv libmydb.so ,it exit!!!without wrong message.why?? I also need my .c to compile to .o and finally to an executable file query link libmydb.so.
when I change the squeuce like this put .c.o before .pc.o:
query:$(OBJ)
cc -o $# $(OBJ) -L$(MYHOME)/lib -lmydb
mv $# $(MYHOME)/bin
func.o:func.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
main.o:main.c
$(CC) -c $(CFLAGS) $< $(INCLUDE)
.pc.o:
$(ESQL) include=$(MYHOME)/include iname=$*.pc
$(CC) -o $*.o $(CFLAGS) $*.c $(INCLUDE) $(DBINC) $(DBLIB)
$(RM) $*.c
$(RM) $*.lis
libmydb.so:$(LIBOBJ)
$(CC) -qmkshrobj -o $# $(LIBOBJ) $(DBLIB)
mv $# $(MYHOME)/lib
it give this message,although I have libmydb.so last step:
prepaid(wmfe)/home/xxx/src>make
cc -g -brtl -c -g -c main.c -I/home/xxx/include
cc -g -brtl -c -g -c func.c -I/home/xxx/include
cc -o query main.o func.o -L/home/xxx/lib -lmydb
ld: 0706-006 Cannot find or open library file: -l mydb
ld:open(): A file or directory in the path name does not exist.
make: 1254-004 The error code from the last command is 255.
Stop.
I can't handle this ,very strange,Help!!
By default make will make the first rule in your makefile, but it must not start with a dot. So the default rule in your makefile is libmydb.so and that is being built.
That rule is only dependent on the LIBOBJ and OBJ is not a dependency so it doesn't care about those. It doesn't exit with no reason, it exits because it has done the job you defined for it. There is no error to report.
If you change the order then the default rule is changed and it tries to compile query. This has no dependencies to the library, so it doesn't try to compile that.
If you want to compile everything you should have, for example, a rule all that lists the dependencies. In this case probably libmydb.so and query at least, in correct order. If this is the first rule it will be the default and your compilation will succeed.

Including a .h file and directing .o files to a directory: Make

I am trying to learn make files.
My directory Structure is
$ ls -R | grep ":$" | sed -e 's/:$//' -e 's/[^-][^\/]*\//--/g' -e 's/^/ /' -e 's/-/|/'
.
|-bin
|---exe
|---obj
|-build
|-include
|-lib
|-make
|-source
What I am trying to do is place my include file conversion.h in include folder, all .c files in source, makefile in make, compiled all .o files in bin/obj and exe in /bin/exe
I referred below posts:
makefile include *.h file in other directory
Using make to move .o files to a separate directory
my makefile is:
VPATH= ./../source
OBJDIR= ./../bin/obj
EXEDIR= ./../bin/exe
#vpath %.o $(OBJDIR)
CFLAGS= -Wall -c -I.
#INCLUDES= -I./../include
objects= binary.o hex.o octal.o
conversion: $(objects)
# gcc -Wall -o conversion $(objects) -I.
binary.o: binary.c conversion.h
gcc $(CFLAGS) $< -o $(OBJDIR)/$#
octal.o: octal.c conversion.h
gcc $(CFLAGS) $< -o $(OBJDIR)/$#
hex.o: hex.c conversion.h
gcc $(CFLAGS) $< -o $(OBJDIR)/$#
clean:
rm -rf $(OBJDIR)/*.o *.o *~ conversion
I am using cygwin.
My questions are:
1) I am not able to include my conversion.h from location ./../include
,-I. works fine if I copy conversion.h to make folder
-but as soon as I replace with -I./../include without any copy of conversion.h in make folder
I get below error
$ make
make: *** No rule to make target 'conversion.h', needed by 'binary.o'. Stop.
2) My makefile does place all .o files to /bin/obj but when I try to use vpath as shown below (instead of using manual placement like --o $(OBJDIR)/$#)
vpath %.o $(OBJDIR)
...
$(OBJDIR)/binary.o: binary.c conversion.h
gcc $(CFLAGS) $< -o $#
...
...
doing above replacement for all .o rules,does not place all .o files to bin/obj directory
Any help would be appreciated.
Thanks
You have to be explicit about the locations of the .h file, the .c files, the .o files, and the executable when you define the targets and their dependencies.
VPATH= ./../source
INCLUDEDIR= ./../include
OBJDIR= ./../bin/obj
EXEDIR= ./../bin/exe
#vpath %.o $(OBJDIR)
INCLUDES= -I./../include
CFLAGS= -Wall -c -I. $(INCLUDES)
objects= $(OBJDIR)/binary.o $(OBJDIR)/hex.o $(OBJDIR)/octal.o
$(EXEDIR)/conversion: $(objects)
# gcc -Wall -o conversion $(objects) -I.
$(OBJDIR)/binary.o: $(VPATH)/binary.c $(INCLUDEDIR)/conversion.h
gcc $(CFLAGS) $< -o $#
$(OBJDIR)/octal.o: $(VPATH)/octal.c $(INCLUDEDIR)/conversion.h
gcc $(CFLAGS) $< -o $#
$(OBJDIR)/hex.o: $(VPATH)/hex.c $(INCLUDEDIR)/conversion.h
gcc $(CFLAGS) $< -o $#
clean:
rm -rf $(OBJDIR)/*.o *.o *~ $(EXEDIR)/conversion
Since your header files are in a separate directory, make cannot locate them. Since it can't locate them, it tries to build them by looking for a target rule. Since it cant find a target, you get the error listed in your question.
The -I./../includes only affects the compiler's include search path. It does not affect how make looks for include.
If you want make to search for your header files you will need to add a vpath for the headers. You will likely get the same error for the source files since they are in a separate directory as well. Thus, you will need to add a vpath for the source files as well.
To get your original to work with vpath as opposed to explicit locations, try the following:
VPATH= ./../source
OBJDIR= ./../bin/obj
EXEDIR= ./../bin/exe
INCLUDES= -I./../include
vpath %.c $(VPATH)
vpath %.h $(INCLUDES)
vpath %.o $(OBJDIR)
CFLAGS= -Wall -c -I. $(INCLUDES)
As noted in my comment and the comments for your referenced question, it is not recommended to use vpath to locate object files.

Unable to link against BFD [duplicate]

This question already has answers here:
Trying to include a library, but keep getting 'undefined reference to' messages
(3 answers)
Closed 8 years ago.
I am trying to include this file in my project: http://cairo.sourcearchive.com/documentation/1.9.4/backtrace-symbols_8c-source.html
But it requires linking against BFD. I have both binutils and binutils-devel installed. I have tried linking with -lbfd as well as directly to /usr/lib64/libbfd.so and /usr/lib64/libbfd.a (which both do exist). I also tried searching pkg-config to see if there was a different flag I should be using, but there is no reference to BFD or binutils in pkg-config.
No matter what I've tried I get the following errors:
undefined reference to 'bfd_init'
undefined reference to 'bfd_openr'
undefined reference to 'bfd_check_format'
undefined reference to 'bfd_checkformat_matches'
undefined reference to 'bfd_close'
undefined reference to 'bfd_map_over_sections'
First I am compiling my logger and the backtrace-symbols.c file I linked to above (as the logger is where I intend to use this for printing traces). Then I am linking those two object files together into a combined object file:
CC = clang
CFLAGS = -g -Wall -c
SOURCE = simplog.c
OBJ = simplog.o, simplog-temp.o, backtrace-symbols.o
all:
$(CC) $(CFLAGS) $(SOURCE); mv simplog.o simplog-temp.o; \
$(CC) -ansi $(CFLAGS) backtrace-symbols.c; \
ld -r simplog-temp.o backtrace-symbols.o -o simplog.o
clean:
rm -f $(OBJ)
Then I am linking this object file into my main project:
CC= clang++
PROG= ./bin/chiplus8
OBJS= ./src/main.o ./src/Chip8.o ./src/EmuCPU.o ./src/SimpleLogger/simplog.o
LIBS=
CXXFLAGS= -g -Wall -std=c++11 $(shell pkg-config --cflags ${LIBS})
LDFLAGS= $(shell pkg-config --static --libs ${LIBS})
all: logger $(PROG)
$(PROG): $(OBJS)
mkdir -p ./bin/
$(CC) -g -rdynamic -o $(PROG) $(LDFLAGS) -lbfd -liberty $(OBJS)
rm -f $(OBJS)
logger:
cd ./src/SimpleLogger; make clean all
clean:
rm -f $(PROG) $(OBJS)
I'm really not sure what I need to do to get this to link properly anymore. Is there something I'm missing?
Change:
$(PROG): $(OBJS)
mkdir -p ./bin/
$(CC) -g -rdynamic -o $(PROG) $(LDFLAGS) -lbfd -liberty $(OBJS)
rm -f $(OBJS)
To this:
$(PROG): $(OBJS)
mkdir -p ./bin/
$(CC) -g -rdynamic -o $(PROG) $(LDFLAGS) $(OBJS) -lbfd -liberty
rm -f $(OBJS)
Object files have to be placed before libraries with the compilation command. See this question.

Adapt Makefile for cross-compilation

I have a makefile that works fine when I compile using /usr/bin/gcc to compile it. However I'm trying to compile it using a crosstool-ng compiler. I've changed CC to the cross-compilers location, and added a prefix to the directory that holds the compiler, but I get an error compiling.
The Makefile is here (sorry, it's long):
CFLAGS ?= -Wall -O0 -ggdb3
PREFIX = /home/me/crosstool-ng-1.18.0/x-tools/i586-system-linux-gnu/
CC = /home/me/crosstool-ng-1.18.0/x-tools/i586-system-linux-gnu/bin/i586-system-linux-gnu-gcc
ALL_CFLAGS = $(CFLAGS) -D_GNU_SOURCE
.phony: all
all: food libfood.so.1.0.0 foo_query
.phony: tools
tool tools: libfood_print foo_print
.phony: install
install: libfood.so.1.0.0
cp libfood.so.1.0.0 $(PREFIX)/lib
cd $(PREFIX)/lib ; \
ln -sf libfood.so.1.0.0 libfood.so.1 ; \
ln -sf libfood.so.1 libfood.so
cp libfood.h $(PREFIX)/include
cp foo_data.h $(PREFIX)/include
cp food $(PREFIX)/bin
cp foo_query $(PREFIX)/bin
%.o: %.c
$(CC) $(ALL_CFLAGS) -c $<
food: food.o foo.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lm -lpthread
libfood.so.1.0.0: libfood.o
$(CC) -shared -Wl,-soname,libfood.so.1 -o libfood.so.1.0.0 libfood.o
libfood_print: libfood_print.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lfood
foo_print: foo_print.o foo.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lm -lpthread
foo_query: foo_query.o
$(CC) $(ALL_CFLAGS) -o $# $^ -lfood
food.o: food.c foo.h foo_data.h
foo.o: foo.c foo.h foo_data.h
foo_print.o: foo_print.c foo_data.h
foo_query.o: foo_query.c foo_data.h
libfood.o: libfood.c libfood.h
$(CC) $(ALL_CFLAGS) -fPIC -c $<
foo_print.o: foo_print.c foo.h
.phony:clean
clean:
rm -rf *.o *~ food libfood.so.1.0.0 foo_print libfood_print foo_query
The error message I'm getting says cannot find -lfood
collect2: ld returned 1 exit status
If anyone could suggest a fix for this I'd be very grateful.
EDIT: My Solution:
I should probably have been clearer but this Makefile was being used to build a package that was included in buildroot. I tried the suggestion by Jonatan, but unfortunately I still got the same error. My workaround was to run buildroot using make -k, and then build again using make.
An easy way to solve this would be:
ALL_CFLAGS += -L$(PREFIX)/lib
If you really want to install your lib in the toolchain, you should look for the usr/lib directory, usually the path is TOOLCHAIN_DIR/TOOLCHAIN_PREFIX/sysroot/usr/lib
Check other binaries in the $(PREFIX)/lib directory, you will notice that they were compile to run in you host, and not in your target.
The files the compiler need to check dependencies, link, and execute in your target, are installed in the sysroot directory.

Resources