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.
Related
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.
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.
I have object code that I have compiled using -fPIC switch in clang that also used the -shared switch. I have then linked all of these into a single .so shared object. Now I want to link this into a single executable file, I'm told by the man page that I should be able to do this using the
ld command and the -l switch. But when I do this, I get the following error:
ld -r -L./ -l:libmymath.so simpleone
ld: attempted static link of dynamic object `libmymath.so'
make: *** [simpleone] Error 1
I have tried doing the same thing with the -dy switch, but it gives me the same error.
I really don't understand why this wouldn't be working.
Here is the makefile I am using to do all of this.
CC= clang
LD= ld -r
CFLAGS= -std=gnu99 -g -Oz -c
CSECFL= -fPIC -I -L
CFLAG3= -shared
RM= /bin/rm -f
OBJ= math.o my*.o
SO= libmymath.so
all: math my_add my_mul
math: math.c
$(CC) $(CFLAGS) $#.c $(CSECFL)
my_add: my_add.c
$(CC) $(CFLAGS) $#.c $(CSECFL)
my_mul: my_mul.c
$(CC) $(CFLAGS) $#.c $(CSECFL)
simplemath: $(OBJ)
$(CC) $(OBJ) -o $#
simplemath.o: $(OBJ)
$(LD) $(OBJ) -o $#
lib1: my_add.o
$(CC) $(CFLAG3) my_add.o -o $(SO)
lib2: $(OBJ)
$(CC) $(CFLAG3) my_mul.o -o $(SO)
lib3: $(OBJ)
$(CC) $(CFLAG3) math.o -o $(SO)
simpleone: $(OBJ)
$(LD) -L./ -l:libmymath.so $#
clean:
$(RM) *.o simplemath* *.t $(SO)
You need to link the objects (*.o) into a static executable, not the shared lib (.so) .so can be opened by the run-time dynamic linker or via a dlopen() call.
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.
I'm having problem reported as below while trying to execute it. Where should I go to let it know where to find the .so lib which is under ${HOME}/projects/OpenImageIO/dist/linux64/lib?
Starting: /home/chaoren/Dropbox/hw2/hw2_3
/home/chaoren/Dropbox/hw2/hw2_3: error while loading shared libraries: libOpenImageIO.so.1.2: cannot open shared object file: No such file or directory
I built this project by importing my Makefile
OFILES = Matrix.o LinearAlgebra.o PerlinNoise.o Camera.o OIIOFiles.o Image.o Utilities.o Grid.o SparceGrid.o VolumeOperations.o Ray.o Face.o Line.o Lights.o Group.o PolySurf.o File.o OBJFile.o Vector.o
AFILES = $(OFILES)
ROOTDIR = .
LIB = $(ROOTDIR)/libVR.a
LINKS = Magick++-config --cppflags --cxxflags --ldflags --libs -lm -lOpenImageIO -L/usr/local/lib -L${HOME}/projects/OpenImageIO/dist/linux64/lib
INCLUDES = Magick++-config --cppflags --cxxflags -I${HOME}/projects/OpenImageIO/dist/linux64/include
CXX = g++ -Wall -g -O2 -D_THREAD_SAFE -pthread -fopenmp
.C.o:
$(CXX) -c $(INCLUDES) $<
all: $(AFILES)
ar rv $(LIB) $?
hw2_1: hw2_1.C
$(CXX) hw2_1.C $(INCLUDES) $(LIB) $(LINKS) -o hw2_1
hw2_2: hw2_2.C
$(CXX) hw2_2.C $(INCLUDES) $(LIB) $(LINKS) -o hw2_2
hw2_3: hw2_3.C
$(CXX) hw2_3.C $(INCLUDES) $(LIB) $(LINKS) -o hw2_3
noiseimage: noiseimage.C
$(CXX) noiseimage.C $(INCLUDES) $(LIB) $(LINKS) -o noiseimage
clean:
rm -f *.o *.gch core $(LIB) vr vrppm *~ vRender hw2_1 hw_2 hw2_3
KDevelop4 uses CMake as its default build system. In CMake all libraries and other program elements are identified in special file (CMakeLists.txt). That file then becomes the basis of the make file that actually builds the executable.