C++ MinGW GCC CodeBlocks static linking - c++

For my C++ program I would like to statically link the following dlls' in my CodeBlocks setup with the MinGW GCC compiler:
libcurl-4.dll
libeay32.dll
ssleay32.dll
Yes, I know I can't statically link these DLLs since these are Dynamic Libraries. However, I can't figure out how to link the static libraries to overcome the required DLLs mentioned above.
I have tried many suggestions already, however, I still can't get it to work. At the moment I just redistribute the DLLs with my software, however, I would like to achieve to send off 1 .exe file.
Thanks for your helpful answers

You either do shared linking using the lib*.dll.a files which makes your project depend on the corresponding .dll files, or you do static linking, in which case your project won't need the additional .dll files.
However, shared linking has the advantage that each .dll file takes care of it's own dependancies. With static linking you must not only link with static libraries your project depends on, but also the static libraries they depend on, and so on.
To make matters more difficult, MinGW/MinGW-w64 GCC is picky about the order in which you specify the static libraries.
If you have the static libraries on our system and they come with the .pc files you can use something like pkg-config --static --libs libcurl to list the static libraries you need to link with.
You can even specify that command in "Other linker options" on the "Linker settings" tab of the "Build options" of your Code::Blocks projects if you surround it with back-quotes: `pkg-config --static --libs libcurl`, provided pkg-config.exe is in the compiler path (or a path specified under "Additonal Paths" under the "Toolchain Executables" tab of the compiler settings).

Related

Xcode linking against static and dynamic library

