Skip to content

Commit 97959b5

Browse files
thyponzcbenz
authored andcommitted
build: include windows toolchain profiler (electron#20949)
This commit allows any electron user to compile electron artifacts by themselves in production mode. When the source code is reproducibly buildable with a given toolchain this change allows them to verify the hash of their build, with the same windows toolchain agains the CI version. This change was tested on top of version https://chromium.googlesource.com/chromium/src/+/fb9837799bb6388ecaee010fc80cc1438e6bb134 which was buildable and reproducible for chromium and electron as well. Further tests may be introduced to allows checking for local reproducibility. EG: building twice an artifact on the same machine, with different time and output directory should yield similar hashes.
1 parent b8ee8c4 commit 97959b5

File tree

2 files changed

+100
-0
lines changed

2 files changed

+100
-0
lines changed

appveyor.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ build_script:
118118
- ninja -C out/Default electron:electron_chromedriver_zip
119119
- ninja -C out/Default third_party/electron_node:headers
120120
- cmd /C %SCCACHE_PATH% --show-stats
121+
- python electron/build/profile_toolchain.py --output-json=out/Default/windows_toolchain_profile.json
122+
- appveyor PushArtifact out/Default/windows_toolchain_profile.json
121123
- appveyor PushArtifact out/Default/dist.zip
122124
- appveyor PushArtifact out/Default/shell_browser_ui_unittests.exe
123125
- appveyor PushArtifact out/Default/chromedriver.zip

build/profile_toolchain.py

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
from __future__ import with_statement
2+
import contextlib
3+
import sys
4+
import os
5+
import optparse
6+
import json
7+
8+
sys.path.append("%s/../../build" % os.path.dirname(os.path.realpath(__file__)))
9+
10+
import find_depot_tools
11+
from vs_toolchain import \
12+
SetEnvironmentAndGetRuntimeDllDirs, \
13+
SetEnvironmentAndGetSDKDir, \
14+
GetVisualStudioVersion, \
15+
NormalizePath
16+
17+
sys.path.append("%s/win_toolchain" % find_depot_tools.add_depot_tools_to_path())
18+
19+
from get_toolchain_if_necessary import CalculateHash
20+
21+
22+
@contextlib.contextmanager
23+
def cwd(dir):
24+
curdir = os.getcwd()
25+
try:
26+
os.chdir(dir)
27+
yield
28+
finally:
29+
os.chdir(curdir)
30+
31+
32+
def calculate_hash(root):
33+
with cwd(root):
34+
return CalculateHash('.', None)
35+
36+
def windows_installed_software():
37+
import win32com.client
38+
strComputer = "."
39+
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
40+
objSWbemServices = objWMIService.ConnectServer(strComputer, "root\cimv2")
41+
colItems = objSWbemServices.ExecQuery("Select * from Win32_Product")
42+
items = []
43+
44+
for objItem in colItems:
45+
item = {}
46+
if objItem.Caption:
47+
item['caption'] = objItem.Caption
48+
if objItem.Caption:
49+
item['description'] = objItem.Description
50+
if objItem.InstallDate:
51+
item['install_date'] = objItem.InstallDate
52+
if objItem.InstallDate2:
53+
item['install_date_2'] = objItem.InstallDate2
54+
if objItem.InstallLocation:
55+
item['install_location'] = objItem.InstallLocation
56+
if objItem.Name:
57+
item['name'] = objItem.Name
58+
if objItem.SKUNumber:
59+
item['sku_number'] = objItem.SKUNumber
60+
if objItem.Vendor:
61+
item['vendor'] = objItem.Vendor
62+
if objItem.Version:
63+
item['version'] = objItem.Version
64+
items.append(item)
65+
66+
return items
67+
68+
69+
def windows_profile():
70+
runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
71+
win_sdk_dir = SetEnvironmentAndGetSDKDir()
72+
path = NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH'])
73+
74+
return {
75+
'pwd': os.getcwd(), # since current windows executable are symbols path dependant, profile the current directory too
76+
'installed_software': windows_installed_software(),
77+
'sdks': [
78+
{'name': 'vs', 'path': path, 'hash': calculate_hash(path)},
79+
{'name': 'wsdk', 'path': win_sdk_dir, 'hash': calculate_hash(win_sdk_dir)}
80+
],
81+
'runtime_lib_dirs': runtime_dll_dirs,
82+
}
83+
84+
85+
def main(options):
86+
if sys.platform == 'win32':
87+
with open(options.output_json, 'wb') as f:
88+
json.dump(windows_profile(), f)
89+
else:
90+
raise OSError("Unsupported OS")
91+
92+
93+
if __name__ == '__main__':
94+
parser = optparse.OptionParser()
95+
parser.add_option('--output-json', metavar='FILE', default='profile.json',
96+
help='write information about toolchain to FILE')
97+
options, args = parser.parse_args()
98+
sys.exit(main(options))

0 commit comments

Comments
 (0)