qt project file Library includes - c++

I know that the library required can be loaded with
LIBS += -L/path/to/lib
recently I have found something like this
LIBS += -L. -L/usr/lib -lphonon -lcurl -ltag -fopenmp -lsayonara_gstreamer
What does "-L." means ?

Uppercase -L increments the libraries search path, while lowercase -l add a library. Then -L. add the build directory as possible recipe of some of the listed libraries.

Related

Program compiles, but cannot run because of missing library that exists

I have an OpenGL program. I have all the include directories, and everything.
Directory Structure:
Main.cpp
Lib/
GL/
GLEW/
glm/
I compile the program by running:
g++ main.cpp -lGL -lm -lX11 -lpthread -lXi -lXrandr -ldl -I. -lglfw -Llib/ -o main -lGLEW
The error is on -lGLEW. The program compiles with no errors, but when I run ./main, it gives me this:
Error while loading shared libraries: libGLEW.so.2.2: No such file or directory.
This is confusing, as in my lib/ directory, libGLEW.so.2.2 is present, so is libGLEW.so and libGLEW.a.
Can someone please help me?
When running a dynamic linked executable, the linker must be able to find all the libraries it needs. It always searches
a list of fixed default paths like /lib and /usr/lib
additional paths defined by the environment variable LD_LIBRARY_PATH
any non-standard paths hard-coded in the binary by the -Wl,-rpath g++ option.
These are your options for making this non-standard library known to the runtime linker.
So either use export LD_LIBRARY_PATH=<somepath>/lib when running or use -Wl,-rpath=<somepath>/lib (with comma and without spaces) when building.

Create shared .so library that has all it's dependencies statically linked

