Đố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.targets
và Custom.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:
- Bạn có thể thiết lập thuộc tính này như là một biến môi trường
- 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í
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? –
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