You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 18:30:41