Suppress import library creation - Visual C++ linker - c++

Is there, a perhaps undocumented way to prevent linker from creating IMPLIB for a DLL or an EXE, despite having __declspec(dllexport) directives within the source code?
Specifying no /IMPLIB results in .LIB created with a default name.
This is important when the declspec directives arrive from 3rd party code which is not under control. This is, for example, the case with boost::serialization. A possible solution would be a way to "undeclare" a DLL export. DEF file also cannot do it (AFAIK), because it can only add to the export list but not remove from it.

Many 3rd party code does not use __declspec(dllexport) directly, but hides it under a macro in order to control it. Typically they want to switch between dllexport and dllimport depending on where the header file is included (inside the dll implementation or by the user of the dll)
If that is the case in the library you try to include it should not be too difficult to alter this behavior via macro manipulation to meet your exact needs.
For example, boost::serialization check the config.hpp and see how you can control it.

According to this, if you supply the .exp file when linking, the linker will not create a .lib file. To be honest, though, I can't tell if this helps in your case.

There is not any way to do this with a linker option, using /implib:"nul" fails miserably when the linker uses it to name the .exp file. The most practical solution is to remove the files again after a build. Project + Properties, Build Events, Post-Build event and paste:
del $(TargetDir)$(TargetName).lib
del $(TargetDir)$(TargetName).exp

Using a .def file containing your exported functions marked with the PRIVATE keyword will tell the linker to skip placing the symbol in your import library.
Refer to this MSDN page for more information about MSVC's .def file syntax.

Nowadays, you can use /NOIMPLIB and /NOEXP in the advanced linker options as per this bug ticket. Works for me on Visual Studio 2019.

Related

Construction of a .dll file and the intermediate .lib

Below is an excerpt from link1.
Microsoft introduced __export in the 16-bit compiler version of Visual
C++ to allow the compiler to generate the export names automatically
and place them in a .lib file. This .lib file can then be used just
like a static .lib to link with a DLL. In newer compiler versions, you
can export data, functions, classes, or class member functions from a
DLL using the __declspec(dllexport) keyword. __declspec(dllexport)
adds the export directive to the object file so you do not need to use
a .def file.
I understand the above paragraph to an extent but not very well.
Below is an excerpt from link2.
When building the DLL, the linker uses the .def file to create an
export (.exp) file and an import library (.lib) file. The linker then
uses the export file to build the DLL file. Executables that
implicitly link to the DLL link to the import library when they are
built.
Now, this makes me confused and made me ask the below questions:
Could anybody, in simple words, tell me what the term exporting
really means? I believe this is making an object accessible from one
piece of the code to other - but hey !!
When building projects with old libraries, I see .def file in majority
of them. But the latest compilers automatically exports objects. Would
the presence of the .def file cause any conflict when converting a older
version visual studio project to the newer one?
What is the use of the .lib(the so called import file) after the generation
of the .dll. Can it be safely deleted?
ARRGGGH !! What is the difference between a static library(.lib) and import library(.lib)? Blunder, huh? But still !!
Is the windows specific phenomenon? I believe it is not. What is the Linux counterpart of the so called import file?
Please feel free to rephrase the question if it is not already lucid.
tell me what the term exporting really means?
It simply means telling the linker that it needs to put an entry into the DLL's export table. The operating system loader uses it later to glue code in different modules together at runtime.
I see .def file in majority of them
Could be very old projects. Or it was just never started as a project that was meant to create a separate module. Like a static library so the source code doesn't have the __declspec attributes. Cross-platform libraries are pretty likely to fit that bill. The C and C++ language specifications still don't have a way to create modules in a standardized way. Everybody does it, nobody does it the same way. Massive time drain.
What is the use of the .lib(the so called import file)
It is necessary in the project that uses the DLL. The linker needs to know that the identifier lives in another building and can't be resolved at link time. It puts an entry in another table that the operating system loader uses, the import table. It is a very simple file, it just list the names of the exported identifiers. Theoretically the DLL itself could be used by the linker to figure this out. Practically that doesn't work because the exported name doesn't have to match the actual name.
What is the difference between a static library(.lib) and import library(.lib)
A static library contains code that is linked into the project that uses the library. An import library does not contain code, just a hint that the code is available elsewhere.
Is the windows specific phenomenon?
Roughly, yes. The Unixes have the same concept but implement it very differently.

Forbid linking against a c++ method

I try to forbid the use of a method, to have a compile error if some piece of code use it.
This is a proprietary legacy module, that I know that some methods are problematic. We have headers files, and dlls.
I can't figure out all the use of this method in the huge project I use (lot of defines, some implicit cast...)
Can the compiler stop (or just warn) if it detect the use of this method?
You can use __declspec(deprecated) in Visual C++ to generate warnings for use of a specific function. You can use #pragma deprecated to deprecate the usage of any symbol (including macros).
See more information on MSDN. This can generate warnings or errors (depending on computer flags) but you can supress them where needed with additional #pragmas
Well, not sure if it works or not (so please correct me), but you might want to play with making libs out of your DLLs
something along the line, from VS command prompt:
dumpbin /exports yourdll.dll
you'll get export symbols output and copy it into .def file
edit .def file to remove unwanted symbols
make lib and link it to your app
lib /def:C:\mydef.def /OUT:C:\mylib.lib

