locked
Updating the path for the application while debugging using props files RRS feed

  • Question

  • I develop native C++ style apps that are usually tested as console apps. I mainly work in VS 2010 and 2012. I use a variety of libraries - for example boost. I have many many moderate size projects with differing dependencies on these libraries. Having been forced to use props files when I transferred from 2008 to 2010 I came to realise props files are extraordinarily useful in managing this context, particularly in a situation where version control and heterogenous setups are the norm (an academic environment).

    But I have hit a problem. It revolves around setting the path used when running the compiled programme from the IDE so that it finds dlls associated with the different libraries. Some people suggest copying the relevant files to the target Directory but this is not practical and it is usually much easier to modify the path in $(LocalDebuggerEnvironment) to include the relevant folders.

    If I want to use boost, I set one global environement variable pointing to the fully installed version of boost I want to use on the build platform: eg

    setx /m BOOST_ROOT "R:\sdks\boost\boost_1_52_0"

    add a copy of a props file such as boost.props below as an item into to the project (to make sure version control sees it), and then add it to the project I want to use boost in using the property manager window. All great - my programs compile and run in the ide and find the relevant dlls - copying dlls is quite impractical for such a large library as boost.

    THE PROBLEM

    This method works excellently for several libraries at once - simply add the relevant props files to the project and the projects find all the includes etc and build perfectly. However, try as I can, I do not seem to find a way to cascade the $(LocalDebuggerEnvironment) variables in such a way that the paths to the dlls cascade - I always seem to get the last one.

    PLEASE HELP

    My boost props file (Note the single line break in the middle of the redefinition of LocalDebuggerEnvironment is essential and reflects that this is a list) one sometimes writes

    ...;%PATH%
$(LocalDebuggerEnvironment)... instead

    <?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">
        <BOOST_BIN>$(BOOST_ROOT)\$(Platform)\lib</BOOST_BIN> 
        <BOOST_LIB>$(BOOST_BIN)</BOOST_LIB>
        <BOOST_INC>$(BOOST_ROOT)</BOOST_INC>
        <BOOST_EXE>$(LocalDebuggerCommand)</BOOST_EXE>
        <BOOST_OPT>$(LocalDebuggerArguments)</BOOST_OPT>
        <LocalDebuggerEnvironment>PATH=$(BOOST_BIN);%PATH%

    $(LocalDebuggerEnvironment)</LocalDebuggerEnvironment>
        <LocalDebuggerCommand>$(BOOST_EXE)</LocalDebuggerCommand>
        <LocalDebuggerArguments>$(BOOST_OPT)</LocalDebuggerArguments>
      </PropertyGroup>
      <PropertyGroup>
        <ExecutablePath>$(ExecutablePath)</ExecutablePath>
      </PropertyGroup>
      <PropertyGroup>
        <LibraryPath>$(BOOST_LIB);$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <PropertyGroup>
      <IncludePath>$(BOOST_INC);$(IncludePath)</IncludePath>
      </PropertyGroup>
      <PropertyGroup>
        <SourcePath>$(BOOST_INC);$(SourcePath)</SourcePath>
      </PropertyGroup>
      <ItemDefinitionGroup>
      </ItemDefinitionGroup>
      <ItemGroup>
        <BuildMacro Include="BOOST_LIB">
          <Value>$(BOOST_LIB)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_INC">
          <Value>$(BOOST_INC)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_BIN">
          <Value>$(BOOST_BIN)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_EXE">
          <Value>$(BOOST_EXE)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_OPT">
          <Value>$(BOOST_OPT)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerEnvironment">
          <Value>$(LocalDebuggerEnvironment)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerCommand">
          <Value>$(LocalDebuggerCommand)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerArguments">
          <Value>$(LocalDebuggerArguments)</Value>
        </BuildMacro>
      </ItemGroup>
    </Project>




    • Edited by 8Ika1oikXJA8H Saturday, April 20, 2013 9:16 PM misprints
    Saturday, April 20, 2013 3:26 PM

