How to link with libtiff - c++

How do I specify in my makefile that I want to link with the libtiff library. Just specifying -ltiff in LDFLAGS is not working.

Either you can use the -L flag (see either manual for the compiler - I am assuming that you are using gcc or g++
or
Set the environment variable LD_LIBRARY_PATH to include the path for the library
But you should also consider static or dynamic linking. The documentation for both compilers are very good to explain how to do either.

Try giving the following options for compilation.
g++ -L[path of libtiff on your machine] -ltiff [your remaining options] ...
-L option is used to tell gcc, where to find the librarires you are trying to link with.

Related

How can I override shared library in LD_LIBRARY_PATH with clang++?

I'm trying to compile a shared library I wrote in C++ to use a specific version of another shared library in the current directory, however it seems to be ignoring that and it uses the (older and incompatible) .so file in my LD_LIBRARY_PATH at runtime. How would I go about overriding the .so file it uses to use my own? I also need to retain the older version for another use on the same system.
Here's my command I'm using to compile: clang++ /data/openpilot/selfdrive/df/libs/libSNPE.so -lsymphony-cpu -lsymphonypower -I/data/openpilot/phonelibs/snpe/include -std=c++14 -lstdc++ -fPIC -o d_f.so dynamic_follow.cc -shared
/data/openpilot/selfdrive/df/libs/libSNPE.so being the library I want to use.
I also tried to use the -l flag before my library file, however it returns cannot find -l/data/openpilot/selfdrive/df/libs/libSNPE.so
Confirmed to still use the library in LD_LIBRARY_PATH with this command as well: clang++ -Wl,-rpath,/data/openpilot/selfdrive/df/libs -L/data/openpilot/selfdrive/df/libs -lSNPE -lsymphony-cpu -lsymphonypower -I/data/openpilot/phonelibs/snpe/include -std=c++14 -stdlib=libc++ -fPIC -o d_f.so dynamic_follow.cc -shared
The -L flag tells where to look for libraries at link time, while LD_LIBRARY_PATH tells where to look for libraries at run-time. So whatever path you set at link-time, this will be ignored when running the executable.
You need to have LD_LIBRARY_PATH include the directory of your dynamic library at run-time for your executable to find it. So you may run your executable like this:
LD_LIBRARY_PATH=/data/openpilot/selfdrive/df/libs:"$LD_LIBRARY_PATH" ./your-exec

C++ using functions from shared library

I have the following problem:
I have two separate c++ projects, and want to use certain functions from one of them in the other. I am compiling using g++, on Linux.
I decided to do this by creating a shared library out of the project from which to use the functions. I added -fPIC to the compiler flags in the Makefile and then created a shared library like this:
g++ -shared -Wl,-soname,libmyproject.so.1 -o libmyproject.so a.o b.o c.o -lc
Then I simply copied the .so file and the header files into the (parent) directory of the new project and added the following to its Makefile:
To LIBS:
-L/../external_proj/libmyproject.so
To CXXFLAGS:
-I/../external_proj
Then I #include the appropriate header file in the destination project code and try to call certain functions from the original project. However, when I compile the destination project I get an error "undefined reference" for the imported function.
My question is then: is there something I'm missing in this setup? Is there perhaps something that needs to be added to the headers in the original project in order to export the functions I want to use?
I should note this is the first time I have attempted to use a shared library in this way. Thanks.
The -L option only specifies the directory where the linker will search for libraries to link with. Then you will need to use the -l option to specify the base name of the shared library (without the "lib" prefix and the ".so" suffix).
But even that will unlikely to be enough. The runtime loader needs to find the shared library, when you attempt to try to execute it. -L and -l will be sufficient to successfully link, but the runtime loader only searches /usr/lib(64)?, and a few other places by default. It does NOT search the current directory, and the ELF binary only records the names of the shared libraries that must be loaded, and not their full pathnames. You have to explicitly record any extra directories to search for any shared libraries, which is the -rpath option.
To finish the job you will also need to pass -rpath to the linker, but g++ does not support this option directory, you will have to use -W to do that.
The full set of options you will likely need are:
-L/../external_proj -lmyproject -Wl,-rpath -Wl,`cd ../external_proj && pwd`
See gcc documentation for more information on the -W option.
Absolute pathnames should be used with -rpath, hence the need to obtain the full pathname to the directory where the shared library is.
The -L flag is to add a path to search libraries in. The -l (lower-case L) is for linking with a library in the search path.
Or you can skip the flags and link with the library directly, almost like you do now (but without the -L option).
If you use the -l option, then remember that for a file libname.so you use only name as the library name. As in -lname. The linker will search for the correct files with the added prefix and suffix.
And lastly an important note about the paths used when linking: If you use -L and -l to link with a shared library, it's only the linker which will find the library. The OS runtime-loader will not be able to see the path used and will not find the library, if it's in a non-standard location. For that you must also set the runtime-path using the special linker option -rpath.
Unfortunately the GCC frontend program g++ doesn't recognize that option, you have to use -Wl to tell g++ to pass on an option to the actual linker. As in -Wl,-rpath,/path/to/libraries.
To summarize, here are the different variants you can use:
Link directly with the library: g++ your_source.cpp ../external_proj/libmyproject.so
Use the -L and -l options: g++ your_source.cpp -L../external_proj -lmyproject
To set the runtime linker path: g++ your_source.cpp -L../external_proj -lmyproject -Wl,-rpath,../external_proj

Autotools - passing optional profiling library to configure script

I have built and installed a shared library to do some profiling of my projects via code instrumentation, specifically with the -finstrument-functions switch of gcc.
It is possible to turn the instrumentation on and off with the compiler switch, and hence I'd like to be able to turn the dependency to the profiling library on and off just by reconfiguring.
I can pass -finstrument-functions to gcc via configure's CFLAGS, but when I try to pass -lmylib via LDFLAGS configure fails with
configure:2796: checking whether we are cross compiling
configure:2804: gcc -o conftest -g -Wall -Wextra -Werror -lmylib conftest.c >&5
configure:2808: $? = 0
configure:2815: ./conftest
./conftest: error while loading shared libraries: libmylib.so.0: cannot open shared object file: No such file or directory
The file exists, I have double checked and compiling and linking a dummy example works as expected.
Interestingly, when I pass the full path to the shared library instead of -lmylib, the error persists, but when I pass the full path to the corresponding static library, configure runs smoothly, and everything is built as expected.
My question in a nutshell: Is there a possibility to pass optional shared libraries to autotools-generated configure scripts, without changing configure.ac?
Thanks,
Andy
It looks like your library is not in the compiler's default library search path.
You may also pass library search path through LDFLAGS with the -L switch:
CFLAGS=-finstrument-functions LDFLAGS="-lmylib -L/path/to/mylib" ./configure ....
fixed by running sudo ldconfig
I'll leave this here in case someone else has the same problem.

how to do static linking of libwinpthread-1.dll in mingw?

I use mingw from here: http://sourceforge.net/projects/mingwbuilds/files/host-windows/releases/4.7.2/32-bit/threads-posix/sjlj/x32-4.7.2-release-posix-sjlj-rev2.7z/download
And I've sucessfully managed to link statically libstdc++-6.dll and libgcc_s_sjlj-1.dll by using -static-libgcc -static-libstdc++ parameters, but I cannot find a command for doing the same with libwinpthread-1.dll.
If your toolchain includes the static winpthreads, adding the option
-static
Will pull in static versions of all libraries it can.
Alternatively, you can remove libwinpthread.dll.a and the DLL itself from the toolchain directories. This might mess up programs linking with libstdc++ and libgcc DLLs though, so be careful.
A third option is to use -Wl,-Bdynamic and -Wl,-Bstatic to select which version you want linked in (which is what -static internally does when ld is called). An example:
gcc -o someexec someobject.o -Wl,-Bdynamic -lsomelibIwantshared -Wl,-Bstatic -lsomelibIwantstatic
If you run your link command with -v added, you should see these options appearing in the ld/collect2 invocation when you use -static-libgcc and -static-libstdc++.
Try this:
-static-libgcc -static-libstdc++ -Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic
Notice the -lstdc++ before -lpthread. It worked for me.
Make sure to add this to the very end of your g++ command line.
You should probably check command line options documentation for GCC.
These's no '-static-something' command, only standard libraries (libgcc and libstdc++) can be set to static linking with one command. For other libraries, you first switch to static linking with "-static" and then list the libraries to include with separate commands, ie "-lpthread".
To statically link winpthread even if threading isn't used in the program, pass the -Bstatic and --whole-archive parameters to the linker:
g++ -o hello.exe hello.cpp -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive
Note the following:
The "whole archive" option should be disabled immediately afterwards.
You don't need to do this hack if your program actually uses symbols from the library (i.e. you use <thread> from C++11), in which case the library won't get dropped when you statically link it.
This hack is intended for MinGW-w64, to fix the libwinpthread-1.dll dependencies.
For anyone working in CMake, this solution is readily implemented in your CMakeLists.txt file as follows...
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
Apparently, CMake does some weird stuff with how the -Wl compiler flags are handled, making the -Wl,-Bstatic -lstdc++ -lwinpthread -Wl,-Bdynamic solution not work, with only two other options seemingly left: the bad compiler flag -static and the ugly compiler flag -Wl,--whole-archive.
Meanwhile, the good option that actually works in CMake, yet seems rather undocumented, is to directly use the linker flags. Hence, in CMake, this seems to be the best way to statically link to all the mingw-w64 C++ dependencies:
target_link_libraries (MyVeryAwesomeApp -static gcc stdc++ winpthread -dynamic)
It should be noted that even if there isn't a library explicitly following -dynamic, it should still be applied in order to ensure that the standard, implicitly linked libraries get linked correctly.
I circumvented this problem by using win32 variant of the mingw toolchain instead of the posix variant. With the win32 variant, -static-libgcc -static-libstdc++ is sufficient for an independent build.
If you are using toolchains from MSys2 (tested with gcc version 12) ,the only way to use winpthread statically is standard -static (forces all library to be static) or simply delete/rename the libwinpthread.dll.a && libpthread.dll.a imp libs.
Other methods like "Bstatic", "-l:libwinpthread.a" will no longer work (due to dependency hell, especially in CMake). The one with whole archive still works but it overrides the program properties.
You may also want static link libgcc and libstdc++ if the dependency comes from them.
Just link with -l:libwinpthread.a
Just add -static to your CFLAGS.
For example: ./configure CFLAGS="-static".
This will link all static libraries to your executable file.

How to use OpenSSL with GCC?

I'm trying to use openssl in a gcc program but it isn't working.
g++ server.cpp /usr/lib/libssl.a -o server
gives an error message, as does anything with the -l option. What must I type on the command line to link with openssl? The file /usr/lib/libssl.a exists, but nevertheless I still get the linker error no such function MD5() exists.
Without knowing the exact errors you are seeing, it is difficult to provide an exact solution. Here is my best attempt.
From the information you provided, it sounds as though the linker is failing because it cannot find a reference to the md5 function in libssl.a. I believe this function is actually in libcrypto so you may need to specify this library as well.
g++ server.cpp -L/usr/lib -lssl -lcrypto -o server
You or others may find this article developerWorks article helpful.
Secure programming with the OpenSSL API
https://developer.ibm.com/technologies/linux/tutorials/l-openssl
It describes most things you need to know to get off the ground with OpenSSL and C/C++. If you find you are following most of the same steps, it might help you see what needs doing.
Good luck.
update
revised link: https://developer.ibm.com/technologies/linux/tutorials/l-openssl
Which has been shuffled around
original link: http://www.ibm.com/developerworks/linux/library/l-openssl.html
Which now goes to a digest page including the article.
Note: keeping both links because they be used to find new discoveries.
In Eclipse IDE select Your Project property --> c/c++ Build --> Settings gcc c linker(from tools settings)--> add to Library Search Path (-L)
/usr/lib -lssl -lcrypto
The location of the library is not fixed. In my case (Ubuntu 18.04), the .a files are located in /usr/lib/x86_64-linux-gnu/. So here are the complete steps:
1) install the library,
sudo apt install libss-dev
2) check the installed files,
dpkg-query -L libssl-dev
3) change the gcc flags -L(library directory) -l(library name), e.g.,
gcc XXX.c XXXXX.c -L/usr/lib/x86_64-linux-gnu/ -lcrypto -lssl
On top of the accepted answers, I could not make compile the OpenSSL example for AES-CCM:
https://github.com/openssl/openssl/blob/master/demos/evp/aesccm.c
To make it work I needed to add two more things:
The Dinamic Linking Library : -ldl
The PThread library to use POSIX threading support: -pthread (Adding directly the library with -lpthread is not recommended )