How to enforce linking an object module or symbol from a library in visual studio [duplicate]

This question already has answers here:
C++ static variable in .lib does not initialize
(2 answers)
Closed 4 years ago.
I have some legacy C++ code which I wan't to move to a (static) library (.lib).
However, the legacy C++ code uses constructors of global objects to do some initialization (pls don't discuss that this may be bad practice - it basically works and it its legacy code I don't want to change). This works as long as the global object becomes part of the .exe, which always happens if the source code and hence its .obj file, containing that global object, is part of the .exe project in visual studio (2008). If I move the module to the library, the linker will not include this module, since it is not referenced by any module of the .exe. So I need to enforce linking that module into the .exe
I know the linker cmd line option /INCLUDE, which I can also specify using #pragma comment(linker, "/iclude: ... "). However, there are some problems:
I need to specify the decorated name of the C++ object. I can work around this by some dummy extern "C" symbol such as an int, still not nice and there are a lot of them.
I either have to specify all symbols in the linker commandline (as I mentioned, there are a lot of them) or, if I use #pragma, the #pragma statement has to be part of some module of the .exe (or included as headerfile by such a module). It did not work to place the #pragma into the source code where the symbol is defined (in the library). So both ways enforce linking the symbols by the build process of the .exe (either by commandline or by sourcecode of the .exe) but not by the code of the library.
So what I'm looking for is a way in visual studio 2008 to enforce linking a module by definition of the module of the library like: "if library X.lib is specified as input of the linker, then module Y.obj of X.lib will always be linked into the .exe, regardless any references by other modules". Preferably not using decorated names.
So I'm going to answer my own question. In fact it is another workaround.
The workaround is not a linker option but a VS setting, that only works if both, the .lib and the .exe are in the same solution and if the dependency of the .exe to the .lib is correctly sepcified in the solution settings.
In the "Linker Property Page" of the VS project of the .exe set "Use Library Dependency Inputs" to "Yes" so the .obj(s) of the .lib will be used instead the .lib as linker input. Since the linker includes all .obj(s) specified as input, whether referenced or not, the effect is similar to specifying all source modules of the .lib as part of the .exe project itself.
http://msdn.microsoft.com/en-us/library/024awkd1%28v=vs.90%29.aspx
One drawback is, that this setting is not .lib specific. It affects all dependent .libs in the solution (but not the libs specified as additional input). Check the linker commandline to know the effect.

Export function from DLL in Visual Studio 2010 using DEF

I inherited a huge C++ multi-project solution with many dynamic libraries but without any
__declspec(dllexport)
I learned that one does not necessarily have to insert any dllexport (would be much work) but that one can use a .def file in addition to corresponding .dll instead.
In order to try that I built a "DLL Hello World" project from here, removed the dllexport from the header and...failed desperately. In the words of already cited page, my key question is how to
"[..] use the .def file when building the DLL."
My .def file is (I try the code only with the Add method):
LIBRARY MathFuncsDll
EXPORTS
?Add#MyMathFuncs#MathFuncs##SANNN#Z
How do I use it when building the DLL in Visual Studio 2010 in order to export the Add method?
After having passed half a day in front of this problem, I just found the solution: it is described here.
To resume the process of symbol export with .def files in VS2010 using my own words:
Tell VS2010 to compile a dynamic library (.dll). This is done in the Property Page of the library's project.
Craft a module definition file (.def) by using mangled (decorated) names (at least when Your language is C++). If You make use of dllexport You can display already exported symbols of Your .dll as described here. If You haven't anything exported yet, see this post.
Add the .def to the library definition in its Property Page.
Compile
Verify the correctness of Your work, for example with Dependency Walker by opening the dependent file, e.g. .exe. You should see the just compiled library in a dependency tree below the dependent file. There should be no errors or warnings, e.g. no red colour.
If You have further questions concerning .def files, look out for the terminus "Module definition file".

how to automatically export names in C++ source to be used in DLL

I have a library, written in C++ (and I have its full source). Due to its LGPL license I can only use it with the proprietary software of my company via dynamic linkage (static linkage works fine). So, I need to build it into a DLL. However, the library is quite big and doesn't export anything (hence no .def file and no __declspec(dllexport) statatements in front of the class and global function names). So, when I build a dll, it's useless, as it doesn't have exported names, so it won't link.
In our company we are using MS Visual C++, which by default does
not export names (while, for instance, GNU GCC, when run via MINGW on Windows does). So, the only option I see at the moment is placing __declspec(dllexport) in front of every name in the library that I'm using (and there are thousands), or writing a .def file for those names. But even if I did that, I will not be able to use the next version of the library,
as I'll have to do this job again. I was looking for a tool that does these exports, or generates a .map file, but none really do this specific task
(there are some DEF generators, but they mostly search the result of DUMPBIN /EXPORT which gives nothing in my case). I was searching the web for answers for two days now, but no good result.
Best regards,
Andriy
IANAL But if the library is LPGL they should be open to dynamic linking.
Have you considered modifying the source file and updating Makefile to give a way to generate the dynamic library and getting it approved by the maintainer ? Chances are they will be open to it and future versions will just work.
I don't think that there is such a automation you want.
My suggestion is editing the source code (as you said); using Notepad++'s macros or using Replace Pioneer
Regards