Static ZLIB (1.2.8) linking on Visual Studio 2012 - visual-studio-2012

I can't, for the love of God, to static link the ZLIB libs. I have been struggling for a couple hours now with no success. Well, I have followed this tutorial and successfuly compiled both zlibstat.lib and zlibwapi.lib for 32 bits. After setting up my project to use the ZLIB folder with the libraries (Linker > General > Additional Library Directories) and setting zlibwapi.lib (only) as an dependency (Linker > Input > Additional Dependencies) I got it to work, however, that was a dynamic link (I need to distribute my application with the ZLIB dll). I usually use dynamic linking on Debug and static on Release.
I have tried looking for what the hell is the zlibstat.lib and whats it used for, if not for static linking, assuming the "stat" suffix.
Are there any preprocessor to be added into my project, something like ZLIB_STATIC or something, to use static linking of ZLIB or should I have never removed the ZLIB_WINAPI from the zlibstat project, just like the above link told me to do? Is it impossible to static link ZLIB (then, whats zlibstat.lib for?)?
I am pretty lost. Any help is GREATLY appreciated.
Edit (Extra information):
Errors:
error LNK2001: unresolved external symbol _inflateInit_#12
error LNK2001: unresolved external symbol _inflate#8
error LNK2001: unresolved external symbol _inflateEnd#4
Linking:
Unlike the dynamic link (that worked) where I added zlibwapi.lib as a dependency, for the static linking I'm trying to achieve I added zlibstat.lib as a dependency instead! No other libs were added!
This question might look like this (kind of).

I have finally managed to solve my problem. For those that end up in such a problem, heres how to solve it:
If you followed the tutorial in my first post, you would have removed ZLIB_WINAPI from the zlibstat project's Preprocessor. However, after setting up my own project (setting ZLIB dependencies path, LIB dependencies libraries etc) that uses ZLIB, I 'accidently' included/defined the damned ZLIB_WINAPI macro in the header file I'm using ZLIB, right before including "zlib.h".
One curious thing about this is that when launching the app on debug mode (which was using dynamic linking), everything succeeded and worked like a charm, without any warnings or whatsoever, HOWEVER, on release mode (which was using the static linking), it crashed.
So, to clear things up, the tutorial tells us to remove the ZLIB_WINAPI preprocessor from the zlibstat project, which produces the static lib, whilst the zlibvc project has the ZLIB_WINAPI in its preprocessor. In other words, that means that if we're using different linkings for each configuration (debug/release), we have to add the ZLIB_WINAPI macro or not!
Define the ZLIB_WINAPI macro before including "zlib.h" if youre using dynamic linking (zlibwapi.lib) and that the zlibvc project remains unmodified (assuming you correctly followed the tutorial from the link above) and do not define it if you removed ZLIB_WINAPI from the zlibstat project (like the tutorial tell us to)!
One helpful macro I used on my own project is as follows:
// Since we used dynamic linking for debug, we have to define the ZLIB_WINAPI
#if defined(_WIN32) && defined(_DEBUG)
#define ZLIB_WINAPI
#endif
#include <zlib.h>
Things got really confusing and I really hope I was clear enough.

Related

How to get object file to link first?

I'm trying to compile a Windows DLL for code originally intended for a Unix platform. One problem I have is that Windows fopen() defaults to O_TEXT, but Unix defaults to O_BINARY.
Windows recommends two ways to solve this:
Use _set_fmode() function, didn't work for me probably because I could not call it from correct context.
Link with binmode.obj object file. This file is included with the compiler, and the compiler knows where to look for it.
The latter worked for my own code, but it does not seem to work for third party static libraries. Looking at the linker output, I can see that static libraries are included before binmode.obj, but binmode.obj was included before my own object files.
The real solution should be to persuade all external libraries to include binmode.obj, but this is somewhat non-trivial and might incur significant maintenance overhead in the future.
So I'd like to try to move the binmode.obj to the beginning of the linker command line, but this proved to be surprisingly difficult. I've tried:
target_link_libraries( mylib PRIVATE binmode.obj ) - Got correct position, but got renamed to binmode.obj.lib casuing linker error.
Tried making a static library with binmode.obj as a pre-compiled object, but got an error that the file has a relative path. I have no idea how to make it a full path.
Tried adding it as a linker flag in different ways, even including using toolchain file, but it all ended up with binmode.obj being placed after libraries.
I'm now out of ideas and feel I need help with this. Any suggestions how to fix this?
#fabian's comment made me read the right part of CMake documentation, which made me realize that UNKNOWN library type could be used. Using the following code in CMake I could make binmode.obj appear before all libraries:
add_library( binmode_obj UNKNOWN IMPORTED GLOBAL )
set_target_properties( binmode_obj PROPERTIES IMPORTED_LOCATION binmode.obj )
target_link_libraries( mylib PUBLIC binmode_obj )
This solved my problem of trying out if link binmode.obj before libraries might fix my original problem. It didn't, unfortunately. But that is another problem...

