Prevent Visual Studio from exporting a function in a static library - c

Odd question: I'm building a static library with Visual Studio and I'm using a source file with a list of utility functions that I also use in the executable project that is importing the static library. As a result I'm getting errors like this:
4>newfuncs.lib(util.obj) : error LNK2005: _shift_left already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _chop already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _crc_begin already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _crc_update already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _crc_result already defined in util.obj
4>newfuncs.lib(util.obj) : error LNK2005: _strtok_r already defined in util.obj
Anyone know how I could figure out how to get Visual Studio to NOT export the functions in util.obj, since those are natively present in the actual executable project.

The simple answer is to pull the functions in util.obj into their own library and have your library and the executable link it.
If you only need the utility functions in a single source file, you can move them into the .c file and declare them static, then they won't have any linkage outside the file they're defined in.
If you really want to do it by not exporting symbols, mark the function with __declspec(selectany), which will tell VS that multiple definitions of the function are equivalent and it's free to choose whichever it likes (make sure they're actually the same!).

So, figured it out: if you use the pragma statement it will integrate the functions into your static library. In my case I put:
#pragma comment(lib, "libev.lib")
in a header and it imported libev into my library. Now when I actually wrote my executable I only needed to link against my library: there is no additional libev dependency.

Related

Linking error while customizing zcalloc and zcfree functions in the zlib library

While integrating the Nurbs library (http://www.rhino3d.com/opennurbs) into my project, I run into the following linking error with the library zlib.
1>zlib.lib(deflate.obj) : error LNK2019: unresolved external symbol _zcfree referenced in function _z_deflateInit2_
1>zlib.lib(inflate.obj) : error LNK2001: unresolved external symbol _zcfree
1>zlib.lib(deflate.obj) : error LNK2019: unresolved external symbol _zcalloc referenced in function _z_deflateInit2_
1>zlib.lib(inflate.obj) : error LNK2001: unresolved external symbol _zcalloc
I checked the function
z_deflateInit2
in the file deflate.c from ZLIB source code,
and guess that this function cannot find the implementation of the two functions zcfree adn zcalloc. The reason is that the Nurbs library customize the function zcfree and zcalloc, which is done in two steps.
Cusomize zcalloc and zcfree in the the Nurbs library code.
opennurbs_zlib.h
extern "C" {
voidpf zcalloc (voidpf, unsigned, unsigned);
void zcfree (voidpf, voidpf);
}
These two functions are implementated in the file opennurbs_zlib_memory.cpp as following
#define voidpf z_voidpf
voidpf zcalloc (voidpf, unsigned items, unsigned size)
{
return oncalloc(items, size);
}
void zcfree (voidpf, voidpf ptr)
{
onfree(ptr);
}
Compile the ZLIB library with the flag: MY_ZCALLOC and Z_PREFIX
As I checked, both these two steps are done, but why I still got the linking error.
Could you give me some advices?
Thanks so much!
Update:
#Dale Lear: thanks for your support. But my situation is different. Instead if linking with the opennurbs.lib, I tried to integrate the source code of opennurbs into my project (like the surface module of point cloud library: http://www.pointclouds.org/blog/trcs/moerwald/). I build zlib from the project zlib in opennurbs solution. This zLib is built with the modified zconfig.h (Z_PREFIX and Z_MYCALL, i guess so, is defined). This means that the function zfree and zalloc is still waiting for implementation. But why does ZLib does not take zcfree() and zcalloc from opennurbs_zlib_memory.cpp. I don't understand why does it take.
From your description and the error log you provided, I'm guessing that the situation is:
1) You are building a Windows program using some version of Microsoft's C++ compiler.
2) You want to statically link with zlib.lib
3) You want to statically link with opennnurbs_staticlib.lib
I cannot determine what version of Microsoft's C++ compiler or opennurbs you're using.
If you are using the latest public release of opennurbs (version 2013-07-11), then the zcfree() and zcalloc() functions are defined in the file opennurbs_zlib_memory.cpp.
If you build opennurbs_staticlib.lib using the opennurbs_staticlib.vcxproj project file that is included with the source code, it will compile opennurbs_zlib_memory.cpp and include the zcfree() and zcalloc() functions in it in opennurbs_staticlib.lib. If you build zlib using the zlib code and zlib/zlib.vcxproj file that is included with opennurbs 2013-07-11, then it will be built with all the necessary defines and you will have two static libraries, zlib.lib and opennurbs_staticlib.lib, that link with all dependencies resolved.
If you are using customized project files, the first thing to check is that you are statically linking the results of compiling opennurbs_zlib_memory.cpp in some way.
If you want to use opennurbs as a DLL, I'd suggest building opennurbs.dll with the opennurbs.vcxproj project file that comes with the source code. This opennurbs.dll will statically include zlib.lib when it links and you do not have to link with anything except the resulting opennurbs.lib to use the DLL version.
Does this help?
-- Dale Lear

