我有一个简单的项目,需要三个只有头的库才能编译:websocketpp,spdlog和nlohmann/json.
项目结构如下所示:
??? src
??? app
? ??? CMakeLists.txt
? ??? src
? ??? test
??? CMakeLists.txt
??? core
? ??? CMakeLists.txt
? ??? include
? ??? src
? ??? test
??? vendor
??? install.cmake
??? nlohmann_json
??? spdlog
??? websocketpp
Run Code Online (Sandbox Code Playgroud)
根CMakeLists.txt如下:
cmake_minimum_required(VERSION 3.6.1 FATAL_ERROR)
..
# External 3rd party libs that we include
include(vendor/install.cmake)
add_subdirectory(core)
add_subdirectory(app)
Run Code Online (Sandbox Code Playgroud)
这个想法基本上是每个子目录都是一个库(例如core
),并app
"聚合"所有子目录.每个库(例如core
)都是这样构建的(core/CMakeLists.txt
):
project(foo-core VERSION 0.1 LANGUAGES CXX)
add_library(foo-core
src/foobar/foobar.cc
src/foobaz/baz.cc) …
Run Code Online (Sandbox Code Playgroud) 使用格式化时有没有办法扩展spdlog
以支持自定义结构作为项目{}
?
所以当我有一个
struct p {
int x;
int y;
int z;
};
p my_p;
Run Code Online (Sandbox Code Playgroud)
我想要做
spdlog::info("p = {}", my_p);
// after registering some kind of formatter object for {p}
Run Code Online (Sandbox Code Playgroud)
代替
spdlog::info("p = (x={}, y={}, z={})", my_p.x, my_p.y, my_p.z);
Run Code Online (Sandbox Code Playgroud) 我想将spdlog包含到我的项目之一中。它是一个只有标头的库。我正在构建的项目正在使用 cmake。目前我正在使用
include_directories('src/logger/spdlog/')
Run Code Online (Sandbox Code Playgroud)
在 cmake 中并将库包含为
#include <spdlog/spdlog.h>
Run Code Online (Sandbox Code Playgroud)
在记录器文件夹内的logs.h中。我收到致命错误,没有这样的文件或目录。在我的应用程序中包含相同库的正确方法是什么?
我正在开发一个使用两个不同库的C++项目:spdlog用于日志记录,mutils-serialization用于将对象序列化为字节(用于通过网络发送).两个库都正确使用命名空间,但是当我尝试编写同时使用它们的程序时,我的编译器(g ++ 6.2)给了我无意义的错误,这些错误似乎表明它试图从spdlog库中实例化一个函数模板通过使用mutils库中的函数模板的定义.
这是我的简单测试程序:
#include <spdlog/spdlog.h>
#include <spdlog/fmt/ostr.h>
#include "TestSerializableObject.h"
int main(int argc, char** argv) {
auto global_logger = spdlog::rotating_logger_mt("global_logger", "log", 1024 * 1024 * 500, 3);
global_logger->set_pattern("[%H:%M:%S.%e] [%l] %v");
global_logger->set_level(spdlog::level::trace);
std::shared_ptr<spdlog::logger> logger(spdlog::get("global_logger"));
auto message = std::make_shared<messaging::TestSerializableObject>(
1, 2, "A message!");
logger->trace("Received a message: {}", *message);
}
Run Code Online (Sandbox Code Playgroud)
TestSerializableObject
是一个实现的简单类mutils::ByteRepresentable
(启用序列化和拉入mutils-serialization库的接口),并提供operator<<
(spdlog能够记录它所需的).如有必要,我可以发布代码.
当我编译它时g++ -std=c++14 -I"./src" -I"./libraries" -I"./libraries/mutils/" -L"./libraries/" -O0 -g3 -Wall "src/LibraryCollisionTest.cpp"
,我得到了这个冗长,丑陋的错误(别担心,我会帮你解析它):
In file included from ./libraries/mutils/mutils.hpp:3:0,
from ./libraries/mutils-serialization/SerializationSupport.hpp:2,
from src/TestSerializableObject.h:10, …
Run Code Online (Sandbox Code Playgroud) 我正在我的应用程序中创建 C++ 库模块。要进行日志记录,我使用spdlog。但是在生产环境中,我不希望我的 lib 模块进行任何日志记录。实现打开/关闭的一种方法是用#ifdef 条件乱扔我的代码,例如...
#ifdef logging
// call the logger here.
#endif
Run Code Online (Sandbox Code Playgroud)
我正在寻找一种方法来避免编写这些条件。可能是一个包装函数,它执行#ifdef 检查并编写它。但是这种方法的问题是我必须为每个日志记录方法(例如信息、跟踪、警告、错误等)编写包装器
有没有更好的办法?
我需要在某些代码之前关闭 spdlog 级别,然后将其返回到之前的值。
如何在关闭之前获得当前级别?
我正在尝试使用 stb_image.h 加载图像,但在 gcc 提供的 <emmintrin.h> 版本中遇到两个编译器错误。我认为可能需要一个编译器选项,但我一直无法找到它是什么。
错误代码:
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/emmintrin.h:1230:10: error: the last argument must be an 8-bit immediate
1230 | return (__m128i)__builtin_ia32_pslldqi128 (__A, __N * 8);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/11.1.0/include/emmintrin.h:1224:10: error: the last argument must be an 8-bit immediate
1224 | return (__m128i)__builtin_ia32_psrldqi128 (__A, __N * 8);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
<emmintrin.h> 中的相关代码:
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_srli_si128 (__m128i __A, const int __N)
{
return (__m128i)__builtin_ia32_psrldqi128 (__A, __N * 8);
}
extern __inline __m128i __attribute__((__gnu_inline__, __always_inline__, __artificial__))
_mm_slli_si128 (__m128i __A, const …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用spdlog
. 我将其合并到我的代码中,但现在出现以下错误:
....fmt\core.h(1016): error C2338: Cannot format argument. To make type T formattable provide a formatter<T> specialization: https://fmt.dev/latest/api.html#formatting-user-defined-types
....fmt/core.h(1013): note: while compiling class template member function 'int fmt::v6::internal::arg_mapper<Context>::map(...)'
with
[
Context=context
]
....fmt/core.h(1213): note: see reference to function template instantiation 'int fmt::v6::internal::arg_mapper<Context>::map(...)' being compiled
with
[
Context=context
]
....fmt/core.h(1027): note: see reference to class template instantiation 'fmt::v6::internal::arg_mapper<Context>' being compiled
with
[
Context=context
]
....fmt/core.h(1198): note: see reference to alias template instantiation 'fmt::v6::internal::mapped_type_constant<int,context>' being compiled
....fmt/core.h(1342): note: see reference …
Run Code Online (Sandbox Code Playgroud) 我使用 spdlog 在 Visual Studio 中运行托管和非托管代码的日志。出于这个原因,我编写了在底层使用 spdlog 的 shell 类。
但是,我的单元测试遇到了问题。我的单元测试在单个可执行文件中运行,因此我需要多次停止并重新启动 spdlog 记录器和日志文件。
我该怎么做呢?我在类中使用此代码当前启动 Windows DLL 中的 spdlog 实例:
private:
API static std::mutex _mutex;
API static std::shared_ptr<spdlog::logger> _instance;
static std::shared_ptr<spdlog::logger> Instance()
{
std::unique_lock<std::mutex> lck(_mutex, std::defer_lock);
lck.lock();
if (_instance == nullptr)
{
_instance = spdlog::rotating_logger_mt("Logger", "EXO", 1024 * 1024 * 5, 4, true);
}
lck.unlock();
return _instance;
}
Run Code Online (Sandbox Code Playgroud) 我需要引用spdlog 1.7.0 revision 1eebff2f51d90cb700b63c6d2449ebcb,而不是最新版本,但我似乎无法做到这一点。指定修订版本需要user/channel#REV 语法,但 conan index 上的食谱似乎没有 user/channel。
如何引用 conan-index 的特定修订版?