What is project reference in Visual Studio - c++

there is a possibility to add an existing project as a "reference" to a solution in VS(talking about C++ now). As far as I understand it means that all the project files will be added to a solution and I can modify any properties and source code, and it will affect the original solution to which this project belongs. Do I have a correct understanding of it? Or is it something else?
I don't really get why we need it, if I need another project I can use it as a lib or DLL file, this reference thing seems to make things more complicated - if I do any changes to project properties I need to think how it will affect building another solution this project belongs to.

In Visual C++ "project-to-project" references within a solution really does two things:
If the referenced project is a static or DLL library, it's implicitly included in your referencing project's link statement.
The referenced project is considered a build-dependency for the referencing project so it will be built first.
That's pretty much it. If you want to include headers in the referenced project, you need to add it your AdditionalIncludes property for the referencing project.
For a DLL project, you can set a property on it to get it's DLL copied to your referencing project's build directory.
See Visual C++ Team Blog which was back in VS 2010 when it was first introduced.
There's a different model of code sharing called Shared Projects where the shared code is built in each referencing project--i.e. there's no shared binaries.

Related

Shared Precompiled Headers

How do I share a precompiled header across multiple projects in the same solution in Visual Studio 2019?
As a requirement, I do not want to create a project just to compile the precompiled header, which then is included and referenced by other projects.
I know the feature simply didn't exist in the past and you'd have to use a pre-build event to copy the actual output file for it to each other project. Since VS has changed a lot over the years, I figure it's time to reask this question because there's no information immediately available on google.
I was looking at this question but it seems that it isn't viable in a production environment.
Or is there something better using C++20 modules?
As far as I concerned, you should need a SharedPCH, it is building the pch and the static library. When ConsoleApplication projects reference the SharedPCH one, the build will automatically link the SharedPCH’s static lib, but several project properties need to be changed as well. As those properties need to be changed similarly for all projects, I suggest you could create the SharedPCH.props and CustomBuildStep.props files and imported them to your projects using the Property Manager tool window.For more details I suggest you could refer to the Blog

Visual Studio C++ Multiple Project Solution Setup

