2010-10-13 12 views
5

Tôi đã đọc về việc sử dụng "Custom.Before.Microsoft.Common.targets" và "Custom.After.Microsoft.Common.targets "để thực hiện một mục tiêu tùy chỉnh trước/sau mỗi lần xây dựng dự án và tôi muốn sử dụng kỹ thuật này để thay đổi thông tin phiên bản trong khi xây dựng trên máy chủ TeamCity build của chúng tôi.MSBuild: Custom.After.Microsoft.Common.targets cho các dự án C++ gốc trong VS2010

Vấn đề là mặc dù nó hoạt động cho các dự án C#, nó dường như không hoạt động cho các dự án C++ gốc.

Sau khi tìm hiểu về tệp Microsoft.Cpp.targets, tôi phát hiện ra rằng đối với các dự án C++ gốc, điều này có vẻ được thực hiện thông qua thiết lập $ (ForceImportBeforeCppTargets) và $ (ForceImportAfterCppTargets).

Tôi dường như không tìm thấy một mẩu thông tin nào trên web về kỹ thuật này cho ứng dụng gốc C++, vì vậy tôi hỏi liệu tôi có đang tìm đúng hướng hay không.

Mọi trợ giúp đều được đánh giá cao.

+0

Tại sao bạn không sử dụng cài đặt Sự kiện xây dựng + Sự kiện trước khi xây dựng và Sự kiện sau khi tạo dựng? –

+0

Chúng tôi không sử dụng các sự kiện trước/sau khi xây dựng vì chúng luôn được thực thi, chúng tôi muốn một cái gì đó chỉ chạy khi xây dựng trên máy chủ và cũng nhận được thông tin phiên bản (và thông tin khác) từ máy chủ xây dựng. Ngoài ra, chúng tôi không muốn phụ thuộc vào việc nhà phát triển có quên đặt thứ gì đó trong các cài đặt sự kiện này hay không, nó phải tự động và 'Custom.Before.Microsoft.Common.targets' cung cấp điều đó nhưng dường như không phải cho mã gốc. – Halt

Trả lời

10

Đối với các dự án VC++, có một chút khác biệt. Bạn xác định một tệp được nhập vào lúc bắt đầu hoặc ở cuối dự án. Để sử dụng phương pháp này, bạn cần phải xác định các giá trị cho các thuộc tính ForceImportBeforeCppTargets hoặc ForceImportAfterCppTargets. Ví dụ: nếu bạn muốn một tệp được đưa vào đầu dự án, bạn có thể chuyển giá trị tại dòng lệnh. Ví dụ tôi vừa tạo một dự án VC++ giả tên là CppTets01. Sau đó, tôi đã tạo hai tệp mẫu bên dưới.

Before.proj

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 


    <Target Name="CustomTargetInBefore" AfterTargets="Build"> 
    <Message Text="From CustomTargetInBefore" Importance="high"/> 
    </Target> 

</Project> 

After.proj

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <Target Name="CustomTargetInAfter" AfterTargets="Build"> 
    <Message Text="From CustomTargetInAfter" Importance="high"/> 
    </Target> 

</Project> 

Sau đó, tôi thực hiện lệnh sau:

msbuild CppTest01.vcxproj 
    /p:ForceImportBeforeCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\Before.proj"; 
    ForceImportAfterCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\After.proj" 

Kết quả là C: \ Temp_NET \ ThrowAway \ CppTest01 \ CppTest01> msbuild CppTest01.vcxproj/p: ForceImportBeforeCppTargets = "C: \ Temp_NET \ ThrowAway \ CppTest01 \ C ppTest01 \ Before.proj"; ForceImportAfterCppTargets = "C: \ Temp_NET \ ThrowAway \ CppTest01 \ CppTest01 \ After.proj "

Microsoft (R) Build Engine Version 4.0.30319.1 
[Microsoft .NET Framework, Version 4.0.30319.1] 
Copyright (C) Microsoft Corporation 2007. All rights reserved. 

Build started 10/18/2010 8:32:55 AM. 
Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" on node 1 (default targets). 
InitializeBuildStatus: 
    Creating "Debug\CppTest01.unsuccessfulbuild" because "AlwaysCreate" was specified. 
ClCompile: 
    All outputs are up-to-date. 
    All outputs are up-to-date. 
