VC2010 C++ - organizing source files

Visual StudioVisual Studio-2010

Visual Studio Problem Overview


I had some questions about how to organize source files in a VC 2010 C++ project. The default filters that are included won't be sufficient as ultimately, I'm going to have a lot of .cpp and .hpp files so it's going ot be messy. I'd like to create a folder at the root of the project called "source" then create folders inside "source" for the various source file categories I'd like to use. When I right click the solution, I only get the option to add a filter, not a folder. I can create folders manually in windows explorer, then include them, but Then I lose my ability to add filters. Is there a way to add new folders (without using windows explorer) and still use filters?

Additionally, is there something similar to $(CURDIR) that I could use to include the source file folder without needing an absolute path?

Thanks in advance for the help

Visual Studio Solutions


Solution 1 - Visual Studio

You're a little confused about how Visual Studio works with C++ files, but that's OK, since the documentation is lousy. First things first: unlike with C# or Java, the arrangement of files in the project has no relation to the arrangement of files on your disk. Files and folders aren't "in" the project, really; the project only lists the names and paths of the files and folders, which have to already exist on your disk.

In general, you create the layout of folders, with source files inside of those folders. You do this outside of Visual Studio. You also create a project file. When you "add a file" to the project, all you do is tell the project where to find the file on disk.

Let's work with a specific example and I'll show you how I would organize it. Suppose you are making a graphing calculator program called SuperCalc. You'll have a Source folder, and then create folders inside of Source to hold the different files. Suppose the folders you create are:

  • SuperCalc\Source\Input
  • SuperCalc\Source\Math
  • SuperCalc\Source\Math\Matrix
  • SuperCalc\Source\Output

You have 3 subdirectories of Source: Input, Output, and Math. The Math subdirectory has a subdirectory called Matrix. You'll have .cpp files in Input, Math, Matrix, and Output. You'll create these directories (folders) using Windows Explorer or the Command Prompt.

Now you will also want to create a solution file (SuperCalc.sln) and a project file (SuperCalc.vcxproj & SuperCalc.vcxproj.filters). Do that inside of Visual Studio. Usually the project file lives in a sub-folder of the solution directory; this will be done automatically for you by Visual Studio. Pick a location for the solution file -- it should be somewhere in the same directory structure (folder tree) as the source code. I would suggest putting it next to the Source directory, in:

  • SuperCalc\Build

Go into VS and pick File > New > Project > Visual Studio Solutions > Blank Solution File. Give the solution a name (maybe "SuperCalc") and a location (the location we just picked in the SuperCalc\Build directory). It will create the solution file for you.

Now right-click on the solution in the Solution Explorer ("Solution SuperCalc, 0 projects"), and pick Add > New Project. Pick a name -- this will be the name of your program executable, like "SuperCalc"! Choose Win32, either Win32 Console Application (this is a DOS-console program) or Win32 Project (this is an ordinary Windows GUI program). Usually I then click on Application Settings to make some important changes: for one thing, I pick Empty Project because I don't want Visual Studio creating files and code for me unless I tell it to. When it's all set up the way I want it, I click FINISH.

Now you've got your solution file and project, created by Visual Studio. You also have your source code, or at least the directory structure (folder tree) where your source code will be, created outside of Visual Studio. It's time to connect the two things together.

If you wanted, you could list all your source files into the Source Files filter of your project. Even though they will come from different directories (Input, Matrix, etc.), there's no required relationship between the locations of the files on disk and their appearance in the project. But if you have a lot of files, it is easier if you create "sub-filters", filters inside the Source Files filter, and give them the names of the sub-folders of Source. That way, you replicate the structure of your disk directories inside of your project file.

Right-click on the Source Files filter of the "SuperCalc" project, and pick Add > Add New Filter. Give it the name Input (the first of the SuperCalc\Source directories). Also create the filters Math and Output. Right-click on the Math filter and pick Add > Add New Filter, to create a sub-filter called Matrix (inside of Math). Now you have these filters:

SuperCalc
Source Files
Input
Math
Matrix
Output

which parallels the directories (folders) you created earlier. This is purely a convenient arrangement for humans. Visual Studio doesn't understand anything special about it. If you just tell VS to "add a file" it won't put the file in the correct filter. You'll have to tell it where to put it.

To add or create your .cpp files, select the filter name corresponding to the directory where the .cpp file is. So, to add or create a file SuperCalc\Source\Math\Matrix\matrix_multiply.cpp, right-click on the Matrix filter in Solution Explorer, and pick Add > Add New File or Add Existing File. (Add Existing File is for when you have already written matrix_multiply.cpp and you just want to tell the project where it is.) Use the dialog box to navigate to the Source\Math\Matrix directory. Repeat this process for all the source files in your whole program.

You also had the question "is there something similar to $(CURDIR) that I could use to include the source file folder without needing an absolute path?" You are in luck: Visual Studio projects don't use absolute paths! They use relative paths. The project file stores the relative path required to get from the directory containing the .vcxproj file to the directory containing the source file. So if you created SuperCalc.sln and SuperCalc.vcxproj where I suggested (the SuperCalc\Build directory), and you add your .cpp files in the source subdirectories, you can go look inside the SuperCalc.vcxproj file using Notepad, and you'll see lines like:

<ClCompile Include="......\Source\Math\Matrix\matrix_multiply.cpp" />

Since there are no absolute paths, you could take the entire SuperCalc directory tree and move it somewhere else, and it would all still work. No need for environment variable hacks like $(CURDIR).

One final thing to know: since you are putting your source files in multiple directories, you might have problems with #includeing headers, the .h or .hpp files. You must tell the compiler the directories where your header files are located. They will probably be scattered among multiple directories. So edit the project settings: right-click on the project name in Solution Explorer, choose Properties, and drill down to Configuration Properties > C/C++ > General. The first field in the property sheet says "Additional Include Directories". Before you do anything else, click on the Configuration drop-down menu and choose All Configurations. If you have both a 32-bit and 64-bit build, click on the Platform drop-down menu and choose All Platforms. Now go to the "Additional Include Directories" and add all the paths to all the source directories, with the paths specified relative to the project file's directory. So for the SuperCalc example, it would look like:

......\Source\Input;......\Source\Math;......\Source\Math\Matrix;......\Source\Output
Once this change is made, a file like Source\Math\Matrix\matrix_multiply.cpp can have a line

#include "input_configuration.hpp"

to #include a file from the Input directory, and it will All Just Work.

(If it doesn't All Just Work, the usual approach is to go back into Project Properties and fiddle with the number of ..\ sequences in front of your Additional Include Directories. Remember that every time you go to make a change you must choose All Configurations again -- otherwise your changes will only apply to the current Configuration (Debug or Release). That setting is not sticky.)

Solution 2 - Visual Studio

It actually IS possible to view (and manipulate) the physical file structure via Visual Studio, as described in this SO post:

> Header/Source file is not an requirement imposed by Visual Studio. > That's just the default layout, and it's virtual, not physical. If you > click "Show all files" in the solution explorer, it will show the > folder tree as it is on the hard drive- which you can manipulate as > you see fit.

Solution 3 - Visual Studio

I m late, but I advise against the accepted answer. The main reason if for code portability. Instead I recommend :

  1. To create the layout of folders and subfolders outside of visual studio (same as the accepted answer but the next points are different). Inside each subfolder create a include and src folder

  2. Then in Configuration Properties > C/C++ > General > "Additional Include Directories" (for All configuration and All Plateforms) add a single folder which is the base of all your subfolder.

  3. To add you src files and includes files in these subfolders.

  4. Finally include each header files using relatives paths to this base folder.

To be clear : if the layout of your project is as follow :

MyProjet
   Math
     include
       random.h
       functions.h
     src
       random.cpp
       functions.cpp
   Probability
      include
        normal.h
      src
        normal.cpp

you should have in functions.cpp the following include statement :

#include"Math/include/functions.h"

if you also need to use the normal code in functions.cpp, then the top of functions.cpp should looks like this:

#include"Math/include/functions.h"
#include"Probability/include/normal.h"

In doing so, you'll be able to re-use your Math subfolder in another project (B) without pain: just by adding the MyProject base folder into the "Additional Include Directories" of project B.

> The key point is to have only one base folder into the "Additional > Include Directories" property.

ps: the intellisense feature of VS 2015 helps a lot to write the #include...

Solution 4 - Visual Studio

Using a build system such as CMake or Premake could help when organizing files, and it has the added benefit of helping you port your code to other platforms. Here is a good presentation on the subject.

As it might be of help to someone, I should also add that having your source files separate from your project file (*.vcxproj) makes it more difficult to create new files, as Visual Studio by default want to create new files in the same folder as your project. The workaround to this problem that I've found so far is to use the Visual Assists extension, as it allows adding new files relative to the directory or your currently open file. See this post for further explanation.

Solution 5 - Visual Studio

If you do want to create your solution and project in a different location than your source code, you can change your working directory:

Project > Properties > Configuration Properties > Debugging > Working Directory

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMegatronView Question on Stackoverflow
Solution 1 - Visual StudiolibrikView Answer on Stackoverflow
Solution 2 - Visual StudiomorgancodesView Answer on Stackoverflow
Solution 3 - Visual StudioMalickView Answer on Stackoverflow
Solution 4 - Visual StudioAdelostView Answer on Stackoverflow
Solution 5 - Visual StudioCaseyView Answer on Stackoverflow