今天写程序时需要写一个命令行解析程序,于是网上搜索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".
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.youkuaiyun.com/detail/lming_08/7352863
gflags的使用
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");
定义以上参数后,就需要在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
版权声明:本文为博主原创文章,未经博主允许不得转载。
-
顶
- 0
-
踩