2009-06-02 3 views
28

과 같은 대상의 내부 항목을 생성의 차이점은 무엇입니까 : CreateItem ItemGroup

<Target Name="DoStuff"> 
    <CreateItem Include="@(IntermediateAssembly)" > 
     <Output TaskParameter="Include" ItemName="FileWrites"/> 
    </CreateItem> 
</Target> 

이 같은

:

<Target Name="DoStuff"> 
    <ItemGroup> 
     <FileWrites Include="@(IntermediateAssembly)" /> 
    </ItemGroup> 
</Target> 

당신이 하나를 사용하는 것 또는 다른 이유는 무엇입니까?

답변

27

3.5 이전의 MSBuild 버전에서는 두 번째 예제와 같이 대상 안에 속성이나 항목을 정의 할 수 없습니다. 따라서 작업이 대신 사용되었습니다 (CreateItem 및 CreateProperty)

ToolsVersion 3.5를 사용하는 경우 더 이상 CreateItem을 사용할 필요가 없습니다.

결국 둘 다 동일한 범위로 동일한 항목을 만듭니다. 두 번째 구문을 사용하는 것이 더 읽기 쉽고 사용자 지정 메타 데이터를 설정하는 것이 훨씬 쉽습니다 (내 의견으로는).

참고 : 3.5 버전의 MSBuild는 .NET 3.5와 함께 설치됩니다. 3.5 기능을 사용하려면 ToolsVersion="3.5"을 MSBuild 파일의 Project 태그에 정의해야합니다.

당신이 궁금해하는 경우에, 나는이 책의 대부분을 내가 실제로 좋아했던 책 Inside the Microsoft® Build Engine: Using MSBuild and Team Foundation Build에서 얻었지만 어떤 식 으로든 관련이 없다.

+0

대단히 고맙습니다. 이것은 내가 알고 싶었던 것입니다! 그 책을 확인해야합니다. – Jake

+2

그래, 그 책은 좋아, 나는 그것을 사랑 :) :) :) 감사합니다. –

+5

그래도 큰 차이가 하나 발견되었습니다 : CreateItem은 와 같은 변환 작업을 통해 Include에 포함 된 와일드 카드를 확장합니다. 반면 ItemGroup 선언은 확장하지 않습니다 . –

7

나는 받아 들여진 응답이 다름을 정의했다고 생각하지 않는다.

차이점은 다음의 MSBuild 스크립트를로드 할 때

  • ItemGroup 평가된다. 대상은 스크립트 내에서 항목의 다른 값으로 이어질 수

이을 실행할 때

  • CreateItem
  • 평가된다.

    디렉토리에서 "* .txt"와 일치하는 모든 파일을 사용하는 작업의 예를 보겠습니다. MSBuild 스크립트가 Visual Studio에로드 된 경우 ItemGroup을 사용하는 경우 VS가 시작될 때 존재했던 파일 만 항목에 포함됩니다.

    CreateItem을 사용하면 대상을 실행할 때 모든 * .txt 파일을 검색합니다.

    +10

    Asker는 둘 다 대상 내부에서 호출되고 있음을 나타냅니다. 당신의 대답을 보면, MSBuild 3.5 이전의 용어로 생각하고있는 것처럼 보입니다. (ItemGroup을 대상 안에 배치 할 수없는 경우). ItemGroup이 대상 안에 있으면 CreateItem을 통해 선언 된 것처럼 동적입니다. (즉, 대상이 실행될 때 평가됩니다.) (51 페이지의 "Microsoft Build Engine 내부 : MSBuild 및 Team Foundation Build 사용"참조 (또는 그냥 시도해보십시오) 참조). – Vaccano

    +0

    @Vaccano : Itemgroup은 대상 내에서 "동적"입니다. 선택한 답변의 주석에서 Johannes Rudolph가 언급 한 예외는 예외입니다. - "CreateItem은 변형 작업을 통해 포함에서 와일드 카드를 확장합니다 ..." ItemGroup 선언은 그렇지 않습니다. – CyberMonk

    17

    CreateItem 및 CreateProperty는 MSBuild 3.5에서 폐기되었습니다 (물론 계속 작동 할 예정 임). Item 내부에서 작업하기 위해 ItemGroup과 PropertyGroup에 대해 비슷한 익숙한 구문이 필요하다는 것은 꽤 분명했습니다.

    그러나 대상 내부의 ItemGroup에는 특별한 특별한 힘이 있습니다. 항목을 수정할 수 있습니다. 예를 들어, 값이 true 인 Primary라는 메타 데이터가있는 Resources 목록의 모든 항목에 true를 추가합니다. 아직없는 경우에만 메타 데이터 복사 :

    <ItemGroup> 
        <Resources Condition=" '%(Primary)' == 'true' "> 
        <Copy Condition=" '%(Copy)' == '' ">true</Copy> 
        </Resources> 
    </ItemGroup> 
    

    다른 마법의 힘이 하나 있습니다. 이제 목록에서 항목을 제거 할 수 있습니다.이 예에서는 리소스 목록에서 값이 비트 맵 인 메타 데이터 유형을 가진 모든 항목을 제거합니다.

    <ItemGroup> 
        <Resources Condition=" '%(Type)'=='Bitmap' " Remove="@(Resources)"/> 
    </ItemGroup> 
    

    이러한 마법력은 현재 밖에 작동하지 않고 작동합니다.

    이 내용에 대한 자세한 내용은 MSBuild에 대한 Sayed Hashimi의 책을 강력하게 추천합니다. Amazon에서 쉽게 찾을 수 있습니다.

    Dan - msbuild 팀.

    1

    여기를 지나가는 다른 사용자를위한 추가 정보 : MSBuild 프로젝트를 작성하는 API가 포함 된 Build-Engine은 ItemGroups를 새로운 방식으로 대상에 추가하는 것을 지원하지 않습니다. 여기에서는 구식 방식을 사용해야합니다.

    관련 문제