【ubuntu】——手动编译安装gflagsglog的完整指南

📅 发布时间:2026/7/3 23:47:53 👁️ 浏览次数:
【ubuntu】——手动编译安装gflagsglog的完整指南
1. 为什么需要手动编译安装gflags和glog如果你在Ubuntu上搞过C项目尤其是那些依赖Google开源库的项目十有八九会碰到gflags命令行参数解析和glog日志记录这两个库。新手通常图省事直接用sudo apt install一把梭确实方便。但等你项目稍微复杂点比如需要链接静态库、或者要指定特定的命名空间、又或者你用的IDE像CLion死活找不到库的cmake配置文件麻烦就来了。我自己就踩过这个坑。当时接手一个老项目它要求gflags必须使用google这个命名空间而系统通过apt安装的版本默认是gflags。结果编译时各种命名冲突错误信息看得人头大。更常见的问题是apt仓库里的版本可能比较旧而你需要用到新版本里的某个特性。这时候手动从源码编译安装就成了唯一靠谱的选择。手动编译听起来有点吓人但其实就像组装乐高。你拿到源代码零件用cmake说明书生成构建规则再用make你的双手把它组装成库文件。这个过程让你对库的构成一清二楚可以灵活定制安装路径、编译选项生成的库也自带完整的pkg-config或cmake支持后续项目引用会顺畅得多。所以别怕麻烦这步“麻烦”能为你后续开发省下更多麻烦。2. 彻底清理系统原有的安装在开始手动安装新版本之前我们必须把系统里通过包管理器安装的旧版本清理干净否则新旧版本混在一起链接时指不定会出什么幺蛾子到时候调试起来更痛苦。2.1 卸载通过apt安装的gflags和glog打开你的终端我们分两步走。首先卸载glogsudo apt-get remove libgoogle-glog-dev接着卸载gflagssudo apt-get remove libgflags-dev这两条命令会移除这两个库的开发包头文件和.so文件。但有时候可能还有一些配置文件或残留文件为了更彻底可以运行sudo apt autoremove来清理不再需要的依赖包。2.2 如何确认真的卸载干净了卸载命令执行完不代表文件就彻底消失了。我们需要手动检查一下。一个快速的方法是使用locate命令配合grep进行过滤。首先确保你的locate数据库是最新的可以运行sudo updatedb这可能需要一点时间。然后我们分别检查# 检查gflags相关文件是否还在系统目录如/usr locate gflags | grep /usr # 检查glog相关文件 locate glog | grep /usr如果这些命令没有输出任何结果或者只输出了一些无关的文档路径那基本就说明从/usr下的主要安装位置清理干净了。如果你之前在其他地方比如/usr/local手动安装过那可能需要去相应目录手动删除include和lib下的相关文件。我们接下来要安装到/usr/local所以确保这里没有旧版本残留也很重要。3. 从源码编译安装gflags好了现在系统是一张白纸我们可以开始从头构建了。首先处理gflags。3.1 获取最新源代码我推荐直接从GitHub上克隆官方仓库这样能保证拿到最新的代码和修复。打开终端找一个你喜欢的目录比如在家目录下操作cd ~ git clone https://github.com/gflags/gflags.git cd gflagsgit clone命令会把整个项目仓库拉取到本地。进入gflags目录后你可以用git tag查看所有发布版本如果想用某个特定稳定版而非最新的开发版可以用git checkout v2.2.2这样的命令切换。3.2 配置与编译安装步骤详解接下来是标准的CMake“三板斧”配置、编译、安装。但这里我们加点“私货”来满足特定需求。创建并进入构建目录这是一个好习惯保持源码目录的干净所有构建产生的中间文件都放在单独的build目录里。mkdir build cd build运行CMake进行配置这是最关键的一步我们可以传递一些选项。cmake .. -DGFLAGS_NAMESPACEgoogle -DCMAKE_CXX_FLAGS-fPIC -DBUILD_SHARED_LIBSON -DCMAKE_INSTALL_PREFIX/usr/local我来解释一下这几个参数-DGFLAGS_NAMESPACEgoogle强制将命名空间设置为google。很多老项目依赖这个不设置的话默认可能是gflags。-DCMAKE_CXX_FLAGS-fPIC告诉编译器生成位置无关代码。这对于生成共享库.so文件是必须的即使你只编译静态库加上也无害。-DBUILD_SHARED_LIBSON默认会同时构建静态库和共享库。设为ON确保共享库被构建大多数动态链接场景需要它。-DCMAKE_INSTALL_PREFIX/usr/local指定安装路径。/usr/local是用户级软件安装的标准位置避免污染系统目录/usr。执行编译使用make命令-j4参数表示用4个线程并行编译能大大加快速度具体数字可以根据你CPU的核心数调整。make -j4这个过程会看到一堆编译输出。如果没有error错误只有warning警告通常可以忽略。安装到系统这步会把编译好的库文件、头文件等复制到之前指定的/usr/local目录下。sudo make install因为要写入/usr/local所以需要sudo权限。3.3 验证gflags安装成功安装完成后怎么确认一切正常呢有几个方法检查安装文件ls /usr/local/include/gflags/ # 应该能看到头文件 ls /usr/local/lib/libgflags* # 应该能看到libgflags.a和libgflags.so等库文件使用pkg-config查询如果安装了pkg-configpkg-config --cflags --libs gflags如果正确安装它会输出类似-I/usr/local/include -L/usr/local/lib -lgflags的信息。写一个简单的测试程序可选但推荐 创建一个test_gflags.cc文件内容如下#include gflags/gflags.h #include iostream DEFINE_string(name, World, Your name); int main(int argc, char** argv) { gflags::ParseCommandLineFlags(argc, argv, true); std::cout Hello, FLAGS_name ! std::endl; return 0; }然后用如下命令编译运行g -o test_gflags test_gflags.cc $(pkg-config --cflags --libs gflags) ./test_gflags --nameLinux如果输出Hello, Linux!那就大功告成了。4. 从源码编译安装gloggflags搞定后glog的安装过程就非常类似了因为它们都使用CMake构建系统。4.1 获取glog源代码同样我们从官方仓库克隆cd ~ git clone https://github.com/google/glog.git cd glog4.2 配置、编译与安装步骤几乎和gflags一模一样# 1. 创建构建目录 mkdir build cd build # 2. 配置。同样我们指定安装前缀并确保生成PIC代码。 cmake .. -DCMAKE_CXX_FLAGS-fPIC -DCMAKE_INSTALL_PREFIX/usr/local # 3. 编译 make -j4 # 4. 安装 sudo make install对于glog通常不需要像gflags那样特别指定命名空间。CMAKE_INSTALL_PREFIX确保它和gflags安装在同一位置。4.3 验证glog安装并了解其结构安装后进行验证ls /usr/local/include/glog/ # 查看头文件 ls /usr/local/lib/libglog* # 查看库文件同样可以写一个简单的测试程序test_glog.cc#include glog/logging.h int main(int argc, char* argv[]) { // 初始化glog第一个参数是程序名通常用argv[0]第二个是日志输出目录空表示除了stderr不输出到文件 google::InitGoogleLogging(argv[0]); LOG(INFO) This is an informational message.; LOG(WARNING) This is a warning message.; // LOG(ERROR)默认会输出到stderr并生成一个堆栈跟踪如果支持 LOG(ERROR) This is an error message.; google::ShutdownGoogleLogging(); return 0; }编译运行g -o test_glog test_glog.cc $(pkg-config --cflags --libs libglog) ./test_glog你会看到不同级别的日志信息输出到终端。注意默认情况下LOG(ERROR)不仅会打印信息还会在程序结束时生成一个堆栈跟踪文件如果系统支持这对于调试非常有用。4.4 glog动态库的位置与链接问题编译你自己的项目时如果遇到“找不到-lglog”或“未定义的引用”错误通常是链接器不知道去哪找我们刚安装的库。因为/usr/local/lib可能不在默认的链接器搜索路径中。解决方法有几种使用pkg-config最推荐就像我们测试程序做的那样让pkg-config自动生成正确的编译和链接标志。g my_program.cc -o my_program $(pkg-config --cflags --libs libglog)手动指定路径g my_program.cc -o my_program -I/usr/local/include -L/usr/local/lib -lglog永久添加库路径如果你不想每次编译都指定-L可以把/usr/local/lib添加到系统库缓存中。echo /usr/local/lib | sudo tee /etc/ld.so.conf.d/local.conf sudo ldconfig执行ldconfig后系统运行时就能找到这个路径下的动态库了。对于编译时很多构建系统如CMake有自己的查找机制确保你的CMakeLists.txt正确使用了find_package或指定了CMAKE_PREFIX_PATH。5. 在真实项目中集成与常见问题排查手动安装完这两个库最终目的是为了在项目里用起来。这里分享一些集成经验和踩过的坑。5.1 编写CMakeLists.txt来查找和使用库对于现代C项目用CMake来管理构建是最佳实践。下面是一个简单的示例展示如何在你的项目的CMakeLists.txt中引用我们手动安装的gflags和glog。cmake_minimum_required(VERSION 3.10) project(MyAwesomeProject) # 设置C标准 set(CMAKE_CXX_STANDARD 11) # 非常重要告诉CMake去 /usr/local 路径下寻找包 list(APPEND CMAKE_PREFIX_PATH /usr/local) # 查找gflags find_package(gflags REQUIRED) # 查找glog find_package(GLOG REQUIRED) # 添加你的可执行文件 add_executable(my_app main.cc) # 将找到的库链接到你的目标 target_link_libraries(my_app PRIVATE gflags::gflags GLOG::GLOG )关键点在于list(APPEND CMAKE_PREFIX_PATH /usr/local)这行指令将我们手动安装的路径添加到CMake的搜索列表中这样find_package命令才能定位到我们编译的库。gflags::gflags和GLOG::GLOG是现代CMake提供的导入目标Imported Target使用它们能自动处理头文件包含路径和链接库非常方便。5.2 你可能遇到的坑及解决方法问题一CMake找不到GLOG包。现象配置时报错Could NOT find GLOG (missing: GLOG_INCLUDE_DIR GLOG_LIBRARY)。排查首先确认/usr/local/lib/cmake/glog/目录下是否存在glog-config.cmake或GLOGConfig.cmake文件。这是我们安装时生成的配置文件CMake靠它来识别包。解决确保CMAKE_PREFIX_PATH包含了/usr/local。如果还不行可以尝试手动指定目录find_package(GLOG REQUIRED PATHS /usr/local/lib/cmake/glog)。问题二编译时链接失败报“undefined reference”。现象代码能通过编译找到头文件但链接阶段失败。排查这通常是链接顺序问题或者没找到库文件。先用ls /usr/local/lib/libglog*确认库文件存在。解决确保target_link_libraries中正确指定了库名。如果是手动用g编译确保-lglog或-lgflags放在源文件或目标文件之后例如g main.cc -lglog正确g -lglog main.cc可能出错。检查是否同时存在静态库.a和动态库.so。链接器默认优先选择动态库如果动态库损坏或路径不对可以尝试强制链接静态库-l:libglog.a。问题三运行时找不到动态库.so文件。现象编译成功但运行程序时提示error while loading shared libraries: libglog.so.1: cannot open shared object file。排查运行ldd ./my_app查看可执行文件的动态库依赖看libglog.so.1的路径是否为not found。解决执行我们前面提到的sudo ldconfig命令更新系统的动态链接器运行时绑定。如果还不行可以临时设置环境变量export LD_LIBRARY_PATH/usr/local/lib:$LD_LIBRARY_PATH但这只是临时方案永久方案还是通过ldconfig。手动编译安装虽然步骤稍多但给你带来了对依赖库的完全掌控力。一旦配置完成你的开发环境就会变得非常稳定和可靠。下次再遇到因为系统库版本不对而导致的诡异bug时你一定会庆幸自己走了手动编译这条路。