Linker cannot find library file with explicit path - linux

In my makefile, I have specified a library dependency as follows:
LDFLAGS := -l/home/karnivaurus/OpenCV-3.0.0/build/lib/libopencv_core.so
all: $(DYNAMIC_NAME)
$(DYNAMIC_NAME): $(OBJS) | $(LIB_BUILD_DIR)
# echo LD -o $#
$(Q)$(CXX) -shared -o $# $(OBJS) $(LINKFLAGS) $(LDFLAGS) $(DYNAMIC_FLAGS)
Now, if I run make all, I get the following error:
/usr/bin/ld: cannot find -l/home/karnivaurus/Libraries/OpenCV-3.0.0-RC1/build/lib/libopencv_core.so
However, in the directory /home/karnivaurus/Libraries/OpenCV-3.0.0-RC1/build/lib, there is definitely a file called libopencv_core.so. I have checked the spelling many times!
Are there any reasons why the linker cannot find this file, even though I have explicitly specified its exact location and passed that to the linker?
Thanks!

Either use -L for the library path and -lopencv_core:
LDFLAGS := -L /home/karnivaurus/OpenCV-3.0.0/build/lib/ -lopencv_core
or just include the full path to the .so file without -l.
LDFLAGS := /home/karnivaurus/OpenCV-3.0.0/build/lib/libopencv_core.so

Related

Linking issue in Cross Compilation for arm in linux using aarch64-linux-gnu-

