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

  • Post author:
  • Post category:其他



今天写程序时需要写一个命令行解析程序,于是网上搜索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,出现报错信息:







The CXX compiler identification is MSVC 16.0.30319.1
Check for working CXX compiler using: Visual Studio 10
Check for working CXX compiler using: Visual Studio 10 -- broken
CMake Error at C:/Program Files (x86)/CMake 2.8/share/cmake-2.8/Modules/CMakeTestCXXCompiler.cmake:54 (message):
  The C++ compiler "C:/Program Files (x86)/Microsoft Visual Studio
  10.0/VC/bin/cl.exe" is not able to compile a simple test program.

  It fails with the following output:

   Change Dir: D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeTmp

  

  Run Build Command:C:\PROGRA~2\MICROS~2.0\Common7\IDE\devenv.com
  CMAKE_TRY_COMPILE.sln /build Debug /project cmTryCompileExec1038135002

  


  Microsoft(R) Visual Studio 10.0.30319.1 版。


  版权所有(C) Microsoft Corp。保留所有权利。


  1>------ 已启动生成: 项目: cmTryCompileExec1038135002, 配置: Debug Win32
  ------


  1>生成启动时间为 2014/5/5 19:27:03。


  1>PrepareForBuild:


  1>
  正在创建目录“D:\software\gflags-2.1.1\cmake-bin\CMakeFiles\CMakeTmp\Debug\”。



  1>InitializeBuildStatus:


  1>
  正在创建“cmTryCompileExec1038135002.dir\Debug\cmTryCompileExec1038135002.unsuccessfulbuild”,因为已指定“AlwaysCreate”。



  1>ClCompile:


  1> 用于 80x86 的 Microsoft (R) 32 位 C/C++ 优化编译器 16.00.30319.01 版


  1> 版权所有(C) Microsoft Corporation。保留所有权利。


  1> 


  1> cl /c /Zi /W3 /WX- /Od /Ob0 /Oy- /D WIN32 /D _WINDOWS /D _DEBUG /D
  "CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise
  /Zc:wchar_t /Zc:forScope /GR /Fo"cmTryCompileExec1038135002.dir\Debug\\"
  /Fd"cmTryCompileExec1038135002.dir\Debug\vc100.pdb" /Gd /TP /analyze-
  /errorReport:prompt testCXXCompiler.cxx


  1> 


  1> testCXXCompiler.cxx


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


  1>


  1>生成失败。


  1>


  1>已用时间 00:00:00.98


  ========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========


  

  

  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:16 (project)


Configuring incomplete, errors occurred!
See also "D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeOutput.log".
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项目,这里安装时可能会出以下错误:


C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: 命令“setlocal
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>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmEnd
3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmErrorLevel
3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: exit /b %1
3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :cmDone
3>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
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类型的参数,该宏的三个参数含义分别为命令行参数名,参数默认值,以及参数的帮助信息。


DEFINE_bool(big_menu, true, "Include 'advanced' options in the menu listing"); 
DEFINE_string(languages, "english,french,german", 
                 "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,应用程序可能并不能链接成功,可能会生成如下报错信息:


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




版权声明:本文为lming_08原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。