Building R Package that uses RcppArmadillo, RcppEigen and depends on Cpp11 Plugins

I followed all the procedures explained so far about this matter either in this website or published notes by Dirk, Hadley or others. However, I still have problems in building my package due to the issue regarding cpp11 plugin.
I used RcppArmadillo.package.skeleton() function. I put my cpp file in the src directory. The NAMESPACE file looks as it should which contains importFrom(Rcpp, sourceCpp) line. I also edited DESCRIPTION file and in the LinkingTo section, I added RcppEigen and other packages I use. I finally ran the compileAttributes(verbose=TRUE) function in R and everything looked OK. Therefore, I think I have done everything as I should. I have to also mention that when I compile my code in R using sourceCpp(), it works perfect and is compiled with no errors!
To illustrate better what my dependencies are, I put the first block of my code here:
#include <RcppArmadillo.h>
#include <RcppNumerical.h>
#include <RcppArmadilloExtensions/sample.h>
#include <Eigen/LU>
#include <algorithm>
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::depends(RcppEigen)]]
// [[Rcpp::depends(RcppNumerical)]]
// [[Rcpp::plugins(cpp11)]]
The problem is when I build my package and I get errors and warnings for the lines I have auto type which relates to cpp11 plugin.
After searching similar posts on this website, I concluded that I have to force my R compiler to use c++11 and there fore I edited my Makvars file located at ~/.R/Makevars and since I use MAC I added this line:
CXX=clang++ -std=c++11 to that file. However, when I do that those 3 errors go away but 50 new errors are generated as all of the Armadillo variable types, such as mat, uvec, etc are not recognized any more. So I don't know how to fix this.
I think basically putting // [[Rcpp::plugins(cpp11)]] should take care of it as the new version of Rcpp supports this plug in and probably that's why when I run sourceCpp in R I get no errors and everything looks fine. But I don't know what happens when building my package. My Rcpp version is 0.12.8 .
Thank you in advance for any sorts of help.
Plugins for both dependencies (ie other headers) and compiler options are for use by sourceCpp().
Packages do this with LinkingTo: and, for the C++11 directive, either src/Makevars or SystemRequirements. See Writing R Extensions which documents this.

Why would a linker try to link to a file I never told it to link to?

I'm getting a linker error indicating that the linker was unable to open a file (a static library) and therefore it fails. I am having a very difficult time troubleshooting this error because I never told the linker to link to the file which it is failing to open.
I am telling the linker to link to several static libraries. Many of the libraries I am linking to are wxWidgets static libraries. I don't need ALL of the modules from wxWidgets, so there are some which I am linking to and many which I am not. The file which the linker can't open is 'wxbase31ud_net.lib'. Like I said, that file is not among the libraries I am linking to. My immediate thought was that this dependency was being introduced implicitly somehow, perhaps by one of the wxwidgets libraries I WAS linking to. I didn't think static linkage worked this way but I didn't have any other ideas. I have been investigating that possibility and I've found nothing which indicates that is the case.
I set the build output verbosity to maximum, and the 'wxbase31ud_net.lib' is never mentioned anywhere until the error is reported.
I confirmed in my cmake project that the file in question was never passed back to me from the FindWxWidgets module, and was never referenced in any of the lists of files I associate with the target.
I grepped through the entire project directory and found no reference to the file anywhere, including the cmake-generated project files (visual studio project files).
What could be causing the linker to try and open this file?
Edit: Also, to be clear, the error I'm seeing is LNK1104
it's probably from a #pragma comment(lib,"???") except in the case of wx the argument to the pragma may be complex macros and it will be difficult to grep. This particular one may be from setup.h with #pragma comment(lib, wxWX_LIB_NAME("base", "")). You should be solving this by adding the directory with the wx libs to the linker's search directories.
The answer by zeromus is correct, this is almost certainly indeed due to including msvc/wx/setup.h which contains #pragma comment(lib)s. Possible solutions:
Simplest: build all the libraries, this will solve the errors and it's not a problem to link with a library you don't use.
Also simple but slightly less obvious: predefine wxNO_NET_LIB when building your project, this will prevent the file above from autolinking this particular library. You may/will need to define more wxNO_XXX_LIB symbols if you're missing other libraries, of course.
Less simple but arguably the least magic too: stop using $(WXWIN)/include/msvc in your include path, then wx/setup.h under it won't be included and nothing will be linked in automatically. The drawback is that you will have to specify all the libraries you do need to link with manually.

