ICU Static linking on Windows [duplicate] - c++

I am trying to use ICU Unicode in my C++ Project.
I have downloaded the libraries from here, and then linked them by:
Adding the lib64 directory to Properties -> Linker -> General -> Additional Library Directories
Adding the names of all the .lib files into the Input tab.
I then #include "ucnv.h", and the build and run.
The program builds fine, but I get this error message saying I need to put the DLL next to the exe.
I do that, and it runs fine. My questions is
How do I statically link ICU to my project?
What I have tried
I have tried downloading the Master from github, and opening the allinone.sln file, and then setting the following:
Release and x64
Changing the output from DLL to Static Lib
Adding U_STATIC_IMPLEMENTATION to all of the project-preprocessors
I then rebuild, and then add each one of the projects release directories to the Additional Library Directories section of my projects properties, and then also adding the names of the libraries to the Input Section.
Now this actually works for UTF-8, however, for another encoding such as Big-5 most of the functions (and basically all essentials) return NULL.
Also, another reason for a static library is because the DLL I downloaded is over 16MB, which is way too big. On ICU docs they even say that they recommend static linking to reduce size (by removing unneeded)

Related

Statically linking ICU on Windows

I am trying to use ICU Unicode in my C++ Project.
I have downloaded the libraries from here, and then linked them by:
Adding the lib64 directory to Properties -> Linker -> General -> Additional Library Directories
Adding the names of all the .lib files into the Input tab.
I then #include "ucnv.h", and the build and run.
The program builds fine, but I get this error message saying I need to put the DLL next to the exe.
I do that, and it runs fine. My questions is
How do I statically link ICU to my project?
What I have tried
I have tried downloading the Master from github, and opening the allinone.sln file, and then setting the following:
Release and x64
Changing the output from DLL to Static Lib
Adding U_STATIC_IMPLEMENTATION to all of the project-preprocessors
I then rebuild, and then add each one of the projects release directories to the Additional Library Directories section of my projects properties, and then also adding the names of the libraries to the Input Section.
Now this actually works for UTF-8, however, for another encoding such as Big-5 most of the functions (and basically all essentials) return NULL.
Also, another reason for a static library is because the DLL I downloaded is over 16MB, which is way too big. On ICU docs they even say that they recommend static linking to reduce size (by removing unneeded)

Visual Studio Static Linking for Standalone Exe

