visual studio 2013 options - c++

If .lib files are for static linking and .dll files for dynamic linking why can I specify in C/C++ -> code generation -> runtime library options select multi threaded or multithreaded DLL when building an explicitly static library (ie when making a .lib) or when building a project and linking to a .lib library?

Visual Studio allows you to specify how the CRT is going to be integrated into your project under C/C++->Code Generation->Runtime Library. This project setting controls how C/C++ routines used explicitly or internally (e.g. exception functions or STL routines) are going to be linked to your project.
You can create a static library which uses the CRT dynamically or statically by specifying the /MT or /MD flag during compilation.
Regarding advantages/disadvantages I'm linking this answer which features a pretty good list of points to keep in mind.
One last thing to notice: if your project is going to use multiple static libraries (including your .lib file), you should make sure that this CRT option matches during the linking phase otherwise you might encounter the (in)famous LNK4098 error.

Related

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

Visual Studio: Static Link to Static Library

I've created a Static Library (no mfc is used in it) in Visual Studio and want to link with it in statically linked mfc project (com-dll actually).
When linking mfc-lib I get a bunch of messages symbol is already defined. This is because I linked standard C++ library twice (once in static library, and other in mfc project).
How do I fix it?
There is a workaround with /FORCE:MULTIPLE, but I think this is a bad decision.
When linking static libraries to a DLL or EXE project, you need to take care, that all projects have been compiled to use the same runtime library. So please set all projects to the same "Use of MFC" and also to the same "Runtime library". If you do not do so, then one project might have been compiled to take the fopen function from the standard CRT while another project might have been compiled to take the fopen function from the MFC. Mixing these is a problem for the linker because he does not know which runtime (and in the example: which fopen) to use.
When linking your DLL or EXE project against another DLL project, this is not a problem. You can have a DLL without MFC usage and link your MFC EXE against that DLL.
If you have a util library that you use very often in different projects, then you might consider setting up different build settings so you can build your library in DEBUG and RELEASE and with and without MFC. Then in your EXE project you can pick the library binary that matches your project settings.

Compile a set of functions to .LIB and .DLL at the same time