Executable exporting symbols BUT not getting exported as they are unreferenced by the executable itself

I have a particular use case where executable needs to export certain symbols, which are imported and used by the dynamically loaded DLLs the executable loads on runtime.
The executable links with some static libraries, which actually have symbols that are exported while the DLLs use these static libraries headers to import those symbols.
If these symbols are not used or un-referenced in the executable, then the linker removes them and hence they do not get exported and hence not available for DLLs at load time.
This i solved on GCC / clang using --whole-archive and -force_load option respectively.
What about MSVC on windows? I use __declspec(dllexport) and __declspec(dllimport) for exporting and importing symbols on windows.
EDIT:
For code reference, you can find the code here: https://github.com/hunkabhicupid/exeexport
The issue is something similar to these posts 1, 2 BUT the answers to these posts did not help me find a solution or i did not find them useful.
Problem: On windows, STATIC LIB which contains an OBJ file that has a function marked __decl-spec(dll¬export) but if the same is not used in the EXE, function does not get exported from the EXE. On other platforms also we have the same problem BUT there we have compiler options like --whole-archive / -force_load, do make it work.
Links:
Link1
Link2
Only solution that come to my mind is to not create STATIC libs, rather include all code (static LIBS) in the executable then:
1. It works on Windows
2. It works on Linux without --whole-archive
3. It works on Mac OS X without -force_load
4. We also need not worry about if 2 & 3 include the dead code, exe bloat etc.
This is the only solution till the linkers become smart and throw out every unused symbol, except those marked specifically for external consumption i.e. marked to be exported.
Does dumpbin /exports {dll} show you the exports properly? Perhaps you should try dumpbin /exports {import lib}?
Based on the info so far I'm guessing the problem is not that the symbols are not exported but rather one of build order. If you get 'unresolved externals' when linking the dll, it seems you expect the exe-exported symbols to be resolved by the linker when linking the dll, but the exe is not built yet. (you probably wired it to reference the dll, so it builds only after the dll is linked).
One way to go about it is to have the dll LoadLibrary the exe and GetProcAddress the functions you want - but that really is a contrived way to achieve what you're after. If these symbols are defined in a static library, why not have both the exe and the dll link against it?

How can I force MSVC++ to ignore CRT dependencies of a static library?

I don't know if it's possible to do this, but I would like the /NODEFAULTLIB to be applied to a static library project.
I have many application projects (A.exe, B.dll, C.dll) that use a common static library D.lib.
This library has a lot of code and also has other .lib dependencies as well. One of them is the openssl library, which seems to have been built for win32 against the Release version of the CRT (i don't have the original project/sources).
So far, to avoid the mixing of the Release/Debug versions of CRT, I have to put the /NODEFAULTLIB:msvcrt.lib linker directive in all leaf projects (A.exe, B.dll). This works but I think it's not the ideal way of dealing with that issue.
I tried to put this property in D.lib project, but it has no effect.
Is there a way to force msvc++ to ignore the msvcrt.lib dependency from the 3rd party library?
A .lib does not have any linker settings because you don't link it, you link to it. A .lib is just an archive of .obj files, sort of like an uncompressed .zip file - that's why you have to put the setting on all projects that link to it.
If you're using VS2005+ you could use property sheets so that you only have to put the setting in one place and then use that property sheet in all projects.
However, OpenSSL is just that - Open Source, so you should be able to get the source for the version you are using and build it again (and add it to your version control system of course). I thought OpenSSL could be built as a DLL or LIB, which would solve your problem as the DLL would not interfere with the linking of your code.
Failing that, you always have the option of slitting your functionality out into a separate DLL so that you only have issues with one project.
To prevent your distributed static link library from depending on a specific MSVC runtime library you need to set this compiler option (in Visual Studio 2010 it looks like):
Configuration Properties -> C/C++ -> Advanced -> Omit Default Library Name = Yes (/ZI)
Now your users can link to your release built static lib from their debug build and not try to link to the incorrect runtime library causing problems, as well as linkers warnings.
Note that may cause link errors if your library actually depends on a specific runtime library or its behavior, and compatible components are not provided in some other way.
My understanding is that if library LIB in linked statically into a DLL, the DLL contains already all relevant code from LIB. Therefore, this coupling cannot be removed. This is just based on my understanding of statical linking, not on experiments.

Resources