I have some problems with linking my macOS app against C libraries.
I have several question related to this issue.
It is better to link app against dynamic or static libraries taking into account that this will be very custom libraries rather not shared with other apps?
I have linked my macOS Xcode app against ~14 static libraries .a and it works fine. I have reconfigured CMakeLists.txt making this libraries and now Xcode project doesn't work. The main change was changing the directory I have
"$(SRCROOT)/../../c/<project_name>/outputs/lib/apple/static"
But now I have both static (.a) and dynamic (.dylib) libraries in the same path
"$(SRCROOT)/../../c/server/outputs/lib/apple"
I don't know whether this should matter, but linking against static libraries causes that after running my Xcode project it complains that it cannot load lib.dylib So maybe it finds this dynamic library under Library Search Paths and tires to load them but don't find them linked?
So I tired to link Xcode macOS app against .dylib libraries and instead of static .a libraries added them in Link Binary with Libraries. The problem is that the error not finding library now also occurs.
Maybe I should change something here ? But what If I will distribute my app to some other computers that will not have libraries in this specific location. How can I include dynamic libraries in Xcode bundle in order to be always findable.
I know I added maybe to many question. But would like to know how to the best solve this issue? Better to link statically or dynamically and then how to correctly achieve this avoiding this error.
UPDATE
It seems that when linking against .dylib it only works when I add path to this library directory to Runpath Search Paths.
It also seems that when I link against static library .a it works when .dylib isn't in the same directory (I moved .a library into /static subdirectory) and then for this moved library error isn't showing any more. But isn't there way to link statically when there is .a and .dylib libraries inside the same directory?
I know this is an old question but it's one of the top results when searching google for "Xcode static linking."
I recently encountered this issue when integrating with Intel IPP, which puts static and dynamic libs in the same directory.
If I used the standard Xcode linking method of adding the library via the "Build Phases | Link Binary with Libraries," Xcode translated that UI into a command line that looked like this:
clang++ ... -L/my/path -lstatic1 -lstatic2 ...
But that causes the linker to prefer the DLL instead of the static library in the same directory.
I worked around this by removing the entries from the "Build Phases | Link Binary with Libraries" window, and adding full relative paths to the libraries in the "Build Settings | Other linker flags" entry:
../../path/to/lib/libstatic1.a ../../path/to/lib/libstatic2.a
This caused Xcode to translate the UI into a command line that looked like this:
clang++ ... ../../path/to/lib/libstatic1.a ../../path/to/lib/libstatic1.a ...
Which linked the libraries statically.
Finally, I have linked this Xcode macOS project with multiple dynamic C libraries (.dylib).
REMARK
In order to link with static libraries (.a) They cannot be placed side by side with dynamic libraries! path/project_name/outputs/lib/apple/*.dylib and then place static libs under path: path/project_name/outputs/lib/apple/static/.a As XCode tries to link dynamic libraries if they found them on Libraries Search Path in Build Settings.
DYNAMIC C LIBRARIES LINKIN IN XCODE
Add dynamic libraries to Build Phases tab and Link Binaries with Libraries section as on the image
Embed all this dynamic libraries in output macOS Application Wrapper
You get something like this:
Then in Build setting add Libraries Search Paths
And finally add Runtime Search Paths in Build Settings

Include a static library in a static library - CodeBlocks

I'm having an issue compiling a static library using Code::Blocks 13.12. I need to use a third party static library from within my own static library. So, I have libOtherLib.a and I'm trying to build libMyLib.a and link in libOtherLib.a. The problem is that the linker is not including libOtherLib.a during the linking phase of the build. Here is some additional information:
I am using the GNU GCC Compiler
In Project build options for the whole project (not specifically Debug or Release)
I have added libOtherLib.a in the Link Libraries list in the Linker Settings
I have added the path to libOtherLib.a in the Search directories -> Linker list
I have added the path to the .h file for libOtherLib.a in the Search directories -> Compiler list
The library compiles completely fine (produces bin/Debug/libMyLib.a with no errors)
Any help would be greatly appreciated. I have an inkling that it is related to this being a Static Library rather than an application (console or otherwise), but I'm not sure how or why. I did change the build target Type to "Console Application" in the Project Properties window and it looked like it was linking in libOtherLib.a, but it had other errors because this code is meant to be a library rather than an application.
Here is the linker command that is executed at the end of the build. libOtherLib.a is not there anywhere, that is the problem, just not sure what the solution is.
ar -r -s bin/Debug/libMyLib.a <all of my .o files>
Possible causes of the problem would also be nice - if this is mostly like the compiler, the linker, the setup or Code::Blocks itself.
When building a static library you are just putting together a bunch of object files into an entity easier to ship and use. There is no linking done when building a static library.
The unresolved references from your library are dealt with when building an application or certain shared objects. You'd just ship your library and require that users also supply the library your library deoends on when building.
If you want to include the library you are depending on in your library you can extract the object files from tgat library and include them into your library. Although technically possible it is questionable if you have the rights to do so. Also, that is normally not the way things are done and I'd recommend against doing so.
You can't link a static library in anoter static library.
However,you can do this:
Suppose MyPrograme.exe need to link static library libMyLib.a,make MyPrograme.exe also link libOtherLib.a.
Since libMyLib.a is static library,there is no need to link libMyLib.a.Just inclue the headers.
When build a static library,it will only be compiled,not be linked.
Despite all this "linking is not the right term for this" philosophy, you can patch Code::Blocks compiler configuration to support this, for example for the GCC/G++ compiler.
http://green-candy.osdn.jp/codeblocks_config.html
The idea is that you replace the "Link object files to static library" script in the "Advanced compiler options" window of GCC with:
rm -f $static_output
$lib_linker -r -s -T $static_output $link_objects
$lib_linker -r -c -T $static_output $link_options
Then you can put the relative path to your "libOtherLib.a" in the "Other linker options" editbox of your projects. This mod is not really officially endorsed but it works in my projects, so you get static libs in static libs just like in MS Visual Studio!

How to add a library to Eclipse C

I have seen several other answers in order to add a library to my C+= project in eclipse.I have tried to add the path to the linker in Miscellaneous section using -L"and the path of the folder" and -l"the name without the lib prefix in the begging and the .so at the end"
I try to add libxl library so i use -lxl (for libxl.so) and -L/home/username/libxl3.5.3.0/lib/ (which the location of the lib file).
I have also tried to give it under the Linker menu and adding the name and the path in the Libraries section.
I get error that: /usr/bin/ld does not find -lxl file and it returns error
I am using -static to linker in order to make an executable that has the all the libs included but when i do not use -static the problem with the lib resolves from build but still when i try to run the program i get error that i the program can not open shared file libxl.so cause the file does not exist.How can i fix this?
When you add the library name to a C++ project in eclipse, do not prefix it with -l. Eclipse will do this for you when it invokes the compiler. For example if you want the boost_regex library, just input boost_regex not lboost_regex. Eclipse will do the rest for you. Or in your specific case, just use xl not lxl. You don't need the - either, nor the -L before paths as erenon points out in the comment below. Note that the above applies to the method of adding libraries using the Project->Properties->C/C++ General->Paths and Symbols dialog form for adding libraries using the Libraries and Library Paths tabs.
You are trying to link statically to a shared library. In my experience I have always used *.a files rather than *.so files to employ static linkage. This other answer Static link of shared library function in gcc seems to suggest that you are not actually able to link statically to *.so files.

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.