前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Chromium】如何提取Chromium的Base库(下)

【Chromium】如何提取Chromium的Base库(下)

原创
作者头像
lealc
修改2024-04-17 11:14:30
1570
修改2024-04-17 11:14:30
举报
文章被收录于专栏:Chromium学习Chromium学习

前言

本篇文章主要记录如何从Chromium中提取Base库,方便后续的学习和使用,同时抛砖引玉,希望带给各位一些启发和帮助。

先上提取后的开源代码,可以开箱即用:Github

本次提取基于Tag=77.0.3865.129,也就是77大版本的最后一个子版本,发布时间为2019年10月18日。

文章较长,分、下两篇,上篇主要讲解如何做,下篇主要讲解问题及解决,大家喜欢可以点点赞。

本篇较为枯燥,整体流程可以先从上篇了解后,遇到问题来本篇进行查阅。

编译问题

问题1:D:\Code\chromium_msvc\src\out\Default\obj\base\base.vcxproj : error  : 无法加载具有重复项目项的项目: ../../../../base/task/promise/promise.h 作为 None 且作为 None 项类型包括在其中。

找到对应的base.vcxproj,右键编辑找到重复行,删除一行即可

autoninja -C out\Default base

代码语言:shell
复制
gn gen out\Default --ide=vs2019 --ninja-executable=D:\Code\chromium_base\src\third_party\ninja\ninja.exe --winsdk=10.0.18362.0 --args="target_cpu=\"x86\" is_debug=true is_clang=false" --filters=//base

问题2:调试等级不符合导致链接失败

检查是否Debug/Release以及MT/MD匹配,如果都匹配的话只能用下面方法:

可以尝试指定调试等级来规避此错误

代码语言:shell
复制
_ITERATOR_DEBUG_LEVEL=0;

问题3:C2712 无法在要求对象展开的函数中使用__try

调整源码如下

代码语言:c++
复制
void TerminateWithHeapCorruption() {
  try {
    // Pre-Windows 10, it's hard to trigger a heap corruption fast fail, so
    // artificially create one instead.
    if (base::win::GetVersion() < base::win::Version::WIN10)
      CreateSyntheticHeapCorruption();
    HANDLE heap = ::HeapCreate(0, 0, 0);
    CHECK(heap);
    CHECK(HeapSetInformation(heap, HeapEnableTerminationOnCorruption, nullptr,
                             0));
    void* addr = ::HeapAlloc(heap, 0, 0x1000);
    CHECK(addr);
    // Corrupt heap header.
    char* addr_mutable = reinterpret_cast<char*>(addr);
    memset(addr_mutable - sizeof(addr), 0xCC, sizeof(addr));

    HeapFree(heap, 0, addr);
    HeapDestroy(heap);
  } catch (const std::exception& e) {
    // Heap corruption exception should never be caught.
    CHECK(false);
  }
  // Should never reach here.
  abort();
}

问题4:收缩转换无效

问题文件:D:\Code\CoreP\src\Chromium\base\win\windows_version.cc

错误提示:从 "int" 到     "unsigned     int" 进行收缩转换无效

代码语言:c++
复制
return base::Version(std::vector<uint32_t>{major, minor, build, patch}); 

更改为:   
  
return base::Version(std::vector<uint32_t>{static_cast<unsigned int>(major), static_cast<unsigned int>(minor), static_cast<unsigned int>(build), static_cast<unsigned int>(patch)});

问题5:TraceArguments参数错误

1>D:\Code\chromium_base\src\base\trace_event\trace_event.h(737,41): error C2661: “base::trace_event::TraceArguments::TraceArguments”: 没有重载函数接受 2 个参数

暂时不需要Trace,可以直接置空(怀疑是模板参数没有对上)

代码语言:c++
复制
template <class ARG1_TYPE> static inline base::trace_event::TraceEventHandle AddTraceEventWithThreadIdAndTimestamp(     
  char phase,     
  const unsigned char* category_group_enabled,   
  const char* name, 
  const char* scope,     
  unsigned long long id,   
  int thread_id,     
  const base::TimeTicks& timestamp,     
  unsigned int flags,     
  unsigned long long bind_id,  
  const char* arg1_name,     
  ARG1_TYPE&& arg1_val) {   
  //base::trace_event::TraceArguments args(arg1_name,   
  //                                       std::forward<ARG1_TYPE>(arg1_val));   
  base::trace_event::TraceArguments args{};  
  return TRACE_EVENT_API_ADD_TRACE_EVENT_WITH_THREAD_ID_AND_TIMESTAMP(    
    phase, category_group_enabled, name, scope, id, bind_id, thread_id,      
    timestamp, &args, flags);
}
后续跟进

仔细review错误提示发现无法匹配模板

代码语言:shell
复制
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_event.h(737,41): error C2661: “base::trace_event::TraceArguments::TraceArguments”: 没有重载函数接受 2 个参数
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_arguments.h(610,3): message : 可能是“base::trace_event::TraceArguments::TraceArguments(int,const char *const *,const unsigned char *,const unsigned __int64 *,CONVERTABLE_TYPE *)”
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_event.h(737,41): message : “base::trace_event::TraceArguments::TraceArguments(int,const char *const *,const unsigned char *,const unsigned __int64 *,CONVERTABLE_TYPE *)”: 应输入 5 个参数,却提供了 2 个
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_arguments.h(587,3): message : 或    “base::trace_event::TraceArguments::TraceArguments(const char *,T1 &&,const char *,T2 &&)”
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_event.h(737,41): message : “base::trace_event::TraceArguments::TraceArguments(const char *,T1 &&,const char *,T2 &&)”: 应输入 4 个参数,却提供了 2 个
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_arguments.h(576,3): message : 或    “base::trace_event::TraceArguments::TraceArguments(const char *,T &)”
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_event.h(737,41): message : “base::trace_event::TraceArguments::TraceArguments(const char *,T &)”: 无法推导“<unnamed-symbol>”的 模板 参数
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_arguments.h(568,3): message : 或    “base::trace_event::TraceArguments::TraceArguments(const char *,T &&)”
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_event.h(737,41): message : “base::trace_event::TraceArguments::TraceArguments(const char *,T &&)”: 无法推导“<unnamed-symbol>”的 模板 参数
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_event.h(737,41): message : 尝试匹配参数列表“(const char *, base::MemoryPressureListener::MemoryPressureLevel)”时
1>D:\Code\CorP_Base\src\Chromium\base\trace_event\trace_event.h(737,41): message : 模板实例化上下文(最早的实例化上下文)为

参考链接

类似问题:c++ - Template access of symbol in unnamed namespace - Stack Overflow

可以发现宽松模式可以编译通过,修改编译选项项目属性 - 配置属性 - C/C++ - 语言 - 符合模式(/permissive-)

官网文档:/permissive- (標準一致性) | Microsoft Learn

问题6:尝试引用已删除的函数

