Google开源命令行参数解析库gflags

来源:互联网 发布:qq邮箱更改域名 编辑:程序博客网 时间:2024/06/05 04:35

今天写程序时需要写一个命令行解析程序,于是网上搜索getopt()的实现代码,但搜到的信息基本上是如何使用getopt(),而系统又是Windows的;于是想到了以前项目中使用到的Google开源命令行解析库gflags。

google开源的gflags是一套命令行参数解析工具,他可以替代getopt(),使用起来更加方便灵活,包括支持C++内建的类型如string,gflags还支持从环境变量、配置文件读取参数(可用gflags代替配置文件)。本文简单介绍gflags的安装与使用。


gflags的安装

gflags源代码可以按照https://code.google.com/p/gflags/给的download链接地址去下载,我的机器是Windows系统,于是下载最新的

gflags-2.1.1.zip,当然tar.gz也可以的。下载完后解压,这时候源代码并不能直接放在应用程序中引用,因为看网上好多例子都include <gflags/gflags.h>,而压缩完的源代码中并没有gflags.h,但是注意到src目录中有个gflags.h.in文件,想必是需要做什么操作将gflags.h.in文件转换为gflags.h;继续浏览根目录gflags-2.1.1,可以看到有个INSTALL.txt文件,可惜里面都是一些Linux安装操作,再看有个CMakeLists.txt文件,这个文件是CMake工具生成工程必备的文件,于是用CMake生成VS工程配置:


点击Configure,出现报错信息:

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. The CXX compiler identification is MSVC 16.0.30319.1  
  2. Check for working CXX compiler using: Visual Studio 10  
  3. Check for working CXX compiler using: Visual Studio 10 -- broken  
  4. CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeTestCXXCompiler.cmake:54 (message):  
  5.   The C++ compiler "C:/Program Files (x86)/Microsoft Visual Studio  
  6.   10.0/VC/bin/cl.exe" is not able to compile a simple test program.  
  7.   
  8.   It fails with the following output:  
  9.   
  10.    Change Dir: D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeTmp  
  11.   
  12.     
  13.   
  14.   Run Build Command:C:\PROGRA~2\MICROS~2.0\Common7\IDE\devenv.com  
  15.   CMAKE_TRY_COMPILE.sln /build Debug /project cmTryCompileExec1038135002  
  16.   
  17.     
  18.   
  19.   
  20.   Microsoft(R) Visual Studio 10.0.30319.1 版。  
  21.   
  22.   
  23.   版权所有(C) Microsoft Corp。保留所有权利。  
  24.   
  25.   
  26.   1>------ 已启动生成: 项目: cmTryCompileExec1038135002, 配置: Debug Win32  
  27.   ------  
  28.   
  29.   
  30.   1>生成启动时间为 2014/5/5 19:27:03。  
  31.   
  32.   
  33.   1>PrepareForBuild:  
  34.   
  35.   
  36.   1>  
  37.   正在创建目录“D:\software\gflags-2.1.1\cmake-bin\CMakeFiles\CMakeTmp\Debug\”。  
  38.   
  39.   
  40.   
  41.   1>InitializeBuildStatus:  
  42.   
  43.   
  44.   1>  
  45.   正在创建“cmTryCompileExec1038135002.dir\Debug\cmTryCompileExec1038135002.unsuccessfulbuild”,因为已指定“AlwaysCreate”。  
  46.   
  47.   
  48.   
  49.   1>ClCompile:  
  50.   
  51.   
  52.   1> 用于 80x86 的 Microsoft (R) 32 位 C/C++ 优化编译器 16.00.30319.01 版  
  53.   
  54.   
  55.   1> 版权所有(C) Microsoft Corporation。保留所有权利。  
  56.   
  57.   
  58.   1>   
  59.   
  60.   
  61.   1> cl /c /Zi /W3 /WX- /Od /Ob0 /Oy- /D WIN32 /D _WINDOWS /D _DEBUG /D  
  62.   "CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise  
  63.   /Zc:wchar_t /Zc:forScope /GR /Fo"cmTryCompileExec1038135002.dir\Debug\\"  
  64.   /Fd"cmTryCompileExec1038135002.dir\Debug\vc100.pdb" /Gd /TP /analyze-  
  65.   /errorReport:prompt testCXXCompiler.cxx  
  66.   
  67.   
  68.   1>   
  69.   
  70.   
  71.   1> testCXXCompiler.cxx  
  72.   
  73.   
  74.   1>LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏  
  75.   
  76.   
  77.   1>  
  78.   
  79.   
  80.   1>生成失败。  
  81.   
  82.   
  83.   1>  
  84.   
  85.   
  86.   1>已用时间 00:00:00.98  
  87.   
  88.   
  89.   ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========  
  90.   
  91.   
  92.     
  93.   
  94.     
  95.   
  96.   CMake will not be able to correctly generate this project.  
  97. Call Stack (most recent call first):  
  98.   CMakeLists.txt:16 (project)  
  99.   
  100.   
  101. Configuring incomplete, errors occurred!  
  102. See also "D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeOutput.log".  
  103. See also "D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeError.log".  
