Link library in Visual Studio, why two different ways? - visual-studio-2013

I need to link library from one project into another, and it looks there are 2 ways, can you tell what is the difference and what is the consequence of having "true" in one setting and "false" in another (the same) setting?:
and another one:
What is the difference, and do I need both setting set to "yes" or just one and if so which one?

A one-line explanation would probably be that the second option specifies something about how the first one works.
Link Library Dependencies set to Yes: if the solution is set up so that the current project has a dependency on another project that produces a .lib file, then that file will be linked in automatically.
Use Library Dependency Inputs set to Yes: useful mostly in Debug builds, when Incremental Linking is enabled. Normally, if a .lib generated by another project changes, and the current project depends on it, the linker can no longer link the current project incrementally (it's difficult for it to know how exactly the .lib changed). If you set this option to Yes, then the linker doesn't use the .lib file generated for the other project, but rather the individual .obj files that were used by the librarian to generate that .lib (as if the .lib didn't exist, and every object file from the other project were given to the linker individually, alongside the .obj files from the current project). This enables it to continue linking incrementally.
As far as I can tell, Use Library Dependency Inputs only makes sense if Link Library Dependencies and Enable Incremental Linking are both also set to Yes, and the current project depends on another project that generates a .lib file that changes often during development.
Additional information here and reference docs here.
UPDATE based on the comment from the OP:
As far as I can tell, the property entry under Project Reference Properties specifies the setting individually for each referenced project (whether to use the .lib from that specific project or not), while the one under Linker - General is the default setting for referenced projects.
For example, if you set the one under Linker - General to No and add a new referenced project, then, for that project, the setting under Project Reference Properties will default to False. However, the settings for referenced projects that were added before keep their individual setting.
I expect the individual setting under Project Reference Properties to override the default from Linker - General, but I haven't actually tested this bit.

Related

Visual Studio Property Sheets Automatic Inclusion

To simplify, suppose I have a situation where I have written two libraries, Lib1 and Lib2. Each library has one configuration: static (.lib) release Win32 (/MD). Each library has a property sheet (include_lib1.props and include_lib2.props, respectively). The property sheet for a given library:
Exports the path to the generated .lib under Library Directories
Exports the path to the library's source under Include Directories
Adds the name of the generated .lib to the linker's input requirements.
Dependencies:
Lib1 has no dependencies (i.e., it just includes Microsoft.Cpp.Win32.user).
Lib2 has one dependency: Lib1 (i.e., Lib2 includes both Microsoft.Cpp.Win32.user and include_lib1.props).
Now I want to write an application. Ostensibly, it depends only on Lib2--but since Lib2 was built using Lib1, the application wants both Lib1.props and Lib2.props* (i.e., it tries to link with Lib1.lib, and fails since Lib1's property sheet isn't there to say where to find it).
My question is: is there a way to make it so that when I include include_lib2.props, it automatically also includes include_lib1.props--or do something equivalent?
*This by itself is curious--the libraries are built with /MD, so could that be it?
The answer seems to be to just add one property sheet into another. Right-clicking on the property sheet allows you to add an existing one.
This very nicely solves the problem in a modular, clean fashion. The altered property sheet can be used in multiple places. Adding it to a new project recursively adds the depending property sheets, which can be viewed in the property pages.

What is the difference between VC++ project lib directories and linker inputs

I am just approaching C++ development (from a C# background), and i am wondering what is the difference between Library Directories in C++ project settings (in Visual Studio):
and the Linker "Inputs" where i can also supply libraries:
Is there any fundamental difference between these?
This setting got fumbled a bit in VS2010, it was much clearer in previous versions. Where the settings you show in your screenshot were present in Tools + Options. Which shows the core intent, they contain directories that are determined by the setup for Visual Studio and its components. The locations of the CRT, MFC, ATL and SDK libraries.
The Linker + Input + Additional Dependencies setting is the important one, there you say exactly what .lib files the linker should link. You can specify the path of a .lib file and be done. But it is not uncommon that you only specify the name of the .lib file, then edit Additional Library Directories to tell the linker where to search for those .lib files. Which is handy if the install location for, say, Boost isn't always the same or you want to switch from one version of Boost to another.
So in summary:
Linker + Input + Additional Dependencies: add the .lib files you need to link
Linker + General + Additional Library Directories: only use if you didn't specify the path of .libs
VC++ directories: don't mess with it
Do note that the last two bullets only specify directories, not .lib files that the linker should link. The first bullet specifies actual .lib files. What is invariably confusing to starting MSVC programmers is that the linker magically knows how to find important .lib files without specifying them explicitly in the Additional Dependencies setting.
That's unfortunately the non-visual part of Visual C++. There are two distinct ways in which a project can specify .lib files that the linker should link without using the setting. The first one is the project template you selected to get the project started. It uses project property sheets, files that specify default settings for a project. You see them with View = Other Windows + Property Manager. An important one is "Core Windows Libraries", it sets the Additional Dependencies setting to link the essential Windows .lib files, the ones you always need like kernel32.lib and user32.lib. Those settings are "inherited" by your project. Otherwise giving meaning to "NoInherit" if you ever run into it.
The second important way is the #pragma comment directive. Which is used in source code, it injects a linker directive. The "lib" variety is important, that tells the linker to link a .lib file. In addition to what you explicitly specify in the linker's Additional Dependencies setting. A very good example of that one is vc/atlmfc/include/afx.h. Search for "#pragma comment". Note the macro soup that selects the proper mfc .lib file, depending on compiler specific settings. And the bunch of extra Windows .lib files an MFC needs to link.
The C++ build model is filled with a maze of twisty little passages. The IDE tries to make you fall in the pit of success but in the process hides what's important to get to the next level of understanding. It isn't different in C#, to know how to make the Reverse() extension method not consume O(n) storage requires digging in.
Most (not all) libraries come with two sets of files:
Header files are #included in the source code that's using the libraries, to provide declarations for functions, classes, constants or whatever else might be needed
Library files are binary code that contains the code of the library. These are used by the linker when it assembles the final executable

Code::Blocks cannot find function declarations or definitions

Codeblocks cannot find definitions or declarations of some functions in my project.
Question: Is there a way to force a re-scan of the source tree?
I believe that all of the relevant files are included into the project.
(Just checked: it cannot find by name a struct declared in an opened file.)
First, let me give a couple of ways to help C::B find your declarations/definitions.
Although somewhat obvious, you should make sure the function is in a file that is either:
1) part of the project itself (i.e. it should be shown in the projects->workspace window). If you intended it to be part of the project but it isn't there, then go to project->add files and add the file.
2) If you don't want/need the file to be part of the project but you still want to access the declarations/definitions, you need to let the project manager know where to find the file. You can do this in project->build options and set the search directories. Be careful when setting the search directories...you can set it for the whole project or build target (debug or executable).
Note: one common problem occurs when you have multiple projects open in C::B. Even though all your projects are "open", there is only one that is "activated". So, just because you have a file open, it doesn't mean the file is part of the activated project. You can do search-->open files" which will find code in a file if it's open but not in the current active project.
The only way to "re-scan", is to rebuild your project after making changes in the source code or project settings. You may have to restart C::B. If you still can't find the declaration/definition after doing the above, I would suggest you make a sample program and see if it will find the declaration/definition. If it does, then you can check the settings between your project and the sample project. In the worst case, you can copy your code from your project to the sample project. If that doesn't work, you can reinstall C::B and try again. Not fun but sometimes it works.
You can try, rebuilding the project, but make sure at least one other file includes the header for the structure or make sure the header and source file are included in the project.

How do I use classes from another project in the same solution in Visual Studio 2010?

I'm working on a object-oriented Windows API wrapper library, written in C++, and I have two projects inside the solution:
The actual library project;
A "test" project, where I write code that uses the library for testing purposes.
My goal is to be able to include and use the library header files on the test project, as if it was an actual project that uses the library.
I solved the file inclusion problem by adding "$(SolutionDir)" to the test project's additional include directories (is there a cleaner way?), but I'm struggling to get the test project to link. I get unreferenced externals errors, which I assume is because the linker can't find the DLL.
I'm completely lost here. I have set up project-to-project references, so that the test project is dependent on the library project, but that did not solve the linking problem. I couldn't find any option in either project's properties that seemed to be relevant to my problem.
Is there a way I can simply hit "Build Solution" and then run the executable?
In your project's properties > Linker > Input, there's a bunch of settings you can specify for the linker, such as, for instance, additionnal dependencies to link with (put the .lib generated by your other project there) and which paths to look for said libraries.

How to associate external files with an assembly

Let's say you have a class library project that has any number of supplemental files that also need to be included with the compiled assembly (e.g. simple text files or even a legacy unmanaged DLL that's wrapped by the assembly as an interop layer). While embedding the supplemental files into the assembly itself is relatively straightforward, we have situations where this is not possible or just undesirable. We need to have them as "sidecar" files (i.e. files alongside the assembly, potentially in subdirectories relative to the assembly)
Adding those files to the project with an appropriate value for "Copy to Output Directory" specified appears to be sufficient for projects that are completely self-contained within a solution. But if a separate project in another solution adds a reference to the assembly, it does not automatically pickup its sidecar files. Is there a way in the project to somehow mark the resulting assembly such that anything referencing the assembly will also know it needs to include the associated sidecar files? How do you do this?
You can use al.exe, but there also appears to be a C# compiler option. You want to create a multifile assembly using the /linkresource C# compiler option. Instructions are here, but the command is similar to this:
csc /linkresource:N.dll /t:library A.cs
Where N.dll is a native DLL that will go wherever the managed assembly goes (including into the GAC.) There's a very clear description at the link I provided.
Have you tried creating a setup for your solution ? There's an option of including sidecar files targeting to application installation directory.
Another option would be to include the sidecar files in the Assembly resources and un-wrap them to disk when run for the first time.
What if you create a merge module containing the library plus its dependencies? Your installer will then need to reference this module, but you will ensure all of the necessary files will be present.
Unfortunately there doesn't appear to be a lot of built-in support in Visual Studio for this, although I can definitely see the use case.
If you use Subversion for your source control, then you could link in an external reference as an externals definition. This would bring in the source code, and you'd be making a reference to the necessary assembly as a project reference instead of a DLL reference, and then the copy to output directory rules would come into play.
If that's not possible, another solution would be to include commands in the pre/post-build events of your in-solution project to copy the most up-to-date sidecar files from the remote assembly on a build. Of course this comes with the caveat that it doesn't set itself up automatically when you include the DLL in your project; you have to take manual steps to set it up.
I deal with this some time ago. Its a common problem.
You can create some postbuild actions:
http://www.codingday.com/execute-batch-commands-before-or-after-compilation-using-pre-build-or-post-build-events/
Hope this helps... :)
It appears to me that you're using the wrong type of reference. There are two types of references- Reference and ProjectReference. Reference is an explicit reference to a specific assembly. ProjectReference is a reference to another project (say .csproj).
What you're looking for is ProjectReference. VS and the default MSBuild targets are setup to do CopyLocal. If you set CopyToOutputPath true for your "sidecar" files, any ProjectReferences to this project now will also pull in the same files.
I'm not sure if you can to ProjectReferences across solutions in the IDE. I deal a lot with MSBuild where sln files are not relevant and this is how I deal with it.
What we did in our project is that we created as separate build file to do all those stuffs.
In your build file you can have tags to build your main solution, then add tags to copy files you need after build.
NAnt is also your option, but right now I'm happy using Rake as my build/debug automation.
Since this cannot be integrated within Visual Studio, what I'm doing is I create a task (either in MSBuild, NAnt or Rake), that executes vsjitdebugger.exe in the end to attach it to my Visual Studio when debugging.
These are just my styles for now, you can maybe create your own style.

Resources