代码语言:shell
复制
C:\Program Files (x86)\Microsoft Visual  Studio\2019\Professional\VC\Tools\MSVC\14.29.30133\include\xmemory(681,47): error  C2280:“std::atomic<base::LockFreeAddressHashSet::Node *>::atomic(const std::atomic<base::LockFreeAddressHashSet::Node *> &)”: 尝试引用已删除的函数

找到数据结构定义:base::LockFreeAddressHashSet::Node

在文件:D:\Code\chromium_base\src\base\sampling_heap_profiler\lock_free_address_hash_set.h

编译文件D:\Code\CoreP\src\Chromium\base\sampling_heap_profiler\sampling_heap_profiler.ccs时出现这个问题

参考:博客

关键原因:std::vectorstd::atomic不能同时使用,因为atomic的定义

代码语言:c++
复制
template <class _Ty> struct atomic : _Choose_atomic_base_t<_Ty> { 
    // atomic value     
    atomic(const atomic&) = delete;     
    atomic& operator=(const atomic&) = delete; 
}

std::vector要求必须要有拷贝构造函数,导致冲突

修复问题:

代码语言:c++
复制
class BASE_EXPORT LockFreeAddressHashSet {
public:
    explicit LockFreeAddressHashSet(size_t buckets_count);
    ~LockFreeAddressHashSet();

    // Checks if the |key| is in the set. Can be executed concurrently with
    // |Insert|, |Remove|, and |Contains| operations.
    ALWAYS_INLINE bool Contains(void* key) const;

    // Removes the |key| from the set. The key must be present in the set before
    // the invocation.
    // Concurrent execution of |Insert|, |Remove|, or |Copy| is not supported.
    ALWAYS_INLINE void Remove(void* key);

    // Inserts the |key| into the set. The key must not be present in the set
    // before the invocation.
    // Concurrent execution of |Insert|, |Remove|, or |Copy| is not supported.
    void Insert(void* key);

    // Copies contents of |other| set into the current set. The current set
    // must be empty before the call.
    // Concurrent execution of |Insert|, |Remove|, or |Copy| is not supported.
    void Copy(const LockFreeAddressHashSet& other);

    size_t buckets_count() const { return buckets_.size(); }
    size_t size() const { return size_; }

    // Returns the average bucket utilization.
    float load_factor() const { return 1.f * size() / buckets_.size(); }

private:
    friend class LockFreeAddressHashSetTest;

    struct Node {
        ALWAYS_INLINE Node(void* key, Node* next);
        std::atomic<void*> key;
        Node* next;
    };

    ALWAYS_INLINE static uint32_t Hash(void* key);
    ALWAYS_INLINE Node* FindNode(void* key) const;

    std::vector<std::shared_ptr<std::atomic<Node*>>> buckets_;
    int size_ = 0;
    const size_t bucket_mask_;
};

std::vector<std::atomic<Node*>> buckets_;修改为std::vector<std::shared_ptr<std::atomic<Node*>>> buckets_;

使用智能指针来规避这个拷贝构造函数缺失的atomic

问题7:C2338 enumerator must define kMaxValue enumerator to use this macro!

问题文件:D:\Code\CoreP\src\Chromium\base\metrics\histogram_macros_internal.h

问题片段:

解决:注释static_assert

问题8:error C2280: “std::unique_ptr<base::ModuleCache::Module,std::default_delete<base::ModuleCache::Module>> &std::unique_ptr<base::ModuleCache::Module,std::default_delete<base::ModuleCache::Module>>::operator =(const  std::unique_ptr<base::ModuleCache::Module,std::default_delete<base::ModuleCache::Module>> &)”: 尝试引用已删除的函数

问题文件:D:\Code\CoreP\src\Chromium\base\sampling_heap_profiler\module_cache.cc

编译文件frame.cc出现问题,

代码语言:c++
复制
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_PROFILER_FRAME_H_
#define BASE_PROFILER_FRAME_H_

#include <memory>

#include "base/sampling_heap_profiler/module_cache.h"

namespace base {

// Frame represents an individual sampled stack frame with full module
// information.
struct BASE_EXPORT Frame {
  Frame(uintptr_t instruction_pointer, const ModuleCache::Module* module);
  ~Frame();

  // The sampled instruction pointer within the function.
  uintptr_t instruction_pointer;

  // The module information.
  const ModuleCache::Module* module;
};

}  // namespace base

#endif  // BASE_PROFILER_FRAME_H_

可以看到依赖文件:

代码语言:c++
复制
#include "base/sampling_heap_profiler/module_cache.h"

检查发现

代码语言:c++
复制
// D:\Code\CoreP\src\Chromium\base\sampling_heap_profiler\module_cache.h  
class BASE_EXPORT ModuleCache {
 public:
  // Module represents a binary module (executable or library) and its
  // associated state.
  class BASE_EXPORT Module {
   public:
    Module() = default;
    virtual ~Module() = default;

    Module(const Module&) = delete;
    Module& operator=(const Module&) = delete;

Module的拷贝构造函数也是默认delete,和atomic相同,也不能直接和vector复用,但是源码有以下函数

代码语言:c++
复制
// D:\Code\CoreP\src\Chromium\base\sampling_heap_profiler\module_cache.cc 
std::vector<const ModuleCache::Module*> ModuleCache::GetModules() const {
  std::vector<const Module*> result;
  result.reserve(native_modules_.size());
  for (const std::unique_ptr<Module>& module : native_modules_)
    result.push_back(module.get());
  return result;
}

std::vector<const ModuleCache::Module*>导致了引用已删除的函数这个问题

unique_ptr删去了右值拷贝函数

代码语言:c++
复制
 template <class _Dx2 = _Dx, enable_if_t<conjunction_v<is_reference<_Dx2>, is_constructible<_Dx2, remove_reference_t<_Dx2>>>, int> = 0>  
   	unique_ptr(pointer, remove_reference_t<_Dx>&&) = delete;

一种解决方案是将所有的unique_ptr替换为shared_ptr可以编译通过,特别注意GetModules这个函数

代码语言:c++
复制
// D:\Code\CoreP\src\Chromium\base\sampling_heap_profiler\module_cache.cc 

std::vector<std::shared_ptr<ModuleCache::Module>> ModuleCache::GetModules() const 
{
  std::vector<std::shared_ptr<ModuleCache::Module>> result;
  result.reserve(native_modules_.size());
  for (const std::shared_ptr<Module>& module : native_modules_)
    result.push_back(std::move(module));
  return result;
}

问题9:C2280 “base::internal::DecoratorWithTaskSource<base::internal::TaskSource::Transaction,T>::DecoratorWithTaskSource(void)”: 尝试引用已删除的函数

问题文件:D:\Code\CoreP\src\Chromium\base\task\thread_pool\task_source.h

涉及的类代码比较简单:

代码语言:c++
复制
// Base implementation for TransactionWith[Owned/Registered]TaskSource (with
// Transaction as the decorator) and RunIntentWithRegisteredTaskSource (with
// RunIntent as the decorator).
template <class Decorator, class T>
class BASE_EXPORT DecoratorWithTaskSource : public Decorator {
public:
    DecoratorWithTaskSource() = default;
    DecoratorWithTaskSource(std::nullptr_t) : DecoratorWithTaskSource() {}
    DecoratorWithTaskSource(T task_source_in, Decorator decorator)
        : Decorator(std::move(decorator)),
        task_source_(std::move(task_source_in)) {
        DCHECK_EQ(task_source_.get(), this->task_source());
    }
    DecoratorWithTaskSource(DecoratorWithTaskSource&& other) = default;
    ~DecoratorWithTaskSource() = default;

