Skip to content

Commit

Permalink
chore: 实现修剪 resources.pri,并将发布脚本移植为 python
Browse files Browse the repository at this point in the history
  • Loading branch information
Blinue committed Oct 10, 2023
1 parent 97c00e2 commit afbe1de
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 34 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,8 @@ jobs:
- name: Setup Conan
run: pip install conan<2.0

- name: Setup MSBuild
uses: microsoft/setup-msbuild@v1

- name: Build
run: pwsh "ci/build.ps1"
run: python "publish.py"

- name: Save hash
id: hash
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
##
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore

my_*/

# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
my_*/

# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
Expand Down
1 change: 1 addition & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
<!-- /Zc:__cplusplus: 更新 __cplusplus 宏 -->
<!-- /volatile:iso: 禁用 volatile 的语义扩展 -->
<!-- /fp:contract: 生成浮点收缩指令。浮点收缩指令是将两个浮点操作合并为一个指令的机器指令,例如 Fused-Multiply-Add (FMA) -->
<!-- fp:contract 可以和其他 fp 选项同时存在,因此每个项目可以分别指定自己的浮点模型 -->
<AdditionalOptions>%(AdditionalOptions) /await:strict /utf-8 /Zc:__cplusplus /volatile:iso /fp:contract</AdditionalOptions>
</ClCompile>
</ItemDefinitionGroup>
Expand Down
29 changes: 0 additions & 29 deletions ci/build.ps1

This file was deleted.

181 changes: 181 additions & 0 deletions publish.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
import ctypes, sys
from ctypes import windll, wintypes
import uuid
import subprocess
import os
import glob
import shutil
from xml.etree import ElementTree

#####################################################################
#
# 使用 vswhere 查找 msbuild
#
#####################################################################

class FOLDERID:
ProgramFilesX86 = uuid.UUID('{7C5A40EF-A0FB-4BFC-874A-C0F2E0B9FA8E}')

# 包装 SHGetKnownFolderPath,来自 https://gist.github.com/mkropat/7550097
def get_known_folder_path(folderid):
class GUID(ctypes.Structure):
_fields_ = [
("Data1", wintypes.DWORD),
("Data2", wintypes.WORD),
("Data3", wintypes.WORD),
("Data4", wintypes.BYTE * 8)
]

def __init__(self, uuid_):
ctypes.Structure.__init__(self)
self.Data1, self.Data2, self.Data3, self.Data4[0], self.Data4[1], rest = uuid_.fields
for i in range(2, 8):
self.Data4[i] = rest>>(8 - i - 1)*8 & 0xff

CoTaskMemFree = windll.ole32.CoTaskMemFree
CoTaskMemFree.restype= None
CoTaskMemFree.argtypes = [ctypes.c_void_p]

SHGetKnownFolderPath = windll.shell32.SHGetKnownFolderPath
SHGetKnownFolderPath.argtypes = [
ctypes.POINTER(GUID), wintypes.DWORD, wintypes.HANDLE, ctypes.POINTER(ctypes.c_wchar_p)
]

fid = GUID(folderid)
pPath = ctypes.c_wchar_p()
if SHGetKnownFolderPath(ctypes.byref(fid), 0, wintypes.HANDLE(0), ctypes.byref(pPath)) != 0:
raise FileNotFoundError()
path = pPath.value
CoTaskMemFree(pPath)
return path

programFilesX86Path = get_known_folder_path(FOLDERID.ProgramFilesX86);

vswherePath = programFilesX86Path + "\\Microsoft Visual Studio\\Installer\\vswhere.exe"
if not os.access(vswherePath, os.X_OK):
raise Exception("未找到 vswhere")

process = subprocess.run(vswherePath + " -latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe", capture_output=True)
msbuildPath = str(process.stdout, encoding="utf-8").splitlines()[0]
if not os.access(msbuildPath, os.X_OK):
raise Exception("未找到 msbuild")

#####################################################################
#
# 编译
#
#####################################################################

os.chdir(os.path.dirname(__file__))