I am trying to build my .so library with all dependencies (mostly boost) statically linked. Currently, I can build statically linked static library and dynamically linked shared library:
I would like to add other dependencies to .so library so that it has 20MB and does not require user to install anything. Note that this is just a temporary solution before we upgrade to new Boost 1.55 on production servers.
I define libraries like this in Makefile ($ARCH can be either 32 or 64):
## Multi-arch library locations
LIB32=/usr/lib/i386-linux-gnu/
LIB64=/usr/lib/x86_64-linux-gnu/
LIBDIR:=$(LIB$(ARCH))
##Library directory
LIB=-L $(LIBDIR)
## DYNAMIC
LIBS=-lboost_serialization -lboost_thread -lboost_date_time -lboost_signals -lboost_iostreams -lboost_system -llog4cplus -lcrypto -lssl -lm
## STATIC
SLIBS=$(LIBDIR)libboost_serialization.a $(LIBDIR)libboost_thread.a $(LIBDIR)libboost_date_time.a $(LIBDIR)libboost_signals.a $(LIBDIR)libboost_iostreams.a $(LIBDIR)libboost_system.a $(LIBDIR)liblog4cplus.a
Shared lib with dynamic linking:
This is my shared lib GCC command:
Makefile:
$(CXX) $(CFLAGS) $(INCLUDE) $(LIB) $(LIBS) -shared -Wl,-soname,$(SHARED_LIB_VERSION) -o $(NEW_LIB_DIR)${SHARED_LIB_VERSION} $(OBJ_CPP_DYN) $(OBJ_C_DYN)
Changes into:
g++ -m64 -Wl,--trace -D NDEBUG -I /usr/include/ -I /usr/local/include -L /usr/lib/x86_64-linux-gnu/ -shared -lboost_serialization -lboost_thread -lboost_date_time -lboost_signals -lboost_iostreams -lboost_system -llog4cplus -lcrypto -lssl -lm -Wl,-soname,libLIBNAMEx64.so -o ../Release/libLIBNAMELIBNAMEx64.so ... and much more .o files ...
Linker says:
-lboost_serialization (/usr/lib/x86_64-linux-gnu//libboost_serialization.so)
-lboost_thread (/usr/lib/x86_64-linux-gnu//libboost_thread.so)
-lboost_date_time (/usr/lib/x86_64-linux-gnu//libboost_date_time.so)
-lboost_signals (/usr/lib/x86_64-linux-gnu//libboost_signals.so)
-lboost_iostreams (/usr/lib/x86_64-linux-gnu//libboost_iostreams.so)
-lboost_system (/usr/lib/x86_64-linux-gnu//libboost_system.so)
-llog4cplus (/usr/lib/x86_64-linux-gnu//liblog4cplus.so)
-lcrypto (/usr/lib/x86_64-linux-gnu//libcrypto.so)
-lssl (/usr/lib/x86_64-linux-gnu//libssl.so)
And it works.
Shared lib with static linking:
I thought I can just replace -shared with -static:
g++ -m64 -Wl,--trace -D NDEBUG -I /usr/include/ -I /usr/local/include -L /usr/lib/x86_64-linux-gnu/ -static -lboost_serialization -lboost_thread -lboost_date_time -lboost_signals -lboost_iostreams -lboost_system -llog4cplus -lcrypto -lssl -lm -Wl,-soname,libLIBNAMEx64_static_link.so -o ../Release/libLIBNAMEx64_static_link.so ... and much more .o files ...
But I get undefined reference errors everywhere.
So where do I configure how are dependencies linked with my binary? How can I achieve my goal?
More things I tried (edit)
-Wl,--library:
I also tried passing libraries directly to linker in a very assertive manner:
-Wl,--library=:/usr/lib/x86_64-linux-gnu/libboost_serialization.a
And without : (which prevents searching for .a):
-Wl,--library=/usr/lib/x86_64-linux-gnu/libboost_serialization.a
But I get the error:
/usr/bin/ld: cannot find -l/usr/lib/x86_64-linux-gnu/libboost_serialization.a
Of course, the file exists at that path.
Pass just library names:
Of course, here it's not even interpreted as linking command:
g++: error: libboost_serialization.a: No such file or directory
Interesting is that if I pass full path instead (/usr/lib/x86_64-linux-gnu/libboost_iostreams.a), GCC doubles it:
g++: error: /usr/lib/x86_64-linux-gnu//usr/lib/x86_64-linux-gnu/libboost_signals.a: No such file or directory
Use command man ld, I got this information:
-static
Do not link against shared libraries. It affects library searching for -l options which follow it. This option also implies --unresolved-symbols=report-all. This option can be used with -shared. Doing so means that a shared library is being created but that all of the library's external references must be resolved by pulling in entries from static libraries.
This option is exactly what you want: create a shared library with all dependencies (mostly boost) statically linked.
-l parameter is used to specify the library name, so you should use boost_serialization instead of /path/libboost_serialization.a:
-larchive
If you specify -lcommon, then ld will search its path-list for occurrences of "libcommon.a" for every common specified.
You can use -L parameter many times to specify the library paths when ld try to search static libraries:
-Lsearchdir
For example:
-L/usr/lib/x86_64-linux-gnu/
You could try -Wl,--whole-archive ${your library} -Wl,--no-whole-archive.

Including headers from /usr/local/include and libraries from /usr/local/lib

I have just installed GLFW on OS X 10.9. The headers were installed to /usr/local/include and the library was installed in /usr/local/lib.
I am wondering what else I would have to do to get my C++ program to include the headers like #include "GLFW/glfw3.h" rather than specifying the whole path like #include "usr/local/include/GLFW/glfw3.h".
Same thing goes for the library because as of now I can't even link the library using -lglfw3. Thanks in advance.
You would pass -I /usr/local/include to the compiler as preprocessor flag, and -L /usr/local/lib to the compiler as linker flag. So to build a single source application small.cc compile it as
g++ -Wall -I /usr/local/include -L /usr/local/lib \
small.cc -o small -lglfw3
If building with make just have
CXXFLAGS += -I/usr/local/include
LDFLAGS += -L/usr/local/lib
in your Makefile
If using shared libraries, add once /usr/local/lib to /etc/ld.so.conf and run ldconfig (at least on Linux).

QMake Linking Problem With GCC

I have a problem with qmake and the make file that it generates. My program needs to be linked against two libraries. I add them in main.pro as follows.
LIBS += -L lib/somelib1/bin -lsomelib1 -L lib/somelib2/bin -lsomelib2
How ever I arrange the above line qmake tells gcc this.
g++ -o programname someobject.o -L lib/somelib1/bin lib/somelib2/bin -lsomelib1 -lsomelib2
The problem is that it should look like this.
g++ -o programname someobject.o -L lib/somelib1/bin -L lib/somelib2/bin -lsomelib1
-lsomelib2
GCC gives the following error.
lib/somelib2/bin: file not recognized: Is a directory
Thanks in advance.
You should not put spaces between the flags and the arguments:
LIBS += -Llib/somelib1/bin -lsomelib1 -Llib/somelib2/bin -lsomelib2
Or
LIBS += -L"lib/somelib1/bin" -lsomelib1 -L"lib/somelib2/bin" -lsomelib2
And why are your static/import libraries in the "bin" directory? There should be .a files in the "lib" directory.
You could try putting the library search paths under the QMAKE_LIBDIR tag. So your qmake file would have:
QMAKE_LIBDIR += lib/somelib1/bin lib/somelib2/bin
LIBS += -lsomelib1 -lsomelib2

"undefined reference" when linking against a static library

g++ (Ubuntu/Linaro 4.4.4-14ubuntu5) 4.4.5
I have the following static library called sdpAPI.a. I am having problems trying to link it with my test application. Just wondering if I am doing something wrong. The static library has been built with g++;
My directory is as follows:
/projects/unit_test/main.c
/projects/unit_test/sdp/inc/sdpAPH.h
/projects/unit_test/sdp/lib/sdpAPI.a
My source code is this:
#include <stdio.h>
#include "sdpAPI.h"
int main(void)
{
printf("----- TEST SDP ------\n");
try {
sdpSessionDescription sdp;
sdp.clear();
}
catch(...) {
printf("----- TEST FAILED --------\n");
return 0;
}
printf("------ TEST SUCCESSFULL ------\n");
return 0;
}
And my Makefile is this:
OBJECT_FILES = main.o
CC = g++
CFLAGS = -Wall -Wextra -Wunreachable-code -ggdb -O0
TARGET = sdp_demo
INC_PATH = -I sdp/inc
LIB_PATH = -L sdp/lib/sdpAPI.a
$(TARGET): $(OBJECT_FILES)
$(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET)
main.o: main.c
$(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) -c main.c
clean:
rm -f $(TARGET) $(OBJECT_FILES) *~
These are the linker errors I am getting:
undefined reference to `sdpSessionDescription::sdpSessionDescription()'
undefined reference to `sdpSessionDescription::clear()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'
undefined reference to `sdpSessionDescription::~sdpSessionDescription()'
Many thanks for any suggestions,
-L specifies the library path, not a specific library. You probably want -L sdp/lib -l sdpAPI to specify both the path and the library name.
Although it will try to prefix and postfix your library name with lib and either .a or .sl (or similar).
So you may also need to rename your library to libsdpAPI.a as per the gcc manpage:
-l xyz
The linker searches a standard list of directories for the library, which is actually a file named libxyz.a.
Also keep in mind that the order of things in the command line matters. By doing $(CC) $(CFLAGS) $(INC_PATH) $(LIB_PATH) $(OBJECT_FILES) -o $(TARGET) (libraries before objects), there are no unresolved symbols at the point where you list the library, so nothing will be brought in from that library.
Then, when you finally bring in the objects (with their unresolved symbols), they stay unresolved because there are no libraries listed after that.
You should usually do libraries after objects:
$(CC) $(CFLAGS) $(INC_PATH) $(OBJECT_FILES) $(LIB_PATH) -o $(TARGET)
to ensure all unresolved symbols are known before checking the libraries.
This won't catch all problems (such as co-dependent libraries which can be fixed using other means) but it will ensure all unresolved symbols in the object files are known about before looking at the libraries.
From the same section of the man page quoted above:
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
-L is used to specify a library path :
-Ldir Add directory dir to the list of directories to be searched for -l.
-l is what you need to specify which library to link against :
-l library Search the library named library when linking.
You probably need -L sdp/lib/ -l sdpAPI
How exactly the different options especially -l and -static worked confused me for a long time. Finally did a man gcc to get more details that I wasn't able to find online. Hope this helps someone else too
-llibrary
-l library
Search the library named library when linking. (The second
alternative with the library as a separate argument is only for
POSIX compliance and is not recommended.)
It makes a difference where in the command you write this option;
the linker searches and processes libraries and object files in the
order they are specified. Thus, foo.o -lz bar.o searches library z
after file foo.o but before bar.o. If bar.o refers to functions in
z, those functions may not be loaded.
The linker searches a standard list of directories for the library,
which is actually a file named liblibrary.a. The linker then uses
this file as if it had been specified precisely by name.
The directories searched include several standard system
directories plus any that you specify with -L.
Normally the files found this way are library files---archive files
whose members are object files. The linker handles an archive file
by scanning through it for members which define symbols that have
so far been referenced but not defined. But if the file that is
found is an ordinary object file, it is linked in the usual
fashion. The only difference between using an -l option and
specifying a file name is that -l surrounds library with lib and .a
and searches several directories.
-static
On systems that support dynamic linking, this prevents linking with
the shared libraries. On other systems, this option has no effect.
This option will not work on Mac OS X unless all libraries
(including libgcc.a) have also been compiled with -static. Since
neither a static version of libSystem.dylib nor crt0.o are
provided, this option is not useful to most people.
-Ldir
Add directory dir to the list of directories to be searched for -l.
Three flags you need to know:
-Ldir
-lLIB
-static
Since you want to link with static library, you need the third flag. Otherwise, you will end up with linking with a dynamic library.