Why doesn't Libtool want to link with a static library? - build

I want to build a shared library that uses ZipArchive using GNU Autotools but I'm having this problem:
Warning: linker path does not have real file for library -lziparch.
I have the capability to make that library automatically link in when
you link to this library. But I can only do this if you have a
shared version of the library, which you do not appear to have
because I did check the linker path looking for a file starting
with libziparch and none of the candidates passed a file format test
using a file magic. Last file checked: /usr/local/ZipArchive/ZipArchive/libziparch.a
The inter-library dependencies that have been dropped here will be
automatically added whenever a program is linked with this library
or is declared to -dlopen it.
If I build a static library or if I use a shared library of ZipArchive it works but the problem is that the makefile that comes with ZipArchive source code only builds a static library.
How can I force Libtool to link with a static library?

Generally, static archives are created with non-pic object files and they cannot be put into shared libraries.
What this message is telling you though, is that when a program links to YOUR library using Libtool, that -lziparch will get added to the link. So you don't need to change anything unless you're building a module for an interpreted language. In that case, you will have to build ZipArchive as a shared library. In addition, this wouldn't work on a platform like MS Windows where shared libraries (DLLs) have to resolve all their symbols at link time.
All that said, if your ziparch static lib is PIC code, you can use the -whole-archive flag when linking it to your library. This would be the least portable solution though.

Related

Telling omake to use static version of a c library

I'm using omake to build a native binary executable. After it links and i try to run it, it fails to run giving the following error:
error while loading shared libraries: libprotobuf-c.so.1: cannot open shared object file: No such file or directory
Is there a way, at compile time, to tell the executable to pick up the static version: libprotobuf-c.a and not the shared on?
I'm not familiar with omake but I believe flag to ocamlc you are looking for is dllpath:
-dllpath dir
Adds the directory dir to the run-time search path for shared C libraries. At link-
time, shared libraries are searched in the standard search path (the one corresponding
to the -I option). The -dllpath option simply stores dir in the produced executable
file, where ocamlrun(1) can find it and use it.
If you can configure omake to pass the appropriate -dllpath argument to ocamlc, you should be good to go.
Under the hood I believe this is using the rpath feature (runtime library search path) of ld, the GNU linker. See https://linux.die.net/man/1/ld . There is also a chrpath utility to change the rpath of an already-built executable.
Another option is running your executable with LD_LIBRARY_PATH set so that the shared library is on the load path. You could also install the shared library system wide if appropriate. A final option is to load the library manually when your application boots using dlopen.
The correct choice depends on how you will distribute this and to who you will distribute this, if at all. Keep in mind if you use rpath/dllpath the end user is unlikely to have protobuf installed in the same location you do.
There doesn't seem to be a global flag that can be passed to ld, the linker, that enforces the linker prefer static libraries to dynamic ones when available. In my case, I set the library name explicitly like so:
OCAML_LINK_FLAGS += -cclib -l:libprotobuf-c.a

Link poco static library to target in cmake

I read a lot of post but I don't yet well understood how to link my target to a static version of a library.
My project depends on poco libraries and, while in linux they are stored in /usr/local/lib (both the static and shared versions) in my windows machine are in d:\libs\poco\lib and d:\libs\poco\bin (where I have an enviroment variable called POCO_DIR = D:\libs\poco)
So, how can I have to write the find_library() directive in cmake file?
Thanks in advance.
You never link with a Poco DLL on windows, not even when you use shared Poco libraries. Linking is always with entries in the %POCO_BASE%/lib. For shared builds, .lib is just a stub ("import library") that takes care of loading the DLL at runtime. See Linking Implicitly for details on how this works.
Poco static libraries can be distinguished from the import libraries for DLLs by the file name - static libs have "mt" ("mtd" for debug binaries, "md" and "mdd" when runtime library DLLs are used) appended to the name. So the import library for PocoFoundation.dll will be named PocoFoundation.lib, while the static library using static runtimes is named PocoFoundationmt.lib. Static library using dynamic runtimes is PocoFoundationmd.lib. See Use Run-Time Library for details.
As for CMake, I am not an expert, but for e.g. static Foundation and Net libraries should be something like this:
FIND_LIBRARY(Poco_LIBRARIES NAMES PocoFoundationmt PocoNetmt PATH_SUFFIXES ${POCO_DIR}/lib)
EDIT: If you define POCO_STATIC in your project, static linking will be automatic through library headers, see e.g. Foundation.h.

Linker can't find lib in Eclipse/JNI/ANT