adding extra (pthread) dll in visual studio 2010 [duplicate]

Just to be clear - I have searched the depths of the internet and back for information on how to do this
I'm looking for assistance setting up pthread_Win32 to work with Visual Studio 2005. I'm programming in C, and I have a number of multithreaded assignments to write using pthread.h. However, since pthread is native to unix, I have to write all of my code, ftp it, and then ssh to my class' remote unix system to run it. It makes development take so much longer, and it's incredibly inefficient. I'd love (more than anything) to be able to get this working on my win32 machine, so I can develop in visual studio as I've been doing for quite some time.
I've installed the pthread.lib file and pthread.h file into the respective lib/header directories, where all of the other files are. The DLL on the other hand (the actual library), I've placed in c:\windows\system32. I've tried to add the DLL as a dependency (right click project -> references -> Add new reference), but as others have stated, all I get is a blank dialogue box with no option to add any DLL files or anything. It seems to recognize the header file, but I get these errors when I compile:
1>Linking...
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_join referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_create referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_exit referenced in function _fcount
From my research, I've determined that this is a problem with the DLL, and I'm assuming it can't find the definitions of the functions I've referenced in my code. I've searched high and low and I can't seem to figure out any way to overcome this problem. I've added the directories of the lib/header files to my linker, just in-case, but that didn't solve the issue. I need to do something, in visual studio, to specify that I need pthreadVC2.dll as a project dependency - and it seems to be impossible (and extremely frustrating) at this point.
Any words of wisdom?
Thank you very much
I have been through this problem recently.
It appears that the __imp__ prefix is prepended to the function name in case pthread.h is included in dynamic linking mode.
Simply add the PTW32_STATIC_LIB define to your project or your source code before including pthread.h should solve the issue.
#define PTW32_STATIC_LIB
#include <pthread.h>
Although, I am not completely over as Visual Studio now trys to link with the _[FuncName] instead of [FuncName]
In visual studio, function seems to be declared differently wether you are going to link them statically (.lib) or dynamically (.dll).
To define a function you will link dynamically :
__declspec (dllimport) int myFunc(int myArgs) ;
To define function you are exporting for dynamic linking :
__declspec (dllexport) int myFunc(int myArgs) ;
And the simpliest, to define a function you will link statically:
int myFunc(int myArgs) ;
[EDIT]
I am going on my investigations and went through this on MS help center.
It seems that to avoid the _[FuncName] effect it is required to define a static linked library function by the following:
int __cdecl myFunc(int MyArgs) ;
Have you added pthreadVC.lib (or whichever particular lib you need) to the project property:
Linker/Input/Additional Dependencies
It's not enough to just have the lib file in a particular directory, the linker needs to be told to use it as an input.
Just adding pthreadVC2.lib to linker list is not suffiecient.
You also have to add addtional lib like pthreadVCE2.lib and pthreadVSE2.lib.
I am facing same issue but then I resolved it through adding these files.

how to get rid of "LINK : warning LNK4049: locally defined symbol "_xmlFree" imported"?

