我有一个包含 2 个项目的解决方案:
我正在观看并关注 Cherno 的 游戏引擎系列,除了我使用的是 C++20 模块。他通过 spdlog
添加了
git submodule add
。我做了同样的事情。然后我将 $(SolutionDir)Almond\vendor\spdlog\include
添加到 Almond 项目中的 Additional Include Directories
。
该库构建良好(带有来自
sal.h
的一堆宏重新定义警告)。当我尝试构建沙盒时,我没有收到任何警告,只有这些错误:
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(杏仁):
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%$");
// Create multithreaded loggers
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(杏仁):
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(沙盒):
import Almond;
class Sandbox : public Almond::Application {
public:
Sandbox() {}
~Sandbox() {}
};
Almond::Application* Almond::CreateApplication() {
return new Sandbox();
}
使用该静态库的项目
该项目是否编译为共享(DLL)或静态(.lib)库? 我假设您将可执行文件与“使用该静态库的项目”链接。如果是这样,您需要从该项目中启用符号可见性。
我不使用 VS,但 CMake 可以通过 GenerateExportHeader 非常优雅地处理这个问题。您需要将
__decl(dllexport)
和 __decl(dllimport)
添加到您的类中或将所有符号可见性公开。
Windows 默认将所有符号设为私有,而 UNIX 变体默认将它们设为公开。
我不确定它是否完全相同的问题,但为了解决 __imp_MapViewOfFileNuma2 的链接问题,我必须将 Onecore.lib 和 Onecoreuap.lib 添加到项目设置 -> 链接器 -> 输入 -> 附加依赖项( https:// learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-mapviewoffilenuma2)