Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

002-chromium新老版本编译 #83

Open
xinali opened this issue Oct 21, 2022 · 0 comments
Open

002-chromium新老版本编译 #83

xinali opened this issue Oct 21, 2022 · 0 comments
Labels

Comments

@xinali
Copy link
Owner

xinali commented Oct 21, 2022

chromium build

[toc]

latest update: 2024.03.08

因为工作需要,需要经常构建多个平台各种版本的chromium,所以可能会遇到各种各样的问题,

在这里做一下记录,会不断更新遇到的最新问题

所有的源码和相关工具,尽力别使用挂载的方式挂在wslvirtualbox/vmware中,挂载的方式,无论是编译,还是git操作,速度都会特别慢

初次构建(latest on linux)

  1. 准备depot_tools:

    git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
    export PATH=/xxx/path/to/depot_tools:$PATH
  2. 获取chromium源码

    mkdir ~/chromium && cd ~/chromium
    fetch --nohooks chromium
  3. 构建及获取依赖

    cd src
    ./build/install-build-deps.sh
    gclient runhooks
  4. 构建chrome

    gn gen out/Default
    autoninja -C out/Default chrome

只要按照流程走,一般构建最新版,不会出问题

初次构建(latest on windows)

直接利用构建脚本

@echo off
rem 设置源码路径
set chromium_dir="G:\chromium"
set chromium_source=%chromium_dir%\src

rem 设置不更新depot_tools
set DEPOT_TOOLS_WIN_TOOLCHAIN=0

rem 设置depot_tools路径
rem 如果有多版本的depot_tools,根据需要设定特定版本
set DEPOT_TOOLS_PATH=G:\codes\depot_tools
set PATH=%DEPOT_TOOLS_PATH%;%PATH%

rem 针对环境存在多个版本python时
rem 可能还需要设置python路径
rem set PYTHON_PATH=G:\tools\Python27
rem set PATH=%PYTHON_PATH%;%PATH%

rem 设置vs版本
set vs2022_install=D:\tools\vs_community

rem 编译
cd %chromium_source%
gn gen out\Release
ninja -C out\Release chrome

build older version

# 切换分支或commit
git checkout old_version

# 设置depot_tools不自动升级 
export DEPOT_TOOLS_UPDATE=0

# 设置依赖
COMMIT_DATE=$(git log -n 1 --pretty=format:%ci)
cd ~/depot_tools
git checkout $(git rev-list -n 1 --before="$COMMIT_DATE" main)

# 清理原始第三方库
git clean -ffd

# 同步第三方库
gclient sync -D --force --reset

# 构建依赖
./build/install-build-deps.sh

# 上古版本构建依赖
./build/gyp_chromium

gclient runhooks

# 构建chrome
gn gen out/Default
ninja -C out/Default chrome

如果想要构建一个调试版本,在gn后,更改out/Default目录args.gn中的参数

is_debug = true
is_component_build = true
symbol_level = 2

编译问题

