Visual Studio — not just a desktop IDE

Visual Studio is one of the better C/C++ source code editors available today that provides Intelligent Code Completion and source code Navigation. However, as an embedded developer, I never build or debug on the target hardware using Visual Studio — so why should I use it? Well… because it is a feature rich source code editor with a fast C/C++ Intellisense feature — and since 98% of my projects use command line builds, nothing requires me to use a specific source code editor.

Oh, by the way Visual Studio provides a good GUI front end for GIT. And don’t forget to install the Spell Checker plugin for comments, the Markdown plugin, Auto Save plugin, etc.

In my day job as an embedded developer I use Visual Studio as my primary editor and VIM for editing while I am in command line window. In my hobby time I use Visual Studio and VIM. A purposeful side effect of this approach is that I don’t have to learn a half dozen editor and/or IDEs.

Here is the caveat: out-of-box Visual Studio’s Intellisense feature does not automagically work when you are doing command line builds. Another issue with VS is that when there are many developers working on the same project — keeping the VS project file (.vxproj) up to date (and merging) can be problematic.

This is how I addressed the issues above — not a perfect solution, but good enough for day-to-day use in a professional/team setting and for personal development.

Colony.Pico — Visual Studio Solution

In my colony.pico repository I have a Visual Studio solution (pico.sln) and project ( .vxproj) files that you can use as templates for your project(s). The trick here is that VS Solution and project files are just XML files that can be hand edited — you just can’t ‘hand edit’ the files in VS itself — an separate editor is required.

Header Search Paths

Here is how I added my project specific header search path to the VS project file.

I added three Property Groups: IncColonyCoreIncPicoSdk , and IncPimoriniPico. A Property Group is really just a value/variable in the context of the XML file. Here is the example of the IncColonyCoreProperty Group for the basic header search paths for colony.core repository.

<PropertyGroup>
<IncColonyCore>$(projectdir);$(ProjectDir)src;$(ProjectDir)\xsrc</IncColonyCore>
</PropertyGroup>

Then I referenced the Property Groups in each of the VS project’s ‘Configuration’ sections. For example in the the Debug|Win32 configuration:

<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>$(IncColonyCore);$(IncPicoSdk);$(IncPimoroniPico)%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>

Source Files

Visual Studio can be setup to use wildcards for adding source code files to the project. The advantage of this is that it means the developer never has to manual add/delete files and there is no long list of file names that can go stale or cause merge conflicts. The disadvantage is that VS only evaluates the wildcards when loading the solution, i.e. it does not recognize new/deleted files once the solution has been opened. The work around for this is to created new/delete files outside of VS and the reopen the solution. Fortunately, VS is pretty fast on opening a solution file. Not ideal — but it is a current limitation of VS.

To add your source code files using wildcards, you need to do the following:

Create an ItemGroup and add CLCompile entry for each unique source code path. For example:

<ItemGroup>
<ClCompile Include="$(ProjectDir)\src\**\*.cpp" />
<ClCompile Include="$(ProjectDir)\src\**\*.c" />
<ClCompile Include="$(ProjectDir)\src\**\*.S" />
<ClCompile Include="$(ProjectDir)\src\**\*.h" />
<ClCompile Include="$(ProjectDir)\src\**\*.asm" />
<ClCompile Include="$(ProjectDir)\tests\**\*.cpp" />
<ClCompile Include="$(ProjectDir)\tests\**\*.c" />
<ClCompile Include="$(ProjectDir)\tests\**\*.S" />
<ClCompile Include="$(ProjectDir)\tests\**\*.h" />
<ClCompile Include="$(ProjectDir)\tests\**\*.asm" />
<ClCompile Include="$(ProjectDir)\projects\**\*.cpp" />
<ClCompile Include="$(ProjectDir)\projects\**\*.c" />
<ClCompile Include="$(ProjectDir)\projects\**\*.S" />
<ClCompile Include="$(ProjectDir)\projects\**\*.h" />
<ClCompile Include="$(ProjectDir)\projects\**\*.asm" />
<ClCompile Include="$(ProjectDir)\*.h" />
</ItemGroup>

Add the ReadOnlyProject Property Group and set its value to true . Without this mod — VS will give you a warning on start-up. It also prevents you from modify the contents of the VS project from VS itself ?.

<PropertyGroup>
<ReadOnlyProject>true</ReadOnlyProject>
</PropertyGroup