Answers

  • After much (days) of effort because of the difficulty of finding clear documentation I have what I believe is a robust solution to the props file per library problem. It is not perfect because it only manages the path and would need modification and become less clear if one wanted to set other environmental variables for the application. Still for me it works on 2010 and (I think) 2012.  In boost I store my libraries in win32\lib and x64\lib while I download mpir binaries from the mpfrc++ site and these paths match the download. I illustrate by attaching three props files; the crucial trick is to create $(path) which is initialised by %PATH% and to keep $(LocalDebuggerEnvironment) to one line - so that it is robust to changing interpetation etc. As stated in the question, I assume envionmental variables on the machine: %BOOST_ROOT%, %MPIR_ROOT% and %MPFR_ROOT% indicating where the packages are installed. Hope this is useful to someone as I have been trying to get this exactly right for a significant time.

    PS if you want to edit these files as XML then you should completely remove them from your projects in properties manager first and save the project.

    boost.props

    ********************************

    <?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">
        <BOOST_BIN>$(BOOST_ROOT)\$(Platform)\lib</BOOST_BIN>
        <BOOST_LIB>$(BOOST_BIN)</BOOST_LIB>
        <BOOST_INC>$(BOOST_ROOT)</BOOST_INC>
        <Path>$(BOOST_BIN);$(Path)</Path>
        <LocalDebuggerEnvironment>PATH=$(Path)</LocalDebuggerEnvironment>
      </PropertyGroup>
      <PropertyGroup />
      <PropertyGroup>
        <LibraryPath>$(BOOST_LIB);$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <PropertyGroup>
        <IncludePath>$(BOOST_INC);$(IncludePath)</IncludePath>
      </PropertyGroup>
      <PropertyGroup>
        <SourcePath>$(BOOST_INC);$(SourcePath)</SourcePath>
      </PropertyGroup>
      <ItemDefinitionGroup>
      </ItemDefinitionGroup>
      <ItemGroup>
        <BuildMacro Include="BOOST_BIN">
          <Value>$(BOOST_BIN)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_LIB">
          <Value>$(BOOST_LIB)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_INC">
          <Value>$(BOOST_INC)</Value>
        </BuildMacro>
        <BuildMacro Include="Path">
          <Value>$(Path)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerEnvironment">
          <Value>$(LocalDebuggerEnvironment)</Value>
        </BuildMacro>
      </ItemGroup>
    </Project>

    **********************************************************************

    mpir.props

    **********************************************************************

    <?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">
        <MPIR_LINK_DEPENDS>mpir.lib</MPIR_LINK_DEPENDS>
        <MPIR_LIB>$(MPIR_ROOT)\dll\$(Platform)\$(Configuration)</MPIR_LIB>
        <MPIR_INC>$(MPIR_ROOT)\dll\$(Platform)\$(Configuration)</MPIR_INC>
        <MPIR_BIN>$(MPIR_ROOT)\dll\$(Platform)\$(Configuration)</MPIR_BIN>
        <Path>$(MPIR_BIN);$(Path)</Path>
        <LocalDebuggerEnvironment>PATH=$(Path)</LocalDebuggerEnvironment>
      </PropertyGroup>
      <PropertyGroup>
        <IncludePath>$(MPIR_INC);$(IncludePath)</IncludePath>
      </PropertyGroup>
      <PropertyGroup>
        <LibraryPath>$(MPIR_LIB);$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <PropertyGroup>
        <SourcePath>$(MPIR_INC);$(SourcePath)</SourcePath>
      </PropertyGroup>
      <ItemDefinitionGroup>
        <Link>
          <AdditionalDependencies>$(MPIR_LINK_DEPENDS);%(AdditionalDependencies)</AdditionalDependencies>
        </Link>
      </ItemDefinitionGroup>
      <ItemGroup>
        <BuildMacro Include="MPIR_LINK_DEPENDS">
          <Value>$(MPIR_LINK_DEPENDS)</Value>
        </BuildMacro>
        <BuildMacro Include="MPIR_LIB">
          <Value>$(MPIR_LIB)</Value>
        </BuildMacro>
        <BuildMacro Include="MPIR_INC">
          <Value>$(MPIR_INC)</Value>
        </BuildMacro>
        <BuildMacro Include="MPIR_BIN">
          <Value>$(MPIR_BIN)</Value>
        </BuildMacro>
        <BuildMacro Include="Path">
          <Value>$(Path)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerEnvironment">
          <Value>$(LocalDebuggerEnvironment)</Value>
        </BuildMacro>
      </ItemGroup>
    </Project>

    *************************************************************

    mpfr.props

    *************************************************************

    <?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">
        <MPFR_LINK_DEPENDS>mpfr.lib</MPFR_LINK_DEPENDS>
        <MPFR_LIB>$(MPFR_ROOT)\dll\$(Platform)\$(Configuration)</MPFR_LIB>
        <MPFR_INC>$(MPFR_ROOT)</MPFR_INC>
        <MPFR_BIN>$(MPFR_ROOT)\dll\$(Platform)\$(Configuration)</MPFR_BIN>
        <Path>$(MPFR_BIN);$(Path)</Path>
        <LocalDebuggerEnvironment>PATH=$(Path)</LocalDebuggerEnvironment>
      </PropertyGroup>
      <PropertyGroup>
        <IncludePath>$(MPFR_INC);$(IncludePath)</IncludePath>
      </PropertyGroup>
      <PropertyGroup>
        <LibraryPath>$(MPFR_LIB);$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <PropertyGroup>
        <SourcePath>$(MPFR_INC);$(SourcePath)</SourcePath>
      </PropertyGroup>
      <ItemDefinitionGroup>
        <Link>
          <AdditionalDependencies>$(MPFR_LINK_DEPENDS);%(AdditionalDependencies)</AdditionalDependencies>
        </Link>
      </ItemDefinitionGroup>
      <ItemGroup>
        <BuildMacro Include="MPFR_LINK_DEPENDS">
          <Value>$(MPFR_LINK_DEPENDS)</Value>
        </BuildMacro>
        <BuildMacro Include="MPFR_LIB">
          <Value>$(MPFR_LIB)</Value>
        </BuildMacro>
        <BuildMacro Include="MPFR_INC">
          <Value>$(MPFR_INC)</Value>
        </BuildMacro>
        <BuildMacro Include="MPFR_BIN">
          <Value>$(MPFR_BIN)</Value>
        </BuildMacro>
        <BuildMacro Include="Path">
          <Value>$(Path)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerEnvironment">
          <Value>$(LocalDebuggerEnvironment)</Value>
        </BuildMacro>
      </ItemGroup>
    </Project>

    *************************************************************





    • Marked as answer by 8Ika1oikXJA8H Sunday, April 21, 2013 11:02 AM
    • Edited by 8Ika1oikXJA8H Monday, April 22, 2013 6:09 AM misprint
    Sunday, April 21, 2013 11:01 AM

