<<<<< Notes on steps when setting up a new Visual Studio project >>>>>

I did this with Visual Studio Professional 2012. I am noting the
changes I had to do to get a project that works the way I want it
to. You may want something else so it is not guaranteed that you can
use this for anything.

* Create an empty solution

Close anything you have open in Visual Studio first. In the FILE menu,
select "new" and then "project". Under "Other Project Types" select
"Visual Studio Solutions". Your only option will now be "Blank
Solution". Fill out the name of the solution and the path where it
should go and click "OK". You now have a solution with no projects in
it in a subdirectory with the same name as the solution.

If you want the solution to not be in a directory named after the
project, close the solution in Visual Studio and move the files in the
directory to where you want them to go. You can now open those files
in the new location with no issues. Once you add files with relative
paths probably this step will be much more cumbersome, so do it now if
you want to do it at all.

* Create new projects inside your solution

Right-click your solution in the Solution Explorer and click "Add" and
then "New Project". Select the kind of project you want, name the
project and click "OK". On the next window click "Next". You now have
several options. I don't want to use any of the autogenerated stuff
that Visual Studio will add to the project, so I select "Empty
project" and deselect all other options. Then click "Finish".

You will now have a project file in a subdirectory of the directory
that the solution is in. The name of the directory is the same as the
name of the project.

* Add existing projects to your solution

If the existing project you are adding has solution names or platforms
that you wish to also add to your new projects, do not add the
existing project to your solution until you have added all the
solutions and platforms that you want to add to your new
projects. Otherwise, as far as I can determine, you will not be able
to add those configurations and platforms to the existing project
without manually editing the project files with a text editor - Visual
Studio will tell you that the platform and configuration is already in
use. See http://www.dpvreony.co.uk/blog/post/v/62. If you add
something by mistake, you can remove it, then delete the now unused
configurations and platforms, create the platforms and configurations
you want and then re-add the existing project. I suspect you can also
do this by creating a new solution only for setting up a new project,
then delete the new solution and just include the new project into the
old solution. I feel like there must be a more reasonable way to
handle this, though, but I don't know about it.

You may have existing projects that you want to add to your
solution. For example if you have a project that generates a DLL that
is needed by another project in your current solution, you may want to
add that DLL-producing project to your solution. This is especially
true if you forsee simultaneously making changes to both the EXE
project and the DLL project, since this way Visual Studio will take
care of tracking the dependencies (see how to set up project
references below).

Right-click your solution in the Solution Explorer and click "Add" and
then "Existing Project". Find the project you want to add click
"Open". The existing project is now in your solution. The path to the
project is relative, so if you move the solution or the project you
either have to move them so the relative path is the same or you have
to remove the project and re-add it.

* Add source files

Right click the project in the Solution Explorer and select "add" and
then "existing item". Then you get a dialog to select the files you
want to add to the project. You should select both the header files
and the implementation files.  These are included using relative
paths, so you can move things around as long as the relative path
between the project file and the source files remains the same.

If you are making a DLL project and there is an implementation file
that defines main(), remember not to include it in your DLL project.

* Properties

Right click the project in the Solution Explorer and select
"Properties".

Remember that you need to set all the properties for every
configuration of every project. You can select "All Configurations" in
the upper left where it says "Configuration:" to make your changes
take effect for all the configurations of the project. Remember to
select a specific configuration for changes that are specific to that
configurationt. If you have more than 2 configurations then you can
also select a subset of configurations by choosing "multiple
configurations" instead of "all configurations".

You can also set a setting across several projects by opening the
property page for one project and then shift-left-clicking other
projects to select more than one at a time - any changes will apply to
all the selected projects.

** Configuration Properties

*** General

-Output Directory = $(SolutionDir)\output\$(Platform)\$(Configuration)\

-Intermediate Directory =
  $(SolutionDir)\output\$(Platform)\$(Configuration)\intermediate\$(MSBuildProjectName)\

-Target Name = output file name without extension, for example "memtailor"

-Target Extension = ensure this is what you want

-Configuration Type = ensure this is what you want

*** C/C++

**** General

-Additional Include Directories = set these up if you need them
  Remember to use relative paths, not absolute!

-Multi-processor Compilation = set to yes

**** Proprocessor

-Preprocessor Definitions = ensure this is what you want. For builds
  with asserts on/off, define macroes that turn asserts on/off.

**** Code Generation

-Enable Minimal Rebuild = set to no It is required to disable this
  setting to enable multi-processor building. I've found
  multiprocessor building to be more useful, but you may not like it
  in which case you should set these settings the other way around.

**** Language
-Open MP Support = change if you need it

**** Precompiled Headers

-Set these fields up if you want to use precompiled headers.

*** Linker

You will only have this tab if you are building a .exe file. Libraries
instead have a tab called "librarian".

**** General

-Additional Library Directories = extra places to look for .dll and
  .lib files.

**** Input

-Additional Dependencies = put in the names of libraries that you want
  to link in, including the .lib or .dll extension. You do not need to
  specify the outputs of other projects in the same solution - these
  are handled using project references.

* Project References

Select your project, click the Project menu and select References. Add
references to any other projects whose output DLL or LIB file you want
to use in the output for this project. This automatically also sets up
project dependencies so you do not need to do that.

* Start-up project

right-click the project in the Solution Explorer and select "set as
start-up project".  This simply means that this project will be the
one that is selected by default when you open the solution.


<<<<< Extra configurations >>>>>

* Release-Assert

You want a version with asserts enabled that is still optimized. That
way you do not have to sit and wait for a very slow non-optimized
debug executable to run with asserts on in the common case that none
of the asserts trigger and all the test pass or if you can see what
the problem is from the assert without needing to go into the
debugger.

