1. 程式人生 > >Google開源命令列引數解析庫gflags

Google開源命令列引數解析庫gflags

今天寫程式時需要寫一個命令列解析程式,於是網上搜索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.   It fails with the following output:  
  8.    Change Dir: D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeTmp  
  9.   Run Build Command:C:\PROGRA~2\MICROS~2.0\Common7\IDE\devenv.com  
  10.   CMAKE_TRY_COMPILE.sln /build Debug /project cmTryCompileExec1038135002  
  11.   Microsoft(R) Visual Studio 10.0.30319.1 版。  
  12.   版權所有(C) Microsoft Corp。保留所有權利。  
  13.   1>------ 已啟動生成: 專案: cmTryCompileExec1038135002, 配置: Debug Win32  
  14.   ------  
  15.   1>生成啟動時間為 2014/5/5 19:27:03。  
  16.   1>PrepareForBuild:  
  17.   1>  
  18.   正在建立目錄“D:\software\gflags-2.1.1\cmake-bin\CMakeFiles\CMakeTmp\Debug\”。  
  19.   1>InitializeBuildStatus:  
  20.   1>  
  21.   正在建立“cmTryCompileExec1038135002.dir\Debug\cmTryCompileExec1038135002.unsuccessfulbuild”,因為已指定“AlwaysCreate”。  
  22.   1>ClCompile:  
  23.   1> 用於 80x86 的 Microsoft (R) 32 位 C/C++ 優化編譯器 16.00.30319.01 版  
  24.   1> 版權所有(C) Microsoft Corporation。保留所有權利。  
  25.   1>   
  26.   1> cl /c /Zi /W3 /WX- /Od /Ob0 /Oy- /D WIN32 /D _WINDOWS /D _DEBUG /D  
  27.   "CMAKE_INTDIR=\"Debug\"" /D _MBCS /Gm- /EHsc /RTC1 /MDd /GS /fp:precise  
  28.   /Zc:wchar_t /Zc:forScope /GR /Fo"cmTryCompileExec1038135002.dir\Debug\\"  
  29.   /Fd"cmTryCompileExec1038135002.dir\Debug\vc100.pdb" /Gd /TP /analyze-  
  30.   /errorReport:prompt testCXXCompiler.cxx  
  31.   1>   
  32.   1> testCXXCompiler.cxx  
  33.   1>LINK : fatal error LNK1123: 轉換到 COFF 期間失敗: 檔案無效或損壞  
  34.   1>  
  35.   1>生成失敗。  
  36.   1>  
  37.   1>已用時間 00:00:00.98  
  38.   ========== 生成: 成功 0 個,失敗 1 個,最新 0 個,跳過 0 個 ==========  
  39.   CMake will not be able to correctly generate this project.  
  40. Call Stack (most recent call first):  
  41.   CMakeLists.txt:16 (project)  
  42. Configuring incomplete, errors occurred!  
  43. See also "D:/software/gflags-2.1.1/cmake-bin/CMakeFiles/CMakeOutput.log".  
  44. 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 期間失敗: 檔案無效或損壞


