Ungoogled Chromium127编译指南 Windows篇 - Rust标准库查找问题修复(十一 ...

种地  金牌会员 | 2024-12-15 11:35:08 | 显示全部楼层 | 阅读模式
打印 上一主题 下一主题

主题 924|帖子 924|积分 2772


1. 引言

在修复Python路径问题后,我们遇到的下一个技术挑衅是Rust标准库的查找问题。在编译过程中,find_std_rlibs.py脚本无法精确处理惩罚Windows环境下的Rust工具链路径,导致编译失败。本文将详细介绍如何解决这个问题。
2. 问题分析

2.1 错误表现

编译过程中会遇到如下错误:
  1. ninja: Entering directory `out\Default'
  2. [19/62261] ACTION //build/rust/std:find_stdlib(//build/toolchain/win:win_clang_x64)
  3. FAILED: obj/build/rust/std/libstd.rlib obj/build/rust/std/liballoc.rlib obj/build/rust/std/libcfg_if.rlib obj/build/rust/std/libcompiler_builtins.rlib obj/build/rust/std/libcore.rlib obj/build/rust/std/libgetopts.rlib obj/build/rust/std/libhashbrown.rlib obj/build/rust/std/liblibc.rlib obj/build/rust/std/libpanic_abort.rlib obj/build/rust/std/libpanic_unwind.rlib obj/build/rust/std/librustc_demangle.rlib obj/build/rust/std/libstd_detect.rlib obj/build/rust/std/libtest.rlib obj/build/rust/std/libunicode_width.rlib obj/build/rust/std/libunwind.rlib obj/build/rust/std/libprofiler_builtins.rlib obj/build/rust/std/librustc_std_workspace_alloc.rlib obj/build/rust/std/librustc_std_workspace_core.rlib obj/build/rust/std/librustc_std_workspace_std.rlib
  4. C:/Users/ym/AppData/Local/Programs/Python/Python310/python.exe ../../build/rust/std/find_std_rlibs.py --rust-bin-dir ../../third_party/rust-toolchain/bin --output obj/build/rust/std --depfile obj/build/rust/std/stdlib.d --depfile-target std --rustc-revision "rustc 1.80.0-nightly (faefc618c 2024-05-07)" --target x86_64-pc-windows-msvc
  5. Traceback (most recent call last):
  6.   File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 132, in <module>
  7.     sys.exit(main())
  8.   File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 53, in main
  9.     rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
  10.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 420, in check_output
  11.     return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  12.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 501, in run
  13.     with Popen(*popenargs, **kwargs) as process:
  14.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 966, in __init__
  15.     self._execute_child(args, executable, preexec_fn, close_fds,
  16.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1435, in _execute_child
  17.     hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
  18. OSError: [WinError 193] %1 is not a valid Win32 application
  19. [24/62261] CXX obj/base/third_party/double_conversion/double_conversion/bignum.obj
  20. ninja: build stopped: subcommand failed.
  21. C:\ungoogled-chromium-windows\build\src>exit
  22. Traceback (most recent call last):
  23.   File "C:\ungoogled-chromium-windows\build.py", line 325, in <module>
  24.     main()
  25.   File "C:\ungoogled-chromium-windows\build.py", line 321, in main
  26.     _run_build_process('third_party\\ninja\\ninja.exe', '-C', 'out\\Default', 'chrome',
  27.   File "C:\ungoogled-chromium-windows\build.py", line 67, in _run_build_process
  28.     subprocess.run(('cmd.exe', '/k'),
  29.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 524, in run
  30.     raise CalledProcessError(retcode, process.args,
  31. subprocess.CalledProcessError: Command '('cmd.exe', '/k')' returned non-zero exit status 1.
复制代码
2.2 错误缘故原由



  • find_std_rlibs.py脚本未精确处理惩罚Windows可实行文件后缀
  • rustc命令调用缺少.exe后缀
  • 工具链路径剖析不适配Windows环境
3. 修复方案

3.1 修改find_std_rlibs.py

打开build/rust/std/find_std_rlibs.py文件,定位到rustc命令构造部门:
修改前:
  1. rustc = os.path.join(args.rust_bin_dir, "rustc")
复制代码
修改后:
  1. rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
复制代码
3.2 完备脚本

  1. #!/usr/bin/env/python3
  2. # Copyright 2021 The Chromium Authors
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. # See BUILD.gn in this directory for an explanation of what this script is for.
  6. import argparse
  7. import os
  8. import stat
  9. import sys
  10. import shutil
  11. import subprocess
  12. import re
  13. from collections import defaultdict
  14. EXPECTED_STDLIB_INPUT_REGEX = re.compile(r"([0-9a-z_]+)(?:-([0-9]+))?$")
  15. RLIB_NAME_REGEX = re.compile(r"lib([0-9a-z_]+)-([0-9a-f]+)\.rlib$")
  16. def main():
  17.   parser = argparse.ArgumentParser("find_std_rlibs.py")
  18.   parser.add_argument("--rust-bin-dir",
  19.                       help="Path to Rust binaries",
  20.                       required=True),
  21.   parser.add_argument("--target", help="Rust target triple", required=False),
  22.   parser.add_argument("--output",
  23.                       help="Path to rlibs without suffixes",
  24.                       required=True)
  25.   parser.add_argument("--depfile", help="Path to write depfile", required=True)
  26.   parser.add_argument("--depfile-target",
  27.                       help="Target to key depfile around",
  28.                       required=True)
  29.   parser.add_argument("--extra-libs",
  30.                       help="List of extra non-libstd sysroot libraries")
  31.   parser.add_argument("--rustc-revision",
  32.                       help="Not used, just passed from GN to add a dependency"
  33.                       " on the rustc version.")
  34.   args = parser.parse_args()
  35.   extra_libs = set()
  36.   if args.extra_libs:
  37.     for lib in args.extra_libs.split(','):
  38.       extra_libs.add(lib)
  39.   # Ask rustc where to find the stdlib for this target.
  40.   rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
  41.   rustc_args = [rustc, "--print", "target-libdir"]
  42.   if args.target:
  43.     rustc_args.extend(["--target", args.target])
  44.   rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
  45.   # Copy the rlibs to a predictable location. Whilst we're doing so,
  46.   # also write a .d file so that ninja knows it doesn't need to do this
  47.   # again unless the source rlibs change.
  48.   # Format:
  49.   # <output path to>/lib<lib name.rlib>: <path to each Rust stlib rlib>
  50.   with open(args.depfile, 'w') as depfile:
  51.     # Ninja isn't versatile at understanding depfiles. We have to say that a
  52.     # single output depends on all the inputs. We choose any one of the
  53.     # output rlibs for that purpose. If any of the input rlibs change, ninja
  54.     # will run this script again and we'll copy them all afresh.
  55.     depfile.write(
  56.         "%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target)))
  57.     def copy_file(infile, outfile):
  58.       depfile.write(f" {infile}")
  59.       if (not os.path.exists(outfile)
  60.           or os.stat(infile).st_mtime != os.stat(outfile).st_mtime):
  61.         if os.path.exists(outfile):
  62.           st = os.stat(outfile)
  63.           os.chmod(outfile, st.st_mode | stat.S_IWUSR)
  64.         shutil.copy(infile, outfile)
  65.     # Each rlib is named "lib<crate_name>-<metadata>.rlib". The metadata
  66.     # disambiguates multiple crates of the same name. We want to throw away the
  67.     # metadata and use stable names. To do so, we replace the metadata bit with
  68.     # a simple number 1, 2, etc. It doesn't matter how we assign these numbers
  69.     # as long as it's consistent for a particular set of rlibs.
  70.     # The rlib names present in the Rust distribution, including metadata. We
  71.     # sort this list so crates of the same name are ordered by metadata. Also
  72.     # filter out names that aren't rlibs.
  73.     rlibs_present = [
  74.         name for name in os.listdir(rustlib_dir) if name.endswith('.rlib')
  75.     ]
  76.     rlibs_present.sort()
  77.     # Keep a count of the instances a crate name, so we can disambiguate the
  78.     # rlibs with an incrementing number at the end.
  79.     rlibs_seen = defaultdict(lambda: 0)
  80.     for f in rlibs_present:
  81.       # As standard Rust includes a hash on the end of each filename
  82.       # representing certain metadata, to ensure that clients will link
  83.       # against the correct version. As gn will be manually passing
  84.       # the correct file path to our linker invocations, we don't need
  85.       # that, and it would prevent us having the predictable filenames
  86.       # which we need for statically computable gn dependency rules.
  87.       (crate_name, metadata) = RLIB_NAME_REGEX.match(f).group(1, 2)
  88.       # Use the number of times we've seen this name to disambiguate the output
  89.       # filenames. Since we sort the input filenames including the metadata,
  90.       # this will be the same every time.
  91.       #
  92.       # Only append the times seen if it is greater than 1. This allows the
  93.       # BUILD.gn file to avoid adding '-1' to every name if there's only one
  94.       # version of a particular one.
  95.       rlibs_seen[crate_name] += 1
  96.       if rlibs_seen[crate_name] == 1:
  97.         concise_name = crate_name
  98.       else:
  99.         concise_name = "%s-%d" % (crate_name, rlibs_seen[crate_name])
  100.       output_filename = f"lib{concise_name}.rlib"
  101.       infile = os.path.join(rustlib_dir, f)
  102.       outfile = os.path.join(args.output, output_filename)
  103.       copy_file(infile, outfile)
  104.     for f in extra_libs:
  105.       infile = os.path.join(rustlib_dir, f)
  106.       outfile = os.path.join(args.output, f)
  107.       copy_file(infile, outfile)
  108.     depfile.write("\n")
  109. if __name__ == '__main__':
  110.   sys.exit(main())
复制代码
4. 验证修复

4.1 测试修改

修改完成后,运行下面的命令继续进行编译即可
  1. python build.py --tarball
复制代码
4.2 检查输出



  • 确认脚本能精确找到Rust标准库
  • 验证天生的库文件路径
  • 检查权限和访问问题
5. 大概遇到的问题

5.1 路径权限



  • 确保对Rust工具链目次有读取权限
  • 验证输出目次的写入权限
  • 检查暂时文件的访问权限
5.2 工具链完备性



  • 验证Rust工具链安装完备
  • 确认所有必要组件存在
  • 检查版本匹配性
6. 结语

通过本文的指导,我们乐成解决了Ungoogled Chromium编译过程中的Rust标准库查找问题。这个修复是确保Rust组件精确编译的关键步调之一。
在下一篇文章《Ungoogled Chromium127编译指南 Windows篇 - Rust编译器包装器修复(十二)》中,我们将继续处理惩罚rustc_wrapper.py的相关问题,以完成Rust工具链的完备设置。请确保按本文的步调精确修复find_std_rlibs的问题,为后续的编译工作创造良好条件。
1. 引言

在修复Python路径问题后,我们遇到的下一个技术挑衅是Rust标准库的查找问题。在编译过程中,find_std_rlibs.py脚本无法精确处理惩罚Windows环境下的Rust工具链路径,导致编译失败。本文将详细介绍如何解决这个问题。
2. 问题分析

2.1 错误表现

编译过程中会遇到如下错误:
  1. ninja: Entering directory `out\Default'
  2. [19/62261] ACTION //build/rust/std:find_stdlib(//build/toolchain/win:win_clang_x64)
  3. FAILED: obj/build/rust/std/libstd.rlib obj/build/rust/std/liballoc.rlib obj/build/rust/std/libcfg_if.rlib obj/build/rust/std/libcompiler_builtins.rlib obj/build/rust/std/libcore.rlib obj/build/rust/std/libgetopts.rlib obj/build/rust/std/libhashbrown.rlib obj/build/rust/std/liblibc.rlib obj/build/rust/std/libpanic_abort.rlib obj/build/rust/std/libpanic_unwind.rlib obj/build/rust/std/librustc_demangle.rlib obj/build/rust/std/libstd_detect.rlib obj/build/rust/std/libtest.rlib obj/build/rust/std/libunicode_width.rlib obj/build/rust/std/libunwind.rlib obj/build/rust/std/libprofiler_builtins.rlib obj/build/rust/std/librustc_std_workspace_alloc.rlib obj/build/rust/std/librustc_std_workspace_core.rlib obj/build/rust/std/librustc_std_workspace_std.rlib
  4. C:/Users/ym/AppData/Local/Programs/Python/Python310/python.exe ../../build/rust/std/find_std_rlibs.py --rust-bin-dir ../../third_party/rust-toolchain/bin --output obj/build/rust/std --depfile obj/build/rust/std/stdlib.d --depfile-target std --rustc-revision "rustc 1.80.0-nightly (faefc618c 2024-05-07)" --target x86_64-pc-windows-msvc
  5. Traceback (most recent call last):
  6.   File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 132, in <module>
  7.     sys.exit(main())
  8.   File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 53, in main
  9.     rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
  10.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 420, in check_output
  11.     return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  12.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 501, in run
  13.     with Popen(*popenargs, **kwargs) as process:
  14.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 966, in __init__
  15.     self._execute_child(args, executable, preexec_fn, close_fds,
  16.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1435, in _execute_child
  17.     hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
  18. OSError: [WinError 193] %1 is not a valid Win32 application
  19. [24/62261] CXX obj/base/third_party/double_conversion/double_conversion/bignum.obj
  20. ninja: build stopped: subcommand failed.
  21. C:\ungoogled-chromium-windows\build\src>exit
  22. Traceback (most recent call last):
  23.   File "C:\ungoogled-chromium-windows\build.py", line 325, in <module>
  24.     main()
  25.   File "C:\ungoogled-chromium-windows\build.py", line 321, in main
  26.     _run_build_process('third_party\\ninja\\ninja.exe', '-C', 'out\\Default', 'chrome',
  27.   File "C:\ungoogled-chromium-windows\build.py", line 67, in _run_build_process
  28.     subprocess.run(('cmd.exe', '/k'),
  29.   File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 524, in run
  30.     raise CalledProcessError(retcode, process.args,
  31. subprocess.CalledProcessError: Command '('cmd.exe', '/k')' returned non-zero exit status 1.
复制代码
2.2 错误缘故原由



  • find_std_rlibs.py脚本未精确处理惩罚Windows可实行文件后缀
  • rustc命令调用缺少.exe后缀
  • 工具链路径剖析不适配Windows环境
3. 修复方案

3.1 修改find_std_rlibs.py

打开build/rust/std/find_std_rlibs.py文件,定位到rustc命令构造部门:
修改前:
  1. rustc = os.path.join(args.rust_bin_dir, "rustc")
复制代码
修改后:
  1. rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
复制代码
3.2 完备脚本

  1. #!/usr/bin/env/python3
  2. # Copyright 2021 The Chromium Authors
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. # See BUILD.gn in this directory for an explanation of what this script is for.
  6. import argparse
  7. import os
  8. import stat
  9. import sys
  10. import shutil
  11. import subprocess
  12. import re
  13. from collections import defaultdict
  14. EXPECTED_STDLIB_INPUT_REGEX = re.compile(r"([0-9a-z_]+)(?:-([0-9]+))?$")
  15. RLIB_NAME_REGEX = re.compile(r"lib([0-9a-z_]+)-([0-9a-f]+)\.rlib$")
  16. def main():
  17.   parser = argparse.ArgumentParser("find_std_rlibs.py")
  18.   parser.add_argument("--rust-bin-dir",
  19.                       help="Path to Rust binaries",
  20.                       required=True),
  21.   parser.add_argument("--target", help="Rust target triple", required=False),
  22.   parser.add_argument("--output",
  23.                       help="Path to rlibs without suffixes",
  24.                       required=True)
  25.   parser.add_argument("--depfile", help="Path to write depfile", required=True)
  26.   parser.add_argument("--depfile-target",
  27.                       help="Target to key depfile around",
  28.                       required=True)
  29.   parser.add_argument("--extra-libs",
  30.                       help="List of extra non-libstd sysroot libraries")
  31.   parser.add_argument("--rustc-revision",
  32.                       help="Not used, just passed from GN to add a dependency"
  33.                       " on the rustc version.")
  34.   args = parser.parse_args()
  35.   extra_libs = set()
  36.   if args.extra_libs:
  37.     for lib in args.extra_libs.split(','):
  38.       extra_libs.add(lib)
  39.   # Ask rustc where to find the stdlib for this target.
  40.   rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
  41.   rustc_args = [rustc, "--print", "target-libdir"]
  42.   if args.target:
  43.     rustc_args.extend(["--target", args.target])
  44.   rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
  45.   # Copy the rlibs to a predictable location. Whilst we're doing so,
  46.   # also write a .d file so that ninja knows it doesn't need to do this
  47.   # again unless the source rlibs change.
  48.   # Format:
  49.   # <output path to>/lib<lib name.rlib>: <path to each Rust stlib rlib>
  50.   with open(args.depfile, 'w') as depfile:
  51.     # Ninja isn't versatile at understanding depfiles. We have to say that a
  52.     # single output depends on all the inputs. We choose any one of the
  53.     # output rlibs for that purpose. If any of the input rlibs change, ninja
  54.     # will run this script again and we'll copy them all afresh.
  55.     depfile.write(
  56.         "%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target)))
  57.     def copy_file(infile, outfile):
  58.       depfile.write(f" {infile}")
  59.       if (not os.path.exists(outfile)
  60.           or os.stat(infile).st_mtime != os.stat(outfile).st_mtime):
  61.         if os.path.exists(outfile):
  62.           st = os.stat(outfile)
  63.           os.chmod(outfile, st.st_mode | stat.S_IWUSR)
  64.         shutil.copy(infile, outfile)
  65.     # Each rlib is named "lib<crate_name>-<metadata>.rlib". The metadata
  66.     # disambiguates multiple crates of the same name. We want to throw away the
  67.     # metadata and use stable names. To do so, we replace the metadata bit with
  68.     # a simple number 1, 2, etc. It doesn't matter how we assign these numbers
  69.     # as long as it's consistent for a particular set of rlibs.
  70.     # The rlib names present in the Rust distribution, including metadata. We
  71.     # sort this list so crates of the same name are ordered by metadata. Also
  72.     # filter out names that aren't rlibs.
  73.     rlibs_present = [
  74.         name for name in os.listdir(rustlib_dir) if name.endswith('.rlib')
  75.     ]
  76.     rlibs_present.sort()
  77.     # Keep a count of the instances a crate name, so we can disambiguate the
  78.     # rlibs with an incrementing number at the end.
  79.     rlibs_seen = defaultdict(lambda: 0)
  80.     for f in rlibs_present:
  81.       # As standard Rust includes a hash on the end of each filename
  82.       # representing certain metadata, to ensure that clients will link
  83.       # against the correct version. As gn will be manually passing
  84.       # the correct file path to our linker invocations, we don't need
  85.       # that, and it would prevent us having the predictable filenames
  86.       # which we need for statically computable gn dependency rules.
  87.       (crate_name, metadata) = RLIB_NAME_REGEX.match(f).group(1, 2)
  88.       # Use the number of times we've seen this name to disambiguate the output
  89.       # filenames. Since we sort the input filenames including the metadata,
  90.       # this will be the same every time.
  91.       #
  92.       # Only append the times seen if it is greater than 1. This allows the
  93.       # BUILD.gn file to avoid adding '-1' to every name if there's only one
  94.       # version of a particular one.
  95.       rlibs_seen[crate_name] += 1
  96.       if rlibs_seen[crate_name] == 1:
  97.         concise_name = crate_name
  98.       else:
  99.         concise_name = "%s-%d" % (crate_name, rlibs_seen[crate_name])
  100.       output_filename = f"lib{concise_name}.rlib"
  101.       infile = os.path.join(rustlib_dir, f)
  102.       outfile = os.path.join(args.output, output_filename)
  103.       copy_file(infile, outfile)
  104.     for f in extra_libs:
  105.       infile = os.path.join(rustlib_dir, f)
  106.       outfile = os.path.join(args.output, f)
  107.       copy_file(infile, outfile)
  108.     depfile.write("\n")
  109. if __name__ == '__main__':
  110.   sys.exit(main())
复制代码
4. 验证修复

4.1 测试修改

修改完成后,运行下面的命令继续进行编译即可
  1. python build.py --tarball
复制代码
4.2 检查输出



  • 确认脚本能精确找到Rust标准库
  • 验证天生的库文件路径
  • 检查权限和访问问题
5. 大概遇到的问题

5.1 路径权限



  • 确保对Rust工具链目次有读取权限
  • 验证输出目次的写入权限
  • 检查暂时文件的访问权限
5.2 工具链完备性



  • 验证Rust工具链安装完备
  • 确认所有必要组件存在
  • 检查版本匹配性
6. 结语

通过本文的指导,我们乐成解决了Ungoogled Chromium编译过程中的Rust标准库查找问题。这个修复是确保Rust组件精确编译的关键步调之一。
在下一篇文章《Ungoogled Chromium127编译指南 Windows篇 - Rust编译器包装器修复(十二)》中,我们将继续处理惩罚rustc_wrapper.py的相关问题,以完成Rust工具链的完备设置。请确保按本文的步调精确修复find_std_rlibs的问题,为后续的编译工作创造良好条件。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

种地

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表