查看 g++ 生成的虚函数表

需求 为了了解父子类对于虚函数表的影响,需要查看编译器生成的虚函数表。 解决 生成包含虚函数表的文件。 # g++ 8 之前 g++ -fdump-class-hierarchy vptr.cpp # g++ 8 之后 g++ -fdump-lang-class vptr.cpp 编译后,后产生一个 *.class 的文件,查看这个文件就可以看到子类的虚函数表了。 参考 c++ 查看对象内存布局 C/C++杂记:深入虚表结构 从编译器的辅助信息看c++对象内存布局 C++在gcc下的单继承,多继承,虚继承的内存布局 如何查看c++的虚函数表 C++知识积累:如何获取虚函数表以及虚函数地址

2023-04-19 · 1 min · 29 words · RamLife

gn 使用细节

需求 在项目中使用 gn 时,会有很多各种各样的构建需求,本文是记录这些细节的实现方法。 解决 静态库 需求: 项目文件夹为 project, 静态库源文件目录为 project/protocol 静态库源文件分为两个文件, a.cpp, b.cpp 静态库名为 proto 解决: 在静态库目录下新建 BUILD.gn, 内容如下: static_library("proto") { sources = [ "a.cpp", "b.cpp", ] } 注意: 库名称 在项目目录下的 BUILD.gn, 新增内容如下: executable("test") { ... deps = [ "//protocol:proto", ] ... } *注意: 冒号前面是文件夹路径,冒号后面是 BUILD.gn 文件中的标识, 如果标识和文件夹名称一致,可以省略冒号及后面的部分。比如,文件夹是 abc, 生成的库也是 abc, 那么依赖这个地方可以直接写成 //abc 即可 * 参考 using gn build

2023-03-15 · 1 min · 60 words · RamLife

gn 和 ninja 编译 hello world

需求 在 gn, ninja 的开发环境下,实现 hello world 的编译,用以摸清最简单用法。 解决 gn 文件准备 gn 相关的文件可以从 simple_build 这个例子里面复制,总共需要复制以下几个文件: .gn 这个文件是隐藏文件,很容易漏掉,并且是 gn 执行时最先寻找的文件。这个文件所在的位置就是项目源码的 root 位置。其中的内容就是简单的指定项目的构建 config 具体是那一个。例子中指定的是 build/BUILDCONFIG.gn. build/BUILDCONFIG.gn, build/BUILD.gn 这两个是针对项目的一些设置包括不同操作系统的设置。 build/toolchain/BUILD.gn 这个是针对工具链的一些设置。 BUILD.gn 这个才是我们一般进行配置的文件,主要是配置需要编译的文件,库,最终的可执行文件等等。注意,不能使用 tab, 只能使用 space. 编译 使用 gn 生成 ninja 编译脚本。下面这条命令会在 out 目录下生成 test 目录,并且生成的 ninja 脚本也放在这个文件夹里面。 gn gen out/test 使用 ninja 正式编译。生成的编译文件和最终文件都放在相应的文件夹里面。 ninja -C out/test/ 运行和查看 直接运行 out/test 目录下的 hello 就可以执行了。 可以使用 gn desc 来查看相关信息. gn desc out/test "//:hello" 参考 GN使用笔记...

2023-03-08 · 1 min · 90 words · RamLife

ubuntu 20.04 安装 gn 和 ninja

需求 需要在 ubuntu 20.04 LTS 上面安装 gn + ninja 的构建环境,用于后续的开发。 解决 安装 ninja ninja 安装非常简单,ubuntu 源当中就有: sudo apt install ninja-build 安装 clang clang 用于 gn 的编译,ubuntu 源当中也有: sudo apt install clang 安装 gn gn 的安装有两种方法: 二进制文件: https://gn.googlesource.com/gn/+/refs/heads/main 这个网页上面可以找到 linux, win, mac 三个下载地址。 源码安装,本文主要介绍源码安装过程。 下载源码 官方源: https://gn.googlesource.com/gn Github: https://github.com/timniederhausen/gn Gitee: https://gitee.com/openharmony/third_party_gn 注意: 直接下载源码 python 那一步过不去,只有 git 拉下来的才可以。 这三个源,时效性是 官方 > github > gitee. 官方源是肯定需要科学才能拉下来的。 如果使用官方源: git clone https://gn.googlesource.com/gn 编译源码 编译前使用 python 检查,编译使用 clang....

2023-03-08 · 1 min · 159 words · RamLife

[转] C++ 或 QT 判断当前模式是Debug还是Release模式

需求 在构建版本的时候,需要在 debug 和 release 版本中有不一样的地方,这时候就需要使用宏来自动识别并展开对应的语句。 解决 C++ #ifdef DEBUG cout << "Debug!" << endl; #else cout << "Release!" << endl; #endif Qt #ifdef QT_DEBUG cout << "Debug!" << endl; #else cout << "Release!" << endl; #endif 参考 C++ 或 QT 判断当前模式是Debug还是Release模式

2023-03-06 · 1 min · 42 words · RamLife

syslog 使用及宏

需求 syslog 虽然使用起来很方便,但是直接使用有几个问题: 虽然有日志信息,但是不够全面不方便定位 那么多的日志都混在一起,没有重点,调试时不方便 debug 和 release 时,日志应该不一样。 解决 日志信息更丰富 syslog 可以使用 __FILE__, __LINE__, __FUNCTION, 这几个来标识出当前的日志是在那个文件,第几行,哪个函数输出的。 syslog(LOG_DEBUG, "%s: %d: %s --> class construct", __FILE__, __LINE__, __FUNCTION__); 使用宏来开关日志 下面这个是普通替代的宏,可以用于开关日志. #ifdef xxx #define LOG(priority, format, ...) syslog(priority, format, ## __VA_ARGS__) #else #define LOG(priority, format, ...) #endif 使用宏来减少输入 但是每条日志都要这样写,就太麻烦了,我们可以使用宏来解决这个问题: #define LOG(priority, format, ...) syslog(priority, "%s: %d: %s --> "#format, __FILE__, __LINE__, __FUNCTION__, ## __VA_ARGS__) LOG(LOG_DEBUG, "class construct"); 上面这条宏,我们在使用时,不需要显式的写出相关的参数,宏展开的时候,会自动帮我们加上这些参数,日志会包含文件名,行号,函数名. 使用宏增加日志等级 当多条日志信息在一起的时候,比较难抓住重点,虽然可以使用搜索,但是终归没有那么方便。我们可以通过宏给日志消息里面附上对应的等级,也方便后期维护时使用脚本进行解析。 #define LOG(priority, format, ....

2023-03-06 · 2 min · 223 words · RamLife