I'm writing a c++ program that is dependent on a c/c++ 3rd-party library. I compiled the 3rd-party library as a static library both on windows and linux. My code works correctly on linux, but on windows there's linking error indicating that my code fails to resolve the symbols in the 3rd-party library.
After some debugging, I found that the unresolved references are non-inline functions in that library and inline functions can be resolved (I've tested). Originally I thought it's the incompatibility between gcc and msvc, because I compiled the .lib files using msvc while attempted to compile my code with g++ through mingw. I recompiled the library with g++ on windows and there's the same problem.
Any idea what might be the solution?
=========Edit===============
Just to clarify, the 3rd-party library is not templated.
I found the problem: I put both the lib*.a (generated on linux) and .lib (generated on windows) of the 3rd-party library in the same directory, because I want this code to be cross-platform. While compiling my code in windows with g++, it seems link to the lib.a files in priority which leads to "unresolved symbols" error. I deleted the lib*.a files and g++ now link to the *.lib file, and works correctly.
Related
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 ?
Forgive the convoluted title.
The setup for this problem is as follows:
I have an open source lib I have built into a bunch of .libs (VTK if you were curious)
I have a library that uses the aforementioned static lib. Lets call it Lib A.
I also have an application that uses the aforementioned library (i.e. VTK) AND also uses Lib A.
During build time, I get a linker error telling me that a function called from Lib A has already been defined in a library that is linked to the application (error: LNK2005)
Any ideas on how to fix this short of switching everything to be dynamically linked?
Alright. I figured out what I was doing wrong.
Lib A was using the statically built version of VTK while the main app was linking against a dynamic-linked version of VTK.
So the problem really was that I had the same functions defined in a .lib and a .dll which caused the linker to fail.
I am writing a program that uses the hashlib++ library (or will use it) but I don't want to add all of it's source files to my project because it's huge. Is there anyway to link to the hashlib++ source files so that I can use it in my project? I've tried linking to the header directly with a simple
#include "path/to/hashlibpp.h"
But I receive a nifty error for it as soon as I attempt to call any functions from the library. For example:
undefined reference to `sha1wrapper::sha1wrapper()
I am using the Code::Blocks IDE and GCC compiler.
First you have to have the library installed on your machine, already compiled into a static or dynamic library file. You can install from source, or you may find a pre-built package available for your OS (depending on which OS you are using). You will need to know the name of the library.
In the case of hashlib++ they have provided instructions to build a static library from source in their README; see section 3.2.
In most cases, dynamic linking is the best choice. This means that the library is linked with the library at run time, instead of adding the library to your executable when it is compiled (which would make your executable file much larger).
Unfortunately, according to their README.txt, hashlib is only available as a static lib, which limits your choices.
When compiling a program on the command line using gcc, the '-l' option links in a library:
gcc -o MyProg -lhl++ MyProg.c
When using an IDE like Code::Blocks, you normally have to specify the libraries to be linked. See this answer for details on how to do this with Code::Blocks.
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.
In MS Visual C++ 2010
I had a single C++ project in my solution which used boost and worked perfectly.
I then decided to convert this project into a static library and create a new project which depends on this static library.
Now, my converted static library builds without errors and warnings (compiler and linker)
but the new project compiles but does not link.
I am getting:
1>LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc100-mt-1_45.lib'
As a test I added the full directory path to the linker options for this library... and then it complained about
1>LINK : fatal error LNK1104: cannot open file 'libboost_date_time-vc100-mt-1_45.lib'
I have now added complete paths to all the libraries and it now builds and run.
I am not happy with this solution because:
I don't want users of the library to
have to worry about linking in
boost.
It is messy
I know an answer would be to create a DLL but is there a way to do this statically and keep the linking at my static library level.
Edit:
If I tell the .exe linker to ignore the boost libs explicitly then it all is ok except the .exe should not have to worry about boost at all.
/NODEFAULTLIB:"libboost_thread-vc100-mt-1_45.lib" /NODEFAULTLIB:"libboost_date_time-vc100-mt-1_45.lib"
Apparently you don't need the .libs, as your exe also links without them. You seem to be using boost header-only methods and classes. So just tell boost to disable auto linking by defining the preprocessor symbol BOOST_ALL_NO_LIB in your project.
If you want to make your .lib unnecessary big by including all of boost, this question seems to hold an answer (which I never really tried myself): Linking static libraries to other static libraries
When building your library, you can include the boost libraries in yours. To do so, in VisualStudio's Librarian > General property page, list your boost libraries as Additional Dependencies.
However, there may be a problem if your clients use boost themselves, and statically link to it (especially a different version than the one you are using).
Did you build boost library? There are certain libraries in Boost that needs to be compiled. In case if you haven't done that, refer to "Getting started in Windows" on how to build the Boost library.
EDIT-1: Boost can be built both as a static and dynamically loadable (dll) libraries.
EDIT-2: If you have already built Boost, then the answer by #Daniel Gehriger tells you how to add it in VS.