Adding libraries to your Visual Studio C++ projects might be cumbersome if you
aint doing "Hello World" applications. You need to specify include paths, library
paths, resource paths etc. For each individual configuration BTW. Then you start
the application and realize you must copy dll/pdb/whatever files to your output
directory. Sure you google the solution and end up having Custom Build Tools or
Steps for each item in your library. That sucks, believe me. But there is much simpler
solution! As always on thig blog...
Let's say you have reusable library in your (D)VCS repository. Codejock Xtreme
Toolkit Pro is a good example of such a library. Lets make it reusable in seconds.
The answer is a property sheet file for you library:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros">
<CodejockDir Condition="'$(CodejockDir)' == ''">$(MSBuildThisFileDirectory)</CodejockDir>
<IsDebug>$([System.Text.RegularExpressions.Regex]::IsMatch($(Configuration), '[Dd]ebug'))</IsDebug>
<CodejockArchSuffix Condition="'$(PlatformArchitecture)' == '64'">x64</CodejockArchSuffix>
<UnicodeSuffix Condition="'$(CharacterSet)' == 'Unicode'">U</UnicodeSuffix>
<DebugSuffix Condition="$(IsDebug)">D</DebugSuffix>
<CodejockBinDir>$(CodejockDir)\Bin\vc$(PlatformToolsetVersion)$(CodejockArchSuffix)</CodejockBinDir>
<CodejockItemName>ToolkitPro1531vc$(PlatformToolsetVersion)$(CodejockArchSuffix)$(UnicodeSuffix)$(DebugSuffix)</CodejockItemName>
</PropertyGroup>
<PropertyGroup>
<IncludePath>$(CodejockDir)\Source;$(IncludePath)</IncludePath>
<LibraryPath>$(CodejockDir)\Lib\vc$(PlatformToolsetVersion)$(CodejockArchSuffix);$(LibraryPath)</LibraryPath>
<SourcePath>$(CodejockDir)\Source;$(SourcePath)</SourcePath>
<LocalDebuggerEnvironment>$(CodejockBinDir);%(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
</PropertyGroup>
<ItemGroup>
<CustomBuild Include="$(CodejockBinDir)\$(CodejockItemName).dll">
<Filter>Libraries\Codejock</Filter>
<Command>xcopy /Y "%(FullPath)" "$(OutDir)"</Command>
<Outputs>$(OutDir)\$(CodejockItemName).dll</Outputs>
</CustomBuild>
<CustomBuild Include="$(CodejockBinDir)\$(CodejockItemName).pdb" Condition="$(IsDebug)">
<Filter>Libraries\Codejock</Filter>
<Command>xcopy /Y "%(FullPath)" "$(OutDir)"</Command>
<Outputs>$(OutDir)\$(CodejockItemName).pdb</Outputs>
</CustomBuild>
</ItemGroup>
<ItemDefinitionGroup>
<ResourceCompile>
<AdditionalIncludeDirectories>$(CodejockDir)\Source;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ResourceCompile>
</ItemDefinitionGroup>
<ItemGroup>
<BuildMacro Include="CodejockDir">
<Value>$(CodejockDir)</Value>
</BuildMacro>
</ItemGroup>
</Project>
Let it have Codejock.props
name and reside in you library root folder.
This is just an ordinary MSBuild file which can act as a property sheet page for
you C++ projects. Now you can just open Property Manager and Add Existing Property
Sheet to your project. This automaticaly adds necessary environment and build process
changes to make the library work for you. Thats it. And it doesnt fucking overwrite
your unchanged dll files every time you hit Build command!
You probably want to understand how does this work? Well, go and RTFM for MSBuild
system.
The only unpleasant thing about this - Solution Explorer displays all those
referenced files as childrens of your Visual Studio project (filter element is ignored).