Hungry Mind , Blog about everything in IT - C#, Java, C++, .NET, Windows, WinAPI, ...

How to properly add custom library dependencies to VC++ project

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).

0 коммент.:

Отправить комментарий

Copyright 2007-2011 Chabster