I got an error when try to link (-aarch64-linux-gnu-ld) (the script containing the Makefile was downloaded from https://github.com/Icenowy/aw-el2-barebone). Error is "aarch64-linux-gnu-ld: Error: unable to disambiguate: -nostartfiles (did you mean --nostartfiles ?)
make: *** [Makefile:31: el2-bb.elf] Error 1" How to recode the line 31? of the Makefile
CROSS_COMPILE = /usr/bin/aarch64-linux-gnu-
DEBUG = 1
CC = $(CROSS_COMPILE)gcc
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
INCLUDES = -I ./include -I ./uboot-headers -ffreestanding
DEFINES = -DSOC_HEADER="\"h6.h\""
ifneq ($(DEBUG),1)
DEFINES += -DNDEBUG
endif
ASFLAGS = $(INCLUDES) $(DEFINES) -D__ASSEMBLY__
CFLAGS = $(INCLUDES) $(DEFINES) -O2
LDSCRIPT = ldscripts/a64.ld
LDSCRIPTS = ldscripts/a64.ld ldscripts/common.ld
LDFLAGS = -nostdlib -nostartfiles -static -T $(LDSCRIPT)
OBJS = start.o init.o uart.o stack.o exceptions.o exception_funcs.o panic.o pgtables.o trapped_funcs.o
all: el2-bb.bin
el2-bb.elf: $(OBJS) $(LDSCRIPTS)
$(LD) $(LDFLAGS) $(OBJS) -o $#
el2-bb.bin: el2-bb.elf
$(OBJCOPY) -O binary $< $#
.PHONY: clean
clean:
rm -f el2-bb.* *.o
-nostartfiles is a gcc option but not an ld option.
If you use gcc to invoke the linker (say with LD=gcc in your Makefile) for making a standalone program that does not use standard startup files, you should use -nostartfiles because gcc links the startup files by default and -nostartfiles disables this.
ld doesn't links any startup files by default, so there is no option to disable linking them. You always pass startup files explicitly to ld. If you don't want startup files, just don't pass them to ld.
In order to see what startup files on your system are create an empty C program:
int main(){}
and compile it:
gcc -c empty.c
gcc -v empty.o
You are likely to see an invocation of ld (or perhaps of collect2, which calls ld) with a long, long list of options and object files.
Now run
gcc -nostartfiles -v empty.o
The .o files are now gone. That's exactly what -nostartfiles does.
When you invoke ld empty.o, these files and options are not there to begin with. In order to make a working program for say a Linux system, you need to pass most of them to ld explicitly. If you are building a program for something other system, you may not need some or all of them. So just don't pass them in.

How do I correctly link a shared object (.so file) in a makefile when cross-compiling?

I have some C++ code on an openSuse platform that I need to compile to be executed on a different linux-based target. Part of the code is a dynamic library libfoo.so. I compile everything with make and then copy the compiled executable prog together with the libfoo.so to the target. When I then run the executable, I get some errors indicating the libfoo could not be initialized. I've tried everything I could find to tell the executable where it can find the libfoo.so but I still get the error.
Could anybody tell me what I am doing wrong here? I feel like it could be an error in the Makefile.
I am very new to C++ and using Makefiles in general, and on top of it all, the target runs kind of a proprietary linux version, so I cannot provide much information about it. I do have the appropriate compiler for it though.
My directory structure on the openSuse platform:
|src
|--Foolib
|----foolib.h
|----libfoo.so
|--Otherlib
|----otherlib.h
|----otherlib.hpp
|---+OtherlibSrcDirectory
|--bar.cpp
|--bar.h
|--Makefile
Directory structure on the target:
|program
|--libfoo.so
|--prog
My Makefile:
LIBS = -LFoolib -lfoo
INC = -I OtherLib -I Foolib
CXXFLAGS += -lpthread -std=c++11 -D_GLIBCXX_USE_NANOSLEEP $(INC)
LDFLAGS = '-Wl,-rpath,$$ORIGIN'
SRC_FILES = bar.cpp
OBJ = $(SRC_FILES:%.cpp=%.o)
prog: $(OBJ)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(LIBS) -o $# $^
%.o: %.cpp
$(CXX) $(CXXFLAGS) $(LIBS) -c $<
Basically, bar.h includes Foolib/foolib.h as well as Otherlib/OtherlibSrcDirectory and bar.cpp includes bar.h. Then some functions from foolib.h are called in bar.cpp and they return error values. If necessary I can provide some more insights into the code but I'll leave it out for now to keep it a bit shorter.
Any help would be highly appreciated!
Found my mistake.
libfoo.so was already on the target machine and it was located in the correct folder (/lib). My program had been able to find it without problems.
My mistake: I executed my program on the target machine without root permissions.
Without root permissions, I am not allowed to initialize Foolib.
sudo ./prog fixed everything.

Makefile searching for a library file

In an auxiliary make file (named arch.make) which contains some libraries, I have wrote
FFLAGS=-g -O2
FPPFLAGS= -DMPI -DFC_HAVE_FLUSH -DFC_HAVE_ABORT
LDFLAGS=-L/export/apps/computer/lapack-3.2
LAPACK_LIBS=-llapack_LINUX
LIBS=$(LAPACK_LIBS)
Then, the Makefile contains
siesta: check-siesta what version $(MPI_INTERFACE) $(FDF) $(WXML) $(XMLPARSER) \
$(COMP_LIBS) $(ALL_OBJS)
$(FC) -o siesta \
$(LDFLAGS) $(ALL_OBJS) $(FDF) $(WXML) $(XMLPARSER) $(MPI_INTERFACE)\
$(COMP_LIBS) $(FoX_LIBS) $(LIBS)
Other variables are fine. Please note $(LIBS) and $(LDFLAGS) which are defined in arch.make.
That library file really exists according to
root#cluster:ObjPar# ls /export/apps/computer/lapack-3.2/lapack_LINUX.a -l
-rw-r--r-- 1 root root 18296682 Jul 10 20:50 /export/apps/computer/lapack-3.2/lapack_LINUX.a
However, the make process exits with the following error
......
dc_lapack.a `FoX/FoX-config --libs --wcml` -llapack_LINUX -lblas
/usr/bin/ld: cannot find -llapack_LINUX
collect2: ld returned 1 exit status
There are many lines before that but I omitted them.
What should I do?
The linker does not find a file called liblapack_LINUX.a or liblapack_LINUX.so. You will need to point to the file directly with
LAPACK_LIBS=/export/apps/computer/lapack-3.2/lapack_LINUX.a
The LDFLAGS variable may be removed.
You are likely to have to link the BLAS library in this way as well if the library is not called libblas.a or libblas.so. The order of linking may also be important. BLAS before LAPACK.

Struggling with a GCC Makefile

I am trying to write what I thought would be quite a simple Makefile and I'm just baffled! I'm not a makefile writer, but I thought I understood them enough to be able to get a simple one working.
Okay, I have a small project in a directory and also in this directory is a libs directory containing many .c files. What I'm trying to do is write a makefile that will build the contents of the /libs directory into a static lib file in the /libs directory and then compile a few source files in the / directory and link it against the built .a file.
I'm sure someone's going to suggest "why not use cmake", but that's not answer I'm looking for (waves hand like a Jedi.. ehehehehe)
CC = gcc
CFLAGS = -Wall
SOURCES = lzx.c csum.c dirs.c listner.c tree.c
OBJECTS = $(SOURCES:.c=.o)
TARGETLIB = libs/mylib.a
TARGET = TestApp
libs/%.o : libs/%.c
$(CC) $CFLAGS -c $<
$(TARGETLIB) : $(OBJECTS)
ar rcs $# $^
$(TARGET) :
$(CC) $CFLAGS Source1.cpp Source2.cpp -llibs/mylib.a -o $#
My understanding was that the first recipe, would compile all the .c files into objects, but it seems to compile the first .c file and then stop.
Any help anyone could give me would be appreciated.
Since Your final app is TARGET, You should make it first Makefile rule. And since it also depends on TARGETLIB it should be given as dependency, like so:
$(TARGET): $(TARGETLIB)
$(CC) $(CFLAGS) Source1.cpp Source2.cpp -Lmylib -o $#
next I assume that *.c files You mentioned are lib files. Thus You will need a prefix to them, since You want to specify them by hand, not via wildcard or rule.
OBJECTS = $(addprefix(libs, $(SOURCES)):.c=.o)
and last thing that comes to my mind is library name, which supposed to be libSOMENAME.a (well, linker searches for this name in path and -Lotherpaths). So we have:
TARGETLIB = libs/libmylib.a
summing it all up:
CC = gcc
CFLAGS = -Wall
SOURCES = lzx.c csum.c dirs.c listner.c tree.c
OBJECTS = $(addprefix(libs, $(SOURCES)):.c=.o)
TARGETLIB = libs/libmylib.a
TARGET = TestApp
$(TARGET) : $(TARGETLIB)
$(CC) $(CFLAGS) Source1.cpp Source2.cpp -static -L./libs -lmylib -o $#
$(TARGETLIB) : $(OBJECTS)
ar rcs $# $^
And yes, this could be written much better, but I assume if You wanted to learn more about Makefiles or linker, and not just shown where You made mistakes, You'd know how to find manual pages.

Cannot compile with makefile - undefined reference to `boost::re_detail

I got an assignment to improve running time of some code. The only problem is, I can't even compile it to run it on my machine in the first place. Every time I try, it stops somewhere in the midst of compiling saying this:
"undefined reference to `boost::re_detail::put_mem_block(void*)'
collect2: ld returned 1 exit status make: * [cpu] Error 1"
This is how makefile looks:
SHELL = /bin/bash
OBJECTS = main.o atom.o molecule.o charges.o pdb.o asa.o amino.o chain.o addition.o string_operation.o pdb_peptide.o protein_chain.o residue_atom.o chain_residue.o residue_contact.o atom_grid.o circles.o atom_space_calculations.o
OBJDIR = obj
VPATH = src:src/ext:$(OBJDIR)
CFLAGS = -O3 -Wall -lm -lboost_regex -L/usr/local/boost/lib
HDIRS = src,src/ext,src/qt_redistributable, usr/lib, usr/local/lib, usr/local/lib/include/boost, /usr/local/lib/lib/
IOPTS = $(addprefix -I, $(HDIRS))
cpu : $(addprefix $(OBJDIR)/, $(OBJECTS) $(CPUOBJS))
g++ $(CFLAGS) -o mcpu $^
$(OBJDIR)/%.o : %.cpp
g++ $(CFLAGS) $(IOPTS) -c $< -o $#
clean :
rm obj/*.o $(PROG)
I'm using Linux Mint x64 and I have tried everything I googled out. Installed the whole boost library in usr/local/lib (for no obvious reason because it didn't help), tried to edit LD PATH (I'm very new to Linux and I have no idea if that went right) and lots of stuff, but this thing doesn't seem to go through. Any help appreciated.
One problem with your makefile happens when you link your program. As you can see in these questions with g++ the order of your arguments at link time is really important. You need to put your libraries after your object files. One easy way to solve would be separating your linker flags (LDFLAGS) from the compiler flags (CFLAGS), and then putting LDFLAGS after $^ (your object files) in the link command.
CFLAGS = -O3 -Wall
LDFLAGS = -L/usr/local/boost/lib -lm -lboost_regex
cpu : $(addprefix $(OBJDIR)/, $(OBJECTS) $(CPUOBJS))
g++ $(CFLAGS) -o mcpu $^ $(LDFLAGS)
$(OBJDIR)/%.o : %.cpp
g++ $(CFLAGS) $(IOPTS) -c $< -o $#
As can be seen in the Catalogue of Built-In Rules:
Linking a single object file
n is made automatically from n.o by running the linker (usually called
ld) via the C compiler. The precise recipe used is:
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
and Variables Used by Implicit Rules:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker,
ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable
instead.
So in this case -lboost_regex should be set or added to LDLIBS, not LDFLAGS.

Resources