Skip to content

Commit

Permalink
Compile l10nUtil.exe with py2exe as one of NVDA's executables, rather…
Browse files Browse the repository at this point in the history
… than using nuitka which took way too long to compile. (#17712)

l10nUtil (which allows translators to download and upload to Crowdin, and convert xliffs to markdown and html) s currently build using nuitka. However, this takes a significant amount of time. On Appveyor this takes roughly 20 minutes, which is more than a rd of the total build time.In many cases, this pushes the buildtime past 60 minutes and the build is cancelled by appveyor.

Description of development approach
Instead of using Nuitka, compile l10nUtil.exe as one of NVDA's executables using py2exe.
Several modules and packages in lxml and markdown extensions needed to be explicitly listed in setup.py for this to work. Also, l1nutil.py, markdownTranslate.py, md2html.py and keyCommandsDoc.py were moved from user_docs to source, which made it easier to handle with py2exe.
l10nUtil.exe still works just the same, and build time is cut down by at least 19 minutes.
  • Loading branch information
michaelDCurran authored Feb 23, 2025
1 parent c756899 commit e6e443b
Show file tree
Hide file tree
Showing 10 changed files with 24 additions and 18 deletions.
2 changes: 1 addition & 1 deletion appveyor/scripts/setSconsArgs.ps1
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
$ErrorActionPreference = "Stop";
$sconsOutTargets = "launcher developerGuide changes userGuide keyCommands client moduleList nvdaL10nUtil"
$sconsOutTargets = "launcher developerGuide changes userGuide keyCommands client moduleList"
if(!$env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:feature_buildAppx) {
$sconsOutTargets += " appx"
}
Expand Down
2 changes: 1 addition & 1 deletion projectDocs/dev/developerGuide/sconscript
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ mdFileSub = env.Substfile(
htmlFile = env.Command(
target=mdFile.abspath.replace(".md", ".html"),
source=mdFileSub,
action=[f'@{sys.executable} user_docs/md2html.py -t developerGuide "$SOURCE" "$TARGET"'],
action=[f'@{sys.executable} source/md2html.py -t developerGuide "$SOURCE" "$TARGET"'],
)
devGuide = env.Command(
target=devDocsOutputDir.File("developerGuide.html"), source=htmlFile, action=Move("$TARGET", "$SOURCE")
Expand Down
4 changes: 1 addition & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ pycaw==20240210

# Packaging NVDA
py2exe==0.13.0.2
# xliff2html is packaged with nuitka
nuitka==2.5.4
# l10nUtil requires Crowdin
# l10nUtil requires Crowdin
crowdin-api-client==1.21.0

# Creating XML unit test reports
Expand Down
16 changes: 4 additions & 12 deletions sconstruct
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ for xliffFile in env.Glob(os.path.join(userDocsDir.path, "*", "*.xliff")):
env.Command(
mdFile,
xliffFile,
[f'@{sys.executable} user_docs/markdownTranslate.py generateMarkdown -x "{xliffFile}" -o "{mdFile}"'],
[f'@{sys.executable} source/markdownTranslate.py generateMarkdown -x "{xliffFile}" -o "{mdFile}"'],
)
# Allow all markdown files to be converted to html in user_docs
for mdFile in env.Glob(os.path.join(userDocsDir.path, "*", "*.md")):
Expand All @@ -360,7 +360,7 @@ for mdFile in env.Glob(os.path.join(userDocsDir.path, "*", "*.md")):
htmlFile = env.Command(
target=mdFile.abspath.replace(".md", ".html"),
source=mdFileSub,
action=[f'@{sys.executable} user_docs/md2html.py -l {lang} -t {docType} "$SOURCE" "$TARGET"'],
action=[f'@{sys.executable} source/md2html.py -l {lang} -t {docType} "$SOURCE" "$TARGET"'],
)
styleInstallPath = os.path.dirname(mdFile.abspath)
installedStyle = env.Install(styleInstallPath, styles)
Expand All @@ -382,7 +382,7 @@ for userGuideFileSub in env.Glob(os.path.join(userDocsDir.path, "*", "userGuide.
keyCommandsHtmlFile = env.Command(
target=userGuideFileSub.abspath.replace("userGuide.md.sub", "keyCommands.html"),
source=userGuideFileSub,
action=[f'@{sys.executable} user_docs/md2html.py -l {lang} -t keyCommands "$SOURCE" "$TARGET"'],
action=[f'@{sys.executable} source/md2html.py -l {lang} -t keyCommands "$SOURCE" "$TARGET"'],
)
env.Depends(keyCommandsHtmlFile, userGuideFileSub)

Expand Down Expand Up @@ -454,7 +454,7 @@ def NVDADistGenerator(target, source, env, for_signature):
action.append(Copy(target[0], file.path))

if certFile or apiSigningToken:
for prog in "nvda_noUIAccess.exe", "nvda_uiAccess.exe", "nvda_slave.exe":
for prog in "nvda_noUIAccess.exe", "nvda_uiAccess.exe", "nvda_slave.exe", "l10nUtil.exe":
action.append(
lambda target, source, env, progByVal=prog: env["signExec"](
[target[0].File(progByVal)], source, env
Expand Down Expand Up @@ -731,11 +731,3 @@ source = env.Dir(os.path.join(os.getcwd(), "dist"))
# Putting the target in the output dir automatically causes AppVeyor to package it as an artefact
target = env.File(os.path.join(outputDir.abspath, "library_modules.txt"))
env.Alias("moduleList", env.GenerateModuleList(target, source))

nvdaL10nUtil = env.Command(
target=outputDir.File("l10nUtil.exe"),
source="user_docs\l10nUtil.py",
ENV=os.environ,
action=f"nuitka --assume-yes-for-downloads --remove-output --standalone --onefile --output-dir={outputDir.abspath} --include-module=mdx_truly_sane_lists --include-module=markdown_link_attr_modifier --include-module=mdx_gh_links $SOURCE",
)
env.Alias("nvdaL10nUtil", nvdaL10nUtil)
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
16 changes: 16 additions & 0 deletions source/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,17 @@ def _genManifestTemplate(shouldHaveUIAccess: bool) -> tuple[int, int, bytes]:
"company_name": f"Bill Dengler, {publisher}",
},
},
{
"script": "l10nUtil.py",
"version_info": {
"version": formatBuildVersionString(),
"description": "NVDA Localization Utility",
"product_name": name,
"product_version": version,
"copyright": NVDAcopyright,
"company_name": publisher,
},
},
],
options={
"verbose": 2,
Expand Down Expand Up @@ -241,6 +252,11 @@ def _genManifestTemplate(shouldHaveUIAccess: bool) -> tuple[int, int, bytes]:
"visionEnhancementProviders",
# Required for markdown, markdown implicitly imports this so it isn't picked up
"html.parser",
"lxml._elementpath",
"markdown.extensions",
"markdown_link_attr_modifier",
"mdx_truly_sane_lists",
"mdx_gh_links",
],
"includes": [
"nvdaBuiltin",
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/test_markdownTranslate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class TestMarkdownTranslate(unittest.TestCase):
os.path.dirname(__file__),
"..",
"..",
"user_docs",
"source",
"markdownTranslate.py",
)
testDir = os.path.join(os.path.dirname(__file__), "..", "markdownTranslate")
Expand Down

0 comments on commit e6e443b

Please sign in to comment.