生成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: 無法解析的外部符號 [email protected],該符號在函式 "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)" ([email protected]@[email protected]@@[email protected][email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@[email protected]@Z) 中被引用  

查閱資料發現是沒有連結上shlwapi.lib,而shlwapi.lib是已經被廢棄的庫;連結上shlwapi.lib庫後再次編譯連結就OK了。

考慮到shlwapi.lib和gflags庫都是靜態庫,因此可以在生成gflags庫時連結上shlwapi.lib,這樣在應用程式中就不用額外地再連結上shlwapi.lib了。

另外需要注意的是,在VS【屬性】-【除錯】中設定的原始命令列引數argv[]中表示字串內容不僅僅是設定的相應字串,他會在字串前加上工程路徑名,而gflags中就沒有了工程路徑名,設定的多少就是多少。

參考資料:

相關推薦

Google開源命令引數解析gflags

今天寫程式時需要寫一個命令列解析程式,於是網上搜索getopt()的實現程式碼,但搜到的資訊基本上是如何使用getopt(),而系統又是Windows的;於是想到了以前專案中使用到的Google開源命令列解析庫gflags。 google開源的gflags是一套命令列引數解析工具,他可以替代getopt

gflags(google開源的一套命令引數解析工具)

gflags是google開源的一套命令列引數解析工具,比getopt()函式功能要強大,使用起來更加方便,gflags還支援從環境變數和配置檔案中讀取引數。目前有C++和Python版本。本文就來詳細介紹C++版本gflags的使用,主要分如下兩個部分 Cont

C++ 命令引數解析

文章目錄 說明 短引數之 getopt() 長引數之 getopt_long() 長引數之 getopt_long_only() 說明 主要參考以下部落格: 部落格一:getopt和g

【tensorflow】命令引數解析

1. tf.app.flags,用於支援接受命令列傳遞引數 import tensorflow as tf #第一個是引數名稱,第二個引數是預設值,第三個是引數描述 tf.app.flags.DEFINE_string('str_name', 'def_v_1',"descrip1")

golang命令引數解析

package main import ( "fmt" "os" ) func main(){ s:= os.Args fmt.Println(s) }   直接執行 輸出結果:[C:\Users\Administrator\AppData\Local\Temp\___go_bui

python命令引數解析

一、getopt模組  getopt.getopt(args, options[, long_options]) args為需要解析的命令列引數列表,一般為sys.argv[1:],這是因為argv[0]為指令碼的路徑。 options為希望識別的引數,如果該命令列引數

python 命令引數解析 argparse簡單分析

在python 2.7 後,不推薦使用 optparse, 而推薦使用 argparse. 其它的不多說,簡單的分析下我遇到的問題:我是想用 argparse 來解析不定長的命令列引數 例如: import argparse import sys parser = ar

命令引數解析

對這種主函式形式一直不是很瞭解,今天研究了一下,所得如下: 當我們成功執行一個程式時,在Windows環境下會生成一個exe檔案,我們可以再命令列中開啟並執行這個程式。 比如說如下程式碼。 #

Golang: 使用flag包進行命令引數解析

最近在使用go開發cli(command-line-interface)時,通過對於官方文件以及他人部落格的學習,在此寫下個人認為更適合自己往後回顧的關於flag的使用說明。 工欲善其事必先利其器,先奉上flag官方文件解析 Demo0: pack

ffmpeg 原始碼學習 -- 之命令引數解析

ffmpeg 原始碼學習 -- 之ffmpeg命令列引數解析 大家通過git在安裝好cygwin之後,下載原始碼到(cygwin)home目錄,通過./configure  ...... ,可以新增一堆引數選項,執行可以生成config.mk等編譯使用的檔案,通過命令對工

Tensorflow:tf.app.run()與命令引數解析

首先給出一段常見的程式碼: if __name__ == '__main__': tf.app.run()12 它是函式入口,通過處理flag解析,然後執行main函式(或者接下來提到的xxx())(最後含有tf.app.run()的檔案,在此行之前肯定能找到def main

Python命令引數解析模組argparse

當寫一個Python指令碼時經常會遇到不同引數不同功能的情況,如何做一個更好看的命令幫助資訊以及對命令引數解析呢? 這就需要使用argparse模組 #!/usr/bin/env python # -*- coding: utf-8 -*- import sys import os impor

命令引數解析函式getopt_long() 使用詳解

當一個用C語言編寫的Linux或UNIX程式執行時,它是從main函式開始的。對這些程式而言,main函式的宣告如下所示: int main(int argc, char *argv[]) 其中argc是程式引數的個數(int),argv是一個代表引數自身的

getopt(win32) -- 命令引數解析函式

GNU libc提供了getopt和getopt_long用於解析命令列引數,很好用,想在windows下使用,就google了幾個win32下的C/C++寫得getopt,並作了一些比較。 程式裡往往會有許多開關的,執行時就要傳入許多引數值來開啟或關閉這些開關。以前

命令引數解析函式--getopt

原型: #include <unistd.h> int getopt(int argc, char * const argv[], const char *optstring); 該函式的argc和argv引數通常直接從main()的引數直接傳遞而來。opt

C 語言命令引數解析

C語言原始碼必須有且只有一個的函式是main函式,我們知道函式可以有引數,那麼main函式有沒有引數呢? 顯然是有的,而且它是固定的,只有兩個,第一個是整型變數(argc),第二個是字元型指標陣列(a

一個命令引數解析

    因工作需要寫一個console工具程式,執行引數很多,記得linux下有一個系統函式getopt可以很好得幫助程式設計師解析命令列引數,但是在VC中沒有這個函式,研究了下linux中對該函式的幫助資訊和標頭檔案g

使用Apache commons-cli包進行命令引數解析

Apache的commons-cli包是專門用於解析命令列引數格式的包。 依賴: <dependency> <groupId>commons-cli</groupId> <artifactId&g

linux命令引數解析學習心得

轉載出處:blog.csdn.net/bailyzheng/article/details/8048733 最近用到一個命令列工具,之前也一直說想把命令列引數解析看一下,今天算是做一個小的總結。 命令列引數解析分類:單個字元的引數(-a -b),還有字串引數(--vide

linux命令引數解析函式 getopt

在學習開原始碼過程中,經常遇到命令列解析函式 getopt,網上查閱了一些資料,總結一下。 說到命令列解析,最簡單的方式就是利用c語言main函式的兩個引數argc和argv來實現,當 C 執行時庫程式啟動程式碼呼叫 main() 時,會將命令列的引數傳過來,引數個數放在a