按照提示,打开文件D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeError.log,看到报错信息为:

LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏

这个解决方案在http://blog.chinaunix.net/uid-20385936-id-3506149.html写的很清楚;替换cvtres.exe之后再次点积Configure后,就没有什么问题了,之后就Generateg一个flags的VS工程。


生成ALL_BUILD项目,然后生成INSTALL项目,这里安装时可能会出以下错误:

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: 命令“setlocal  
  2. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: "C:\Program Files (x86)\CMake 2.8\bin\cmake.exe" -DBUILD_TYPE=Debug -P cmake_install.cmake  
  3. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd  
  4. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmEnd  
  5. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone  
  6. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmErrorLevel  
  7. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: exit /b %1  
  8. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmDone  
  9. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd  
  10. 3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :VCEnd”已退出,代码为 1。  

这个一般是权限问题,退出VS,重新以管理员省份打开该工程,再次生成INSTALL项目就没有问题了;在C:\Program Files (x86)目录中可以看到已经有gflags目录,之后就可以引用该目录下的库进行编程了。在这里为方便大家不用做以上操作,直接获得gflags库的使用,这里提供我已经编译好的库和头文件,地址为:http://download.csdn.net/detail/lming_08/7352863


gflags的使用

使用flags需要包含头文件  #include <gflags/gflags.h> 
gflags主要支持的参数类型包括bool,int32, int64, uint64, double, string等,定义参数通过DEFINE_type宏实现,如下所示,分别定义了一个bool和一个string类型的参数,该宏的三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息。
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. DEFINE_bool(big_menu, true"Include 'advanced' options in the menu listing");   
  2. DEFINE_string(languages, "english,french,german",   
  3.                  "comma-separated list of languages to offer in the 'lang' menu");   
gflag不支持列表,用户通过灵活借助string参数实现,比如上述的languages参数,可以类型为string,但可看作是以逗号分割的参数列表。

定义以上参数后,就需要在main()函数中执行gflags::ParseCommandLineFlags(&argc, &argv, true);

然后就可以在应用程序中使用FLAGS_big_menu、FLAGS_languages表示获取到的命令行参数值。

注意:直接#include <gflags/gflags.h>并链接上gflags.lib或gflags_nothreads.lib,应用程序可能并不能链接成功,可能会生成如下报错信息:

[plain] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. gflags.lib(gflags.obj) : error LNK2019: 无法解析的外部符号 __imp__PathMatchSpecA@8,该符号在函数 "public: class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __thiscall gflags::`anonymous namespace'::CommandLineFlagParser::ProcessOptionsFromStringLocked(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,enum gflags::FlagSettingMode)" (?ProcessOptionsFromStringLocked@CommandLineFlagParser@?A0x8a801983@gflags@@QAE?AV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@ABV45@W4FlagSettingMode@3@@Z) 中被引用  

查阅资料发现是没有链接上shlwapi.lib,而shlwapi.lib是已经被废弃的库;链接上shlwapi.lib库后再次编译链接就OK了。

考虑到shlwapi.lib和gflags库都是静态库,因此可以在生成gflags库时链接上shlwapi.lib,这样在应用程序中就不用额外地再链接上shlwapi.lib了。

另外需要注意的是,在VS【属性】-【调试】中设置的原始命令行参数argv[]中表示字符串内容不仅仅是设置的相应字符串,他会在字符串前加上工程路径名,而gflags中就没有了工程路径名,设置的多少就是多少。


参考资料:

http://blog.chinaunix.net/uid-20385936-id-3506149.html

http://blog.chinaunix.net/uid-20196318-id-3440642.html

http://www.cnblogs.com/dkblog/archive/2012/02/15/2352315.html

版权声明:本文为博主原创文章,未经博主允许不得转载。

0

0 0
原创粉丝点击