none
Customizing compile options based on an Item property associated to a source file RRS feed

  • Question

  • Hi,

    I am trying to simplify C++ projects (.vcxproj) that have common patterns for properties associated with source files.

    For example:

      <ItemGroup>
        <ClCompile Include="SourceFile.cpp">
          <DisableLanguageExtensions>false</DisableLanguageExtensions>
          ... and many other settings ...
        </ClCompile>

    And replace it with something like:

      <Import Project="BuildSettings.props" />
      <ItemGroup>
        <ClCompile Include="SourceFile.cpp">
          <CustomBuildProperty>ABC</CustomBuildProperty>
        </ClCompile>

    Where "BuildSettings.props" can handle all the settings when this CustomBuildProperty is set to ABC.

    I thought I could do something like this in BuildSettings.props:

      <ItemDefinitionGroup>
        <ClCompile Condition="'%(ClCompile.CustomBuildProperty)' == 'ABC'">
          <DisableLanguageExtensions>false</DisableLanguageExtensions>
          ... and many other settings ...
        </ClCompile>
      </ItemDefinitionGroup>

    But this doesn't seem to work?

    Is this something that MSBuild can do? Is there something wrong with the approach above?

    Thanks
    Brian

    Tuesday, May 28, 2019 11:42 PM

Answers

  • Hi,

    Looks like I am able to do something close to what I want by doing the following:

      <Target Name="Build_BeforeCPP" BeforeTargets="ClCompile">
        <ItemGroup>
          <ClCompile Condition="%(ClCompile.CustomBuildProperty) == 'ABC'">
            <DisableLanguageExtensions>false</DisableLanguageExtensions>
            … more settings ...
          </ClCompile>
        </ItemGroup>
      </Target>

    By using a target, I am able to use conditions/properties on a way that appear to apply properly to individual items. As long as the target runs before the actual ClCompile process then it all appears to work as desired.

    This now allows the Imported *.props file to abstract all the settings and only rely on individual Property tags against individual Source files as needed.

    Thanks
    Brian

    Saturday, June 1, 2019 1:18 PM

