I'm fairly new to C++ and I know how to link external libraries in Visual Studio, but I'm not sure how to include them with the .exe file that is made when you build. How do I include a library with that so the other PC doesn't have to have the libraries installed in the same exact location on the disk that I do (or in other words just with the application)? I tried putting the .dll files directly with the .exe but it says it can't locate them.
This depends on the type of linkage that you use for the library. You basicaly have 2 options:
static linking
dynamic linking
When you statically link your program with a library, that library is embedded into the resulting application (exe). So you need to distribute only that resulting application.
Or the library can be linked dynamically. This means that the actual library code will be looked up at runtime (by OS) from dll file (on Windows). In this case you must be sure, that user will have dlls you need on their computer. To see where Windows searches for dlls see this msdn page. Basically you want your dlls to reside in the folder, where your program is, so Widnows can find it. Or if you are using some system libraries (e.g. Direct3D) your user will probably have those dlls already installed.
Related
I have some confusion about static and dynamic linked libraries and .lib and .dll files.
I have a project with two libraries, one I built myself and one is from an open source library.
The one I built myself is a separate project in the same solution (Visual Studio 2015, C++), and I don't need to copy over the .lib files or create a DLL for the executable to build and run
For the other open source library, I do need to copy over the .lib file and the DLL into the executable folder. However, I thought it would be possible to statically link a .lib file and not have to copy over the DLL.
Does this mean I need to compile the Open Source library differently? Like change the define __declspec(dllexport) to __declspec(dllimport) ? Or change /mD to /mT in compiler options?
I tried both of these, but it's still saying that it can't start without the .dll
Or can I get away with changing a setting in the executable project to link this library statically? If so, what are these settings?
EDIT: I know this is a standard question that can be looked up on google, but I haven't been able to find an exact answer for a while. Mainly, I'm confused about what settings need to be changed, and which project they need to be changed in. (The library or the executable).
I'm under assumption that static linking means the library is built into the executable, and dynamic linking means the library needs to be in a separate file, if this is incorrect, please let me know. Otherwise, I need to know how to build the library into the executable file.
And I can go ahead and change the build options in the open source library, and I tried this already.
Thanks,
-D
In Windows, dll files (dynamically linked libraries) need to be in the same directory as the application or on the search path. lib files (static libraries) need to be statically linked during linking (the last step of building the application). It's common in Windows so have a library come with both a dll and lib file. In this case, the lib file is an import library containing the information needed to easily link to the dll.
Place the dll file where your application will be built and statically link with the lib file. Go to 'Project->Properties->Link->Input->Additional Dependencies' and 'Project->Properties->Link->General->Additional Library Directories' to specify the static libraries you want to link.
Edit: It seems I misunderstood the question. The question is how to recompile a dynamic library as a static library. You need the source code of the library you are using along with it's Visual Studio Project file. Open the library and in `Project->Properties->General->Configuration Type' change it from Dynamic Library to Static Library.
Beware that Dynamic Library uses the Linker group of properties while the Static Library uses the Librarian group of properties. Changing between these types may cause the project to drop essential linker flags options. Since every library is different, I can't predict what you will have to do work around this. Make sure to backup the project file so you can see the original options and flags.
I had to change the setting for "Static Library" for All Configurations, not just Debug, although it was building in Debug. Not sure what may have caused this. Possibly because the debug and release builds for the library were set to the same folder, it may have been overwriting the debug builds with release builds when building
I'm trying to use libcurl library in my application.
when i start my application, it asks for libcurl.dll and zlib1.dll
to exist in the same folder. when i add them everything works fine but i want to include
them to the executable.
how can i statically add both dll's to the application?
You cannot statically link dlls into an executable. The purpose of dynamic libraries is to be loaded dynamically during runtime from an external image (dll file). You should check whether curl and zlib provide proper static libraries and link against them instead of lib stubs for the dlls.
Consider that linking against static external libraries makes your binary potentially vulnerable against any security issues in statically linked blobs. That means that you will have to update any binary you statically linked against those libraries instead of simply updating the libraries themselves.
I'm trying to add PNG support to my application and thus I want to include libpng. I know it needs zlib and thus I downloaded that as well. I went into the png folder/projects/vstudio and I opened the solution. I compiled it and it went just fine. I added some headers from it into my application and I copied the lib files. My program is a dll written in c++ which is later used from C#. When I run it in C# it complains about not finding my dll (tough if I remove the png part it works fine). I've had this problem before and it usually means a dll dependency is wrong.
Now... libpng compiled both some .lib files and some .dll files. The dll files are bigger. My only guess is that it needs the dll files as well but I've seen that people can link to libpng without a dll.
So my questions is: How can I compile libpng(and zlib for that instance) into just static libraries and how can I include those in my projects? I've searched around the internet and I couldn't find anything useful.
To make all your libraries static, you would have to recompile everything "from scratch" as static libraries.
This simply means you should create a set of projects for each library you have in your sequence and set the output type to static library.
After that you should eliminate library dependencies between the libraries themselves (this means you should link the output of some projects to another projects, e.g. if your "libpng" library uses "libzip", it means you should first compile the "libzip" and link that output (static library) to your "libpng" project.
In the very end you would have a big set of static libraries compiled for your platform, which you can use in your projects.
Also to mention, try googling more carefully. I'm sure someone has this done and you would probably need to download a package of .lib files for your platform (I know that very often the "dev" bundle of libraries only includes an import library paired with appropriate .dll file, but there are a lot of enthusiasts like you :)
A library can be used in an application in two ways:
Statically-linked
Dynamically-linked
But how to do that using both Visual Studio (windows) & GCC?
I know libraries are distributed only in these 4 ways:
Source
header-only libraries
*.lib files for windows. *.a for linux
*.dll (windows) & *.so (linux).
Source distribution is just compiled."header-only libraries" are nothing but a source distribution.
Now if the desired library is distributed in *.lib form. Inorder to use it.
On Visual Stuido :
We add directory path containing headers(*.h) to Configuration Properties > General > Additional Include Directories
we add each *.lib file to Configuration Properties > Linker > Input > Additional Dependencies
we add directory path of *.lib files to: Configuration Properties > Linker > Additional Library Directories
How to do the same thing for GCC/MingW?
I don't know how to build my application when the library is distributed as *.dll or *.so too. Can someone tell me what do I need to do in these situations for both Visual studio (windows) and GCC(linux)/mingw(windows)
On GCC, for static linking, you'll include the library in the command line. Lets say you've glib-2.0.lib and your program that uses GLib library is my_prog.c, then you invoke GCC as
gcc my_prog.c -L<library_dir_here> -lglib-2.0.
As for the dll and so, dynamic libraries are something you don't link to your programs by passing them to your linker. Instead the operating system gives you a function to load them when it's required, at run time. Thats the reason it's called dynamic. In Windows you've LoadLibrary and on Linux you've dlopen. Both these functions get a string (which is the dll or so's name) and load it if it's avaiable on the machine. Once it's loaded, the function you require from the library is looked-up by passing its name to GetProcAddress on Windows and dlsym on Linux; both returns a function pointer, with which you can call that function. Since you're not directly calling the functions provided by the libraries directly, but thru' function pointers, there'll be no need for you to link them statically (i.e. pass them to the linker) when you build your app.
For DLL distributions the scenario is similar to that of .lib files. (your #3)
You will have to configure your project to build a DLL. The project will build LIB and DLL files.
Depending on your needs/architecture/design you can either
Link against the LIB file just as you do in your #3 above. Note that the DLL file will have to exist on the target machine at run-time otherwise the application will not load.
Call "LoadLibrary()" from the client app and skip the linking part/no need to have the LIB used in the client application.
I can't help you with the gcc specific questions.
I'm wondering how to make a release build that includes all necessary dll files into the .exe so the program can be run on a non-development machine without it having to install the microsoft redistributable on the target machine.
Without doing this you get the error message that the application configuration is not correct and to reinstall.
Choose Project -> Properties
Select Configuration -> General
In the box for how you should link MFC, choose to statically link it.
Choose Linker -> Input. Under Additional Dependencies, add any libraries you need your app to statically link in.
You need to set the run-time library (Under C/C++ -> Code Generation) for ALL projects to static linkage, which correlates to the following default building configurations:
Multithreaded Debug/Release
Singlethreaded Debug/Release
As opposed to the "DLL" versions of those libraries.
Even if you do that, depending on the libraries you're using, you might have to install a Merge Module/framework/etc. It depends on whether static LIB versions of your dependencies are available.
Be aware that Microsoft do not recommend that you static link the runtime into your project, as this prevents it from being serviced by windows update to fix critical security bugs. There are also potential problems if you are passing memory between your main .exe and .dll files as if each of these static links the runtime you can end up with malloc/free mismatch problems.
You can include the DLLs with the executable, without compiling them into the .exe and without running the redist tool - this is what I do and it seems to work fine.
The only fly in the ointment is that you need to include the files twice if you're distributing for a wide range of Windows versions - newer OSs need the files in manifest-defined directories, and older ones want all the files in the program directory.
You'd be looking to static link (as opposed to dynamically link)
I'm not sure how many of the MS redistributables statically link in.
If you are looking to find out which dll's your target machine is missing then use depends.exe which used to come with MSDev, but can also be found here. Testing this on a few target machines should tell you which dll's you need to package with your application.
You should use a static link and add all libraries you need under additional dependencies.