I am trying to build a large Java/c++ project involving JNI and ANT in Eclipse, under Linux. One of the source c++ files calls the log10() function for mathematical calculations. The project compiles fine, but fails at linking, where it complains that it cannot find the libm.so library necessary to link log10().
My problem is that I am unable to properly tell Eclipse to link that file, even after the following steps:
Added the correct library path in the linker options,
Added a reference to libm in the linker include list,
Added -lm to the full compile options list,
Set LD_LIBRARY_PATH to point to the library's location,
Copied the library to the current directory.
What am I doing wrong/has anyone had such experiences with correctly linking libs in Eclipse? Any suggestions?
This is a bit confusing.
If you fail to find your library at runtime inside your java environment :
Try loading your .so library inside the java environment before making any calls to log10.
System.LoadLibrary("m");
Notice how I left "lib" and ".so" out.
However, you are complaining of a Linker problem from C++, you cannot link to a dynamic file. You can only link to a static library, or a static export library (so you need a libm.a file to which to link at compile time, and then your program will require libm.so at runtime).
Could you post the exact message you are receiving and when you are receiving it ?

g++ Linking vs VisualC++ Linking

I have been trying to get this working for a while now and am unable to find an answer elsewhere, here is my problem.
When I make a static library in Visual C++ any dependencies that this library uses are carried on to the executable program that I link the library to. Here is an example
Test.lib depends on
- SDL
- OpenGL
TestApp.exe links Test.lib
In Visual C++ I do not have to add the dependencies for Test.lib in my TestApp executable, they are carried over and it works great.
However when I port my code to Linux g++ (With the Code::Blocks IDE), if I make a Static Library which is .a in g++, and I make a TestApp that links the library, it gets undefined references to the dependencies.
Is g++ able to do this, and if so what am I missing to have the dependencies carried over to my executable?
As for my settings for my library I simply use the IDE's Static Library setting.
With Microsoft's compiler, header files can have library dependency information in them (source files, too, but this is typically done in headers); this gets compiled into the object file, and the linker understands and applies that information. That can be handy: you don't have to remember long, funky names, and if you compile two source files with incompatible options you may get a library name conflict that the linker will complain about. Most compilers and linkers don't do this kind of thing, and you have to tell the linker explicitly which libraries you want to link with.
Static libraries do not statically link with other libraries. Does that sound right?
However you can pack many object files together with a tool called ar.
What happens on windows is probably because you have the (SDL, opengl32) dlls somewhere in a system env path.

Statically linking to libarchive on Windows with MinGW

I've been using libarchive in my project for some time now and it's working great, at the moment I am dynamically linking to it, so on Windows the libarchive.dll file has to present on the system.
I would now like to statically link to the library so I don't have to bother distributing the DLL, but I'm having real trouble trying to achieve this!
Currently, in my make file, I have something like this:
-Lpath/to//libarchive/ -larchive
And this works, but it does a dynamic link. I don't know how to enforce a static link.
I can see in the libarchive directory there are two a files, libarchive.dll.a and libarchive_static.a. I suppose I want to link to libarchive_static.a but I can't seem to specify this, doing -larchive_static in the make file results in linker errors.
I was under the impression that static libraries under windows are lib files, but I get no such file type when I build libarchive.
How can I make a .lib file from libarchive. Also, as an extra question, what is the difference between an a file and a lib file?
Update
To statically link to libarchive, your library command for make should contain:
-Lpath/to//libarchive/ -larchive_static
This will link to the libarchive_static.a file. However, you also need to define LIBARCHIVE_STATIC in your code.
Now the problem is that libarchive depends on the bzip2 libraries (as well as others), and if you do not have a static build of them you will get linker errors something like:
undefined reference to `BZ2_bzCompressInit'
You need a static build of the dependent libraries and a similar command to the linker after the libarchive command:
-Lpath/to/bzip2/ -lbzip2
You can either build bzip2 from source, or do it the easy way and get a pre-built binary from the Gnu32Win project here: http://gnuwin32.sourceforge.net/packages.html
Just add libarchive_static.a explicitly to your link command.
gcc -o YourApp.exe $(OBJS) path/to/libarchive_static.a $(OtherLibs)
".lib" files differ from compiler to compiler (Borland, Microsoft etc.), ".a" is an old "archive" format from UNIX's ar tool. It is now used only for the bundling of static libraries.
Currently, in my make file, I have something ...
And this works, but it does a dynamic link
The .a file actually contains some code for dynamic linking to the .dll file, not the libarchive itself. On the startup the pointers to functions are allocated and dynamic linking is done.