Files
cromite/tools/images/win-sdk/gen-setenv.py

169 lines
6.3 KiB
Python

#!/usr/bin/env python3
#
# This script generates JSON files that are easier-to-parse equivalents of
# the SetEnv batch script provided by Visual Studio, which sets necessary
# environment variables. These JSON files are used by the Chromium build
# system to obtain specific paths to Microsoft SDK resources.
#
# The GenerateSetEnvCmd() function is lightly modified from
# https://chromium.googlesource.com/chromium/tools/depot_tools.git/+/5eef793337de052b29dc5ec6eb22676938dadbe4/win_toolchain/package_from_installed.py
#
# original code from
# https://github.com/iskunk/ungoogled-chromium-windows/blob/feature/win_cross/cross-build/gen-setenv.py
import collections
import glob
import json
import os
import sys
dir = sys.argv[1]
_vc_tools = glob.glob('VC/Tools/MSVC/*', root_dir=dir)[0]
_win_version = glob.glob('[1-9]*', root_dir=f'{dir}/Windows Kits/10/Lib')[0]
def GenerateSetEnvCmd(target_dir):
"""Generate a batch file that gyp expects to exist to set up the compiler
environment.
This is normally generated by a full install of the SDK, but we
do it here manually since we do not do a full install."""
vc_tools_parts = _vc_tools.split('/')
# All these paths are relative to the root of the toolchain package.
include_dirs = [
['Windows Kits', '10', 'Include', _win_version, 'um'],
['Windows Kits', '10', 'Include', _win_version, 'shared'],
['Windows Kits', '10', 'Include', _win_version, 'winrt'],
]
include_dirs.append(['Windows Kits', '10', 'Include', _win_version, 'ucrt'])
include_dirs.extend([
vc_tools_parts + ['include'],
vc_tools_parts + ['atlmfc', 'include'],
])
libpath_dirs = [
vc_tools_parts + ['lib', 'x86', 'store', 'references'],
['Windows Kits', '10', 'UnionMetadata', _win_version],
]
# Common to x86, x64, and arm64
env = collections.OrderedDict([
# Yuck: These have a trailing \ character. No good way to represent this
# in an OS-independent way.
('VSINSTALLDIR', [['.\\']]),
('VCINSTALLDIR', [['VC\\']]),
('INCLUDE', include_dirs),
('LIBPATH', libpath_dirs),
])
# x86. Always use amd64_x86 cross, not x86 on x86.
env['VCToolsInstallDir'] = [vc_tools_parts[:]]
# Yuck: This one ends in a path separator as well.
env['VCToolsInstallDir'][0][-1] += os.path.sep
env_x86 = collections.OrderedDict([
(
'PATH',
[
['Windows Kits', '10', 'bin', _win_version, 'x64'],
vc_tools_parts + ['bin', 'HostX64', 'x86'],
vc_tools_parts +
['bin', 'HostX64', 'x64'], # Needed for mspdb1x0.dll.
]),
('LIB', [
vc_tools_parts + ['lib', 'x86'],
['Windows Kits', '10', 'Lib', _win_version, 'um', 'x86'],
['Windows Kits', '10', 'Lib', _win_version, 'ucrt', 'x86'],
vc_tools_parts + ['atlmfc', 'lib', 'x86'],
]),
])
# x64.
env_x64 = collections.OrderedDict([
('PATH', [
['Windows Kits', '10', 'bin', _win_version, 'x64'],
vc_tools_parts + ['bin', 'HostX64', 'x64'],
]),
('LIB', [
vc_tools_parts + ['lib', 'x64'],
['Windows Kits', '10', 'Lib', _win_version, 'um', 'x64'],
['Windows Kits', '10', 'Lib', _win_version, 'ucrt', 'x64'],
vc_tools_parts + ['atlmfc', 'lib', 'x64'],
]),
])
# arm64.
env_arm64 = collections.OrderedDict([
('PATH', [
['Windows Kits', '10', 'bin', _win_version, 'x64'],
vc_tools_parts + ['bin', 'HostX64', 'arm64'],
vc_tools_parts + ['bin', 'HostX64', 'x64'],
]),
('LIB', [
vc_tools_parts + ['lib', 'arm64'],
['Windows Kits', '10', 'Lib', _win_version, 'um', 'arm64'],
['Windows Kits', '10', 'Lib', _win_version, 'ucrt', 'arm64'],
vc_tools_parts + ['atlmfc', 'lib', 'arm64'],
]),
])
def BatDirs(dirs):
return ';'.join(['%cd%\\' + os.path.join(*d) for d in dirs])
set_env_prefix = os.path.join(target_dir, r'Windows Kits/10/bin/SetEnv')
with open(set_env_prefix + '.cmd', 'w') as f:
# The prologue changes the current directory to the root of the
# toolchain package, so that path entries can be set up without needing
# ..\..\..\ components.
f.write('@echo off\n'
':: Generated by win_toolchain\\package_from_installed.py.\n'
'pushd %~dp0..\\..\\..\n')
for var, dirs in env.items():
f.write('set %s=%s\n' % (var, BatDirs(dirs)))
f.write('if "%1"=="/x64" goto x64\n')
f.write('if "%1"=="/arm64" goto arm64\n')
for var, dirs in env_x86.items():
f.write('set %s=%s%s\n' %
(var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else ''))
f.write('goto :END\n')
f.write(':x64\n')
for var, dirs in env_x64.items():
f.write('set %s=%s%s\n' %
(var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else ''))
f.write('goto :END\n')
f.write(':arm64\n')
for var, dirs in env_arm64.items():
f.write('set %s=%s%s\n' %
(var, BatDirs(dirs), ';%PATH%' if var == 'PATH' else ''))
f.write('goto :END\n')
f.write(':END\n')
# Restore the original directory.
f.write('popd\n')
with open(set_env_prefix + '.x86.json', 'wt', newline='') as f:
assert not set(env.keys()) & set(env_x86.keys()), 'dupe keys'
json.dump(
{
'env':
collections.OrderedDict(
list(env.items()) + list(env_x86.items()))
}, f, indent=2)
with open(set_env_prefix + '.x64.json', 'wt', newline='') as f:
assert not set(env.keys()) & set(env_x64.keys()), 'dupe keys'
json.dump(
{
'env':
collections.OrderedDict(
list(env.items()) + list(env_x64.items()))
}, f, indent=2)
with open(set_env_prefix + '.arm64.json', 'wt', newline='') as f:
assert not set(env.keys()) & set(env_arm64.keys()), 'dupe keys'
json.dump(
{
'env':
collections.OrderedDict(
list(env.items()) + list(env_arm64.items()))
}, f, indent=2)
GenerateSetEnvCmd(dir)
# EOF