首页 > 系统相关 >Ungoogled Chromium127编译指南 Windows篇 - 链接工具修复(十三)

Ungoogled Chromium127编译指南 Windows篇 - 链接工具修复(十三)

时间:2024-12-14 09:30:34浏览次数:6  
标签:Chromium127 resource undname Windows Ungoogled pdbutil exe path line

1. 引言

在完成Rust编译器包装器的修复后,我们遇到了编译过程最后阶段的链接问题。在Windows环境下,链接器无法正确找到llvm-pdbutil.exe和undname.exe这两个重要工具。本文将详细介绍如何解决这个问题。

2. 问题分析

2.1 错误表现

链接阶段报错找不到必要的工具:

  • llvm-pdbutil.exe无法被正确定位
  • undname.exe工具无法被找到和使用
FAILEC: gen/chrome/chrome_resource_allowlist.txt
C:/Users/ym/AppData/Local/Programs/Python/Python39/python.exe ../../tools/resources/generate_resource_allowlist.py -o gen/chrome/chrome_resource_allowlist.txt chrome.dll.pdb
Traceback (most recent call last):
  File "C:\ungoogled-chromium-windows\build\src\tools\resources\generate_resource_allowlist.py", line 165, in <module>
    main()
  File "C:\ungoogled-chromium-windows\build\src\tools\resources\generate_resource_allowlist.py", line 161, in main
    WriteResourceAllowlist(args)
  File "C:\ungoogled-chromium-windows\build\src\tools\resources\generate_resource_allowlist.py", line 140, in WriteResourceAllowlist
    resource_ids.update(func(input))
  File "C:\ungoogled-chromium-windows\build\src\tools\resources\generate_resource_allowlist.py", line 61, in GetResourceAllowlistPDB
    pdbutil = subprocess.Popen(
  File "C:\Users\ym\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 951, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\ym\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 1420, in _execute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
OSError: [WinError 193] %1 不是有效的 Win32 应用程序。
ninja: build stoppeC: subcommand failed.

C:\ungoogled-chromium-windows\build\src>exit
Traceback (most recent call last):
  File "C:\ungoogled-chromium-windows\build.py", line 464, in <module>
    main()
  File "C:\ungoogled-chromium-windows\build.py", line 455, in main
    _run_build_process('third_party\\ninja\\ninja.exe', '-C', 'out\\Default', 'chrome',
  File "C:\ungoogled-chromium-windows\build.py", line 78, in _run_build_process
    subprocess.run(('cmd.exe', '/k'),
  File "C:\Users\ym\AppData\Local\Programs\Python\Python39\lib\subprocess.py", line 528, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '('cmd.exe', '/k')' returned non-zero exit status 1.

2.2 错误原因

  • 工具路径解析逻辑未考虑操作系统差异
  • 资源生成脚本中的工具调用方式不正确

3. 修复方案

3.1 修改generate_resource_allowlist.py

需要修改资源生成脚本中的工具调用逻辑:

# 修改前
pdbutil = subprocess.Popen(['llvm-pdbutil', 'dump', '-publics', path],
                         stdout=subprocess.PIPE)
# 修改后
pdbutil_exe = 'llvm-pdbutil.exe' if sys.platform == 'win32' else 'llvm-pdbutil'
pdbutil_path = os.path.join(llvm_bindir, pdbutil_exe)
pdbutil = subprocess.Popen([pdbutil_path, 'dump', '-publics', path],
                         stdout=subprocess.PIPE)

3.2 完善工具调用

对undname工具的调用也需要类似修改:

修改前

  for name in names:
    undname = subprocess.Popen(['undname', name],
                               stdout=subprocess.PIPE)

修改后

  undname_exe = 'undname.exe' if sys.platform == 'win32' else 'undname'
  for name in names:
    undname = subprocess.Popen([undname_exe, name],
                             stdout=subprocess.PIPE)

3.3 完整脚本

#!/usr/bin/env python
# Copyright 2016 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

__doc__ = """generate_resource_allowlist.py [-o OUTPUT] INPUTS...

INPUTS are paths to unstripped binaries or PDBs containing references to
resources in their debug info.

This script generates a resource allowlist by reading debug info from
INPUTS and writes it to OUTPUT.
"""

# Allowlisted resources are identified by searching the input file for
# instantiations of the special function ui::AllowlistedResource (see
# ui/base/resource/allowlist.h).

import argparse
import os
import subprocess
import sys

import ar

llvm_bindir = os.path.join(os.path.dirname(sys.argv[0]), '..', '..',
                           'third_party', 'llvm-build', 'Release+Asserts',
                           'bin')


def ExtractAllowlistFromFile(path, resource_ids):
  with open(path, 'rb') as f:
    data = f.read()
  # When symbol_level=0, only mangled names exist.
  # E.g.: _ZN2ui19AllowlistedResourceILi22870EEEvv
  prefix = b'AllowlistedResourceILi'
  start_idx = 0
  while start_idx != -1:
    start_idx = data.find(prefix, start_idx)
    if start_idx != -1:
      end_idx = data.find(b'E', start_idx)
      resource_ids.add(int(data[start_idx + len(prefix):end_idx]))
      start_idx = end_idx


def GetResourceAllowlistELF(path):
  # Produce a resource allowlist by searching for debug info referring to
  # AllowlistedResource.
  # This used to use "readelf -p .debug_str", but it doesn't seem to work with
  # use_debug_fission=true. Reading the raw file is faster anyways.
  resource_ids = set()
  ExtractAllowlistFromFile(path, resource_ids)
  return resource_ids


def GetResourceAllowlistPDB(path):
  # Produce a resource allowlist by using llvm-pdbutil to read a PDB file's
  # publics stream, which is essentially a symbol table, and searching for
  # instantiations of AllowlistedResource. Any such instantiations are demangled
  # to extract the resource identifier.
  # 在 Windows 环境下添加 .exe 扩展名
  pdbutil_exe = 'llvm-pdbutil.exe' if sys.platform == 'win32' else 'llvm-pdbutil'
  pdbutil_path = os.path.join(llvm_bindir, pdbutil_exe)
  pdbutil = subprocess.Popen(
        [pdbutil_path, 'dump', '-publics', path],
        stdout=subprocess.PIPE)

  names = set()
  for line in pdbutil.stdout:
    line = line.decode('utf8')
    # Read a line of the form
    # "733352 | S_PUB32 [size = 56] `??$AllowlistedResource@$0BFGM@@ui@@YAXXZ`".
    if '`' not in line:
      continue
    sym_name = line[line.find('`') + 1:line.rfind('`')]
    # Under certain conditions such as the GN arg `use_clang_coverage = true` it
    # is possible for the compiler to emit additional symbols that do not match
    # the standard mangled-name format.
    # Example: __profd_??$AllowlistedResource@$0BGPH@@ui@@YAXXZ
    # C++ mangled names are supposed to begin with `?`, so check for that.
    if 'AllowlistedResource' in sym_name and sym_name.startswith('?'):
      names.add(sym_name)
  exit_code = pdbutil.wait()
  if exit_code != 0:
    raise Exception('llvm-pdbutil exited with exit code %d' % exit_code)

  resource_ids = set()
  undname_exe = 'undname.exe' if sys.platform == 'win32' else 'undname'
  for name in names:
    undname = subprocess.Popen([undname_exe, name],
                             stdout=subprocess.PIPE)
    found = False
    for line in undname.stdout:
      line = line.decode('utf8')
      # Read a line of the form
      # "void __cdecl ui::AllowlistedResource<5484>(void)".
      prefix = ' ui::AllowlistedResource<'
      pos = line.find(prefix)
      if pos == -1:
        continue
      try:
        resource_ids.add(int(line[pos + len(prefix):line.rfind('>')]))
      except ValueError:
        continue
      found = True
      break
    exit_code = undname.wait()
    if exit_code != 0:
      raise Exception('llvm-undname exited with exit code %d' % exit_code)
    if not found:
      raise Exception('Unexpected undname output')
  return resource_ids


def GetResourceAllowlistFileList(file_list_path):
  # Creates a list of resources given the list of linker input files.
  # Simply grep's them for AllowlistedResource<...>.
  with open(file_list_path) as f:
    paths = f.read().splitlines()

  paths = ar.ExpandThinArchives(paths)

  resource_ids = set()
  for p in paths:
    ExtractAllowlistFromFile(p, resource_ids)
  return resource_ids


def WriteResourceAllowlist(args):
  resource_ids = set()
  for input in args.inputs:
    with open(input, 'rb') as f:
      magic = f.read(4)
      chunk = f.read(60)
    if magic == b'\x7fELF':
      func = GetResourceAllowlistELF
    elif magic == b'Micr':
      func = GetResourceAllowlistPDB
    elif magic == b'obj/' or b'/obj/' in chunk:
      # For secondary toolchain, path will look like android_clang_arm/obj/...
      func = GetResourceAllowlistFileList
    else:
      raise Exception('unknown file format')

    resource_ids.update(func(input))

  # The last time this broke, exactly two resources were still being found.
  if len(resource_ids) < 100:
    raise Exception('Suspiciously few resources found. Likely an issue with '
                    'the regular expression in this script. Found: ' +
                    ','.join(sorted(resource_ids)))
  for id in sorted(resource_ids):
    args.output.write(str(id) + '\n')


def main():
  parser = argparse.ArgumentParser(usage=__doc__)
  parser.add_argument('inputs', nargs='+', help='An unstripped binary or PDB.')
  parser.add_argument('-o',
                      dest='output',
                      type=argparse.FileType('w'),
                      default=sys.stdout,
                      help='The resource list path to write (default stdout)')

  args = parser.parse_args()
  WriteResourceAllowlist(args)


if __name__ == '__main__':
  main()

4. 验证修复

4.1 测试步骤

  1. 修改generate_resource_allowlist.py文件
  2. 确保工具存在于正确路径
  3. 重新执行编译命令:
python build.py --tarball

4.2 验证要点

  • 确认llvm-pdbutil.exe能被正确调用
  • 验证undname.exe工具运行正常
  • 检查资源生成过程完整性

5. 可能遇到的问题

5.1 工具路径问题

  • 确保LLVM工具链安装完整
  • 验证工具所在目录已添加到PATH
  • 检查文件访问权限设置

5.2 环境配置问题

  • 确认Python环境变量设置
  • 验证Windows系统兼容性
  • 检查构建脚本权限

6. 结语

通过本文的指导,我们成功解决了Ungoogled Chromium编译过程中最后链接阶段的工具调用问题。这个修复确保了编译过程能够顺利完成。

至此,我们已经解决了Chromium编译过程中的主要技术难点。在下一篇文章中,我们将验证编译完成的Ungoogled Chromium,探索其特性。请确保按本文的步骤正确修复链接工具的问题,为最终的编译成功奠定基础。

标签:Chromium127,resource,undname,Windows,Ungoogled,pdbutil,exe,path,line
From: https://blog.csdn.net/qqyy_sj/article/details/144441455

相关文章

  • 在CodeBolcks+Windows API下的C++编程教程——给你的项目中添加头文件和菜单
    0.前言我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”:学习编程......
  • 在CodeBolcks+Windows API下的C++编程教程——给你的项目中添加资源文件和图标
    0.前言我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”:学习编程......
  • Windows 与 Linux 下 Ping IPv6 地址 | 常用网络命令
    注:本文为网络命令相关文章合辑。未整理去重。一、IPv6概述IPv6即“Internet协议版本6”,因IPv4地址资源面临耗尽问题而被引入以替代IPv4。IPv6则提供了理论上多达2128......
  • QT windows下使用CMake,设置步骤 mingw lvgl编译运行
    参考https://blog.csdn.net/qq_33963083/article/details/95920238针对我安装的qt,目录如下然后用qtcreate打开打开项目中的CMakeLists.txt可以使用的项目如下gitclone--recursivehttps://github.com/Sanya-123/lvgl_port_qt.git......
  • 星海智算:【Ollama镜像】Windows云部署教程
    1、下载和安装​Ollama官网地址:https://ollama.com/访问ollama界面,选择Download安装因为本次ollama部署在windows镜像中,所以在DownloadOllama中选择windows版本安装完成后,就可以在开始菜单中启动ollama了  右下角状态栏中出现ollama图标说明启动成功GPU算力云平台......
  • 在windows下使用C语言进行图形编程 SDL2开发环境搭建
    此篇文章在2023年9月7日被记录你是否对C语言命令行黑框感到厌倦,今天来为你的C编程增加一些可视化窗口吧!1、windows下安装C编译器这对于一个开发者来说简直是太业余了,如果你是一个开发者,你的电脑上怎么会没有gcc呢,如果你是一个新手,可以转到这个链接:https://zhuanlan.zhihu.c......
  • Windows系统基础(二):本地组与本地安全策略
    本地组和本地安全策略文章目录本地组和本地安全策略1.用户与组概念基本概念:常见组类型:2、用户与组设置常见操作方式:注意事项:3、内置账户控制访问常见内置账户及其功能:账户控制访问配置:4、本地安全组策略组策略的作用:常用的本地安全策略:应用场景:1.用户与组概......
  • Windows系统基础(三):服务端口指南
    服务端口文章目录服务端口一、WEB服务端口二、网络服务端口三、邮件服务端口四、远程服务端口五、其它服务端口总结一、WEB服务端口80(HTTP):HTTP是网站的默认端口,用于明文传输网页内容。虽然速度快,但缺乏加密保护,容易被中间人攻击。443(HTTPS):HTTPS是基于S......
  • 在 Windows Server 上,你可以通过 PowerShell 来开启和配置 Active Directory(AD)、分布
    在WindowsServer上,你可以通过PowerShell来开启和配置ActiveDirectory(AD)、分布式文件系统(DFS)、卷影复制(VolumeShadowCopy)和重复数据删除(DataDeduplication)。以下是详细的PowerShell配置脚本,涵盖了这些功能的启用和管理。1.配置ActiveDirectory(AD)要配置Active......
  • Windows Server 上启用存储空间中的重复数据删除功能(Data Deduplication),你可以按照以
    WindowsServer上启用存储空间中的重复数据删除功能(DataDeduplication),你可以按照以下步骤在PowerShell中配置。1.启用重复数据删除功能首先,确保你的系统已经安装了DataDeduplication功能。如果没有安装,可以使用以下命令进行安装:powershellCopyCodeInstall-WindowsFea......