本篇文章主要记录如何从Chromium中提取Base库,方便后续的学习和使用,同时抛砖引玉,希望带给各位一些启发和帮助。
先上提取后的开源代码,可以开箱即用:Github
本次提取基于Tag=77.0.3865.129,也就是77大版本的最后一个子版本,发布时间为2019年10月18日。
文章较长,分上、下两篇,上篇主要讲解如何做,下篇主要讲解问题及解决,大家喜欢可以点点赞。
本篇较为枯燥,整体流程可以先从上篇了解后,遇到问题来本篇进行查阅。
找到对应的base.vcxproj,右键编辑找到重复行,删除一行即可
autoninja -C out\Default base
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
检查是否Debug/Release以及MT/MD匹配,如果都匹配的话只能用下面方法:
可以尝试指定调试等级来规避此错误
_ITERATOR_DEBUG_LEVEL=0;
调整源码如下
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();
}
问题文件:D:\Code\CoreP\src\Chromium\base\win\windows_version.cc
错误提示:从 "int" 到 "unsigned int" 进行收缩转换无效
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)});
1>D:\Code\chromium_base\src\base\trace_event\trace_event.h(737,41): error C2661: “base::trace_event::TraceArguments::TraceArguments”: 没有重载函数接受 2 个参数
暂时不需要Trace,可以直接置空(怀疑是模板参数没有对上)
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错误提示发现无法匹配模板
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
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::vector
和std::atomic
不能同时使用,因为atomic的定义
template <class _Ty> struct atomic : _Choose_atomic_base_t<_Ty> {
// atomic value
atomic(const atomic&) = delete;
atomic& operator=(const atomic&) = delete;
}
而std::vector
要求必须要有拷贝构造函数,导致冲突
修复问题:
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
问题文件:D:\Code\CoreP\src\Chromium\base\metrics\histogram_macros_internal.h
问题片段:
解决:注释static_assert
问题文件:D:\Code\CoreP\src\Chromium\base\sampling_heap_profiler\module_cache.cc
编译文件frame.cc出现问题,
// 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_
可以看到依赖文件:
#include "base/sampling_heap_profiler/module_cache.h"
检查发现
// 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复用,但是源码有以下函数
// 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删去了右值拷贝函数
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这个函数
// 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;
}
问题文件:D:\Code\CoreP\src\Chromium\base\task\thread_pool\task_source.h
涉及的类代码比较简单:
// 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);
展开为
// 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的定义,可以得到出错的结构体为
using TransactionWithRegisteredTaskSource = BasicTransactionWithTaskSource<RegisteredTaskSource>;
针对结构体TransactionWithRegisteredTaskSource
,pooled_single_thread_task_runner_manager.cc
中仅三处相关
// 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;
}
初步估计是调用函数导致拷贝引起的错误,注释这三处即可成功编译通过,进一步确认了问题所在
解决方案:正常移动语义进行函数调用不会触发拷贝构造,但是这个
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)
构造函数却调用到:
DecoratorWithTaskSource(std::nullptr_t) : DecoratorWithTaskSource() {}
出现错误,这里需要注释这个函数,同时会引发所有retrue nullptr的伴生错误
将所有的return nullptr修改为return {}即可
最终Class为:
// 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);
};
问题代码调整为:
DCHECK_EQ(size_t{static_cast<size_t>(*selected_offset)}, languages_to_offset.size());
modp_b64.lib与base.dll不匹配,这里在项目添加预处理宏定义即可解决
_ITERATOR_DEBUG_LEVEL=0;
回到初始生成的all.sln``D:\Code\chromium_base\src\out\Default\all.sln
打开可以发现,base库依赖基本上都在sln都会有说明
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
列表如下:
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
文件,里面会有详细的第三方库依赖
# Windows.
if (is_win) {
libs += [
"cfgmgr32.lib",
"powrprof.lib",
"propsys.lib",
"setupapi.lib",
"userenv.lib",
"wbemuuid.lib",
"winmm.lib",
]
}
部分错误如下:
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均消除
部分错误如下:
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
部分错误如下:
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
部分错误如下:
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
源码地址:地址
官方编译教程:教程
【版本3.23.2.0】:CMake - Upgrade Your Software Build System
参考:boringssl/BUILDING.md at chromium-3945 · google/boringssl (github.com)
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.
否则会报错
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
C:\Users\Leal>perl -v
This is perl 5, version 38, subversion 0 (v5.38.0) built for MSWin32-x64-multi-thread
报错:
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.
参考:链接
找到*\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 : 将上面下载的模块都配置一下系统环境变量
D:\Software\Strawberry\perl\bin;D:\Software\Strawberry\perl\site\bin;D:\Software\Go\bin;D:\Software\NASM
点击Configure
提示如下则配置成功,继续生成
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
错误如下:
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,引入即可
1>wmi.obj : error LNK2001: 无法解析的外部符号 _CLSID_WbemLocator
引入静态lib:wbemuuid.lib
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
参考:文档
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) 中引用了该符号
参考:文档
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) 中引用了该符号
一般是因为文件缺失导致,搜索文件目录下所有代码,找到对应定义的文件补上即可
base::Win32StackFrameUnwinder
D:\Code\chromium_base\src\base\profiler\win32_stack_frame_unwinder.cc
错误如下:
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) 中引用了该符号
查看定义发现:
#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.lib
和crypto.lib
。然后在Base项目引入boringssl.lib
即可
调整优化级别,将禁用优化调整最大优化(/O2)即可
注意关闭全程序优化
解决如下:
// 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*);
};
读到这里,给大家点个赞,基本上提取一个开源库的功能模块都是大致的流程,最终成果在这里,感兴趣的看官可以自行下载进行学习哈,码字不易求个赞,谢谢。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。