If you get an assert or test failure that you need to go into the
debugger for, simply select the debug configuration and run the
program again.

** Make the new configuration

If some existing project already uses the configuration you want to
make, then it will already exist in your solution.

*** If the configuration does not exist in your solution

Select the configuration drop-down from the top of the screen and
select "new" Set it to copy settings from the Release build
configuration. Mark the "create new project configurations" tick-box.

If you do not see "new" on the configuration drop-down (I don't know
why it disappears sometimes), instead select Configuration Manager and
select new from the drop-down in the upper left corner. This will
create the new configuration across all your projects in the
solution. If you only want a configuration to be available for a single
project, instead select the configuration drop-down for that project in
the middle part of the Configuration Manager.

*** If the configuration already exists in your solution

Go into the Configuration Manager, find the project you want to add
the existing configuration to, right-click the drop-down in the
Configuration column and click "New". After that things are the same
as above, except you need to do this for each project.

** Fix settings

Go into Configuration Properties -> C/C++ -> Preprocessor ->
Preprocessor Definitions.  Now select the Release configuration, copy
the preprocessor settings from there (ctrl-v), go back to
Release-Assert and paste (ctrl-c) the debug preprocessor settings
there. You also need to go to C/C++ -> Code Generation and set Runtime
Library to a debug setting - select whatever is selected for your
Debug configuration. If your project links in external libraries you
might need to select a debug version of those libraries too - do
whatever you debug configuration does. If you can get away with not
using external debug libraries that might be good since possibly they
have been built with optimization turned off in which case they will
be slow.

If you have more than one project you need to fix the settings for
each project. If you get mysterious errors about missing linker
symbols or incompatible libraries then possibly that is because you
forgot to do the above for one of your projects that is being depended
upon by one of the other projects that you did remember to do this
for.

* Debug-NoAssert

Sometimes you are debugging an issue that is not an assertion
failure. In that case you may need to run some significant computation
for a while until you get to the issue, such as a segmentation
fault. To debug you have to compile without optimization, so this can
be very slow and it will be even worse if you also have asserts turned
on. So it is good to have a build that you can debug but where asserts
are not turned on. To realize this, duplicate the debug build as above
and defined NDEBUG or, alternatively, do not define whatever
preprocessor macroes you've got that turn assertions on. You do this
in C/C++ -> Preprocessor -> Preprocessor Definitions.

* WarningAsError

If you want to have no warnings in your build you'll want to set use
the setting "treat warnings as errors". Unfortunately, if your code
has many warnings, you probably want your code to still be compilable
even though you have not fixed all the warnings yet. When needing to
meet a deadline, you might let some warnings stand until a few days
later. To avoid having to go through all your projects and turn "treat
warnings as errors" on and off, you can make a new project that has
this setting permanently turned on. Really you should have one with
asserts and one without, though I just make a single one with asserts
on. So I duplicate the Debug build and go into C/C++ -> General ->
Treat Warnings as Errors and set it to "yes" for each project.


<<<<< Specific instructions for gtest >>>>>

I had to define the preprocessor macro "_VARIADIC_MAX=10" to build
gtest in MSVC.  This step should become unnecessary in future once
MSVC supports variadic templates.

To enable test files to include gtest.h, add an additional relative include path
to gtest/include/.

I've found the easiest thing to get gtest building is to just include
the file at gtest/src/gtest-all.cc from a file in my own test
project. This requires an addtional relative include path for gtest/
since that file includes all the other .cc files using a path relative
to the base directory of gtest. This way you do not have to deal with
outdated external Visual Studio project files or project files that do
not have the compiler flags that you need and then you have to edit
them anyway even if they are up to date.



<<<<< Setting up 64 bit compilation >>>>>

The default setting is to compile in 32 bit mode, so unless you
changed that you have now got a 32 bit project. One of the problems
with this is that you now can use no more than 2-3 GB of ram before
getting an allocation failure, even if your computer has much more
free RAM than that.

If you included an existing project with a 64 bit platform build then
that option will already exist in your solution.

* If you do not have a 64 bit mode yet

At the top of your screen it will say "Win32". It is the third
drop-down in the middle if you did not move your toolbars. Click it
and select "Configuration Manager". At the right it says "Active
solution platform" and then "Win32". Click the drop-down that says
"Win32" and select "<New>". Where it says "Type or select the new
platform", select x64 and make sure "create new project platforms" is
selected. That's it, you can now select a 64 bit mode by choosing
between x86 and x64 in the drop-down at the top.

* If you have a 64 bit mode already

I don't know that you can do this directly then. The best work-around
I've found is to remove the projects that already have 64 bit from the
solution, then delete 64 bit, re-create it and then add the removed
projects back into the solution.

* Fixing settings

Visual Studio may or may not have done this for you already. I suspect
it does this if and only if you have not altered the preprocessor
defines from the default values:

 - change the preprocessor define WIN32 to WIN64.

<<<<< Comitting files to version tracking system >>>>>

You want to include these files for version tracking:

  .vcxproj: Stores a MSVC project
  .sln: Stores a MSVC solution, which contains references to a set of projects
  .vcxproj.filters: Specifies for example that .h files go in the Header Files node

These files are safe to delete (after you close the project/solution) and do not
need to be tracked:

  .suo: local settings, such as what windows you've got open
  .sdf: browsing database of what is defined where - is autogenerated form the source
  .opensdf: should only exist while a project/solution is open.  
  output/: if you did what it says above, this is output files
  intermediate/: if you did what it says above, this is intermediate files

This file I'm not sure about

  .vcxproj.user: supposedly only relevant to converting old MSVC projects, but I am
    still getting it generated every time I open a new project. For that reason
    I assume that this does not need to be tracked.