I've read multiple posts with regards to this topic, but none of them have enabled me to build a statically linked exe.
In my release configuration (x64) I have the following:
Configuration Properties -> General : Use of MFC - Use MFC in a Static Library
Configuration Properties -> C/C++ -> Code Generation : Runtime Library - Multi-threaded (/MT)
Configuration Properties -> Linker -> Command Line : Additional Options - I have all the required Windows libs "kernel32.lib", etc. (as use of MFC removed them from the "All Options" window above)
Configuration Properties -> Manifest Tool -> Input and Output : Embed Manifest - No
Note that in Configuration Properties -> Linker -> Input there are 5 lib files that I'm using in my project, eg glfw3.lib and I'm using Full optimisation (/Ox).
After building the project and running the exe myself I receive errors "The code execution cannot proceed because glfw3.dll was not found..." etc.
Using dependencywalker I can see that it needs the dlls associated with the libs, which it of course cannot find.
Am I misunderstanding how to do this or is there something else that might be wrong?
(I'm using Visual Studio 2017)
Yes, it appears you have a slight misunderstanding.
If something is offered as a DLL, then it is meant to be used as a DLL. There may be some way to incorporate a DLL into an executable, but it would be a hack. That's not how things are supposed to work.
The lib file that you are linking against exists simply in order to provide you with functions that you can link against, and these do nothing but delegate to the corresponding functions in the dynamically loaded DLL. Without it you would have to locate each entrypoint of the DLL yourself, which would be perfectly doable, but a bit cumbersome.
So: you must either find a version of glfw3 which is packaged as a statically linkable library (I have no idea whether one exists) or live with the fact that your .exe will need to be shipped together with glfw3.dll.

Are lib files exclusively statically linked or do they need to be compiled specifically (VS2015)

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

Linking a lib statically in VC++

Probably I am missing here something but that is my first time on Windows that I need to link a lib statically so that the executable won't be dependent on a dll.I do it with LIBPNG.
I do it like this:
I added libpng headers : C/C++ -> Additional Include Directories
Added library directory to the linker: Linker - > General ->
Additional Library Directories
Added linker additional dependencies:Linker -> Input
Compile the exe ok.When calling it I am getting :
"The program can't start because libpng16.dll is missing from your
computer."
Which means libpng hasn't compiled into the executable.How do I fix that without reference the whole pnglib project code into my executable project?
On Windows a .lib is a library file, usually this simply contains code that loads a dll, looksup the exported functions and provides wrappers to them. But, you can build the lib differently so that instead of these wrapper stubs, it contains the actual binary code. The operation and structure of the .lib is the same - what code it contains depends on how its built.
So, if you've built libpng16 as a 'dynamic' lib/dll pair then you will need the dll part when you deploy it. If you built it as a 'static' lib only, then you'll get what you want.
The point is - you need to build the lib in the format you want in the first place. It is not possible to take a lib/dll pair and convert it into a static lib, nor is it possible to merge a dll into your executable. (well, not possible after you've built it - perfectly possibly if you change the lib's settings and recompile to produce in static lib form, of course)

Visual Studio 2010 - Create Convenience Static Library OpenCv

For learning purposes, i wanted to create a static library, a "package" of the lib files used in opencv to then link it against my app "opencvuser". Doing so, i get tremendous amounts of erros. (LNK2005 and LNK2019)
My Setup:
Project: staticLib
I've created a static library application without precompiled headers.
Under librarian i've put D:\OpenCV248\build\x64\vc10\staticlib as an additional library
directory. And I've specified all available .lib files as additional
dependencies. (opencv_core248d.lib, opencv_imgproc248d.lib, opencv_highgui248d.lib, ...) Source
Project: opencvuser
I've added C:\OpenCV240\build\include as an additional include directory
Then i've listed "staticLib" under "Properties -> References"
What i expect: Now i should get the same functionallity, as i would add the opencv lib files instead of my built staticLib.lib is my expectation correct?
What i've checked so far:
All Projects are x64
Runtime-Library is set in both Projects to "Multi-threaded Debug"
Anyone knows if the Runtime-Library setting on the static libraries are set to "Multi-threaded Debug"?
You are getting those linker errors because the OpenCV libs you are trying to use were statically linked against the CRT. In your project, you are dynamically linking to CRT and these things won't mix. I would recommend that you don't try to create a "package" of all the OpenCV libs and instead just link to the specific libs you need where you need them.
But I am also going to show you how to solve your problem:
You need to recompile OpenCV without statically linking to the CRT.
You can check out the OpenCV documentation for instructions on how to compile OpenCV using CMake and Visual Studio 2010.
When you run CMake, after you pressed the "Configure" button, look for an option called "BUILD_WITH_STATIC_CRT" and disable it. Then you can press "Generate", open the solution with VS2010 and compile OpenCV.
In your VS2010 project, use the following settings:
In the "opencvuser" project configuration, under Librarian, additional library directories you need to add the path to where the .lib files that you built are located. For me, it's in "c:\opencv248\mybuild\lib\Debug\".
Under Additional Dependencies, you need to include all the OpenCV lib files (opencv_core248d.lib, etc). I also needed to include Comctl32.lib and zlibd.lib because if I didn't I would get some linker errors.
Here are the dependencies I put in:
opencv_calib3d248d.lib
opencv_contrib248d.lib
opencv_core248d.lib
opencv_features2d248d.lib
opencv_flann248d.lib
opencv_gpu248d.lib
opencv_haartraining_engined.lib
opencv_highgui248d.lib
opencv_imgproc248d.lib
opencv_legacy248d.lib
opencv_ml248d.lib
opencv_nonfree248d.lib
opencv_objdetect248d.lib
opencv_ocl248d.lib
opencv_photo248d.lib
opencv_stitching248d.lib
opencv_superres248d.lib
opencv_ts248d.lib
opencv_video248d.lib
opencv_videostab248d.lib
Comctl32.lib
zlibd.lib
Also, in the "opencvuser" project you need to add an empty .cpp file. If you don't add this file, the solution will be empty and Visual Studio won't compile it. I just added a file called "dummy.cpp" to the project. That file is completely empty. Don't put a "main()" function in it because it will collide with the main function in the other project and you will get an error.
In the "staticlib" project, under Linker->General, Additional library directories, you need to include the path to the opencvuser.lib file. For me, it's "..\debug". Also, under Linker->Input, Additional Dependencies, you need to add the "opencvuser.lib" file.
Set project dependencies
You also need to make sure that the projects are built in the right order (first opencvuser, then staticlib). To do this, right-click on the solution and choose Properties. In that window, under Common Properties->Project dependencies, make sure that "opencvuser" does not have a dependency on "staticlib", but "staticlib" must have a dependency on "opencvuser".
That's it, now your project should work. Here are the contents of the two files, and the project running.