0. Disclaimer
This question is only about Visual Studio C++ project/solution configuration and may involve subjectivity.
However, the idea behind this post is to share our approaches to configure a large Visual Studio solution.
I'm not considering any tool like CMake/Premake here.
1. Problem
How do you handle a large scaled C++ application architecture and configuration using Visual Studio?
What is, for you, the best way to setup a new Visual Studio solution composed of multiple projects?
What Visual Studio project/solution configuration feature are you trying to avoid? (Ex: Filters instead of folders)
2. Personnal approach
2.1. Context
I'm a software developer for a video game company, so I will take a very simplified game engine architecture to illustrate my words:
2.2. File Structure
My Visual Studio solution would probably look something like this:
Where Application is an executable and every other projects are libraries (Dynamically linked).
My approach would be to separate each project into two folders: include, src
And the inner structure would be separated into folders following my namespaces:
2.3. Project Configuration
The following lines will assume there is only one $(Configuration) and $(Platform) available (Ex: Release-x64) and that referencing .lib files into Linker/Input/Additional Dependencies is done for each project.
I would here define a Bin (Output), Bin-Int (Intermediate output) and Build (Organized output) folder, let's say they are located in $(SolutionDir):
$(SolutionDir)Bin\
$(SolutionDir)Bin-Int\
$(SolutionDir)Build\
The Bin and Bin-Int folders are playgrounds for the compiler, while the Build folder is populated by each project post-build event:
$(SolutionDir)Build\$(ProjectName)\include\ (Project includes)
$(SolutionDir)Build\$(ProjectName)\lib\ (.lib files)
$(SolutionDir)Build\$(ProjectName)\bin\ (.dll files)
This way, each $(SolutionDir)Build\$(ProjectName)\ can be shared as an independent library.
Note: Following explainations may skip $(SolutionDir) from the Build folder path to simplify reading.
If B is dependent of A, Build\B\include\ will contain B and A includes. The same way, Build\B\bin\ will contain B and A binaries and Build\B\lib\ will contain B and A .lib files (If and only if B is ok to expose A to its user, otherwise, only B .lib files will be added to Build\B\lib\).
Projects reference themselves relatively to Build\ folders. Thus, if B is dependent of A, B include path will reference $(SolutionDir)Build\A\include\ (And not $(SolutionDir)A\include\), so any include used by A will be available for B without specifying it explicitly. (But result to sections 2.6.2., 2.6.3. and 2.6.4. technical limitations).
After that, I make sure that my solution has a proper Project Dependencies configuration so the Build Order, when building the whole solution, will consider and respect my project dependencies.
2.4. User Project Configuration
Our EngineSDK user (Working onto Application) will only have to setup Application such as:
Include Directories: $(SolutionDir)Build\Engine\include\
Library Directory: $(SolutionDir)Build\Engine\lib\
Post-build: Copy $(SolutionDir)Build\Engine\bin\* to $(OutDir)
Additional Dependencies: Any .lib file upstream in the dependency hierarchy is listed here
This is the typical Visual Studio configuration flow of a lot of C++ library.
Common library folder architecture that I try to preserve:
lib\
include\
bin\
Here are some example of libraries using this folder architecture model (Do note that bin is exclusively for dynamically linked libraries as statically linked libraries don't bother with DLLs):
SFML: https://www.sfml-dev.org/
SDL: https://www.libsdl.org/
2.5. Advantages
Clear folder architecture
Ability to export a library directly by copy-pasting or zipping a sub-folder of $(SolutionDir)Build\
2.6. Technical limitations
The approach I wrote here has some drawbacks. These limitations are the reason of this post as I want to improve myself:
2.6.1. Tedious configuration
Dealing with 10 or less projects is fine, however, with bigger solutions (15+ projects), it can quickly become a mess. Project configurations are very rigid, and a small change in project architecture can result into hours of project configuration and debugging.
2.6.2. Post-build limitation
Let's consider a simple dependency case:
C is dependent of B and B is dependent of A.
C is an executable, and B and A are libraries
B and A post-build events update their Build\$(ProjectName)\ directory
When changing the source code of A, then compiling it, Build\A\ will get updated. However, as B has been previously compiled (Before A changes), its Build\B\ folder contains a copy of previous A binaries and includes. Thus, executing C (Which is only aware of B as a dependency), will use old A binaries/includes. A workaround I found for this problem is to manually trigger B post-build event before executing C. However, forgetting to trigger an intermediate project post-build can result into headaches during debugging (Not loaded symbols, wrong behaviour...).
2.6.3. Multiple times single header reference
Another limitation for this approach is "Multiple times single header reference".
This problem can be explained by considering the project dependency image at section 2.1..
Considering that Graphics and Physics are both including Maths headers, and that Engine is including Build\Graphics\include\ and Build\Physics\include\, typing a header name will show multiple identical results:
2.6.4. De-synchronized symbol referencing
If B is dependent of A and any header changes in A (for instance, we add a new function), Rescan File/Rescan Solution will be needed to access the new symbol from B.
Also, navigating to files or symbol can make us move to the wrong header (Copied header instead of the original one).
3. Interrogations and learning perspectives
3.1. Project Reference
During my Visual Studio software developer journey, I came through the project Reference concept, but I can't find how it can solve the technical limitations of my current approach, nor how it can helps me to re-think it.
3.2. Property sheets
As every project configuration of my solution is following the same principle but the content (Include dirs, library dirs...) for each one is different, I'm not sure how to make a great usage of property sheets.
3.3. Exploring GitHub
Currently I'm struggling finding some good project architecture references. I would be pleased finding some Visual Studio configured solution on GitHub or any code sharing platform. (I know that CMake and Premake are prefered in most case when sharing code, however, learning more about Visual Studio project configuration is my actual goal).
Thanks for reading my words, I hope that you are also interested into discussing about this subject and maybe we can share our approaches.

Create a Second C++ Project in Visual Studio 2010

I am looking for detailed steps to create a second Static Lib Project in Visual Studio 2010
that my first project will reference.
This project will be in source control and used by others so the referencing needs to be able to work on all folder structures. (if possible)
I have done this before but have had problems recently. I mostly end up adding random references to everything and every folder in my project until it works as I do not know the correct steps to accomplish it.
This will be my projects folder structure
<Whatever Structure>/MyProject/MainProject
<Whatever Structure>/MyProject/SecondProject
<Whatever Structure>/MyProject/MyProject.sln
I need my SecondProject to be built as a Static Lib library.
Inside my FirstProject I would like to reference files from my SecondProject as
#include <SecondProject/<filename or class or namespace>
As I said above Detailed Steps to accomplish this would be greatly appreciated.
I have searched many other posts but most just pertain to Header Files or they are half the steps.
Thank you.
#include is solely used for headers. This is parsed at compile time. Since you want to use headers from <Whatever>/MyProject/SecondProject as just SecondProject/, obviously <Whatever>/MyProject/ must be among the include directories. Probably the best way to specify it would be as just ../, because that means you don't have to hardcode <Whatever>
After compiling, the next step is linking. The easiest solution here is to go the the property pages of MainProject, Common Properties > Frameworks & References, and use [Add New Reference...] button. Linking will make the compiled functions inside the .lib available.

How do you add a C++ project reference in Visual Studio?

In C# it's pretty simple to add a project reference that will build the dependency, put the resulting assembly in the original's Debug/ directory and properly compile against that assembly.
So at the moment, I have a project with the Main() and a static library project in one solution. However, when I compile the Main() project and I look in the bin/Debug/ directory I don't find either the Static.lib file or the .obj files, which I think would need to be there, or something... I'm getting linker errors.
I think maybe I have to Configure the project to find the .obj and the .lib file produced by the static library project (which compiles fine, and actually produces those files.)
I'm missing something, and I'm not very well versed in Visual Studio with C++.
How do I add the reference in the Main project to use the library produced by the static library project?
The first thing you'll have to unterstand is, that static libraries are nothing like .NET assemblies. They are linked into the .exe and are not distributed as separate entity.
Your linker errors are most likely a result of you not linking to the library.
There are several ways to define libraries that have to be linked.
One is int the project settings under linker -> input -> additional dependencies,
the other would be the cheap route via #pragma comment(lib, "path to library")
You can add the name of the .lib files you need by going in project property->Linker->Input->Additional Dependencies
Then you will have to give the folder where your library is in VC++ Directories->Library Directerories.
Here is a very comprehensive answer: visual c++: #include files from other projects in the same solution
It describes the settings for the linker but also other essentials when referencing another C++ project. (especially when coming from C# but not being too versed in C++)
In .NET, one of design goals was due make this process a lot easier and automatic. Mission accomplished there.
In the native C++ world, the process is much more manual. Here is roughly my process for hooking up different modules together.
Include all relevant modules in the solution.
Set the output
directory of each project to the same directory. Either Right click
on each project, choose properties and in general, set the output
directory to: $(SolutionDir)\Bin\$(Configuration)\$(PlatformTarget).
For reduced headaches, Set this for all configurations and platforms.
Then all the files will be placed in somewhere like
\your-solution\bin\Debug\x64.
Set the project dependencies - Right click on each project that will be linking to another -> Choose Build Dependencies and select the referenced projects.
Set up the linking process, by Right clicking on the calling project and choosing
properties. Go to linker -> Input and add: $(SolutionDir)\Bin\$(Configuration)\$(PlatformTarget)\MyLibrary.lib
For the actual functions that are going to linked to, I set the
function declarations to something like (There are a lot of variations on the function declaration, a bit outside of the scope here):
#define DllExport __declspec( dllexport )
extern "C" void DllExport WINAPI` Testing();
In actual cpp file of the calling function, I add something like the following:
#include "..\MyLibrary\mylibrary.h"
Then in the actual calling function. simply add called function:
Testing();
If you are building multiple projects in the same solution, use a project reference to automatically link your libraries and executables together:
https://learn.microsoft.com/en-us/visualstudio/msbuild/common-msbuild-project-items?view=vs-2019#projectreference
which is explained pretty well here:
https://milania.de/blog/Project_references_in_Visual_Studio_and_C%2B%2B
The advantage to this approach, is that the build order will be correct. Using Additional Dependencies, as suggested in the other answers, will not maintain the proper build order.

MSVC Dependencies vs. References

I have always used the Visual Studio Dependencies option to ensure that, for example, when building my C++ projects, any dependent LIB or DLL projects are also built. However, I keep hearing people mention 'references' and wondered, with VS 2010 on the horizon, I should be changing how I do this.
Are there any benefits to using references to dependencies or is the former a .NET feature only? I am currently using VS2008.
I prefer using references since these were introduced for unmanaged C++ in VS 2005. The difference (in unmanaged C++ developer's perspective) is that reference is stored in .vcproj file, while project dependencies are stored in .sln file.
This difference means that when you reuse your project in different solutions (and I often do) you don't need to redefine the inter-project relationships again.
Visual Studio is smart enough not to depend gravely on the paths of the projects when it establishes the reference relationship.
It used to be in VS2008 that a project dependency on a static library would automatically result in the right configuration (Debug|Release) would be linked in. It looks like VS2010 lost that ability with the move to msbuild. Sigh.
'References' are a .NET thing and don't apply to native C++; they are different than dependent projects. A dependent project in a solution is a project that must be built before (or after depending on which way the dependency goes) another project.
A reference is an assembly that contains types used in the project. The analogous thing in a native C++ project might be the include files used by a project and the .lib files that get linked in (the native C++ project 'consumes' those items even if they aren't built in another step of the solution).