Magpie/scripts/publish.py
Xu 04ff6ea0a3
支持使用 clang-cl 编译 (#1195)
* chore: native 项目支持 clang-cl

* chore: 修复 clang 编译错误

* chore: 修复部分 clang 编译警告

* chore: 修复警告

* chore: 修复所有警告,优化 llvm 查找

* chore: 启用 LTO

* chore: 支持 ARM64

* chore: _ConanDeps 支持 clang-cl

* chore: 编译选项改变 _ConanDeps 自动重新编译

* chore: profile 更改时重新编译 _ConanDeps

* chore: 将 hu 和 ka 加入项目文件,但不参与生成
否则不参与批量替换

* chore: Magpie 项目支持并行编译

* chore: 添加几个提高性能的编译选项

* chore: 优化 _ConanDeps

* chore: publish.py 支持参数

* chore: CI 支持 clang 编译

* chore: 修复 CI 的 conan 缓存

* chore: 优化编译选项,修复 CI

* chore: 修复 CI

* chore: 改变参数顺序

* chore: 添加编译选项支持针对当前硬件生成优化代码

* chore: 优化 CI 脚本

* chore: publish.py 添加 --use-native-march 选项

* chore: 脚本集中在 scripts 文件夹,msbuild 启用并行编译

* chore: clang, x64 配置启用 CX16 指令

* chore: 更新依赖

* chore: 更新格式设置

* chore: 增加额外的斜杠以提高兼容性

* chore: 修复效果文件复制
2025-07-15 17:40:04 +08:00

143 lines
4.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import sys
import os
import subprocess
import glob
import re
import argparse
try:
# https://docs.github.com/en/actions/learn-github-actions/variables
if os.environ["GITHUB_ACTIONS"].lower() == "true":
# 不知为何在 Github Actions 中运行时默认编码为 ANSI并且 print 需刷新流才能正常显示
for stream in [sys.stdout, sys.stderr]:
stream.reconfigure(encoding="utf-8")
except:
pass
argParser = argparse.ArgumentParser()
argParser.add_argument("--compiler", choices=["MSVC", "ClangCL"], default="MSVC")
argParser.add_argument("--platform", choices=["x64", "ARM64"], default="x64")
argParser.add_argument("--use-native-march", action="store_true")
argParser.add_argument("--version-major", type=int, default=0)
argParser.add_argument("--version-minor", type=int, default=0)
argParser.add_argument("--version-patch", type=int, default=0)
argParser.add_argument("--version-tag", default="")
argParser.add_argument("--pfx-path", default="")
argParser.add_argument("--pfx-password", default="")
args = argParser.parse_args()
#####################################################################
#
# 使用 vswhere 查找 msbuild
#
#####################################################################
programFilesX86Path = os.environ["ProgramFiles(x86)"]
vswherePath = programFilesX86Path + "\\Microsoft Visual Studio\\Installer\\vswhere.exe"
if not os.access(vswherePath, os.X_OK):
raise Exception("未找到 vswhere")
p = subprocess.run(
vswherePath
+ " -latest -requires Microsoft.Component.MSBuild -find MSBuild\\**\\Bin\\MSBuild.exe",
capture_output=True,
)
msbuildPath = str(p.stdout, encoding="utf-8").splitlines()[0]
if not os.access(msbuildPath, os.X_OK):
raise Exception("未找到 msbuild")
#####################################################################
#
# 编译
#
#####################################################################
os.chdir(os.path.dirname(__file__) + "\\..")
p = subprocess.run("git rev-parse --short HEAD", capture_output=True)
commitId = str(p.stdout, encoding="utf-8")[0:-1]
versionNumProps = ""
if args.version_major != 0 or args.version_minor != 0 or args.version_patch != 0:
versionNumProps = f";MajorVersion={args.version_major};MinorVersion={args.version_minor};PatchVersion={args.version_patch}"
# 更新 RC 文件中的版本号
version = f"{args.version_major}.{args.version_minor}.{args.version_patch}.0"
version_comma = version.replace(".", ",")
for project in os.listdir("src"):
rcPath = f"src\\{project}\\{project}.rc"
if not os.access(rcPath, os.R_OK | os.W_OK):
continue
with open(rcPath, mode="r+", encoding="utf-8") as f:
src = f.read()
src = re.sub(
r"FILEVERSION .*?\n", "FILEVERSION " + version_comma + "\n", src
)
src = re.sub(
r"PRODUCTVERSION .*?\n", "PRODUCTVERSION " + version_comma + "\n", src
)
src = re.sub(
r'"FileVersion", *?".*?"\n', '"FileVersion", "' + version + '"\n', src
)
src = re.sub(
r'"ProductVersion", *?".*?"\n',
'"ProductVersion", "' + version + '"\n',
src,
)
f.seek(0)
f.truncate()
f.write(src)
versionTagProp = "" if args.version_tag == "" else f";VersionTag={args.version_tag}"
p = subprocess.run(
f'"{msbuildPath}" Magpie.sln -m -t:Rebuild -restore -p:RestorePackagesConfig=true;Configuration=Release;Platform={args.platform};UseClangCL={args.compiler == "ClangCL"};UseNativeMicroArch={args.use_native_march};OutDir={os.getcwd()}\\publish\\{args.platform}\\;CommitId={commitId}{versionNumProps}{versionTagProp}'
)
if p.returncode != 0:
raise Exception("编译失败")
#####################################################################
#
# 清理不需要的文件
#
#####################################################################
os.chdir("publish\\" + args.platform)
# 删除文件,忽略错误
def remove_file(file):
try:
os.remove(file)
except:
pass
for pattern in ["*.pdb", "*.lib", "*.exp"]:
for file in glob.glob(pattern):
remove_file(file)
print("清理完毕", flush=True)
#####################################################################
#
# 为 TouchHelper 签名
#
#####################################################################
if args.pfx_path != "":
pfxPath = os.path.join("..\\..", args.pfx_path)
# 取最新的 Windows SDK
windowsSdkDir = max(
glob.glob(programFilesX86Path + "\\Windows Kits\\10\\bin\\10.*")
)
passwordOption = "" if args.pfx_password == "" else f'/p "{args.pfx_password}"'
p = subprocess.run(
f'"{windowsSdkDir}\\x64\\signtool.exe" sign /fd SHA256 /a /f "{pfxPath}" {passwordOption} TouchHelper.exe'
)
if p.returncode != 0:
raise Exception("签名失败")