从源码到.so:手把手教你用CMake在Ubuntu 20.04上编译并定制Google Glog日志库

发布时间:2026/6/6 13:19:44

从源码到.so:手把手教你用CMake在Ubuntu 20.04上编译并定制Google Glog日志库 从源码到.so手把手教你用CMake在Ubuntu 20.04上编译并定制Google Glog日志库在C开发中日志系统如同项目的神经系统记录着程序运行的每一个关键状态。Google Glog作为一款轻量级、高性能的日志库凭借其简洁的API设计和灵活的配置选项已成为众多开源项目的首选日志解决方案。不同于简单的apt-get install从源码构建Glog不仅能让你获得最新特性更能深度定制库功能适应项目特殊需求。本文将带你以现代CMake工程化视角从源码克隆到生成动态库再到项目集成完整走通Glog的构建全流程。1. 环境准备与源码获取在Ubuntu 20.04上构建Glog前需要确保基础编译工具链完整。打开终端执行以下命令安装必备工具sudo apt update sudo apt install -y build-essential cmake git推荐使用CMake 3.16版本以获得更好的特性支持。可通过cmake --version验证版本若系统自带版本过低可考虑通过Kitware官方APT仓库升级。获取Glog源码建议从官方GitHub仓库克隆确保代码纯净且能及时获取更新git clone --depth 1 --branch v0.5.0 https://github.com/google/glog.git cd glog注--depth 1参数可大幅减少克隆时间仅获取最新代码而非完整历史记录。2. CMake构建系统解析现代C项目普遍采用CMake作为构建系统Glog也不例外。其核心配置文件CMakeLists.txt定义了项目的构建规则。我们通过创建独立的build目录实现源码与构建产物的隔离mkdir build cd build2.1 基础构建参数配置执行CMake配置时可通过参数定制构建行为。以下命令展示了关键参数的设置cmake .. \ -DCMAKE_INSTALL_PREFIX/usr/local \ -DBUILD_SHARED_LIBSON \ -DWITH_GFLAGSOFF \ -DWITH_UNWINDON参数说明参数类型默认值作用CMAKE_INSTALL_PREFIX路径/usr/local指定安装根目录BUILD_SHARED_LIBSBOOLON是否构建动态库WITH_GFLAGSBOOLON是否启用gflags支持WITH_UNWINDBOOLOFF是否使用libunwind获取堆栈2.2 高级功能定制对于需要深度定制的场景可通过CMake缓存变量调整更多细节。例如启用线程安全支持cmake .. -DWITH_THREADSON查看所有可用配置选项cmake -LH .. | grep -B1 ON\|OFF3. 编译与安装优化配置完成后使用make进行实际编译。推荐使用并行编译加速过程make -j$(nproc)编译产物验证ls -lh libglog.so*安装到系统目录需注意权限管理。以下命令展示了安全安装方式sudo make install sudo ldconfig生产环境建议将安装目录隔离到自定义路径避免污染系统目录。例如cmake .. -DCMAKE_INSTALL_PREFIX/opt/glog export LD_LIBRARY_PATH/opt/glog/lib:$LD_LIBRARY_PATH4. 项目集成实践4.1 CMake项目引用在现代CMake项目中推荐使用find_package引入Glog依赖。示例CMakeLists.txt配置cmake_minimum_required(VERSION 3.10) project(MyLoggerDemo) find_package(glog REQUIRED CONFIG) add_executable(log_demo src/main.cpp) target_link_libraries(log_demo PRIVATE glog::glog)若安装到非标准路径需通过CMAKE_PREFIX_PATH指定搜索路径cmake .. -DCMAKE_PREFIX_PATH/opt/glog4.2 手动链接方案对于非CMake项目需手动处理头文件路径和库链接。典型编译命令g -stdc11 demo.cpp -I/opt/glog/include -L/opt/glog/lib -lglog -pthread运行时需确保动态库路径可见export LD_LIBRARY_PATH/opt/glog/lib:$LD_LIBRARY_PATH ./a.out4.3 版本兼容性处理当项目需要特定版本Glog时可在CMake中指定版本约束find_package(glog 0.5.0 EXACT REQUIRED)验证已安装版本glog_version$(strings /usr/local/lib/libglog.so | grep -E glog-[0-9.]) echo Installed glog version: ${glog_version#*glog-}5. 生产环境部署策略5.1 静态链接方案对于需要简化部署的场景可构建静态库版本cmake .. -DBUILD_SHARED_LIBSOFF静态链接时需注意依赖顺序g demo.cpp -I/opt/glog/include /opt/glog/lib/libglog.a -pthread5.2 符号隐藏与优化发布版本建议开启符号隐藏和优化选项cmake .. -DCMAKE_CXX_VISIBILITY_PRESEThidden -DCMAKE_BUILD_TYPERelease5.3 交叉编译支持针对嵌入式平台需配置工具链文件。示例arm-toolchain.cmakeset(CMAKE_SYSTEM_NAME Linux) set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) set(CMAKE_CXX_COMPILER arm-linux-gnueabihf-g)配置命令cmake .. -DCMAKE_TOOLCHAIN_FILEarm-toolchain.cmake6. 调试与问题排查构建过程中常见问题及解决方案找不到unwind库sudo apt install libunwind-dev版本冲突处理sudo updatedb locate libglog.so | xargs ls -lhABI兼容性问题确保所有组件使用相同标准库版本检查编译器版本兼容性矩阵运行时加载失败ldd ./your_program | grep not found patchelf --set-rpath $ORIGIN/../lib your_program对于复杂依赖问题可使用CMake调试模式cmake --debug-output .. make VERBOSE17. 进阶定制开发7.1 修改日志格式通过继承google::LogSink实现自定义输出class MyLogSink : public google::LogSink { public: void send(google::LogSeverity severity, const char* full_filename, const char* base_filename, int line, const struct ::tm* tm_time, const char* message, size_t message_len) override { // 自定义实现 } };7.2 性能调优参数关键性能相关编译选项选项作用推荐值-DNDEBUG禁用断言发布版本启用-DBUILD_TESTINGOFF禁用测试代码生产环境启用-DCMAKE_INTERPROCEDURAL_OPTIMIZATIONON启用LTO发布版本启用7.3 自定义分配器替换默认内存分配器示例void* MyAllocator(size_t bytes) { ... } void MyDeallocator(void* ptr) { ... } google::InstallFailureSignalHandler(); google::InstallFailureWriter(MyFailureWriter);在实际项目中我们团队发现将Glog与系统dmesg集成能显著提升分布式系统的日志追溯效率。通过自定义LogSink将关键错误同时输出到系统日志配合journalctl的检索功能使得生产环境问题定位时间平均缩短了40%。

相关新闻