2009-09-10 1 views
1

내 TFS 빌드에서 작업을 좀 더 일반적인 방식으로 만들려고했는데 수행하려고하는 작업 중 하나는 작업을 사용하는 빌드에 따라 다른 디렉터리에 일부 파일을 복사하는 것입니다. 속성을 사용한다는 생각에 놀랐지 만, 깔끔하게 처리 할 수있는 방법을 생각할 수 없었기 때문에 동일한 대상 파일의 다른 위치에서 수행 할 수 있었기 때문에 항목 메타 데이터를 사용하려고했습니다. 나는 이번에 만 일하고 있습니다, 나는 속성을 사용하고 싶습니다. 여기 속성을 사용하여 항목 메타 데이터 설정

는 내가하고 싶은 작업은 다음과 같습니다 후, 불행하게도

<Copy SourceFiles="@(FilesToCopy)" DestinationFiles="@(FilesToCopy-&gt;'%(DestinationParentPath)\Destination\%(RecursiveDir)%(Filename)%(Extension)')" ContinueOnError="false" ></Copy> 

:

<ItemGroup> 
    <DestinationParent Include="$(DeploymentPath)"> 
    <DestinationParentPath>$(DeploymentPath)</QuartzParentPath> 
    </DestinationParent> 
</ItemGroup> 

그리고 나중에 빌드를, 나는 항목의 메타 데이터를 참조하여 대상 폴더에 어떤 파일을 복사하려고 빌드가 실행되면 BuildLog에 다음이 표시됩니다.

Copying file from "$(BinariesRoot)\%(ConfigurationToBuild.FlavorToBuild)\<File being copied>" to "\Destination\<File being copied>". 

% (DestinationParentPath) had 어떤 이유로 든 빈 문자열로 확장됩니다. % (DestinationParent.DestinationParentPath)를 사용하면 단순히 % (DestinationParentPath)를 사용해야한다고 오류가 발생했습니다. $ (DeploymentPath)는 빌드의 다른 여러 위치에서 예상대로 올바른 문자열로 확장됩니다.

혼란의 또 다른 소스는 다음에서 알 수있는 바와 같이 (ConfigurationToBuild.FlavorToBuild) %를 사용하여, 올바른 값, 즉 시험을 수득이다 :

EDIT이 루트 노드 프로젝트에서 정의되는 반면, DestinationParentPath가있는 ItemGroup은 대상 노드 아래에 정의됩니다. 이것도 차이가 있습니까?

<ItemGroup> 
    <ConfigurationToBuild Include="Test|Any CPU"> 
    <FlavorToBuild>Test</FlavorToBuild> 
    <PlatformToBuild>Any CPU</PlatformToBuild> 
    </ConfigurationToBuild> 
</ItemGroup> 

나는 확신하기 때문에 당신이 항목의 메타 데이터에 문자열에만 관심이있을 때 포함] 속성이 관련이있는 것처럼 그것은 보이지 않는다 "테스트 | 모든 CPU는"실제 파일을 참조하지 않습니다.

다시 한번 왜 % (DestinationParentPath)가 빈 문자열로 확장됩니까?

편집 : 나는 또한 DestinationParentPath에 대한 실제 경로를 하드 코딩했음을 언급하는 것을 잊어 버렸지 만, 여전히 % (DestinationParentPath)가 빈 문자열로 확장되었습니다.

답변

1

EDIT : 루트 노드 Project에서 정의되며 DestinationParentPath가있는 ItemGroup은 대상 노드에서 정의됩니다. 이것도 차이가 있습니까?

네, 차이가 있습니다. Target 내에 ItemGroup을 정의하는 기능은 msbuild 3.5의 새로운 기능입니다. 선언적으로 보았음에도 불구하고 런타임에서는 실제로 이전 스타일의 CreateItem/CreateProperty 작업을 호출 한 것처럼 실행됩니다. 이것만으로도 잠재적 인 문제가 발생합니다. 포함 된 작업이 처음 호출 될 때 고려해야합니다. Order of operations is not always obvious to the naked eye. "논리적"종속성이 없더라도 생성 된 작업에 따라 % (DestinationParentPath)를 사용하는 작업을 만드는 것이 현명 할 수 있습니다.

또한 오래된 msbuild 범위 지정/버그가 있습니다. Dynamically created properties & items are not visible to "sibling" tasks. 또한 items updated in nested builds aren't always bubbled up.

링크의 해결 방법을 확인하면 문제가 있어도 도움이 될만한 자료를 찾을 수 있습니다.

+0

당신의 답변과 링크를 주셔서 감사합니다. 내 문제를 해결하는 방법을 알아 냈습니다. :) (그래, 그래, 조금은 성가시다. 그럼에도 불구하고 꽤 잘 돌아 간다.) 아직도 나에게 혼란스런 질문 하나가있다. 위에서 언급 한 % (Configuration.FlavorToBuild)가 글로벌 ... 항목으로 취급되는 것 같습니다. 이것이 제가 현장의 다른 부분에서 사용할 수있는 이유입니까? –

+1

구성 항목은 팀 빌드에 의해 프로세스 초기에 설정되므로 추가 작업없이 스크립트 전체에서 작동한다는 것은 놀라운 일이 아닙니다. ///// 아마도 "범위"는 잘못된 단어입니다. 속성과 항목은 msbuild에서 항상 "전역"이며, $ (foo)가 나타나는 위치에 관계없이 항상 "같은"$ (foo)를 참조한다는 의미에서 사용됩니다. C# analogy : 네임 스페이스 키워드가없고 오직 하나의 클래스 정의 만 있다고 상상해보십시오. 일반적으로이 클래스의 단일 인스턴스를 항상 참조로 전달합니다. 첫 번째 링크는 흐름 제어를 설명합니다. 후기 2는 부실 복사본이 전달되거나 전달되는 단점을 설명합니다. –