    DecoratorWithTaskSource& operator=(DecoratorWithTaskSource&&) = default;

    T take_task_source() { return std::move(task_source_); }

protected:
    T task_source_;

    DISALLOW_COPY_AND_ASSIGN(DecoratorWithTaskSource);
};

实际编译出错文件为:D:\Code\CoreP\src\Chromium\base\task\thread_pool\pooled_single_thread_task_runner_manager.cc

其中DISALLOW_COPY_AND_ASSIGN(DecoratorWithTaskSource);展开为

代码语言:c++
复制
// Put this in the declarations for a class to be uncopyable.
#define DISALLOW_COPY(TypeName) \
  TypeName(const TypeName&) = delete

// Put this in the declarations for a class to be unassignable.
#define DISALLOW_ASSIGN(TypeName) TypeName& operator=(const TypeName&) = delete

// Put this in the declarations for a class to be uncopyable and unassignable.
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
  DISALLOW_COPY(TypeName);                 \
  DISALLOW_ASSIGN(TypeName)

可以发现又是两个delete函数,触发了调用这种delete函数导致报错

仔细分析出错的结构体

base::internal::DecoratorWithTaskSource<base::internal::TaskSource::Transaction,T>::DecoratorWithTaskSource(void)

对应task_source.h中定义的BasicTransactionWithTaskSource结构体

结合T的定义,可以得到出错的结构体为

代码语言:c++
复制
using TransactionWithRegisteredTaskSource = BasicTransactionWithTaskSource<RegisteredTaskSource>;

针对结构体TransactionWithRegisteredTaskSource,pooled_single_thread_task_runner_manager.cc中仅三处相关

代码语言:c++
复制
// pooled_single_thread_task_runner_manager.cc

// line 129
EnqueueTaskSource(TransactionWithRegisteredTaskSource::FromTaskSource(
    std::move(task_source)));

// line 151
bool should_wakeup = EnqueueTaskSource(
    { std::move(registered_task_source), std::move(transaction) });

// line 201
// Enqueues a task source in this single-threaded worker's priority queue.
// Returns true iff the worker must wakeup, i.e. task source is allowed to run
// and the worker was not awake.
bool EnqueueTaskSource(
    TransactionWithRegisteredTaskSource transaction_with_task_source) {
    CheckedAutoLock auto_lock(lock_);
    priority_queue_.Push(std::move(transaction_with_task_source));
    if (!worker_awake_ && CanRunNextTaskSource()) {
        worker_awake_ = true;
        return true;
    }
    return false;
}

初步估计是调用函数导致拷贝引起的错误,注释这三处即可成功编译通过,进一步确认了问题所在

解决方案:正常移动语义进行函数调用不会触发拷贝构造,但是这个

代码语言:c++
复制
DecoratorWithTaskSource(std::nullptr_t) : DecoratorWithTaskSource() {} 
DecoratorWithTaskSource(T task_source_in, Decorator decorator)   
  : Decorator(std::move(decorator)), task_source_(std::move(task_source_in)) { 
  DCHECK_EQ(task_source_.get(), this->task_source());
}

导致本该正常调用DecoratorWithTaskSource(T task_source_in, Decorator decorator)构造函数却调用到:

代码语言:c++
复制
DecoratorWithTaskSource(std::nullptr_t) : DecoratorWithTaskSource() {}

出现错误,这里需要注释这个函数,同时会引发所有retrue nullptr的伴生错误

将所有的return nullptr修改为return {}即可

最终Class为:

代码语言:c++
复制
// Base implementation for TransactionWith[Owned/Registered]TaskSource (with
// Transaction as the decorator) and RunIntentWithRegisteredTaskSource (with
// RunIntent as the decorator).
template <class Decorator, class T>
class BASE_EXPORT DecoratorWithTaskSource : public Decorator {
public:
    DecoratorWithTaskSource() = default;

    DecoratorWithTaskSource(T task_source_in, Decorator decorator)
        : Decorator(std::move(decorator)),
        task_source_(std::move(task_source_in)) {
        DCHECK_EQ(task_source_.get(), this->task_source());
    }

    // 修改点++
    // DecoratorWithTaskSource(std::nullptr_t) : DecoratorWithTaskSource() {}

    DecoratorWithTaskSource(DecoratorWithTaskSource&& other) = default;
    ~DecoratorWithTaskSource() = default;

    DecoratorWithTaskSource& operator=(DecoratorWithTaskSource&&) = default;

    T take_task_source() { return std::move(task_source_); }

protected:
    T task_source_;

