I have a C++ project and I am linking to an external library (using all of its headers and source files). I did this by going into the project configuration and adding the source.a library that i wanted to link to. Now my question is how do I know if my library is linked to my program statically or dynamically. I have read numerous thread about the types of linking however i am still not sure about the type of linking I have. Any suggestions on this regard would be helpful
I did this by going into the project configuration and adding the source.a library...
It's static. If it were dynamic you would have added a .dylib file instead (which apparently you don't have one of).
Related
I am working on a little project to understand the chain of compiler and linker better.
Suppose that i have the libraries libfoo.a and libbar.a. I want to create a library libmy.a, that acts like a wrapper or top level API to both libraries. The target is, that only libmy.a should be required to build an executable, that uses my defined wrapper functions. I created a cmake project and set up the library
cmake_minimum_required(VERSION 3.14)
project(Wrapper)
set(CMAKE_CXX_STANDARD 11)
add_library(my STATIC ${SOME_SRC_FILES})
#set up the lib/inc paths and libs to link
target_include_directories(my PUBLIC /path/to/Foo/inc/ /path/to/Bar/inc/)
target_link_directories(my PUBLIC /path/to/Foo/lib/ /path/to/Bar/lib)
target_link_libraries(my PUBLIC foo bar)
That works fine and there is no problem in compilation. However, if I try to reference the object from an external project, it tells me, that I have undefined references to the functions in libfoo.a and libbar.a. As far as I understand the problem, the linker only creates a declaration in the libmy.a, without including its definition from the external library. I checked this by opening libmy.a with the nm libmy.a command, where the used functions of the external libraries are declared, but undefined.
I came across one solution that used ar to combine multiple library files. However I would like to avoid such methods, because if it is not a single library, but a bunch of, say 10 libraries, it is not suitable to search each library for a definition and copy it into libmy.a. Just throwing all libraries together isn't a solution either, because the file will get too big.
Is it importand to note, that one of these library packages is CUDA?
I am sure there is a solution, but I was not able to find one. Any help would be appreciated
The target is, that only libmy.a should be required to build an executable
This is already an unconventional goal for static libraries.
Static libraries normally only contain the object code built from the source code for that library. Users of that library must also link to the libraries that your library requires, because the definitions have not been copied in to your library when it was built.
Tools like ar can be used to combine multiple static libraries together, since they are just archives of object code. The tool can not predict which object code the end-user will use though, so it will bundle entire libraries. Otherwise, the end user may be looking for a definition that you left out and then need to link in a 2nd copy of the dependency lib anyways.
If you want to provide a library that has everything the end-user needs, cut down to what your wrapper actually uses, you can build a shared library. Shared libraries are considered executable, so the compiler knows that any unreferenced object code is not going to be used, and it will not be included in the shared library.
You can force the entire static libraries to be included in shared libraries though.
On GCC you can use the linker argument: --whole-archive to ensure that all of the object code from the following libraries is included.
On MSVC, you can use the /WHOLEARCHIVE:<library file name> argument to do the same.
I wrote a static library (compiled with TDM-gcc 4.8.1 in Windows 7 for x64) that has dependencies on other static libraries. Boost libraries (locale and system) to be specific.
Since I'm building a static library I assumed that the libraries I'm dependend on would automatically included in my final .a, especially since I'm using them in my code.
But when I'm trying to build an executable that statically links to my aforementioned library there are still undefined references to some boost parts, that are definitely used in my library.
Is there a way to fix that?
Any help is gladly appreciated. Thank you
Edit:
I haven't been careful enough, because I now know what causes the problem. I'm using codeblocks and all the necessary arguments for building the archive are declared in the project prooperties. But codeblocks doesn't even call the linker when building my library. Instead it calls ar.exe and passes all object files of my project. That way, no external library are ever included. So, I have too look for away to tell codeblocks to build the library in the right way..
Your executable needs to link against all the relevant libraries, including the ones it directly depends on, plus the ones it indirectly depends on. When you link a static library you typically do not embed other static libraries within it.
I am working on a project with SDL. I feel like a lot of my code could/should be reusable for any other projects I might want to take on.
I was going to start a library project, but I don't know how to go about linking to the SDL libraries.
Usually, I go to Project Settings and edited Mingw32 Linker to include the libraries (ming32, SDLmain, and SDL). But the linker does not show up in the settings.
So my questions:
Is there no linker settings because building a library is only a compiling operation?
And in general, is it possible to build a library on top of the existing libraries? That is, write my library using SDL functions and stucts. Or would I have to get the source code and rebuild entirely with my code included?
Also, advice on shared vs. static in this instance?
(Also, any advice for where to go about learning more about compilers and linkers and such. I got through data structures in school but no farther)
As an introduction, you have to distinguish very well static library from dynamic ones, they are completely different beasts... said that, to your questions:
Is there no linker settings because building a library is only a compiling operation?
I guess you are creating a static library in this case. A static library is simply the collection in one single object file of all the individual object files (i.e., the .o files produced by the compiler) that make up your source tree. No more, no less.
With a static library you don't need to specify which are the dependencies, since it is understood that it is when compiling the final executable that your library will be linked with all the other libraries that it depends upon. Therefore it is only at that time (final executable build) that any missing symbol will be detected, and all other libraries must be available.
A shared library (also dynamic library), is an executable file that embeds all the static libraries that it depends upon. It can also have external dependencies with other shared library, which would not be embedded.
And in general, is it possible to build a library on top of the existing libraries? That is, write my library using SDL functions and stucts. Or would I have to get the source code and rebuild entirely with my code included?
It is perfectly possible, both for static and dynamic libraries.
Also, advice on shared vs. static in this instance?
In this instance it is not possible to advice, because you don't specify enough information.
Look at this: When to use dynamic vs. static libraries, and this, to have a sort of guideline.
(Also, any advice for where to go about learning more about compilers and linkers and such. I got through data structures in school but no farther)
I think that the two links above give you plenty of information. If you want to further go into details, you could start from this wikipedia article and browse from there.
The library you are building can have external dependencies. That means that you can link it with SDL or any other external libraries that you like.
I think this page explains all your other questions: DLL Creation in MingW
I need to provide an SDK with a static library. Let's call it "libsdk.a".
This library should hopefully be standalone, meaning a simple example "example.cpp" could link against it without any other library, except the system ones.
Here my configuration :
cmake for all my 10 dependencies libraries. There is a static library (.a) generated for each of my module. These libraries contain only object files .o of the given module. Dependency tree is not flat, some of them depends on others.
a simple example "example.cpp", with a cmake, which compiles and works. At this level, cmakes generates a very complex link command to deal with deps tree.
external dependencies such as boost (some static libraries too)
At the moment, I tried this :
make an archive of the different .a generated but it doesn't work because linking against this lib tells me the archive a no index (even after ranlib). Yet, I remembered I could add .a libraries inside .a files without problems.
extract all .o object (with ar -x) files from all *.a files and recreated a "libsdk.a" with all these object files. It doesn't work either (unresolved references). Moreover, it includes all objects even those which are not needed... My working example takes 3.7M. This library is around 35M.
make a .so shared library. It seems to work but I would prefer having a static library.
compile all statically but then linker complains it doesn't find -lgcc_s. Ok I want to compile in static but not that far, and just my own libs together !
So my final question : is there any way I can generate my static lib containing all my other libs, and not system ones ?
BTW, another interesting topic on that :
Combining static libraries
Thank you for any piece of advice to open my mind !
What you are trying to do by hand is the job of the linker. While it's feasible, you shouldn't bother with it.
When you compile libsdk.a, make sure that all of its dependencies are linked statically. If you do this, libsdk.a should be standalone. Static linking means copying the code to the right places in the final executable, so anything that is linked statically will not need to be provided in an external file.
See this post on CMake mailing list. libutils.cmake attached to the message has MERGE_STATIC_LIBS() macro that does the job. On Linux (and all other Unixes except OSX) it uses ar to pack and unpack objects files.
I am working on a c++ project that links to a static library. However, I want to use intel's TBB, which is only available as a dynamic library. I tried to set this up in visual studio but I can't get it to work. Does anyone have detailed directions to do this if it is possible?
Typically when a library is made available as a dynamic library (.dll), it also comes with a .lib file to link against (as discussed in this question). This can be added to the project's list of inputs the same way that a static library is
Project Properties->Configuration Properties->Linker->Input->Additional Dependencies (in VS2008)
If a .lib is not available, then you'll have to load the .dll at runtime using Win32 API function LoadLibraryEx and then subsequent calls to GetProcAddress to get the addresses of the functions you need.
Are you talking about linking to a RUNTIME library? No you can only link to one. You have to either change your project, or you have to recompile the TBB to link to static runtime as well.