I build one DLL on windows with microsoft-visual-c 6.0 including the source code from libxml2. Now I have used some xmlFree() calls in my code and I now get the linker warning LNK4049.
I have not the slightest idea, how to get rid of this warning. I googled, but all info I found was above my comprehension (I use normally gcc under solaris). Is there a simple receipt (add/remove compiler-flag or #define/#undef or similar)?
Thanks,
Peter
I was getting this warning when statically linking against libxml2_a.lib with MSVC 11. I haven't tried the DLL version so I'm not sure if it is affected in the same way.
The solution was to define these symbols in your project or makefile to tell the libxml2 header files to assume static linkage and avoid dll-importing and dll-exporting the xmlFree variable at the same time:
LIBXML_STATIC
The same applies to libxslt/libexslt too:
LIBXSLT_STATIC
LIBEXSLT_STATIC
Hope this helps.
I will add bit more context for others who face similar error like following.
We did libxml upgrade from 2.9.4 to 2.9.14 and we observed following errors which are similar to above .
warning LNK4217: locally defined symbol xmlStrcmp imported in function
"void __cdecl ::updateRunElement(struct _xmlNode *,class xml::XmlDoc &,struct _xmlNode *,struct const &)"
(?updateRunElement#YAXPEAU_xmlNode##AEAVXmlDoc#xml#2##2##Z)
LINK : error LNK1218: warning treated as error; no output file generated
warning LNK4217: locally defined symbol xmlFreeDoc imported in function "public: __cdecl xml::XmlDoc::~XmlDoc(void)" (??1XmlDoc#xml##QEAA#XZ)
LINK : error LNK1218: warning treated as error; no output file generated
All the other answers for this error points to set runtime library to /md (Multithreaded dll) or viceversa.
I also tried to suppress these warning by
#pragma warning( disable : 4217 1218) and also by project setting "Disable Specific Warnings" but both did not work as keep giving warnings/errors.
But as #vladimir. (Thanks for the answer) suggested defining LIBXML_STATIC as preprocessor in the project where you are using libxml library either as static or dynamically linked should fix all these warning errors.

How do I install pthread_win32 (Windows pthread / posix thread library) for Visual Studio 2005?

Just to be clear - I have searched the depths of the internet and back for information on how to do this
I'm looking for assistance setting up pthread_Win32 to work with Visual Studio 2005. I'm programming in C, and I have a number of multithreaded assignments to write using pthread.h. However, since pthread is native to unix, I have to write all of my code, ftp it, and then ssh to my class' remote unix system to run it. It makes development take so much longer, and it's incredibly inefficient. I'd love (more than anything) to be able to get this working on my win32 machine, so I can develop in visual studio as I've been doing for quite some time.
I've installed the pthread.lib file and pthread.h file into the respective lib/header directories, where all of the other files are. The DLL on the other hand (the actual library), I've placed in c:\windows\system32. I've tried to add the DLL as a dependency (right click project -> references -> Add new reference), but as others have stated, all I get is a blank dialogue box with no option to add any DLL files or anything. It seems to recognize the header file, but I get these errors when I compile:
1>Linking...
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_join referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_create referenced in function _main
1>main.obj : error LNK2019: unresolved external symbol _imp_pthread_exit referenced in function _fcount
From my research, I've determined that this is a problem with the DLL, and I'm assuming it can't find the definitions of the functions I've referenced in my code. I've searched high and low and I can't seem to figure out any way to overcome this problem. I've added the directories of the lib/header files to my linker, just in-case, but that didn't solve the issue. I need to do something, in visual studio, to specify that I need pthreadVC2.dll as a project dependency - and it seems to be impossible (and extremely frustrating) at this point.
Any words of wisdom?
Thank you very much
I have been through this problem recently.
It appears that the __imp__ prefix is prepended to the function name in case pthread.h is included in dynamic linking mode.
Simply add the PTW32_STATIC_LIB define to your project or your source code before including pthread.h should solve the issue.
#define PTW32_STATIC_LIB
#include <pthread.h>
Although, I am not completely over as Visual Studio now trys to link with the _[FuncName] instead of [FuncName]
In visual studio, function seems to be declared differently wether you are going to link them statically (.lib) or dynamically (.dll).
To define a function you will link dynamically :
__declspec (dllimport) int myFunc(int myArgs) ;
To define function you are exporting for dynamic linking :
__declspec (dllexport) int myFunc(int myArgs) ;
And the simpliest, to define a function you will link statically:
int myFunc(int myArgs) ;
[EDIT]
I am going on my investigations and went through this on MS help center.
It seems that to avoid the _[FuncName] effect it is required to define a static linked library function by the following:
int __cdecl myFunc(int MyArgs) ;
Have you added pthreadVC.lib (or whichever particular lib you need) to the project property:
Linker/Input/Additional Dependencies
It's not enough to just have the lib file in a particular directory, the linker needs to be told to use it as an input.
Just adding pthreadVC2.lib to linker list is not suffiecient.
You also have to add addtional lib like pthreadVCE2.lib and pthreadVSE2.lib.
I am facing same issue but then I resolved it through adding these files.

Link error LNK2005 when trying to compile several CUDA files together

I have a CUDA program that works fine, but that is currently all written in one file. I'd like to split this big file into several smaller ones, in order to make it easier to maintain and navigate.
The new structure is :
foo.cuh
foo.cu
bar.cuh
bar.cu
main.cu
The .cuh header files contain structs and function prototypes, and the .cu files contain the function definitions (as usual). The main file includes bar.cuh, and bar.cu includes foo.cuh. All the .cu files include cutil_inline.h, in order to be able to use the CUDA functions.
Hence :
// main.cu
#include "bar.cuh"
#include <cutil_inline.h>
int main() [...]
// bar.cu
#include "bar.cuh"
#include "foo.cuh"
#include <cutil_inline.h>
[...]
// foo.cu
#include "foo.cuh"
#include <cutil_inline.h>
[...]
The problem is that when I compile my Visual Studio 2008 project with this new structure, I get tons of link errors :
error LNK2005: "void __cdecl __cutilBankChecker(unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,unsigned int,char *,int,char *,int)" (?__cutilBankChecker##YAXIIIIIIPADH0H#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cutilCondition(int,char *,int)" (?__cutilCondition##YAXHPADH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cutilExit(int,char * *)" (?__cutilExit##YAXHPAPAD#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "int __cdecl cutGetMaxGflopsDeviceId(void)" (?cutGetMaxGflopsDeviceId##YAHXZ) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeCallNoSync(enum cudaError,char const *,int)" (?__cudaSafeCallNoSync##YAXW4cudaError##PBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeCall(enum cudaError,char const *,int)" (?__cudaSafeCall##YAXW4cudaError##PBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cudaSafeThreadSync(char const *,int)" (?__cudaSafeThreadSync##YAXPBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
error LNK2005: "void __cdecl __cufftSafeCall(enum cufftResult_t,char const *,int)" (?__cufftSafeCall##YAXW4cufftResult_t##PBDH#Z) already defined in cuda_generated_foo.cu.obj cuda_generated_bar.cu.obj
I understand what they mean (all those symbols already defined are part of cutil_inline.h) but I have to include this header in all files, otherwise it does not compile. What am I doing wrong ?
UPDATE: To clarify the situation :
* with all code in one big file, it compiles, links and runs fine
* with the new structure (several smaller files) and including cutil_inline.h in all .cu files, it compiles correctly but fails during linking
* with the new structure and including cutil_inline.h only in the main file, it fails during compilation, saying that the cutil function are unknown in the files where cutil_inline.h was not included (as expected, but I had to try everything)
- List item
This error also happened in my program. I solved it by adding the keyword inline before __global__ or __device__. Then, the error went away.
Somehow, the functions in cutil_inline.h aren't flagged as "inline" when they are compiled.
If you got this error in a normal non-Cuda C++ project, the answer would simply be that you have function definitions (not just declarations) in the header file and the "inline" keyword in missing.
You might have to generate the corresponding .i files (pre-processor) output to really see what's going on after all macro expansion.
EDIT 1/2/2009
If you can't figure out what's wrong just by reading the .h files, because of some macro expansion obfuscation, here's how you generate the .i file:
In the Visual Studio "Solution
Explorer" window, right-click on the
source file and choose "Properties".
In the properties tree, select
"C/C++", "Preprocessor".
Change the "Generate Preprocessed
File" from "No" to one of the other
options.
Then compile the file. The compiler
will write the preprocessor output
to a file and then stop without
actually compiling. You can see in
the .i file produced what the final
result of all macro expansions is.
You will have to go back and reset
that property back to "No" in order
to get the project to compiler to
work properly again.
Do you need to link with the cutil library (i.e. cutil32D.lib for 32-bit debug etc.)?
For some reason you have multiple definitions. Are you using the NVIDIA Cuda.rules file to enable Visual Studio to compile your .cu files to .obj files? It looks like you have modified the rules to link with cutil, whereas you should use the NVIDIA Cuda.rules to tell VS how to compile .cu to .obj, then modify the standard linker properties to pull in the cutil library.
Consider using 'static' instead of 'inline' to avoid warnings during compilation. That's according to this answer. The causes to this error are discussed here:
However, that's most likely caused by including .cuh files (containing your kernels) into a usual .h file. Either:
make a separate dll filled with your .cuh and .cu files, and link against that;
or rename your .h files to .cuh and .cpp to cu. For this option, make sure to also do this: https://stackoverflow.com/a/20057857/9007125
In the context menu for your .cu file (that you just renamed), select Properties. Then go to General and make sure Item Type is set to CUDA C/C++.
Mind you, the second option will make your project compile a lot slower (compiles 4 times slower)

Resources