ManifestResourceCompile: 
    All outputs are up-to-date. 
Link: 
    All outputs are up-to-date. 
Manifest: 
    All outputs are up-to-date. 
FinalizeBuildStatus: 
    Deleting file "Debug\CppTest01.unsuccessfulbuild". 
    Touching "Debug\CppTest01.lastbuildstate". 
CustomTargetInBefore: 
    From CustomTargetInBefore 
CustomTargetInAfter: 
    From CustomTargetInAfter 
Done Building Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" (default targets). 


Build succeeded. 
    0 Warning(s) 
    0 Error(s) 

Time Elapsed 00:00:00.21 

Như bạn có thể thấy từ đầu ra các mục tiêu đã được tiêm thành công vào quá trình xây dựng. Nếu bạn muốn liên hệ lại điều này với Custom.Before.Microsoft.Common.targetsCustom.Before.Microsoft.Common.targets thì bạn nên biết rằng kỹ thuật được sử dụng có một chút khác biệt. Cụ thể là nếu bạn tạo các tệp đó, chúng sẽ tự động được nhập vào mọi dự án C#/VB.NET. Trong trường hợp này, bạn phải đặt thuộc tính này. Bạn thực sự có hai lựa chọn ở đây:

  1. Bạn có thể thiết lập thuộc tính này như là một biến môi trường
  2. Bạn có thể sử dụng một kỹ thuật, ImportBefore & ImportAfter mà là cụ thể cho VC++

Đối # 1 hãy để tôi giải thích một chút.Trong MSBuild khi bạn truy cập một thuộc tính với cú pháp $ (PropName) thì nếu một thuộc tính với tên PropName không tồn tại MSBuild sẽ tra cứu trong các biến môi trường để xem nếu một giá trị tồn tại, nếu nó thì giá trị đó được trả về . Vì vậy, nếu bạn có một máy chủ xây dựng mà bạn muốn bao gồm một tệp cho mỗi bản dựng VC++, thì chỉ cần tạo các thuộc tính đó dưới dạng các biến môi trường. Bây giờ cho kỹ thuật khác.

Nhập trước khi nhập/sau Trong VC++, khái niệm mới được giới thiệu. Trong Microsoft.Cpp.Win32.targets bạn có thể thấy khai báo ở đầu tệp .targets.

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportBefore\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportBefore')" /> 

Sau đó, có một về phía đáy

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportAfter\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportAfter')" /> 

Một tờ khai nhập khẩu tương tự tồn tại cho các nền tảng mục tiêu khác nữa. Hãy xem các tệp tại %ProgramFiles32%\MSBuild\Microsoft.Cpp\v4.0\Platforms\ để biết tên cụ thể.

Với kỹ thuật này nếu bạn muốn tệp được nhập thì chỉ cần tạo tệp kết thúc bằng .targets và đặt tệp đó vào thư mục thích hợp. Ưu điểm của việc này là nó sẽ được nhập vào mọi bản dựng VC++ cho nền tảng đó và bạn có thể tạo nhiều tệp khác nhau. Hạn chế là bạn phải đặt chúng vào các thư mục cụ thể đó. Đó là sự khác biệt chính giữa cả hai kỹ thuật. Với kỹ thuật đầu tiên này, bạn có thể chỉ định vị trí tệp qua thuộc tính và không được tự động bao gồm cho mỗi bản dựng, nhưng đối với phương pháp thứ hai, nhưng bạn không thể thay đổi vị trí

+0

Xin lỗi về điều đó, tôi đã cung cấp thông tin sai. Tôi đã xem xét điều này sâu hơn một chút và đã khắc phục vấn đề. Tôi đã cập nhật câu trả lời của mình để phản ánh những phát hiện của mình. –

+0

Cảm ơn, câu trả lời tuyệt vời, bạn đã xác nhận những gì tôi bắt đầu nghi ngờ. Bây giờ tôi biết tôi đang đi đúng hướng. – Halt

+0

OK, xin lỗi vì sự trật bánh. –

3

Bạn cũng có thể thêm nội dung dự án vào một trong số *.props tệp từ thư mục %LOCALAPPDATA%\Microsoft\MSBuild\v4.0\

Nó có cùng tác dụng.