背景知识

由于学校老师要求分析一个开源C++项目,推荐了Google 的 glog,看了一下发现还不错,所以趁此机会学一下 glog的使用。克服了多种困难之后,打算写写博客记录一下其中“艰辛的过程”。

Google Glog是Google的一个开源库,用于实现应用级别的logging。 它提供了一系列类似于C++流风格的logging API,以及一些预定义的宏。它有点类似于C里面的assert,但是比它具备更丰富的输出信息以及使用灵活性。出处

实验环境

Windows10 20H2,
VS Code 1.63.2,
WSL 2 环境的Ubuntu20.04

实验细节

1. 软件包的下载

在Windows的Ubuntu子系统(wsl)中,确认git可以使用,然后从Github克隆 glog 项目代码

git clone https://github.com/google/glog.git

在主机的VS Code中安装Remote - WSL插件, 目的是在主机的VS Code中打开WSL中的文件夹,便于写代码测试

2. 构建环境的准备

为了构建如此“大型”的C++项目,我们需要使用构建工具,本次实验使用cmake。在wsl中安装cmake使用一行命令即可完成:

sudo apt install cmake

同样地,安装 C++的编译器。听说VSCode中有一个C++语言的支持插件 clangd 比较有名,所以打算在本次实验搭建基于clang的开发环境,调试器也选择了选择lldb。使用gcc作为编译器当然也可以。
在wsl的终端输入软件名 --version并回车,如果没有安装过,系统会提示你安装的。例如:

$ g++ --version

Command 'g++' not found, but can be installed with:

sudo apt install g++

Ubuntu 的软件安装过程简单,不再赘述.

VS Code的插件安装也比较简单,我安装的有:CMake, CMake Tools, clangd, CodeLLDB以及简体中文包

关于WSL下开发环境的搭建,可以看这个B站视频: 使用 VS Code + Clangd + CMake 搭建 C/C++开发环境

3. 构建 glog 并安装至系统中

我们需要了解一些关于使用cmake构建的知识。不懂的话,可以看这个: 软件构建: CMake 快速入门

下面就是照着 glogREADME文档 操作了
使用 cd 命令进入glog的文件夹下,再进行 cmake 的经典 configure 操作:

cd glog
cmake -S . -B build -G "Unix Makefiles"

Tips: 其实涉及到 cmake 的操作也可以使用 VS Code 的 CMake 插件来完成

仍旧照着文档来,这一步是真正生成 glog 的二进制文件

cmake --build build

文档给出了两个可选步骤,一是测试构建出的软件,二是将构建好的软件安装到系统中(这样以后用着更方便)

cmake --build build --target test
cmake --build build --target install

注意:安装时可能会遇到权限的问题,只要在命令前面加 sudo 就好了。
一般而言,开源软件包在系统中的安装位置是: /usr/local/...
其下的 lib目录是存放库文件(library)的,include目录是存放头文件的。

一个简单的理解:头文件里是函数的定义,库文件里是函数的实现(二进制形式,不易破解)

对于使用动态链接得到的程序,在运行时必须能找到动态链接库(Linux下是 libXXX.so文件,so后面也可以有软件的版本号,Windows则是XXX.dll文件)。对于使用静态链接得到的程序,则不需要依赖动态链接库(Linux下的.a文件 和 Windows 下的 .lib文件属于静态链接库文件)

详细的知识自己去看吧: 库、动态库和静态库(.dll,.so,.lib,.a)

4. 在自己的代码中使用 glog

终于要使用 glog 啦!它的使用方法在 README 里写得很好,建议看Github上的最新版(虽然是英文的)
当然,中文译文也可以方便搜到:Glog官方文档翻译

在 wsl 下新建一个存放测试文件的文件夹GlogTest,然后新建glogtest.cpp文件,把测试代码写在这里面就可以了。

至于如何运行测试代码,有多种方式。前提是必须有C++的编译器!

你可以使用 VS Code 的 Code Runner 插件,也可以自己写 launch.jsontasks.json文件。

自己写配置文件的好处就是,可以方便的进行参数配置(链接哪个库?要不要优化?开不开调试选项?……)。而且这些东西对于理解程序构建的过程还是很重要的。

我的 launch.json文件如下:

{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "lldb",
            "request": "launch",
            "name": "My Debug",
            "program": "${workspaceFolder}/build/${fileBasenameNoExtension}",
            "args": [],
            "cwd": "${workspaceFolder}",
            "preLaunchTask": "Build C++"
        }
    ]
}

tasks.json文件:

{
    "version": "2.0.0",
    "tasks": [
        {
            "type": "shell",
            "label": "Build C++",
            "command": "clang++",
            "args": [
                "-g",
                "-Wall",
                "-std=c++11",
                "-lglog",
                "-o",
                "${workspaceFolder}/build/${fileBasenameNoExtension}",
                "${file}"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

记得手动在工作区目录下新建一个bulid 文件夹,上面的配置里用到了!分开存放源文件和二进制文件是个好习惯。

注意,如果报错 error while loading shared libraries: libglog.so.1,那说明是程序在运行时没有找到 共享目标文件, 也就是 动态链接库,看这篇就可以解决: “error while loading shared libraries: xxx.so.x” 错误的原因和解决办法

5. 运行的效果

在VS Code中运行如下代码:

/* glogtest.cpp */

#include <cstdio>
#include <glog/logging.h>

int main(int argc, char* argv[]) {
    // Initialize Google’s logging library.
    google::InitGoogleLogging(argv[0]);

    std::printf("Hello google glog!\n");

    int num_cookies = 1234;
    LOG(INFO) << "Found " << num_cookies << " cookies";
    std::printf("INFO!\n");

    LOG(WARNING) << "Found " << ++num_cookies << " cookies";
    std::printf("Warning!\n");

    LOG(ERROR) << "Found " << ++num_cookies << " cookies";
    std::printf("Error!\n");

    LOG(FATAL) << "Found " << ++num_cookies << " cookies";
    std::printf("FATAL!\n");

    return 0;
}

终端输出的截图如下:
输出结果
可以看到,默认情况下,仅仅ERROR级别和FATAL级别的日志会额外输出到标准流中(stdout,stderr之类)。INFOWARNING级别的仅仅保存在日志中(log文件)。

在Linux下,log文件可以在 /tmp目录下查找到:
查找log文件
看到蓝色的软链接了吗?软链接文件指向对应类别的最新的 log 文件。

下面推荐一篇文章,介绍了glog输出日志的详细介绍。注意其中有关编译安装的部分似乎已经失效了!
Google开源库之Glog库详解

其中谈到:

在glog中,默认提供了四种级别的log,分别是INFO、WARNING、ERROR、FATAL。对应的等级分别是0,1,2,3。最终的结果不仅会在屏幕终端显示出来,同时会将log日志写入到/tmp/<program name>.<hostname>.<user name>.log.<severity level>.<date>.<time>.<pid>这个文件中

当然,glog 的 README里肯定也写了:
在这里插入图片描述

最后

想了解更多用法,还是推荐去看 glog 的 README: https://github.com/google/glog

如果有用,记得点个赞!懒得登录就算了~

Logo

更多推荐