All replies

  • After much (days) of effort because of the difficulty of finding clear documentation I have what I believe is a robust solution to the props file per library problem. It is not perfect because it only manages the path and would need modification and become less clear if one wanted to set other environmental variables for the application. Still for me it works on 2010 and (I think) 2012.  In boost I store my libraries in win32\lib and x64\lib while I download mpir binaries from the mpfrc++ site and these paths match the download. I illustrate by attaching three props files; the crucial trick is to create $(path) which is initialised by %PATH% and to keep $(LocalDebuggerEnvironment) to one line - so that it is robust to changing interpetation etc. As stated in the question, I assume envionmental variables on the machine: %BOOST_ROOT%, %MPIR_ROOT% and %MPFR_ROOT% indicating where the packages are installed. Hope this is useful to someone as I have been trying to get this exactly right for a significant time.

    PS if you want to edit these files as XML then you should completely remove them from your projects in properties manager first and save the project.

    boost.props

    ********************************

    <?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">
        <BOOST_BIN>$(BOOST_ROOT)\$(Platform)\lib</BOOST_BIN>
        <BOOST_LIB>$(BOOST_BIN)</BOOST_LIB>
        <BOOST_INC>$(BOOST_ROOT)</BOOST_INC>
        <Path>$(BOOST_BIN);$(Path)</Path>
        <LocalDebuggerEnvironment>PATH=$(Path)</LocalDebuggerEnvironment>
      </PropertyGroup>
      <PropertyGroup />
      <PropertyGroup>
        <LibraryPath>$(BOOST_LIB);$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <PropertyGroup>
        <IncludePath>$(BOOST_INC);$(IncludePath)</IncludePath>
      </PropertyGroup>
      <PropertyGroup>
        <SourcePath>$(BOOST_INC);$(SourcePath)</SourcePath>
      </PropertyGroup>
      <ItemDefinitionGroup>
      </ItemDefinitionGroup>
      <ItemGroup>
        <BuildMacro Include="BOOST_BIN">
          <Value>$(BOOST_BIN)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_LIB">
          <Value>$(BOOST_LIB)</Value>
        </BuildMacro>
        <BuildMacro Include="BOOST_INC">
          <Value>$(BOOST_INC)</Value>
        </BuildMacro>
        <BuildMacro Include="Path">
          <Value>$(Path)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerEnvironment">
          <Value>$(LocalDebuggerEnvironment)</Value>
        </BuildMacro>
      </ItemGroup>
    </Project>

    **********************************************************************

    mpir.props

    **********************************************************************

    <?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">
        <MPIR_LINK_DEPENDS>mpir.lib</MPIR_LINK_DEPENDS>
        <MPIR_LIB>$(MPIR_ROOT)\dll\$(Platform)\$(Configuration)</MPIR_LIB>
        <MPIR_INC>$(MPIR_ROOT)\dll\$(Platform)\$(Configuration)</MPIR_INC>
        <MPIR_BIN>$(MPIR_ROOT)\dll\$(Platform)\$(Configuration)</MPIR_BIN>
        <Path>$(MPIR_BIN);$(Path)</Path>
        <LocalDebuggerEnvironment>PATH=$(Path)</LocalDebuggerEnvironment>
      </PropertyGroup>
      <PropertyGroup>
        <IncludePath>$(MPIR_INC);$(IncludePath)</IncludePath>
      </PropertyGroup>
      <PropertyGroup>
        <LibraryPath>$(MPIR_LIB);$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <PropertyGroup>
        <SourcePath>$(MPIR_INC);$(SourcePath)</SourcePath>
      </PropertyGroup>
      <ItemDefinitionGroup>
        <Link>
          <AdditionalDependencies>$(MPIR_LINK_DEPENDS);%(AdditionalDependencies)</AdditionalDependencies>
        </Link>
      </ItemDefinitionGroup>
      <ItemGroup>
        <BuildMacro Include="MPIR_LINK_DEPENDS">
          <Value>$(MPIR_LINK_DEPENDS)</Value>
        </BuildMacro>
        <BuildMacro Include="MPIR_LIB">
          <Value>$(MPIR_LIB)</Value>
        </BuildMacro>
        <BuildMacro Include="MPIR_INC">
          <Value>$(MPIR_INC)</Value>
        </BuildMacro>
        <BuildMacro Include="MPIR_BIN">
          <Value>$(MPIR_BIN)</Value>
        </BuildMacro>
        <BuildMacro Include="Path">
          <Value>$(Path)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerEnvironment">
          <Value>$(LocalDebuggerEnvironment)</Value>
        </BuildMacro>
      </ItemGroup>
    </Project>

    *************************************************************

    mpfr.props

    *************************************************************

    <?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">
        <MPFR_LINK_DEPENDS>mpfr.lib</MPFR_LINK_DEPENDS>
        <MPFR_LIB>$(MPFR_ROOT)\dll\$(Platform)\$(Configuration)</MPFR_LIB>
        <MPFR_INC>$(MPFR_ROOT)</MPFR_INC>
        <MPFR_BIN>$(MPFR_ROOT)\dll\$(Platform)\$(Configuration)</MPFR_BIN>
        <Path>$(MPFR_BIN);$(Path)</Path>
        <LocalDebuggerEnvironment>PATH=$(Path)</LocalDebuggerEnvironment>
      </PropertyGroup>
      <PropertyGroup>
        <IncludePath>$(MPFR_INC);$(IncludePath)</IncludePath>
      </PropertyGroup>
      <PropertyGroup>
        <LibraryPath>$(MPFR_LIB);$(LibraryPath)</LibraryPath>
      </PropertyGroup>
      <PropertyGroup>
        <SourcePath>$(MPFR_INC);$(SourcePath)</SourcePath>
      </PropertyGroup>
      <ItemDefinitionGroup>
        <Link>
          <AdditionalDependencies>$(MPFR_LINK_DEPENDS);%(AdditionalDependencies)</AdditionalDependencies>
        </Link>
      </ItemDefinitionGroup>
      <ItemGroup>
        <BuildMacro Include="MPFR_LINK_DEPENDS">
          <Value>$(MPFR_LINK_DEPENDS)</Value>
        </BuildMacro>
        <BuildMacro Include="MPFR_LIB">
          <Value>$(MPFR_LIB)</Value>
        </BuildMacro>
        <BuildMacro Include="MPFR_INC">
          <Value>$(MPFR_INC)</Value>
        </BuildMacro>
        <BuildMacro Include="MPFR_BIN">
          <Value>$(MPFR_BIN)</Value>
        </BuildMacro>
        <BuildMacro Include="Path">
          <Value>$(Path)</Value>
        </BuildMacro>
        <BuildMacro Include="LocalDebuggerEnvironment">
          <Value>$(LocalDebuggerEnvironment)</Value>
        </BuildMacro>
      </ItemGroup>
    </Project>

    *************************************************************





    • Marked as answer by 8Ika1oikXJA8H Sunday, April 21, 2013 11:02 AM
    • Edited by 8Ika1oikXJA8H Monday, April 22, 2013 6:09 AM misprint
    Sunday, April 21, 2013 11:01 AM
  • Hi,

    Glad to see this issue has been resolved and thank you for sharing your solutions here.

    Have a nice day,


    Jack Zhai [MSFT]
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, April 22, 2013 1:49 AM
  • Thanks for your comment.

    The solution mapped out here is actually vital to allowing me to enable my students to easily use these and other critical libraries in a heterogeneous source controlled microsoft environment. If a student downloads their code onto their laptop they cannot expect the installation of boost to be in the same place as in a locked down public machine. Nor can expect them to have detailed knowledge. The checked in version of their code have to be independent of the location of the library.

    I dont really understand why your microsoft team has not provided clear working examples of this sort of thing. An entire generation has moved away from you for development even though the product is basically very good. But these edge issues are actually critical to successful rollout and practical solutions (although existing) are not adequatly addressed. I should not have to take days of trial and error to find a way through. There are numerous unanswered and half answered questions on this topic out there where people are obviously trying to do very similar things.

    Have a nice day.

    Monday, April 22, 2013 6:36 AM