All replies

  • Hi Brian,

    Welcome to MSDN forum.

    >>Is there something wrong with the approach above?

    When building the project, build system(msbuild.exe) will read the value from ItemGroup and PropertyGroup. 

    Please check this:

    <ClCompile
    Condition="'%(ClCompile.CustomBuildProperty)' == 'ABC'">

    When msbuild read value from ClCompile Item, it needs to determine if one of its metadate is "ABC"? It depends on the ClCompile which contains CustomBuildProperty has been read by msbuild before it reads ClCompile which contains the <ClCompile ... 'ABC'">. But I think the order is random or at-the-same time, which causes your script doesn't work.

    Best Regards

    Lance


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, May 29, 2019 10:09 AM
  • What would be the best way to accomplish this goal?

    It seems undesirable to have to cut & paste a set of multiple properties for each source item in the project that needs customization? This also is less flexible to have build settings controlled from a central location?

    Note: This is only needed when some source files have different settings than other source files in the same project. If all the source files have the same settings then the "normal" way of having conditions in ItemDefinitionGroup works fine.

    Wednesday, May 29, 2019 12:02 PM
  • Hi Brian,

    1.As far as I know, the msbuild doesn't suggest move the Reserved Items and Properties into .targets file or .props file.

    (Please distinguish the difference between MSBuild Reserved Content and custom Items and Properties)

    e.g: For DisableLanguageExtensions, it's an Item metadata which corresponds to the setting:

    If we move this Item metadata to BuildSettings.props, the cps project system can't recognize the Item-metadata directly. Which may mess up the settings. 

    2.Also, the DisableLanguageExtensions is for ClCompile Item, not for one associated source file. As I know, MSbuild doesn't support setting DisableLanguageExtensions for one stand-alone source file. Instead, it supports for the whole ClCompile Item.

    3.Always, the MSBuild Properties,Items,Item-metadate are directly defined in .xxproj file. Then the cps project system could recognize them well. (If we do some UI change by project=>properties, the changes would be modified to .xxproj file) 

    And for custom properties, items, metadate, targets we can add it in .xxproj file. Or move them to BuildSetting.props. 

    Sorry for the inconvenience but I'm afraid the answer to your question is negative.

    Best Regards

    Lance


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, May 30, 2019 7:41 AM
  • Hi,

    If we move this Item (DisableLanguageExtensions) metadata to BuildSettings.props, the cps project system can't recognize the Item-metadata directly. Which may mess up the settings. 

    That is why the intent is to replace the original set of Item metadata (with multiple values) with a single property to capture the original behaviour in a consolidated Item property (CustomBuildProperty=ABC in my example)

    The only difference between CustomBuildProperty and DisableLanguageExtensions (as far as I understand) is that DisableLanguageExtensions is directly used by the Target/Task but I would like to reference this Item property elsewhere in BuildSettings.props which will then set these Target/Task properties like DisableLanguageExtensions.

    Also, the DisableLanguageExtensions is for ClCompile Item, not for one associated source file.

    Can you clarify this statement? CLCompile Items are individual Source files? and we most certainly can associate this setting against an arbitrary subset of CPP source files within the same project.

    Always, the MSBuild Properties,Items,Item-metadate are directly defined in .xxproj file. Then the cps project system could recognize them well. (If we do some UI change by project=>properties, the changes would be modified to .xxproj file) 

    From my observations, the IDE works quite well modifying known CPP/Build properties as well as leaving any custom build properties in the .vcxproj file.

    ...

    I can't help but feel that the intent of my question or the full extent of MSBuild capabilities may not be understood in your responses. Is it possible to have a deeper review for possible options here?

    Thanks
    Brian

    Thursday, May 30, 2019 12:15 PM
  • Hi Brian,

    I've done more tests but I have no idea how to make the settings work. And sorry for my misunderstanding in last reply.

    Let's get back to your first question(3 pics):

    In that way, if you imported the BuildSettings.props successfully, then the DisableLanguageExtensions will be set. But not for single SourceFile.cpp, but for all source files in ClCompile Item.

    And for: "This is only needed when some source files have different settings than other source files in the same project. " It seems what you want is a situation like:

    <ClCompile Include="SourceFileA.cpp">
          <CustomBuildProperty>ABC</CustomBuildProperty>
    </ClCompile>

    <ClCompile Include="SourceFileB.cpp">
          <CustomBuildProperty>DEF</CustomBuildProperty>
    </ClCompile>

    Then SourceFileA.cpp has different settings from SourceFileB.cpp.(A uses ABC settings while B uses DEF settings), right?

    For this kind of needs, I have no idea how to achieve it by importing xxx.props or targets file. Because the content from the xx.props is used for the whole project file context.

    Please correct me if I still misunderstand something.

    Best Regards

    Lance


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, May 31, 2019 9:29 AM
  • Hi,

    Your example above summarizes what I would like to do.

    I have certainly not been able to find a way to just do this with Imported *.props (with ItemDefinitionGroup/conditions).

    I wonder if there may be a way to inject an early evaluated target via the Imported *.props that may be able to inspect these attributes and then set the other appropriate ClCompile attributes onto any items that match the CustomBuildProperty values? Can targets set properties on Items during Target evaluation time?

    I think it is possible to inject a Target to do this pre-evaluation if the above setting properties is possible?

    Thoughts?

    Thanks
    Brian

    Friday, May 31, 2019 12:05 PM
  • Hi,

    Looks like I am able to do something close to what I want by doing the following:

      <Target Name="Build_BeforeCPP" BeforeTargets="ClCompile">
        <ItemGroup>
          <ClCompile Condition="%(ClCompile.CustomBuildProperty) == 'ABC'">
            <DisableLanguageExtensions>false</DisableLanguageExtensions>
            … more settings ...
          </ClCompile>
        </ItemGroup>
      </Target>

    By using a target, I am able to use conditions/properties on a way that appear to apply properly to individual items. As long as the target runs before the actual ClCompile process then it all appears to work as desired.

    This now allows the Imported *.props file to abstract all the settings and only rely on individual Property tags against individual Source files as needed.

    Thanks
    Brian

    Saturday, June 1, 2019 1:18 PM
  • Hi friend,

    Thanks for sharing your solution here. It seems the approach you find which uses target to do the judgement can work for your situation.

    It seems your issue is solved bu it, you can consider marking it as answer so that other members with similar issue can benefit from it.

    Have a nice day!

    Best Regards

    Lance


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Monday, June 3, 2019 10:00 AM