使用Git子模块时遇未解析外部符号问题(C++20模块)
C++20模块下静态库链接spdlog的未解析外部符号问题
问题背景
- 解决方案包含两个项目:静态库项目
Almond、依赖该静态库的Sandbox项目 - 跟随The Cherno的《Game Engine Series》教程开发,使用C++20模块,通过
git submodule add引入spdlog,已将$(SolutionDir)Almond\vendor\spdlog\include添加到Almond项目的附加包含目录 Almond库编译正常(仅存在sal.h宏重定义警告),但Sandbox编译时出现链接错误
链接错误信息
Severity Code Description Project File Line Suppression State Error LNK1120 4 unresolved externals Sandbox C:\source\Almond\bin\Debug-x64\Sandbox\Sandbox.exe 1 Error LNK2019 unresolved external symbol __imp_MapViewOfFileNuma2 referenced in function MapViewOfFile2 Sandbox C:\source\Almond\Sandbox\Almond.lib(stdout_color_sinks.h_D07BG2BYL2KQ67JA.obj) 1 Error LNK2001 unresolved external symbol __imp_MapViewOfFileNuma2 Sandbox C:\source\Almond\Sandbox\Almond.lib(spdlog.h_UEKL7NPFP4GR8605.obj) 1 Error LNK2001 unresolved external symbol "private: static class std::shared_ptr<class spdlog::logger> Almond::Log::s_CoreLogger" (?s_CoreLogger@Log@Almond@@0V?$shared_ptr@Vlogger@spdlog@@@std@@A::<!Log>) Sandbox C:\source\Almond\Sandbox\Almond.lib(Log.ixx.obj) 1 Error LNK2001 unresolved external symbol "private: static class std::shared_ptr<class spdlog::logger> Almond::Log::s_ClientLogger" (?s_ClientLogger@Log@Almond@@0V?$shared_ptr@Vlogger@spdlog@@@std@@A::<!Log>) Sandbox C:\source\Almond\Sandbox\Almond.lib(Log.ixx.obj) 1 Error LNK2001 unresolved external symbol "char const * const spdlog::details::os::default_eol" (?default_eol@os@details@spdlog@@3QEBDEB) Sandbox C:\source\Almond\Sandbox\Almond.lib(Log.ixx.obj) 1
相关代码
Log.ixx(Almond项目)
export module Log; import <memory>; import <spdlog/spdlog.h>; import <spdlog/sinks/stdout_color_sinks.h>; export namespace Almond { class Log { private: static std::shared_ptr<spdlog::logger> s_CoreLogger; static std::shared_ptr<spdlog::logger> s_ClientLogger; public: static void Init() { spdlog::set_pattern("%^[%T] %n: %v%$"); // 创建多线程日志器 s_CoreLogger = spdlog::stdout_color_mt("ALMOND", spdlog::color_mode::always); s_CoreLogger->set_level(spdlog::level::trace); s_ClientLogger = spdlog::stdout_color_mt("APP", spdlog::color_mode::always); s_ClientLogger->set_level(spdlog::level::trace); } inline static std::shared_ptr<spdlog::logger>& GetCoreLogger() { return s_CoreLogger; } inline static std::shared_ptr<spdlog::logger>& GetClientLogger() { return s_ClientLogger; } }; }
EntryPoint.ixx(Almond项目)
export module EntryPoint; import Application; import Log; #ifdef ALMOND_PLATFORM_WINDOWS export int main(int argc, char** argv) { Almond::Log::Init(); auto app = Almond::CreateApplication(); app->Run(); delete app; } #endif
Main.cpp(Sandbox项目)
import Almond; class Sandbox : public Almond::Application { public: Sandbox() {} ~Sandbox() {} }; Almond::Application* Almond::CreateApplication() { return new Sandbox(); }
问题分析与解决建议
1. 静态成员变量未定义
Log类中的s_CoreLogger和s_ClientLogger仅在类内声明,未提供定义。需在Log.ixx中添加静态成员的定义,放在类外部、命名空间内:
export module Log; // 原有代码... namespace Almond { std::shared_ptr<spdlog::logger> Log::s_CoreLogger; std::shared_ptr<spdlog::logger> Log::s_ClientLogger; }
2. Windows API符号缺失
__imp_MapViewOfFileNuma2是Windows内核API,需链接kernel32.lib:
- 方案一:在
Almond项目的链接器 -> 输入 -> 附加依赖项中添加kernel32.lib - 方案二:在
Log.ixx开头添加编译指令:#pragma comment(lib, "kernel32.lib")
3. spdlog实现未编译进静态库
spdlog::details::os::default_eol未找到,是因为spdlog的源文件未被编译到Almond库中:
- 将spdlog源码目录(
vendor/spdlog/src)下的所有.cpp文件添加到Almond项目中,一起编译 - 或单独编译spdlog为静态库,再在
Almond和Sandbox项目的链接器中添加spdlog库的引用
4. C++20模块链接检查
确保Sandbox项目已正确添加Almond为依赖项,且Visual Studio中模块的导入/导出设置正确,Almond生成的.lib文件被Sandbox链接。
内容的提问来源于stack exchange,提问作者NaniNoni
相关产品推荐
相关产品推荐