There is any preprocessor trick or something in which you can compile both, a lib and dll version, at the same time of a set of functions?
The compiler doesn't have to know whether you're making a static or dynamic library -- it just makes object files.
You can then take those object files and pass them to the library manager (creating a static library) or the linker (and create a shared object / DLL), and yes you can do both with the same object files, as long as you use a linker definition file to control DLL exports.
A convenient way to do with with Visual Studio is to set up a DLL project dependent on the static library, and select the "Use Library Dependency Inputs" option for that dependency, in order to ensure that all global objects are included and not just those defined in the same compilation unit as an export. Then the files will only be compiled once, but used to build two libraries. (Of course, if you're running into issues with global objects, your static library is likely broken for other consumers anyway.)
I'm not certain of the details on how to do this in Visual Studio, but basically you'll just have to set up two build products that build from the same source code, but with different build settings, such as a macro that enables/disables the declspec() attributes used in dlls.
I think in Visual Studio this might manifest as having two projects in your solution.
To my best knowledge, you need to create two independent projects sharing the same source files. And qualify the references you want to expose with a preprocessor symbol such as _DLL, substituted with empty for a static lib or with dll_export/dll_import when building or invoking the dynamic lib.
Since the library/DLL option is per-configuration and a single project may have multiple configurations, you can do this by adding (for example) static-debug, dynamic-debug, and so on. This is similar to how the CRT is handled, with static and dynamic, debug and not, and in the past threaded and not.
In order to do this, you'll need to use the configuration manager to add additional configurations for your projects, then you can do a batch build and select any combination of those you like.
You may want to use a text editor to copy the existing configurations and rename them, if you have many custom settings which are in the project/configuration itself (instead of global project or in a split properties file).
Outputting static library or dynamic library does not depend on compiler. It is linker's job. Compiler generates .obj files which are linked by linker into (when conditions are met, such as you need entry point for .exe) what you want.
Specifically, MS linker link.exe has several output flags:
no flag: .exe is produced;
/LIB: static library .lib produced;
/DLL: dynamic library .dll and import library .lib produced;
In case of /DLL you also want to decorate your exported functions/classes with __declspec(dllexport), so linker will put them in the import library. Also, note that static library and import library are NOT equivalent, even though they both have .lib extension. There are also additional files can be produced by the linker: here is link to MSDN article on link.exe options.
EDIT: As Ben pointed out, link.exe /LIB really invokes lib.exe for static library. Running link /LIB yields (Windows SDK 7.1 SP1):
D:\Programs\Windows SDK 7.1>link /lib
Microsoft (R) Library Manager Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
usage: LIB [options] [files]
options:
/DEF[:filename]
/ERRORREPORT:{NONE|PROMPT|QUEUE|SEND}
/EXPORT:symbol
/EXTRACT:membername
/INCLUDE:symbol
/LIBPATH:dir
/LIST[:filename]
/LTCG
/MACHINE:{ARM|EBC|IA64|MIPS|MIPS16|MIPSFPU|MIPSFPU16|
SH4|THUMB|X64|X86}
/NAME:filename
/NODEFAULTLIB[:library]
/NOLOGO
/OUT:filename
/REMOVE:membername
/SUBSYSTEM:{BOOT_APPLICATION|CONSOLE|EFI_APPLICATION|
EFI_BOOT_SERVICE_DRIVER|EFI_ROM|EFI_RUNTIME_DRIVER|
NATIVE|POSIX|WINDOWS|WINDOWSCE}[,#[.##]]
/VERBOSE
/WX[:NO]

Linking error -> Managed DLL to Unmanaged Lib

I have a managed C++ dll which uses a unmanaged C++ lib. I've added the lib file in the managed project's "Additional Dependencies". Unfortunately I get a dozen of std::locale already defined in msvcprtd.lib linking errors.
Any idea? Do I have to build both as dll and link them together?
You probably need to change the runtime library setting for one of your projects so that they are both the same. The "Multi-threaded Debug DLL" option in the runtime library settings means that your project will be linked against the DLL version of the runtime lirary, not that your project is a DLL. Where-as "Multi-Threaded Debug" means it will link against a .lib version of the standard library.
When you link together 2 projects that use different settings, then they end up with duplicate references. One reference from the static runtime library, and one from the DLL runtime library. This is the source of your errors.
Which setting you should pick depends on whether you want to distribute the runtime DLLs with your project (or count on the user already having them). If you want to go for this option, select the DLL runtime library, otherwise select the non-DLL version. The down side of the non-DLL version is that all the runtime library code will be embedded in your DLL/EXE, which will increase it's size.
EDIT: Actually, looking into it a bit more. This link indicates that with CLR projects (which I suspect yours is, being managed C++) you can't use the static linked option, so you need to use the "Multi-threaded Debug DLL" option for both.

Visual Studio: How to specify different runtime libraries for the linker? (/MTd, MDd, etc)

I'm linking to a few libraries in VS2008. If my knowledge of the linker is correct, MTd is for static linking and MDd is for dynamic linking (to a DLL.) My goal is to statically link some libraries and dynamic link others. The project options seems to only have one setting for all libraries in the linker input. How would I do this?
Your project will be given a sensible C Runtime Library default after you set it up, depending on how you answer the New Project Wizard prompts. You can inspect and alter this (if needed) as follows:
right-click the relevant project in Solution Explorer, select Properties
look under Configuration Properties, C/C++, Code Generation, Runtime Library.
Other libraries can be linked however you want, you just specify the library to link to under Linker, Input, Additional Dependencies.
Even if you are linking to a DLL, it will still have a .LIB file (of the correct form for a DLL) to resolve external references, unless you are manually loading the DLL and discovering required function entry points.
You do need to make sure that the LIB files you link to use the same CRT as your app does, or things can go unexpectedly wrong.
No, you're mixing it up. The /MD vs /MT options is only relevant to which CRT version you link. There are two, the static version (/MT) which you should use only if you don't use any DLLs in your project. And the DLL version, a version that every binary in your process can share so that you won't have heap allocation misery. The kind of misery you get into when memory is allocated by one module and freed by another.
Choosing your own libraries is entirely up to you. Mixing and matching is fine, the linker just gets another kind of .lib. An import library instead of a static library. Just keep in mind to use /MD when you use DLLs.
The linker options your describing are for the CRT only. The static version will limit how you share memory between modules.
All other libraries you use will have be linked in based on the .lib files you provide(or not) to the linker.
There are 3 ways to use a MS library
statically link static library (.lib equivelant of an .a archive of .o)
statically link the stub (.lib compiler generated loadlib/getproc) of a dynamic library
manually load a dynamic library (loadlib/getprocaddress)