if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64 src\\CONAN_INSTALL") != 0:
raise Exception("编译 CONAN_INSTALL 失败")

if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Effects") != 0:
raise Exception("编译 Effects 失败")

if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Magpie.Core") != 0:
raise Exception("编译 Magpie.Core 失败")

if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;BuildProjectReferences=false;OutDir=..\\..\\publish\\ src\\Magpie") != 0:
raise Exception("编译 Magpie 失败")

if os.system("\"" + msbuildPath + "\" /p:Configuration=Release;Platform=x64;OutDir=..\\..\\publish\\ src\\Updater") != 0:
raise Exception("编译 Updater 失败")

#####################################################################
#
# 清理不需要的文件
#
#####################################################################

os.chdir(os.getcwd() + "\\publish")

# 删除文件,忽略错误
def remove_file(file):
try:
os.remove(file)
except:
pass

# 删除文件夹,忽略错误
def remove_folder(folder):
try:
shutil.rmtree(folder)
except:
pass

remove_file("Microsoft.Web.WebView2.Core.dll")

for pattern in ["*.pdb", "*.lib", "*.exp", "*.winmd", "*.xml", "*.xbf", "dummy.*"]:
for file in glob.glob(pattern):
remove_file(file)

for file in glob.glob("*.pri"):
if file != "resources.pri":
remove_file(file)

for folder in ["Microsoft.UI.Xaml", "Magpie.App"]:
remove_folder(folder)

#####################################################################
#
# 修剪 resources.pri
# 参考自 https://github.com/microsoft/microsoft-ui-xaml/pull/4400
#
#####################################################################

windowsSdkDir = sorted(glob.glob(programFilesX86Path + "\\Windows Kits\\10\\bin\\10.*"))[-1];
makepriPath = windowsSdkDir + "\\x64\\makepri.exe"
if not os.access(makepriPath, os.X_OK):
raise Exception("未找到 makepri")

if os.system("\"" + makepriPath + "\" dump /dt detailed /o") != 0:
raise Exception("dump 失败")

tree = ElementTree.parse("resources.pri.xml")

for resourceNode in tree.getroot().findall("ResourceMap/ResourceMapSubtree/ResourceMapSubtree/ResourceMapSubtree/NamedResource"):
name = resourceNode.get("name")

if not name.endswith(".xbf"):
continue

# 我们仅需 19h1 和 21h1 的资源,分别用于 Win10 和 Win11
for key in ["compact", "Compact", "v1", "rs2", "rs3", "rs4", "rs5"]:
if key in name:
# 将文件内容替换为一个空格(Base64 为 "IA==")
resourceNode.find("Candidate/Base64Value").text = "IA=="
break

tree.write("resources.pri.xml", encoding="utf-8")

with open("priconfig.xml", "w", encoding="utf-8") as f:
print("""<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<resources targetOsVersion="10.0.0" majorVersion="1">
<packaging>
<autoResourcePackage qualifier="Scale" />
<autoResourcePackage qualifier="DXFeatureLevel" />
</packaging>
<index startIndexAt="resources.pri.xml" root="">
<default>
<qualifier name="Language" value="en-US" />
<qualifier name="Contrast" value="standard" />
<qualifier name="Scale" value="200" />
<qualifier name="HomeRegion" value="001" />
<qualifier name="TargetSize" value="256" />
<qualifier name="LayoutDirection" value="LTR" />
<qualifier name="DXFeatureLevel" value="DX9" />
<qualifier name="Configuration" value="" />
<qualifier name="AlternateForm" value="" />
<qualifier name="Platform" value="UAP" />
</default>
<indexer-config type="priinfo" emitStrings="true" emitPaths="true" emitEmbeddedData="true" />
</index>
</resources>""", file=f)

os.system("\"" + makepriPath + "\" new /pr . /cf priconfig.xml /in Magpie.App /o")

os.remove("resources.pri.xml")
os.remove("priconfig.xml")

0 comments on commit afbe1de

Please sign in to comment.