1. 引言
在修复Python路径问题后,我们遇到的下一个技术挑衅是Rust标准库的查找问题。在编译过程中,find_std_rlibs.py脚本无法精确处理惩罚Windows环境下的Rust工具链路径,导致编译失败。本文将详细介绍如何解决这个问题。
2. 问题分析
2.1 错误表现
编译过程中会遇到如下错误:
- ninja: Entering directory `out\Default'
- [19/62261] ACTION //build/rust/std:find_stdlib(//build/toolchain/win:win_clang_x64)
- 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
- 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
- Traceback (most recent call last):
- File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 132, in <module>
- sys.exit(main())
- File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 53, in main
- rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 420, in check_output
- return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 501, in run
- with Popen(*popenargs, **kwargs) as process:
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 966, in __init__
- self._execute_child(args, executable, preexec_fn, close_fds,
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1435, in _execute_child
- hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
- OSError: [WinError 193] %1 is not a valid Win32 application
- [24/62261] CXX obj/base/third_party/double_conversion/double_conversion/bignum.obj
- ninja: build stopped: subcommand failed.
- C:\ungoogled-chromium-windows\build\src>exit
- Traceback (most recent call last):
- File "C:\ungoogled-chromium-windows\build.py", line 325, in <module>
- main()
- File "C:\ungoogled-chromium-windows\build.py", line 321, in main
- _run_build_process('third_party\\ninja\\ninja.exe', '-C', 'out\\Default', 'chrome',
- File "C:\ungoogled-chromium-windows\build.py", line 67, in _run_build_process
- subprocess.run(('cmd.exe', '/k'),
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 524, in run
- raise CalledProcessError(retcode, process.args,
- 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命令构造部门:
修改前:
- rustc = os.path.join(args.rust_bin_dir, "rustc")
复制代码 修改后:
- rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
复制代码 3.2 完备脚本
- #!/usr/bin/env/python3
- # Copyright 2021 The Chromium Authors
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- # See BUILD.gn in this directory for an explanation of what this script is for.
- import argparse
- import os
- import stat
- import sys
- import shutil
- import subprocess
- import re
- from collections import defaultdict
- EXPECTED_STDLIB_INPUT_REGEX = re.compile(r"([0-9a-z_]+)(?:-([0-9]+))?$")
- RLIB_NAME_REGEX = re.compile(r"lib([0-9a-z_]+)-([0-9a-f]+)\.rlib$")
- def main():
- parser = argparse.ArgumentParser("find_std_rlibs.py")
- parser.add_argument("--rust-bin-dir",
- help="Path to Rust binaries",
- required=True),
- parser.add_argument("--target", help="Rust target triple", required=False),
- parser.add_argument("--output",
- help="Path to rlibs without suffixes",
- required=True)
- parser.add_argument("--depfile", help="Path to write depfile", required=True)
- parser.add_argument("--depfile-target",
- help="Target to key depfile around",
- required=True)
- parser.add_argument("--extra-libs",
- help="List of extra non-libstd sysroot libraries")
- parser.add_argument("--rustc-revision",
- help="Not used, just passed from GN to add a dependency"
- " on the rustc version.")
- args = parser.parse_args()
- extra_libs = set()
- if args.extra_libs:
- for lib in args.extra_libs.split(','):
- extra_libs.add(lib)
- # Ask rustc where to find the stdlib for this target.
- rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
- rustc_args = [rustc, "--print", "target-libdir"]
- if args.target:
- rustc_args.extend(["--target", args.target])
- rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
- # Copy the rlibs to a predictable location. Whilst we're doing so,
- # also write a .d file so that ninja knows it doesn't need to do this
- # again unless the source rlibs change.
- # Format:
- # <output path to>/lib<lib name.rlib>: <path to each Rust stlib rlib>
- with open(args.depfile, 'w') as depfile:
- # Ninja isn't versatile at understanding depfiles. We have to say that a
- # single output depends on all the inputs. We choose any one of the
- # output rlibs for that purpose. If any of the input rlibs change, ninja
- # will run this script again and we'll copy them all afresh.
- depfile.write(
- "%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target)))
- def copy_file(infile, outfile):
- depfile.write(f" {infile}")
- if (not os.path.exists(outfile)
- or os.stat(infile).st_mtime != os.stat(outfile).st_mtime):
- if os.path.exists(outfile):
- st = os.stat(outfile)
- os.chmod(outfile, st.st_mode | stat.S_IWUSR)
- shutil.copy(infile, outfile)
- # Each rlib is named "lib<crate_name>-<metadata>.rlib". The metadata
- # disambiguates multiple crates of the same name. We want to throw away the
- # metadata and use stable names. To do so, we replace the metadata bit with
- # a simple number 1, 2, etc. It doesn't matter how we assign these numbers
- # as long as it's consistent for a particular set of rlibs.
- # The rlib names present in the Rust distribution, including metadata. We
- # sort this list so crates of the same name are ordered by metadata. Also
- # filter out names that aren't rlibs.
- rlibs_present = [
- name for name in os.listdir(rustlib_dir) if name.endswith('.rlib')
- ]
- rlibs_present.sort()
- # Keep a count of the instances a crate name, so we can disambiguate the
- # rlibs with an incrementing number at the end.
- rlibs_seen = defaultdict(lambda: 0)
- for f in rlibs_present:
- # As standard Rust includes a hash on the end of each filename
- # representing certain metadata, to ensure that clients will link
- # against the correct version. As gn will be manually passing
- # the correct file path to our linker invocations, we don't need
- # that, and it would prevent us having the predictable filenames
- # which we need for statically computable gn dependency rules.
- (crate_name, metadata) = RLIB_NAME_REGEX.match(f).group(1, 2)
- # Use the number of times we've seen this name to disambiguate the output
- # filenames. Since we sort the input filenames including the metadata,
- # this will be the same every time.
- #
- # Only append the times seen if it is greater than 1. This allows the
- # BUILD.gn file to avoid adding '-1' to every name if there's only one
- # version of a particular one.
- rlibs_seen[crate_name] += 1
- if rlibs_seen[crate_name] == 1:
- concise_name = crate_name
- else:
- concise_name = "%s-%d" % (crate_name, rlibs_seen[crate_name])
- output_filename = f"lib{concise_name}.rlib"
- infile = os.path.join(rustlib_dir, f)
- outfile = os.path.join(args.output, output_filename)
- copy_file(infile, outfile)
- for f in extra_libs:
- infile = os.path.join(rustlib_dir, f)
- outfile = os.path.join(args.output, f)
- copy_file(infile, outfile)
- depfile.write("\n")
- if __name__ == '__main__':
- sys.exit(main())
复制代码 4. 验证修复
4.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 错误表现
编译过程中会遇到如下错误:
- ninja: Entering directory `out\Default'
- [19/62261] ACTION //build/rust/std:find_stdlib(//build/toolchain/win:win_clang_x64)
- 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
- 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
- Traceback (most recent call last):
- File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 132, in <module>
- sys.exit(main())
- File "C:\ungoogled-chromium-windows\build\src\build\rust\std\find_std_rlibs.py", line 53, in main
- rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 420, in check_output
- return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 501, in run
- with Popen(*popenargs, **kwargs) as process:
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 966, in __init__
- self._execute_child(args, executable, preexec_fn, close_fds,
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 1435, in _execute_child
- hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
- OSError: [WinError 193] %1 is not a valid Win32 application
- [24/62261] CXX obj/base/third_party/double_conversion/double_conversion/bignum.obj
- ninja: build stopped: subcommand failed.
- C:\ungoogled-chromium-windows\build\src>exit
- Traceback (most recent call last):
- File "C:\ungoogled-chromium-windows\build.py", line 325, in <module>
- main()
- File "C:\ungoogled-chromium-windows\build.py", line 321, in main
- _run_build_process('third_party\\ninja\\ninja.exe', '-C', 'out\\Default', 'chrome',
- File "C:\ungoogled-chromium-windows\build.py", line 67, in _run_build_process
- subprocess.run(('cmd.exe', '/k'),
- File "C:\Users\ym\AppData\Local\Programs\Python\Python310\lib\subprocess.py", line 524, in run
- raise CalledProcessError(retcode, process.args,
- 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命令构造部门:
修改前:
- rustc = os.path.join(args.rust_bin_dir, "rustc")
复制代码 修改后:
- rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
复制代码 3.2 完备脚本
- #!/usr/bin/env/python3
- # Copyright 2021 The Chromium Authors
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- # See BUILD.gn in this directory for an explanation of what this script is for.
- import argparse
- import os
- import stat
- import sys
- import shutil
- import subprocess
- import re
- from collections import defaultdict
- EXPECTED_STDLIB_INPUT_REGEX = re.compile(r"([0-9a-z_]+)(?:-([0-9]+))?$")
- RLIB_NAME_REGEX = re.compile(r"lib([0-9a-z_]+)-([0-9a-f]+)\.rlib$")
- def main():
- parser = argparse.ArgumentParser("find_std_rlibs.py")
- parser.add_argument("--rust-bin-dir",
- help="Path to Rust binaries",
- required=True),
- parser.add_argument("--target", help="Rust target triple", required=False),
- parser.add_argument("--output",
- help="Path to rlibs without suffixes",
- required=True)
- parser.add_argument("--depfile", help="Path to write depfile", required=True)
- parser.add_argument("--depfile-target",
- help="Target to key depfile around",
- required=True)
- parser.add_argument("--extra-libs",
- help="List of extra non-libstd sysroot libraries")
- parser.add_argument("--rustc-revision",
- help="Not used, just passed from GN to add a dependency"
- " on the rustc version.")
- args = parser.parse_args()
- extra_libs = set()
- if args.extra_libs:
- for lib in args.extra_libs.split(','):
- extra_libs.add(lib)
- # Ask rustc where to find the stdlib for this target.
- rustc = os.path.join(args.rust_bin_dir, "rustc.exe")
- rustc_args = [rustc, "--print", "target-libdir"]
- if args.target:
- rustc_args.extend(["--target", args.target])
- rustlib_dir = subprocess.check_output(rustc_args).rstrip().decode()
- # Copy the rlibs to a predictable location. Whilst we're doing so,
- # also write a .d file so that ninja knows it doesn't need to do this
- # again unless the source rlibs change.
- # Format:
- # <output path to>/lib<lib name.rlib>: <path to each Rust stlib rlib>
- with open(args.depfile, 'w') as depfile:
- # Ninja isn't versatile at understanding depfiles. We have to say that a
- # single output depends on all the inputs. We choose any one of the
- # output rlibs for that purpose. If any of the input rlibs change, ninja
- # will run this script again and we'll copy them all afresh.
- depfile.write(
- "%s:" % (os.path.join(args.output, "lib%s.rlib" % args.depfile_target)))
- def copy_file(infile, outfile):
- depfile.write(f" {infile}")
- if (not os.path.exists(outfile)
- or os.stat(infile).st_mtime != os.stat(outfile).st_mtime):
- if os.path.exists(outfile):
- st = os.stat(outfile)
- os.chmod(outfile, st.st_mode | stat.S_IWUSR)
- shutil.copy(infile, outfile)
- # Each rlib is named "lib<crate_name>-<metadata>.rlib". The metadata
- # disambiguates multiple crates of the same name. We want to throw away the
- # metadata and use stable names. To do so, we replace the metadata bit with
- # a simple number 1, 2, etc. It doesn't matter how we assign these numbers
- # as long as it's consistent for a particular set of rlibs.
- # The rlib names present in the Rust distribution, including metadata. We
- # sort this list so crates of the same name are ordered by metadata. Also
- # filter out names that aren't rlibs.
- rlibs_present = [
- name for name in os.listdir(rustlib_dir) if name.endswith('.rlib')
- ]
- rlibs_present.sort()
- # Keep a count of the instances a crate name, so we can disambiguate the
- # rlibs with an incrementing number at the end.
- rlibs_seen = defaultdict(lambda: 0)
- for f in rlibs_present:
- # As standard Rust includes a hash on the end of each filename
- # representing certain metadata, to ensure that clients will link
- # against the correct version. As gn will be manually passing
- # the correct file path to our linker invocations, we don't need
- # that, and it would prevent us having the predictable filenames
- # which we need for statically computable gn dependency rules.
- (crate_name, metadata) = RLIB_NAME_REGEX.match(f).group(1, 2)
- # Use the number of times we've seen this name to disambiguate the output
- # filenames. Since we sort the input filenames including the metadata,
- # this will be the same every time.
- #
- # Only append the times seen if it is greater than 1. This allows the
- # BUILD.gn file to avoid adding '-1' to every name if there's only one
- # version of a particular one.
- rlibs_seen[crate_name] += 1
- if rlibs_seen[crate_name] == 1:
- concise_name = crate_name
- else:
- concise_name = "%s-%d" % (crate_name, rlibs_seen[crate_name])
- output_filename = f"lib{concise_name}.rlib"
- infile = os.path.join(rustlib_dir, f)
- outfile = os.path.join(args.output, output_filename)
- copy_file(infile, outfile)
- for f in extra_libs:
- infile = os.path.join(rustlib_dir, f)
- outfile = os.path.join(args.output, f)
- copy_file(infile, outfile)
- depfile.write("\n")
- if __name__ == '__main__':
- sys.exit(main())
复制代码 4. 验证修复
4.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企服之家,中国第一个企服评测及商务社交产业平台。 |