    DISALLOW_COPY_AND_ASSIGN(DecoratorWithTaskSource);
};

问题10:base\win\embedded_i18n\language_selector.cc(280,3): error C2397: 从“int”转换到“size_t”需要收缩转换

问题代码调整为:

代码语言:c++
复制
DCHECK_EQ(size_t{static_cast<size_t>(*selected_offset)}, languages_to_offset.size());

链接问题

问题1:error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(modp_b64.obj 中)

modp_b64.lib与base.dll不匹配,这里在项目添加预处理宏定义即可解决

代码语言:shell
复制
_ITERATOR_DEBUG_LEVEL=0;

问题2:Base.lib(message_window.obj) : error LNK2019: 无法解析的外部符号 impUnregisterClassW@8,函数 "public: __thiscall base::win::MessageWindow::WindowClass::~WindowClass(void)" (??1WindowClass@MessageWindow@win@base@@QAE@XZ) 中引用了该符号

回到初始生成的all.sln``D:\Code\chromium_base\src\out\Default\all.sln打开可以发现,base库依赖基本上都在sln都会有说明

代码语言:shell
复制
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2019
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(base)", "../../base", "{2DB4D15C-6F55-E3F9-9F62-BAF9F400AB88}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(allocator)", "../../base/allocator", "{2267EEC9-4D70-E7A4-0EF5-D1F2A69E967B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(numerics)", "../../base/numerics", "{4BE302CC-F7FC-EFF2-05C2-9C61A6544D47}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(third_party)", "../../base/third_party", "{58835CE7-3154-A040-2101-3B76A20890A4}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(dynamic_annotations)", "../../base/third_party/dynamic_annotations", "{3EB179D1-B0E7-960E-A0FA-FE5110E1B7EB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(win)", "../../base/win", "{0BA19AEF-47B0-E061-AAF0-738CC65D2595}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(build)", "../../build", "{7CB24CA3-E57B-E55E-CAC7-97459575F246}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(config)", "../../build/config", "{1CD1C417-4E2E-9F62-E130-BA99FD217097}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(win)", "../../build/win", "{E936C38C-5604-6DE2-7CED-9FEA0DF11A63}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(third_party)", "../../third_party", "{E54C5E2B-49D1-936F-DAF8-6CBCD3FF5629}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(boringssl)", "../../third_party/boringssl", "{5510EA3F-D31C-BD5B-F544-2C06226B8A5E}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(src)", "../../third_party/boringssl/src", "{E5FD4A5F-0944-EA91-3B27-B4E1D3211DAB}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(third_party)", "../../third_party/boringssl/src/third_party", "{39AC7E2B-C988-6FF6-33FA-B126C315B670}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(fiat)", "../../third_party/boringssl/src/third_party/fiat", "{3224DF4C-8242-A756-E5A2-B442A6DF4B82}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(modp_b64)", "../../third_party/modp_b64", "{24B6AEA1-C90E-FAD9-8515-E99C759A9A08}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "(nasm)", "../../third_party/nasm", "{8092AD1C-24A7-9B8A-6139-F3B4095B1A93}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocator", "obj/base/allocator/allocator.vcxproj", "{C45F27A8-5DF0-811E-0EC3-1C1F2F10E2EA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base", "obj/base/base.vcxproj", "{CF4F866E-6E9C-91F5-03DC-EB1AC77D2E82}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_static", "obj/base/base_static.vcxproj", "{B02D958A-562E-0F1E-4D7C-A8CE1557E417}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_numerics", "obj/base/numerics/base_numerics.vcxproj", "{E5B4C9C8-69A8-BA95-1D47-FE31FD509ED3}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic_annotations", "obj/base/third_party/dynamic_annotations/dynamic_annotations.vcxproj", "{1C754DBD-134F-4D47-AA7E-364C2F220B2D}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_image", "obj/base/win/pe_image.vcxproj", "{C8FAA401-2354-FF8A-048C-35D69E679223}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "buildflag_header_h", "obj/build/buildflag_header_h.vcxproj", "{466FA559-E572-3251-B914-21F7E3AF5097}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common_deps", "obj/build/config/common_deps.vcxproj", "{F10E67BE-E9DA-2EE1-3EC6-B3AF647FA5B7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_library_deps", "obj/build/config/shared_library_deps.vcxproj", "{153EFDF5-B301-5517-7DF1-50ADC512A4E8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "default_exe_manifest", "obj/build/win/default_exe_manifest.vcxproj", "{AC6DB6A7-767D-BCB2-36F1-5646D5AC1136}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runtime_libs", "obj/build/win/runtime_libs.vcxproj", "{BDA415C1-2350-2506-4F0F-4149AB68C9DB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boringssl", "obj/third_party/boringssl/boringssl.vcxproj", "{500CD92E-FFDC-58A7-1782-3EC90B8CE3C7}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boringssl_asm", "obj/third_party/boringssl/boringssl_asm.vcxproj", "{4001576D-0609-D362-682F-22AF764A1392}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fiat_license", "obj/third_party/boringssl/src/third_party/fiat/fiat_license.vcxproj", "{3E60B12C-FC82-C20F-A143-4B2A6D39BFDB}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "modp_b64", "obj/third_party/modp_b64/modp_b64.vcxproj", "{AC4436D8-F0D7-A920-148B-28F505C7450B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nasm", "obj/third_party/nasm/nasm.vcxproj", "{47DC20FA-FA02-F3BD-A8F5-836F6D873E5B}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "allocator_x64", "x64/obj/base/allocator/allocator_x64.vcxproj", "{3081BB50-0F08-1A1C-927B-B125A4DC7CD6}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_static_x64", "x64/obj/base/base_static_x64.vcxproj", "{4BBDD124-DAB2-61B1-7112-69D3632F647E}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_x64", "x64/obj/base/base_x64.vcxproj", "{7018B75F-8FC2-4CF2-2D18-0C1F1708761F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "base_numerics_x64", "x64/obj/base/numerics/base_numerics_x64.vcxproj", "{11B677D0-7A54-DA3C-3AA6-2C9CC3AC893A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "dynamic_annotations_x64", "x64/obj/base/third_party/dynamic_annotations/dynamic_annotations_x64.vcxproj", "{1F21A6BC-939E-B5DD-E965-3BF0954617E4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pe_image_x64", "x64/obj/base/win/pe_image_x64.vcxproj", "{B9D168CD-3653-784D-EA83-D5B781DE4ED8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "buildflag_header_h_x64", "x64/obj/build/buildflag_header_h_x64.vcxproj", "{F57DFE7B-3CAD-7594-8F09-4B63401CBD62}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common_deps_x64", "x64/obj/build/config/common_deps_x64.vcxproj", "{FF3FA165-4DE4-C671-CC74-DDC07F5F65D4}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "shared_library_deps_x64", "x64/obj/build/config/shared_library_deps_x64.vcxproj", "{2E1B7990-A17F-C747-78C1-115FBAA45589}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runtime_libs_x64", "x64/obj/build/win/runtime_libs_x64.vcxproj", "{3BF58E3A-1B95-1F2C-50C2-032F43120305}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boringssl_asm_x64", "x64/obj/third_party/boringssl/boringssl_asm_x64.vcxproj", "{0F6508C1-CF2A-A0AF-6E4B-F52D9B5F8F43}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "boringssl_x64", "x64/obj/third_party/boringssl/boringssl_x64.vcxproj", "{64472894-57FD-F2FE-AA10-B024A4239F4F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fiat_license_x64", "x64/obj/third_party/boringssl/src/third_party/fiat/fiat_license_x64.vcxproj", "{1EC23B56-50E9-2507-DC9E-F162085EA18F}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "modp_b64_x64", "x64/obj/third_party/modp_b64/modp_b64_x64.vcxproj", "{36B9D0FB-0484-6E36-EDBF-3251326A8F61}"
EndProject

只看32位版本,编译动态库Base.dll总共依赖如下所有模块

可以找到对应的proj文件,进行对应迁移,例如allocator项目,源码放在src/base/allocator上面,项目在D:\Code\chromium_base\src\out\Default\obj\base\allocator

问题3:error LNK2019: 无法解析的外部符号

列表如下:

代码语言:shell
复制
1>Base.lib(wmi.obj) : error LNK2001: 无法解析的外部符号 _CLSID_WbemLocator   
  
1>Base.lib(win_util.obj) : error LNK2019: 无法解析的外部符号 __imp__InitPropVariantFromCLSID@8,函数 "bool __cdecl base::win::SetClsidForPropertyStore(struct IPropertyStore *,struct _tagpropertykey const &,struct _GUID const &)" (?SetClsidForPropertyStore@win@base@@YA_NPAUIPropertyStore@@ABU_tagpropertykey@@ABU_GUID@@@Z) 中引用了该符号 
  
1>Base.lib(win_util.obj) : error LNK2019: 无法解析的外部符号 __imp__SetupDiEnumDeviceInfo@12,函数 "bool __cdecl base::win::IsKeyboardPresentOnSlate(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,struct HWND__ *)" (?IsKeyboardPresentOnSlate@win@base@@YA_NPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHWND__@@@Z) 中引用了该符号 
1>Base.lib(win_util.obj) : error LNK2019: 无法解析的外部符号 __imp__SetupDiGetClassDevsW@16,函数 "bool __cdecl base::win::IsKeyboardPresentOnSlate(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,struct HWND__ *)" (?IsKeyboardPresentOnSlate@win@base@@YA_NPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHWND__@@@Z) 中引用了该符号 
  
1>Base.lib(win_util.obj) : error LNK2019: 无法解析的外部符号 __imp__CM_Get_Device_IDW@16,函数 "bool __cdecl base::win::IsKeyboardPresentOnSlate(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,struct HWND__ *)" (?IsKeyboardPresentOnSlate@win@base@@YA_NPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHWND__@@@Z) 中引用了该符号 
1>Base.lib(win_util.obj) : error LNK2019: 无法解析的外部符号 _PowerDeterminePlatformRoleEx@4,函数 "enum _POWER_PLATFORM_ROLE __cdecl base::win::`anonymous namespace'::GetPlatformRole(void)" (?GetPlatformRole@?A0xe029d9ab@win@base@@YA?AW4_POWER_PLATFORM_ROLE@@XZ) 中引用了该符号

通过找到源码路径D:\Code\chromium_base\src\base下面的BUILD.gn文件,里面会有详细的第三方库依赖

代码语言:shell
复制
# Windows.   
  if (is_win) {      
  libs += [       
    "cfgmgr32.lib",       
    "powrprof.lib",       
    "propsys.lib",       
    "setupapi.lib",     
    "userenv.lib",       
    "wbemuuid.lib",       
    "winmm.lib",  
  ] 
}

问题4:error Link2019 无法解析的外部符号

部分错误如下:

代码语言:shell
复制
1>Base.lib(base_paths_win.obj) : error LNK2019: 无法解析的外部符号 __imp__CoTaskMemFree@4,函数 "public: void __thiscall base::win::ScopedCoMem<wchar_t>::Reset(wchar_t *)" (?Reset@?$ScopedCoMem@_W@win@base@@QAEXPA_W@Z) 中引用了该符号 1>Base.lib(base_paths_win.obj) : error LNK2019: 无法解析的外部符号 _SHGetKnownFolderPath@16,函数 "bool __cdecl base::PathProviderWin(int,class base::FilePath *)" (?PathProviderWin@base@@YA_NHPAVFilePath@1@@Z) 中引用了该符号 
1>Base.lib(message_window.obj) : error LNK2019: 无法解析的外部符号 __imp__DefWindowProcW@16,函数 "private: static long __stdcall base::win::MessageWindow::WindowProc(struct HWND__ *,unsigned int,unsigned int,long)" (?WindowProc@MessageWindow@win@base@@CGJPAUHWND__@@IIJ@Z) 中引用了该符号 1>Base.lib(message_window.obj) : error LNK2019: 无法解析的外部符号 __imp__UnregisterClassW@8,函数 "public: __thiscall base::win::MessageWindow::WindowClass::~WindowClass(void)" (??1WindowClass@MessageWindow@win@base@@QAE@XZ) 中引用了该符号  
1>Base.lib(scoped_com_initializer.obj) : error LNK2019: 无法解析的外部符号 __imp__CoUninitialize@0,函数 "public: virtual __thiscall base::win::ScopedCOMInitializer::~ScopedCOMInitializer(void)" (??1ScopedCOMInitializer@win@base@@UAE@XZ) 中引用了该符号 1>Base.lib(scoped_com_initializer.obj) : error LNK2019: 无法解析的外部符号 __imp__CoInitializeEx@8,函数 "private: void __thiscall base::win::ScopedCOMInitializer::Initialize(enum tagCOINIT)" (?Initialize@ScopedCOMInitializer@win@base@@AAEXW4tagCOINIT@@@Z) 中引用了该符号

分析发现均为系统API,仔细review,检查导入库

勾选后,系统模块相关的Link Error均消除

问题5:error Link2019 无法解析的外部符号

部分错误如下:

代码语言:shell
复制
1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__StackWalk64@36,函数 "private: void __thiscall base::debug::StackTrace::InitTrace(struct _CONTEXT const *)" (?InitTrace@StackTrace@debug@base@@AAEXPBU_CONTEXT@@@Z) 中引用了该符号 
1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymSetOptions@4,函数 "bool __cdecl base::debug::`anonymous namespace'::InitializeSymbols(void)" (?InitializeSymbols@?A0xe584d94c@debug@base@@YA_NXZ) 中引用了该符号 1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymCleanup@4,函数 "bool __cdecl base::debug::`anonymous namespace'::InitializeSymbols(void)" (?InitializeSymbols@?A0xe584d94c@debug@base@@YA_NXZ) 中引用了该符号 
1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymFunctionTableAccess64@12,函数 "private: void __thiscall base::debug::StackTrace::InitTrace(struct _CONTEXT const *)" (?InitTrace@StackTrace@debug@base@@AAEXPBU_CONTEXT@@@Z) 中引用了该符号 1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymGetModuleBase64@12,函数 "private: void __thiscall base::debug::StackTrace::InitTrace(struct _CONTEXT const *)" (?InitTrace@StackTrace@debug@base@@AAEXPBU_CONTEXT@@@Z) 中引用了该符号 
1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymGetLineFromAddr64@20,函数 "public: void __thiscall base::debug::`anonymous namespace'::SymbolContext::OutputTraceToStream(void const * const *,unsigned int,class std::basic_ostream<char,struct std::char_traits<char> > *,char const *)" (?OutputTraceToStream@SymbolContext@?A0xe584d94c@debug@base@@QAEXPBQBXIPAV?$basic_ostream@DU?$char_traits@D@std@@@std@@PBD@Z) 中引用了该符号 
1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymInitialize@12,函数 "bool __cdecl base::debug::`anonymous namespace'::InitializeSymbols(void)" (?InitializeSymbols@?A0xe584d94c@debug@base@@YA_NXZ) 中引用了该符号 1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymGetSearchPathW@12,函数 "bool __cdecl base::debug::`anonymous namespace'::InitializeSymbols(void)" (?InitializeSymbols@?A0xe584d94c@debug@base@@YA_NXZ) 中引用了该符号 
1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymSetSearchPathW@8,函数 "bool __cdecl base::debug::`anonymous namespace'::InitializeSymbols(void)" (?InitializeSymbols@?A0xe584d94c@debug@base@@YA_NXZ) 中引用了该符号 
1>Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymFromAddr@20,函数 "public: void __thiscall base::debug::`anonymous namespace'::SymbolContext::OutputTraceToStream(void const * const *,unsigned int,class std::basic_ostream<char,struct std::char_traits<char> > *,char const *)" (?OutputTraceToStream@SymbolContext@?A0xe584d94c@debug@base@@QAEXPBQBXIPAV?$basic_ostream@DU?$char_traits@D@std@@@std@@PBD@Z) 中引用了该符号

找到Base.lib(stack_trace_win.obj) : error LNK2019: 无法解析的外部符号 __imp__SymSetOptions@

D:\Code\CoreP\src\Chromium\base\debug\stack_trace_win.cc

F5进去会找到DBGHelp.h,同样依赖库新增Dbghelp.lib

问题6:error Link2019 无法解析的外部符号

部分错误如下:

代码语言:shell
复制
1>Base.lib(file_version_info_win.obj) : error LNK2019: 无法解析的外部符号 _GetFileVersionInfoSizeW@8,函数 "public: static class std::unique_ptr<class FileVersionInfoWin,struct std::default_delete<class FileVersionInfoWin> > __cdecl FileVersionInfoWin::CreateFileVersionInfoWin(class base::FilePath const &)" (?CreateFileVersionInfoWin@FileVersionInfoWin@@SA?AV?$unique_ptr@VFileVersionInfoWin@@U?$default_delete@VFileVersionInfoWin@@@std@@@std@@ABVFilePath@base@@@Z) 中引用了该符号 1>Base.lib(file_version_info_win.obj) : error LNK2019: 无法解析的外部符号 _GetFileVersionInfoW@16,函数 "public: static class std::unique_ptr<class FileVersionInfoWin,struct std::default_delete<class FileVersionInfoWin> > __cdecl FileVersionInfoWin::CreateFileVersionInfoWin(class base::FilePath const &)" (?CreateFileVersionInfoWin@FileVersionInfoWin@@SA?AV?$unique_ptr@VFileVersionInfoWin@@U?$default_delete@VFileVersionInfoWin@@@std@@@std@@ABVFilePath@base@@@Z) 中引用了该符号 1>Base.lib(file_version_info_win.obj) : error LNK2019: 无法解析的外部符号 _VerQueryValueW@16,函数 "struct A0xfc011f89::LanguageAndCodePage * __cdecl `anonymous namespace'::GetTranslate(void const *)" (?GetTranslate@?A0xfc011f89@@YAPAULanguageAndCodePage@1@PBX@Z) 中引用了该符号

同样在D:\Code\CoreP\src\Chromium\base\file_version_info_win.cc

找到winver.h的这个函数GetFileVersionInfoSize

引入version.lib

问题7:error Link2019 无法解析的外部符号

部分错误如下:

代码语言:shell
复制
1>Base.lib(md5_boringssl.obj) : error LNK2019: 无法解析的外部符号 __imp__MD5_Init,函数 "void __cdecl base::MD5Init(struct md5_state_st *)" (?MD5Init@base@@YAXPAUmd5_state_st@@@Z) 中引用了该符号 
1>Base.lib(md5_boringssl.obj) : error LNK2019: 无法解析的外部符号 __imp__MD5_Update,函数 "void __cdecl base::MD5Update(struct md5_state_st *,class base::BasicStringPiece<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &)" (?MD5Update@base@@YAXPAUmd5_state_st@@ABV?$BasicStringPiece@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@1@@Z) 中引用了该符号 
1>Base.lib(md5_boringssl.obj) : error LNK2019: 无法解析的外部符号 __imp__MD5_Final,函数 "void __cdecl base::MD5Final(struct base::MD5Digest *,struct md5_state_st *)" (?MD5Final@base@@YAXPAUMD5Digest@1@PAUmd5_state_st@@@Z) 中引用了该符号 
1>Base.lib(md5_boringssl.obj) : error LNK2019: 无法解析的外部符号 __imp__MD5,函数 "void __cdecl base::MD5Sum(void const *,unsigned int,struct base::MD5Digest *)" (?MD5Sum@base@@YAXPBXIPAUMD5Digest@1@@Z) 中引用了该符号

同样找到:D:\Code\CoreP\src\Chromium\base\hash\md5_boringssl.cc

函数MD5_Init依赖D:\Code\chromium_base\src\third_party\boringssl\src\include\openssl\md5.h

需要第三方库boring_ssl,在目录D:\Code\chromium_base\src\third_party\boringssl

具体采用版本:src/third_party/boringssl/src: https://boringssl.googlesource.com/boringssl.git@4dfd5af70191b068aebe567b8e29ce108cee85ce

源码地址:地址

官方编译教程:教程

下载环境准备
cmake下载

【版本3.23.2.0】:CMake - Upgrade Your Software Build System

perl下载

参考:boringssl/BUILDING.md at chromium-3945 · google/boringssl (github.com)

代码语言:shell
复制
CMake 3.0 or later is required. A recent version of Perl is required. On Windows, Active State Perl has been reported to work, as has MSYS Perl. Strawberry Perl also works but it adds GCC to PATH, which can confuse some build tools when identifying the compiler (removing C:\Strawberry\c\bin from PATH should resolve any problems). If Perl is not found by CMake, it may be configured explicitly by setting PERL_EXECUTABLE.

否则会报错

代码语言:shell
复制
CMake Error at D:/Software/qt/Tools/CMake_64/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:230 (message): 
Could NOT find Perl (missing: PERL_EXECUTABLE) 
Call Stack (most recent call first): 
D:/Software/qt/Tools/CMake_64/share/cmake-3.23/Modules/FindPackageHandleStandardArgs.cmake:594 (_FPHSA_FAILURE_MESSAGE) 
D:/Software/qt/Tools/CMake_64/share/cmake-3.23/Modules/FindPerl.cmake:84 (FIND_PACKAGE_HANDLE_STANDARD_ARGS) 
CMakeLists.txt:32 (find_package)

官方建议下载这个

也可以下载这个:Strawberry Perl for Windows

代码语言:shell
复制
C:\Users\Leal>perl -v 
  
This is perl 5, version 38, subversion 0 (v5.38.0) built for MSWin32-x64-multi-thread
下载Go

https://golang.google.cn/dl/go1.21.5.windows-amd64.msi 下载链接

下载NASM

报错:

代码语言:shell
复制
The ASM_NASM compiler identification is unknown   
  
Didn't find assemblerCMake Error at crypto/CMakeLists.txt:60 (enable_language): No CMAKE_ASM_NASM_COMPILER could be found.

参考:链接

下载:NASMrelease

编译

找到*\CMake_64\bin\cmake-gui.exe

srouce_code:D:/Code/CoreP/src/third_party/src/boringssl/src

build_path:D:/Code/CoreP/src/third_party/src/build

配置environment path : 将上面下载的模块都配置一下系统环境变量

代码语言:shell
复制
D:\Software\Strawberry\perl\bin;D:\Software\Strawberry\perl\site\bin;D:\Software\Go\bin;D:\Software\NASM

点击Configure

提示如下则配置成功,继续生成

代码语言:shell
复制
Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22631. The ASM_NASM compiler identification is NASMFound assembler: D:/Software/NASM/nasm.exe Configuring done   Generating done

目录D:/Code/CoreP/src/third_party/src/build打开BoringSSL.sln

编译所有工程,拿到生成的crypto.lib拷贝到lib目录,然后迁移(D:\Code\chromium_base\src\third_party\boringssl)boringssl的dll工程到第三方库目录,引入此crypto.lib,生成boringssl.dll

问题8:error Link2019 无法解析的外部符号

错误如下:

代码语言:shell
复制
1>base64.obj : error LNK2019: 无法解析的外部符号 _modp_b64_encode,函数 "void __cdecl base::Base64Encode(class base::BasicStringPiece<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *)" (?Base64Encode@base@@YAXABV?$BasicStringPiece@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@1@PAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) 中引用了该符号 
1>base64.obj : error LNK2019: 无法解析的外部符号 _modp_b64_decode,函数 "bool __cdecl base::Base64Decode(class base::BasicStringPiece<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *)" (?Base64Decode@base@@YA_NABV?$BasicStringPiece@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@1@PAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@Z) 中引用了该符号

迁移D:\Code\chromium_base\src\third_party\modp_b64这个工程,静态lib工程,生成对应lib,引入即可

问题9:error Link2019 无法解析的外部符号

代码语言:shell
复制
1>wmi.obj : error LNK2001: 无法解析的外部符号 _CLSID_WbemLocator

引入静态lib:wbemuuid.lib

问题10:error Link2019 无法解析的外部符号

代码语言:shell
复制
1>win_util.obj : error LNK2019: 无法解析的外部符号 __imp__CM_Get_Device_IDW@16,函数 "bool __cdecl base::win::IsKeyboardPresentOnSlate(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,struct HWND__ *)" (?IsKeyboardPresentOnSlate@win@base@@YA_NPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHWND__@@@Z) 中引用了该符号 1>win_util.obj : error LNK2019: 无法解析的外部符号 _PowerDeterminePlatformRoleEx@4,函数 "enum _POWER_PLATFORM_ROLE __cdecl base::win::`anonymous namespace'::GetPlatformRole(void)" (?GetPlatformRole@?A0xe029d9ab@win@base@@YA?AW4_POWER_PLATFORM_ROLE@@XZ) 中引用了该符号 1>win_util.obj : error LNK2019: 无法解析的外部符号 __imp__SetupDiEnumDeviceInfo@12,函数 "bool __cdecl base::win::IsKeyboardPresentOnSlate(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,struct HWND__ *)" (?IsKeyboardPresentOnSlate@win@base@@YA_NPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHWND__@@@Z) 中引用了该符号 1>win_util.obj : error LNK2019: 无法解析的外部符号 __imp__SetupDiGetClassDevsW@16,函数 "bool __cdecl base::win::IsKeyboardPresentOnSlate(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > *,struct HWND__ *)" (?IsKeyboardPresentOnSlate@win@base@@YA_NPAV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAUHWND__@@@Z) 中引用了该符号 1>win_util.obj : error LNK2019: 无法解析的外部符号 __imp__IsOS@4,函数 "bool * __cdecl base::win::`anonymous namespace'::GetDomainEnrollmentStateStorage(void)" (?GetDomainEnrollmentStateStorage@?A0xe029d9ab@win@base@@YAPA_NXZ) 中引用了该符号 1>win_util.obj : error LNK2019: 无法解析的外部符号 __imp__InitPropVariantFromCLSID@8,函数 "bool __cdecl base::win::SetClsidForPropertyStore(struct IPropertyStore *,struct _tagpropertykey const &,struct _GUID const &)" (?SetClsidForPropertyStore@win@base@@YA_NPAUIPropertyStore@@ABU_tagpropertykey@@ABU_GUID@@@Z) 中引用了该符号

引入:Propsys.lib

参考:文档

问题11:error Link2019 无法解析的外部符号

代码语言:shell
复制
1>launch_win.obj : error LNK2019: 无法解析的外部符号 _CreateEnvironmentBlock@12,函数 "class base::Process __cdecl base::LaunchProcess(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,struct base::LaunchOptions const &)" (?LaunchProcess@base@@YA?AVProcess@1@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABULaunchOptions@1@@Z) 中引用了该符号
1>launch_win.obj : error LNK2019: 无法解析的外部符号 _DestroyEnvironmentBlock@4,函数 "class base::Process __cdecl base::LaunchProcess(class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > const &,struct base::LaunchOptions const &)" (?LaunchProcess@base@@YA?AVProcess@1@ABV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@ABULaunchOptions@1@@Z) 中引用了该符号

参考:文档

问题12:error Link2019 无法解析的外部符号

代码语言:shell
复制
1>native_unwinder_win.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall base::Win32StackFrameUnwinder::Win32StackFrameUnwinder(void)" (??0Win32StackFrameUnwinder@base@@QAE@XZ),函数 "public: virtual enum base::UnwindResult __thiscall base::NativeUnwinderWin::TryUnwind(struct _CONTEXT *,unsigned int,class base::ModuleCache *,class std::vector<struct base::Frame,class std::allocator<struct base::Frame> > *)const " (?TryUnwind@NativeUnwinderWin@base@@UBE?AW4UnwindResult@2@PAU_CONTEXT@@IPAVModuleCache@2@PAV?$vector@UFrame@base@@V?$allocator@UFrame@base@@@std@@@std@@@Z) 中引用了该符号
1>native_unwinder_win.obj : error LNK2019: 无法解析的外部符号 "public: __thiscall base::Win32StackFrameUnwinder::~Win32StackFrameUnwinder(void)" (??1Win32StackFrameUnwinder@base@@QAE@XZ),函数 "public: virtual enum base::UnwindResult __thiscall base::NativeUnwinderWin::TryUnwind(struct _CONTEXT *,unsigned int,class base::ModuleCache *,class std::vector<struct base::Frame,class std::allocator<struct base::Frame> > *)const " (?TryUnwind@NativeUnwinderWin@base@@UBE?AW4UnwindResult@2@PAU_CONTEXT@@IPAVModuleCache@2@PAV?$vector@UFrame@base@@V?$allocator@UFrame@base@@@std@@@std@@@Z) 中引用了该符号
1>native_unwinder_win.obj : error LNK2019: 无法解析的外部符号 "public: bool __thiscall base::Win32StackFrameUnwinder::TryUnwind(bool,struct _CONTEXT *,class base::ModuleCache::Module const *)" (?TryUnwind@Win32StackFrameUnwinder@base@@QAE_N_NPAU_CONTEXT@@PBVModule@ModuleCache@2@@Z),函数 "public: virtual enum base::UnwindResult __thiscall base::NativeUnwinderWin::TryUnwind(struct _CONTEXT *,unsigned int,class base::ModuleCache *,class std::vector<struct base::Frame,class std::allocator<struct base::Frame> > *)const " (?TryUnwind@NativeUnwinderWin@base@@UBE?AW4UnwindResult@2@PAU_CONTEXT@@IPAVModuleCache@2@PAV?$vector@UFrame@base@@V?$allocator@UFrame@base@@@std@@@std@@@Z) 中引用了该符号

一般是因为文件缺失导致,搜索文件目录下所有代码,找到对应定义的文件补上即可

代码语言:c++
复制
base::Win32StackFrameUnwinder

D:\Code\chromium_base\src\base\profiler\win32_stack_frame_unwinder.cc

问题13:error Link2019 无法解析的外部符号

错误如下:

代码语言:shell
复制
1>md5_boringssl.obj : error LNK2019: 无法解析的外部符号 __imp__MD5_Init,函数 "void __cdecl base::MD5Init(struct md5_state_st *)" (?MD5Init@base@@YAXPAUmd5_state_st@@@Z) 中引用了该符号
1>md5_boringssl.obj : error LNK2019: 无法解析的外部符号 __imp__MD5_Update,函数 "void __cdecl base::MD5Update(struct md5_state_st *,class base::BasicStringPiece<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > const &)" (?MD5Update@base@@YAXPAUmd5_state_st@@ABV?$BasicStringPiece@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@1@@Z) 中引用了该符号
1>md5_boringssl.obj : error LNK2019: 无法解析的外部符号 __imp__MD5_Final,函数 "void __cdecl base::MD5Final(struct base::MD5Digest *,struct md5_state_st *)" (?MD5Final@base@@YAXPAUMD5Digest@1@PAUmd5_state_st@@@Z) 中引用了该符号
1>md5_boringssl.obj : error LNK2019: 无法解析的外部符号 __imp__MD5,函数 "void __cdecl base::MD5Sum(void const *,unsigned int,struct base::MD5Digest *)" (?MD5Sum@base@@YAXPBXIPAUMD5Digest@1@@Z) 中引用了该符号

查看定义发现:

代码语言:c++
复制
#if defined(BORINGSSL_IMPLEMENTATION)
#define OPENSSL_EXPORT __declspec(dllexport)
#else
#define OPENSSL_EXPORT __declspec(dllimport)
#endif

实际函数定义在D:\Code\CoreP\src\third_party\boringssl\src\crypto\fipsmodule\md5\md5.c

也就是在boringssl的项目中,需要boringssl.lib

在boringssl项目中直接引入ssl.libcrypto.lib。然后在Base项目引入boringssl.lib即可

问题14:无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > * logging::g_swallow_stream" (?g_swallow_stream@logging@@3PAV?$basic_ostream@DU?$char_traits@D@std@@@std@@A)

调整优化级别,将禁用优化调整最大优化(/O2)即可

注意关闭全程序优化

问题14:LNK2001 无法解析的外部符号 "public: static void __cdecl base::internal::BindStateBaseRefCountTraits::Destruct(class base::internal::BindStateBase const *)" (?Destruct@BindStateBaseRefCountTraits@internal@base@@SAXPBVBindStateBase@23@@Z)

解决如下:

代码语言:c++
复制
// D:\Code\CorP_Base\src\Chromium\Base\callback_internal.h
struct BindStateBaseRefCountTraits {
  static void Destruct(const BindStateBase*);
};

改为

struct BindStateBaseRefCountTraits {   
  BASE_EXPORT static void Destruct(const BindStateBase*);
};

结语

读到这里,给大家点个赞,基本上提取一个开源库的功能模块都是大致的流程,最终成果在这里,感兴趣的看官可以自行下载进行学习哈,码字不易求个赞,谢谢。

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 编译问题
    • 问题1:D:\Code\chromium_msvc\src\out\Default\obj\base\base.vcxproj : error  : 无法加载具有重复项目项的项目: ../../../../base/task/promise/promise.h 作为 None 且作为 None 项类型包括在其中。
      • 问题2:调试等级不符合导致链接失败
        • 问题3:C2712 无法在要求对象展开的函数中使用__try
          • 问题4:收缩转换无效
            • 问题5:TraceArguments参数错误
              • 后续跟进
            • 问题6:尝试引用已删除的函数
              • 问题7:C2338 enumerator must define kMaxValue enumerator to use this macro!
                • 问题8:error C2280: “std::unique_ptr<base::ModuleCache::Module,std::default_delete<base::ModuleCache::Module>> &std::unique_ptr<base::ModuleCache::Module,std::default_delete<base::ModuleCache::Module>>::operator =(const  std::unique_ptr<base::ModuleCache::Module,std::default_delete<base::ModuleCache::Module>> &)”: 尝试引用已删除的函数
                  • 问题9:C2280 “base::internal::DecoratorWithTaskSource<base::internal::TaskSource::Transaction,T>::DecoratorWithTaskSource(void)”: 尝试引用已删除的函数
                    • 问题10:base\win\embedded_i18n\language_selector.cc(280,3): error C2397: 从“int”转换到“size_t”需要收缩转换
                    • 链接问题
                      • 问题1:error LNK2038: 检测到“_ITERATOR_DEBUG_LEVEL”的不匹配项: 值“0”不匹配值“2”(modp_b64.obj 中)
                        • 问题2:Base.lib(message_window.obj) : error LNK2019: 无法解析的外部符号 impUnregisterClassW@8,函数 "public: __thiscall base::win::MessageWindow::WindowClass::~WindowClass(void)" (??1WindowClass@MessageWindow@win@base@@QAE@XZ) 中引用了该符号
                          • 问题3:error LNK2019: 无法解析的外部符号
                            • 问题4:error Link2019 无法解析的外部符号
                              • 问题5:error Link2019 无法解析的外部符号
                                • 问题6:error Link2019 无法解析的外部符号
                                  • 问题7:error Link2019 无法解析的外部符号
                                    • 下载环境准备
                                  • 问题8:error Link2019 无法解析的外部符号
                                    • 问题9:error Link2019 无法解析的外部符号
                                      • 问题10:error Link2019 无法解析的外部符号
                                        • 问题11:error Link2019 无法解析的外部符号
                                          • 问题12:error Link2019 无法解析的外部符号
                                            • 问题13:error Link2019 无法解析的外部符号
                                              • 问题14:无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > * logging::g_swallow_stream" (?g_swallow_stream@logging@@3PAV?$basic_ostream@DU?$char_traits@D@std@@@std@@A)
                                                • 问题14:LNK2001 无法解析的外部符号 "public: static void __cdecl base::internal::BindStateBaseRefCountTraits::Destruct(class base::internal::BindStateBase const *)" (?Destruct@BindStateBaseRefCountTraits@internal@base@@SAXPBVBindStateBase@23@@Z)
                                                • 结语
                                                领券
                                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档