.NET 組件 Determinism 實驗
0 |
前一篇文章我學到一個 .NET 組件編譯名詞 - Determinism。是指 .NET 編譯組件時停用加入 Timestamp 及隨機產生的 GUID 的做法,改以原始碼內容、工作路徑... 等條件為依據,確保相同程式碼在相同環境編譯出來的組件二進位內容完全一致,這有助於識別組件是否來自可信任來源(例如:配合雜湊碼驗證),或是某些比對組件二進位差異決定編譯步驟的連續編譯系統。
光看理論沒實地驗證覺得心虛,反正難度不高,動手簡單實驗觀察一下心裡才踏實。我開了一個 .NET Framework Class Library 專案 - FooLibrary。修改 FooLibrary.csproj 以下兩處設定,分別存成 FooLibraryD1.csproj、FooLibraryD2.csproj、FooLibraryND1.csproj、FooLibraryND2.csproj 四個檔案:
四個 FooLibrary*.csproj 的設定差異如下,AssemblyVersion 則寫死 1.0.0.0 (要同時測試 Deterministic = true/false 不能自動跳號):
專案 | Deterministic | OutputPath |
---|---|---|
FooLibraryD1.csproj | true | bin\DebugD1\ |
FooLibraryD2.csproj | true | bin\DebugD2\ |
FooLibraryND1.csproj | false | bin\DebugND1\ |
FooLibraryND2.csproj | false | bin\DebugND2\ |
用一個 DOS 批次檔,使用 MSBuild 依序建置四個 csproj 產生 FooLibrary.dll 分別寫入各自 bin\DebugD* 目錄,稍後再比對各目錄的 FooLibrary.dll,即可驗證二進位內容是否完全相同。(刪除 obj 目錄以確保 MSBuild 不會沿用前次編譯的結果)
msbuild FooLibraryD1.csproj
rmdir /s /q obj
msbuild FooLibraryD2.csproj
rmdir /s /q obj
msbuild FooLibraryND1.csproj
rmdir /s /q obj
msbuild FooLibraryND2.csproj
rmdir /s /q obj
依據理論,DebugD1 與 DebugD2 目錄下的 FooLibrary.dll 使用 <Deterministic>true</Deterministic>
編譯 true,理應完全相同;而 DebugND1 與 DebugND2 為 <Deterministic>false</Deterministic>
,每次編譯結果都不會相同。使用 File Compare DOS 工具驗證,一如預期,DebugD1 與 DebugD2 相同,DebugND1 與 DebugND2 不同,實驗成功。
Experiment of how .NET compiler deterministic parameter affects assembly binary.
Comments
Be the first to post a comment