1. 程式人生 > >Apollo程式碼解析:3. 命令列引數傳遞google gflags

Apollo程式碼解析:3. 命令列引數傳遞google gflags

簡介

  • 在百度Apollo中gflag被廣泛的應用在各種全域性變數中,例如節點名,變數名,各種狀態標誌中。
  • gflags 是google開源的一套命令列引數解析工具,比 getopt 功能更加強大,使用起來更加方便。
  • 什麼是 命令列引數解析工具 呢? 這裡拿python做例子,例如:python test.py cmd1 cmd2
    其中cmd1cmd2 就是命令列引數,gflags就是用來解析cmd1 cmd2 到程式中的。
  • ps: 在cpp中命令列引數就是字串

1. 安裝 gflags

build和安裝教程在INSTALL檔案中有, 該教程支援pkg-config, CMake, 以及 Bazel.

1.1 cmake

如果gflags不是安裝在預設路徑下,則環境變數gflags_DIR 需要是 <prefix>/lib/cmake/gflags 該資料夾下需要是有 gflags-config.cmake 的檔案。

如果gflags安裝在預設路徑下CMake 可以通過 find_package(gflags REQUIRED)

或者新增單執行緒靜態庫:
find_package(gflags COMPONENTS nothreads_static)
自動找到 gflags 。

新增dependency和execute
add_executable(foo main.cc)


target_link_libraries(foo gflags)

1.2 Bazel

WORKSPACE中新增以下語句

git_repository(
    name   = "com_github_gflags_gflags",
    commit = "<INSERT COMMIT SHA HERE>",
    remote = "https://github.com/gflags/gflags.git",
)

bind(
    name = "gflags",
    actual = "@com_github_gflags_gflags//:gflags"
, ) bind( name = "gflags_nothreads", actual = "@com_github_gflags_gflags//:gflags_nothreads", )

ps
gflags_nothreads 強制單執行緒
gflags 多執行緒

然後新增到BUILD中:

cc_binary(
    name = "foo",
    srcs = ["main.cc"],
    deps = ["//external:gflags"],
)

2. 使用 gflags

2.1. 首先需要#include "gflags.h"

#include <gflags/gflags.h>

2.2. 巨集定義

將需要的命令列引數使用gflags的巨集來定義,例如:DEFINE_xxxxx(變數名,預設值,help-string) 定義在檔案當中,注意:是全域性的, 例如Apollo中的FLAGS_control_node_name就是一個全域性的一個string。gflags支援以下型別:

DEFINE_bool: boolean
DEFINE_int32: 32-bit integer
DEFINE_int64: 64-bit integer
DEFINE_uint64: unsigned 64-bit integer
DEFINE_double: double
DEFINE_string: C++ string

2.3. main函式新增

在main函式中開始的地方加入,以下這句話:

google::ParseCommandLineFlags(&argc, &argv, true);
//如果設為true,則該函式處理完成後,argv中只保留argv[0],argc會被設定為1。
//如果為false,則argv和argc會被保留,但是注意函式會調整argv中的順序。

2.4 呼叫

在後續程式碼中使用FLAGS_變數名訪問對應的命令列引數方法如下:

printf("%s", FLAGS_mystr);

2.5 測試

在編譯成可執行檔案之後,使用:./exe --引數1=值1 --引數2=值2 ... 來為這些命令列引數賦值。

./mycmd --var1="test" --var2=3.141592654 --var3=32767 --mybool1=true --mybool2 --nomybool3

3. gflags進階使用

3.1. 在其他檔案中使用定義的flags變數

  • 有些時候需要在main之外的檔案使用定義的flags變數,這時候可以使用巨集定義DECLARE_xxx(變數名)宣告一下(就和c++中全域性變數的使用是一樣的,extern一下一樣)
DECLARE_bool: boolean
DECLARE_int32: 32-bit integer
DECLARE_int64: 64-bit integer
DECLARE_uint64: unsigned 64-bit integer
DECLARE_double: double
DECLARE_string: C++ string

在對應的.h檔案中進行DECLARE_xxx宣告,需要使用的檔案直接include就行了。
檢驗輸入引數是否合法:gflags庫支援定製自己的輸入引數檢查的函式,如下:

static bool ValidatePort(const char* flagname, int32 value) {
   if (value > 0 && value < 32768)   // value is ok
     return true;
   printf("Invalid value for --%s: %d\n", flagname, (int)value);
   return false;
}
DEFINE_int32(port, 0, "What port to listen on");
static const bool port_dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);

3.2 判斷flags變數是否被使用者使用