chromium代码非常复杂,所以在不同的系统不同的版本的编译过程中会遇到非常多的问题,以下主要是记录我自己遇到的各种问题

  1. 代理问题

    如果直接在shell的配置文件里设置代理,在运行gclient sync/fetch --nohooks chromium时都不一定有问题,但是在运行gclient runhooks 可能会出错,解决办法是设置.boto文件/home/[user]/.boto,类似于

    [Boto]
    debug = 0
    num_retries = 10
    
    proxy = [proxy ip]
    proxy_port = [proxy port]

    在启动shell时,载入.boto配置文件export NO_AUTH_BOTO_CONFIG="/home/[user]/.boto"

  2. webrtc版本问题(其他库操作相同)

    cd src/third_party/webrtc
    git checkout $(git rev-list -n 1 --before="$COMMIT_DATE" main)

    然后在src/DEPS中更改对应的webrtccommit id ,这种方法在很多情况下都适用,但是在某些情况下不适用,在这种方法失效时,还有另一种更加直接的方法,在对应的源码网站上下载该commit的源码,然后放在对应目录下,这种方法的前提是,不停执行gclient sync -D --force --reset 直至最后一个需要处理的库为你需要处理的库为止,然后就可以直接build

    在处理该问题时,还遇到一个奇怪的问题,在google源码站上有某个commit ,代码也是根据该commit拉取的代码,但是却无法checkout到该commit,这时候就必须使用第二种方法

    20230815 update:

    针对这种无法checkout到固定commit,最近发现了一个新的方法,比如webrtc库,这里可以直接这么干

    fetch --nohooks webrtc
    git checkout branch-heads/m79

    然后把checkout完成的代码放到chromium/src/third_party/webrtc目录下

  3. python问题

    a. 目前部分老版本所使用的脚本,均为python2,如果使用python3,则出错,更改默认的python版本即可
    b. 其自带的python编译脚本存在编码错误,这个一般存在老版本中,会提示如下错误

    UnicodeDecodeError: 'gbk' codec can't decode byte 0xxx in position yyyy: illegal multibyte sequence
    

    vscode打开提示是utf-8编码,但是使用如下的代码会发现其编码

    def guess_encoding(filename, encodings=None):
       if encodings is None:
           encodings = ['utf-8', 'iso-8859-1', 'gbk', 'big5', 'windows-1252', 'utf-16', 'utf-32']
    
       for enc in encodings:
           try:
               with open(filename, 'r', encoding=enc) as f:
                   f.read()
               return enc
           except UnicodeDecodeError:
               pass
       return None

    在找到具体编码后,打开文件时,比如open(file_name, 'r', encoding='windows-1252')即可

    c. depot_tools自带python版本在处理os.path.relpath问题

    在部分chromium版本对应的depot_tools中使用的python版本为3.11.2貌似存在问题,大概是这种情况

    Traceback (most recent call last):
      File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 418, in <module>
        ret = main()
              ^^^^^^
      File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 413, in main
        return args.func(args, remaining_args)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 275, in _Generate
        processor._GenerateModule(
      File "G:\chromium\src\mojo\public\tools\bindings\mojom_bindings_generator.py", line 243, in _GenerateModule
        generator.GenerateFiles(filtered_args)
      File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 280, in GenerateFiles
        self.WriteWithComment(self._GenerateWebUiModule(),
                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "G:\chromium\src\mojo\public\tools\mojom\mojom\generate\template_expander.py", line 34, in GeneratorInternal
        parameters = generator(*args, **kwargs2)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 266, in _GenerateWebUiModule
        return self._GetParameters()
               ^^^^^^^^^^^^^^^^^^^^^
      File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 228, in _GetParameters
        self._GetJsModuleImports(),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "G:\chromium\src\mojo\public\tools\bindings\generators\mojom_ts_generator.py", line 633, in _GetJsModuleImports
        os.path.relpath(
      File "<frozen ntpath>", line 766, in relpath
    

    具体的修复方法

  4. 编译参数问题

    如果想要获取chromium默认的编译参数,可以使用

    gn args out\Release --list
    

    windows系统上,使用默认参数编译,可以正常打印出调用堆栈信息,并精确到具体的函数及行号。

    类似于

     base::internal::TaskTracker::RunTaskImpl [0x00007FFC2C6E1322+146] (...\task_tracker.cc:679)
     base::internal::TaskTracker::RunContinueOnShutdown [0x00007FFC2C6E1271+113] (...\task_tracker.cc:656)
     base::internal::TaskTracker::RunTaskWithShutdownBehavior [0x00007FFC2C6E08EF+143] (...\task_tracker.cc:692)
     base::internal::TaskTracker::RunTask [0x00007FFC2C6E0259+1993] (...\task_tracker.cc:525)
     base::internal::TaskTracker::RunAndPopNextTask [0x00007FFC2C6DF3CA+778] (...\task_tracker.cc:418)
     base::internal::WorkerThread::RunWorker [0x00007FFC2C707E63+1171] (...\worker_thread.cc:438)
     base::internal::WorkerThread::RunPooledWorker [0x00007FFC2C707862+34] (...\worker_thread.cc:323)
     base::internal::WorkerThread::ThreadMain [0x00007FFC2C707668+248] (...\worker_thread.cc:303)
     base::`anonymous namespace'::ThreadFunc [0x00007FFC2C834A92+450] (...\platform_thread_win.cc:142)
    

    linux操作系统上,默认无法打印出调用堆栈涉及的具体行号

    类似于

    #1 0x7fb8361725fa base::debug::StackTrace::StackTrace()
    #2 0x7fb8361725b5 base::debug::StackTrace::StackTrace()
    #3 0x7fb8236b7899 net::CertVerifyProc::Verify()
    #4 0x7fb823704d76 net::(anonymous namespace)::DoVerifyOnWorkerThread()
    #5 0x7fb823706441 base::internal::FunctorTraits<>::Invoke<>()
    #6 0x7fb8237063cf base::internal::InvokeHelper<>::MakeItSo<>()
    #7 0x7fb8237062cd base::internal::Invoker<>::RunImpl<>()
    #8 0x7fb823706197 base::internal::Invoker<>::RunOnce()
    #9 0x7fb82370788b base::OnceCallback<>::Run()
    #10 0x7fb823706b4f base::internal::ReturnAsParamAdapter<>()
    #11 0x7fb823706f1d base::internal::FunctorTraits<>::Invoke<>()
    #12 0x7fb823706ed3 base::internal::InvokeHelper<>::MakeItSo<>()
    #13 0x7fb823706e6d base::internal::Invoker<>::RunImpl<>()
    #14 0x7fb823706de7 base::internal::Invoker<>::RunOnce()
    

    如果想在linux下打印出的堆栈显示具体的行号,可以在out/Release/args.gn增加配置项

    enable_stack_trace_line_numbers = true
    

    该配置项只在近两年的版本中支持,古早的版本可能不支持。

    该配置项需要注意一点,在启用is_asan时,调用StackTrace是无法打印出带有行号信息的,但是AddressSanitizer触发时会打印出行号

    类似于

    [801212:801212:0306/100934.195483:INFO:debug_logger.h(28)] chromium(STACK): ~DebugLogger#0 0x5561d07c968e (/home/xina1i/chromium/src/out/Release/chrome+0xca4b68d)
    #1 0x7f7dfc58397c (/home/xina1i/chromium/src/out/Release/libbase.so+0x158397b)
    #2 0x7f7dfc4a6cb4 (/home/xina1i/chromium/src/out/Release/libbase.so+0x14a6cb3)
    #3 0x7f7dfc4a6b25 (/home/xina1i/chromium/src/out/Release/libbase.so+0x14a6b24)
    ...
    #111 0x7f7ceba29e40 (/usr/lib/x86_64-linux-gnu/libc.so.6+0x29e3f)
    #112 0x5561d0782a1a (/home/xina1i/chromium/src/out/Release/chrome+0xca04a19)
    
    =================================================================
    ==801212==ERROR: AddressSanitizer: heap-use-after-free on address 0x5110004111c0 at pc 0x7f7dfbc24f3f bp 0x7ffeb089feb0 sp 0x7ffeb089fea8
    READ of size 1 at 0x5110004111c0 thread T0 (chrome)
        #0 0x7f7dfbc24f3e in base::internal::(anonymous namespace)::CrashImmediatelyOnUseAfterFree(unsigned long) base/memory/raw_ptr_asan_hooks.cc:53:17
        #1 0x7f7dfbc249bf in base::internal::(anonymous namespace)::SafelyUnwrapForDereference(unsigned long) base/memory/raw_ptr_asan_hooks.cc:76:5
        #2 0x5561ef31666f in BubbleContentsWrapper* base::internal::RawPtrHookableImpl<true>::SafelyUnwrapPtrForDereference<BubbleContentsWrapper>(BubbleContentsWrapper*) base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr_hookable_impl.h:85:9
        #3 0x5561ef43f109 in base::raw_ptr<BubbleContentsWrapper, (partition_alloc::internal::RawPtrTraits)0>::GetForDereference() const base/allocator/partition_allocator/src/partition_alloc/pointers/raw_ptr.h:833:12
    
    
  5. git问题

    git配置文件.git/config(linux), .gitconfig(windows)

    a. fatal: Out of memory, malloc failed
    git缓存不够,通过更改git的配置项postbuffer=1048576000

    b. Conflicting directory
    目录冲突,这个很有可能是因为git配置项中的depot_tools目录不对,改到对应的目录即可

  6. vs环境问题

    a. No supported Visual Studio can be found. Supported versions are: 17.0 (2022), 16.0 (2019), 15.0 (2017)
    找不到安装的vs信息,解决: set vs2022_install=D:\tools\vs_community

    b. Exception: Path "D:\Windows Kits\10\\include\10.0.22621.0\\um" from environment variable "include" does not exist. Make sure the necessary SDK is installed.
    这个是表明目前构建的chromium版本需要的windows SDK版本错误或者是找不到对应的版本,

    ​ 首先设置SDK目录set WINDOWSSDKDIR=D:\Windows Kits\10

    ​ 然后查看D:\Windows Kits\10\Include目录下是否存在10.0.22621.0版本的SDK,如果不存在,则安装即可

    c. midl.exe output different from files
    该问题,根据经验应该是msvc的版本混乱了,比如最新版的需要vs2022,老版本的需要vs2017

    ​ 安装完vs2017之后,没有重启,可能会存在该问题,重启之后,打开特定的vs2017命令行,重新编译即可

    d. 提示构建代码需要更高版本的clang,比如third_party/llvm-build中的clang版本是11.0,但是提示需要使用11.0 or newer
    这个问题一般在编译老版本时出现,主要的原因在于使用了高版本的msvc,比如安装了vs2019

    ​ 但随着vs的更新其对应的msvc也会更新,这就导致部分msvc的头文件不再支持clang10.0

    ​ 但是我没找到在编译过程中设定只使用固定msvc的方法,最后没办法我装了旧版本的vs2017解决了这个问题

  7. 编译工具问题

    a. LLVM ERROR: out of memory
    这个问题在chromium最近(2024.03.04)的版本中经常性遇到,也不知道后期能不能解决
    我们在正常默认编译的情况下,会使用ninja -C out\Release chrome进行编译,

    ninja会将所有可使用的cpu全部占用,所以就会有一个问题跑满的情况下,

    会出现大量的clang进程直接把所有的内存也占满,导致oom,解决办法: ninja -C out\Release -j 12

    限制并发数,从而限制内存的使用,具体使用几个并发,可以自己测试

还有部分上古版本,会涉及到编译器和其对应的c++标准等,这类的,最好的解决办法是找到当时最新的对应系统进行编译,不然会恶心到想吐。

调试技巧

该部分内容主要写一些在调试chromium或者其组件过程中可能使用到的部分技巧

使用带console调试

我们在调试chromium时,如果可以使用日志的话,一般会使用日志,但是在很多third_party库中无法直接使用base库中的日志功能,可能需要fprintf这类的输出来显示我们需要的日志,所以有时候带consolechromium就很有用。

  1. Build.gn中添加链接选项

    if (is_win) {
        ldflags = ["/SUBSYSTEM:CONSOLE"]
    }
    
  2. 启动时启用日志并设置日志等级: .\out\Release\chrome.exe --enable-logging --v=0

    在比较新的系统中,直接使用这种方法应该会报错

    ERROR at //BUILD.gn:43:13: Assignment had no effect.
      ldflags = ["/SUBSYSTEM:CONSOLE"]
                ^--------------------
    You set the variable "ldflags" here and it was unused before it went
    out of scope.
    

    比较通用的方法是引入chromium自身提供的win_console支持

    import("//build/config/win/console_app.gni")
    

    在最新版的chromium中已经默认支持console编译(2024.03.05)

@xinali xinali changed the title chromium新老版本编译 002-chromium新老版本编译 Apr 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant