about 3 years ago

昨天花了一點時間研究一下,Visual C++ 該怎麼客製 Clean 的行為。

簡單講,我想要在 Clean Project 的同時刪除特定的目錄。不像 Build 有 Pre-build Event 或 Post-build Event 可以掛上額外的工作,客製 Clean 行為似乎沒有那麼簡單,至少 Visual Studio 並沒有 UI 可以直接操作。

研究 .vcxproj

研究了一下 vcxproj 的文件格式,我發現整個 C++ 專案的編譯流程,都是由 Microsoft.Cpp.targets 這個文件定義的。每個 .vcxproj 透過 <Import> tag 將之引入,確立整個專案的建構流程。

  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />

所以我打開 Microsoft.Cpp.target 文件,發現裡面又透過另一個檔案 Microsoft.CppClean.targets 來定義 Clean 的行為:

  <Import Project="$(VCTargetsPath)\Microsoft.CppClean.targets" />

感覺我離目標越來越近了,再打開 Microsoft.CppClean.targets 文件,我馬上看見了兩個空的 Target tag:

  <!-- BeforeCppClean: Redefine this target in your project in order to run tasks just before Clean. -->
  <Target Name="BeforeCppClean">
  </Target>

  <!-- AfterCppClean: Redefine this target in your project in order to run tasks just after Clean. -->
  <Target Name="AfterCppClean">
  </Target>

OK,所以其實 Visual C++ 在 Clean 的流程中已經保留了 BeforeCppClean 和 AfterCppClean 兩個事件,分別在 Clean 之前和之後觸發,我只要複寫這兩個事件就行了。

複寫 BeforeCppClean

現在我要重新定義 Target,作法是寫一個自己的 .target 文件,然後再透過 <Import> 標籤引入 vcxproj。
實際上要做的工作就寫在 Target 標籤裡。

// 我自己定義的 MyCppClean.target
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="BeforeCppClean">            // 複寫 BeforeCppClean
    <Message Text="Delete XXXX Folder!" />  // 印出訊息
    <RemoveDir Directories="XXXX" />        // 刪除 XXXX 這個目錄
  </Target>
</Project>

最後我們把自定義的 target 引入專案,在 .vcxproj 中加入一行:

<Project>
  ...
  <Import Project="MyCppClean.target" />
</Project>

這樣子 Clean 專案時,就會刪除特定目錄了。

參考連結

← 錯誤「Powershell 檔案無法載入,因為這個系統上已停用指令碼執行」 無法驗證此版本的『安裝 OS X Yosemite』 →
 
comments powered by Disqus