在gflags.h中,還定義了一些平常用不到的函式和結構體。這裡舉一個例子,判斷引數port有沒有被使用者設定過

    google::CommandLineFlagInfo info;
    if(GetCommandLineFlagInfo("port" ,&info) && info.is_default) {
        FLAGS_port = 27015;
    }

3.3 定製你自己的help資訊與version資訊

  • version資訊:使用google::SetVersionString設定,使用google::VersionString訪問
  • help資訊:使用google::SetUsageMessage設定,使用google::ProgramUsage訪問
  • 注意:google::SetUsageMessagegoogle::SetVersionString這兩個函式的呼叫必須google::ParseCommandLineFlags之前執行

相關推薦

Apollo程式碼解析3. 命令引數傳遞google gflags

簡介 在百度Apollo中gflag被廣泛的應用在各種全域性變數中,例如節點名,變數名,各種狀態標誌中。 gflags 是google開源的一套命令列引數解析工具,比 getopt 功能更加強大,使用起來更加方便。 什麼是 命令列引數解析工具 呢? 這裡拿p

Python關於命令引數argparse寫入圖片路徑

什麼是命令列引數? 命令列引數是在執行時給予程式/指令碼的標誌。它們包含我們程式的附加資訊,以便它可以執行。 並非所有程式都有命令列引數,因為並非所有程式都需要它們。 為什麼我們使用命令列引數? 如上所述,命令列引數在執行時為程式提供附加資訊。 這允許我們在不改變程式碼的情況下動

【linux】Valgrind工具集詳解(八)Memcheck命令引數詳解

【linux】Valgrind工具集詳解(五):命令列詳解中不夠全,在此專門針對Memcheck工具中的命令列引數做一次詳細的解釋。 Memcheck命令列選項 –leak-check=<no|summary|yes|full> [default: summary]

Go基礎程式設計獲取命令引數

package main import ( "fmt" "os" //os.Args所需的包 ) func main() { args := os.Args //獲取使用者輸入的所有引數 //如果使用者沒有輸入

C語言使用命令引數用字串讀取流和輸出流進行文字檔案的複製

#include<stdio.h> int main(int argc,char *argv[]) {   //檢查使用者的引數是否正確   if(argc<3)   {     printf("用法:命令 原始檔名 目標檔名\n");     return -1;

Apollo程式碼解析2. log系統google glog

Apollo中的glog 在Apollo中google glog 被廣泛使用,glog 是 google 的一個 c++ 開源日誌系統,輕巧靈活,入門簡單,而且功能也比較完善。 1. 安裝 以下是官方的安裝方法,一句命令: git clone h

Apollo程式碼解析4. control模組

0. 簡介: 閱讀本章之前預設已經閱讀了: 首先來看看整體的邏輯圖: 由此可知planning和control是整個Apollo的核心,由於個人喜好的原因先看control模組。 開啟control模組: 可見整個模組是由main.cc

Tensorflowtf.app.run()與命令引數解析

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

3.QT中QCommandLineParser和QCommandLineOption解析命令引數

 1新建專案 main.cpp #include<QCoreApplication> #include<QCommandLineParser>

python argparse命令引數解析詳解

## 簡介 本文介紹的是***[argparse](https://docs.python.org/3/library/argparse.html)***模組的基本使用方法,尤其詳細介紹**add_argument**內建方法各個引數的使用及其效果。 本文翻譯自[argparse的官方說明](ht

MFC解析啟動命令引數——CCommandLineInfo類

MFC中CCommandLineInfo類被用於分析啟動應用時的命令列引數。 MFC應用一般都會在它的應用物件中使用函式InitInstance()建立這個類的一個本地例項。然後把該物件傳給CWinApp::ParseCommandLine(),ParseCommandLine()又重複呼叫

C++ 命令引數解析

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

Windows API一日一練 3 使用命令引數

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

【tensorflow】命令引數解析

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

FFmpeg 解析命令引數

FFmpeg 命令列基礎語法: ffmpeg [global_options] {[input_file_options] -i input_file}...{[output_file_options] output_file}... global_options:全域性引

golang命令引數解析

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

go語言解析命令引數的實現

一、實現程式碼如下 // fffggg project main.go package main import (     "flag"     "fmt" ) func main() {     var num int     var mode string   

Python解析命令引數

使用Python編寫應用程式或是指令碼的時候,經常會用到命令列引數。C語言中有庫函式getopt解析短命令列引數,使用getopt_long解析短命令和長命令的組合。 Python使用getopt模組,同時解析短命令和長命令。看具體使用例子 #!/usr/bin/python import sys

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