一、gflags是什么
gflags是google的一个开源的处理命令行参数的库,使用c++开发,具备python接口。
二、下载安装
1.下载:https://gflags.github.io/gflags/
2.解压安装
tar zxvf gflags-2.0.tar.gz && cd gflags-2.0 && ./configure && make && make install
这时 gflags 库会默认安装在 /usr/local/lib/ 下,头文件放在 /usr/local/include/gflags/ 中。
三、gflags支持以下类型
将需要的命令行参数使用gflags的宏,DEFINE_xxxxx(变量名,默认值,help-string) 定义在文件当中。
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
四、若需要在其它文件中使用gflags的变量,可以使用宏定义声明下:DECLARE_xxx(变量名),之后在代码中便可以使用FLAGS_XXX格式使用命令行的参数了。
五、定制自己的help和version信息
version信息:使用google::SetVersionString(const std::string& usage)设定,使用google::VersionString访问
help信息:使用google::SetUsageMessage(const std::string& usage)设定,使用google::ProgramUsage访问
注意:google::SetUsageMessage和google::SetVersionString必须在google::ParseCommandLineFlags之前执行
一般在main函数的头几行编写这些信息。
六、特殊的flags
–flagfile:–flagfile=f 告诉commandlineflags从这个文件中读取出所有的命令行参数,f文件应该有特殊的格式要求,是一个参数的list,每行一个参数,格式如下:
–languages=english
(更详细的介绍请参考官网 https://gflags.github.io/gflags/)
#include
#include <gflags/gflags.h>
using namespace std;
using namespace google;
DEFINE_string(host, “127.0.0.1”, “the server port”);
DEFINE_int32(port, 9090, “program listen port”);
DEFINE_bool(sign, true, “switch mode”);
static std::string g_version;
static std::string g_help;
std::string& getVersion() {
g_version = “0.1”;
return g_version;
}
std::string& getHelp() {
g_help = “help info”;
return g_help;
}
int main(int argc, char** argv) {
google::SetVersionString(getVersion());
google::SetUsageMessage(getHelp());
google::ParseCommandLineFlags(&argc, &argv, true);
cout « “host = “ « FLAGS_host « endl;
cout « “port = “ « FLAGS_port « endl;
if (FLAGS_sign) {
cout « “sign is true …” « endl;
}
else {
cout « “sign is false …” « endl;
}
google::ShutDownCommandLineFlags();
return 0;
}
编译,使用makefile
GFLAGS_DIR = /usr/local/include/gflags/
LIB_DIR = /usr/local/lib/
a.out: simple_flags.cpp
g++ -I${GFLAGS_DIR} -L${LIB_DIR} simple_flags.cpp -lgflags
clean:
$(RM) -r a.out
执行,不给参数:
./a.out
host = 127.0.0.1
port = 9090
sign is true …
给参数:
./a.out -host 172.168.16.8 -port 2356
host = 172.168.16.8
port = 2356
sign is true …
使用文件file,文件内容如下:
–host=172.16.12.10
–port=8955
–sign=false
执行:
./a.out –flagfile=flag
host = 172.16.12.10
port = 8955
sign is false …
查看version和help信息:
./a.out -version
a.out version 0.1
./a.out -help
a.out: help info
Flags from simple_flags.cpp:
-host (the server port) type: string default: “127.0.0.1”
-port (program listen port) type: int32 default: 9090
-sign (switch mode) type: bool default: true
Flags from src/gflags.cc:
-flagfile (load flags from file) type: string default: “”
-fromenv (set flags from the environment [use ‘export FLAGS_flag1=value’])
type: string default: “”
-tryfromenv (set flags from the environment if present) type: string
default: “”
-undefok (comma-separated list of flag names that it is okay to specify on
the command line even if the program does not define a flag with that
name. IMPORTANT: flags in this list that have arguments MUST use the
flag=value format) type: string default: “”
Flags from src/gflags_completions.cc:
-tab_completion_columns (Number of columns to use in output for tab
completion) type: int32 default: 80
-tab_completion_word (If non-empty, HandleCommandLineCompletions() will
hijack the process and attempt to do bash-style command line flag
completion on this value.) type: string default: “”
Flags from src/gflags_reporting.cc:
-help (show help on all flags [tip: all flags can have two dashes])
type: bool default: false currently: true
-helpfull (show help on all flags – same as -help) type: bool
default: false
-helpmatch (show help on modules whose name contains the specified substr)
type: string default: “”
-helpon (show help on the modules named by this flag value) type: string
default: “”
-helppackage (show help on all modules in the main package) type: bool
default: false
-helpshort (show help on only the main module for this program) type: bool
default: false
-helpxml (produce an xml version of help) type: bool default: false
-version (show version and build info and exit) type: bool default: false
八、多文件引用(DECLARE_XXX使用)
gflagdef.h文件
复制代码
1 #ifndef GFLAG_DEF_H
2 #define GFLAG_DEF_H
3 #include <gflags/gflags.h>
4
5 DECLARE_int32(port);
6 DECLARE_string(host);
7 DECLARE_bool(sign);
8
9 #endif
复制代码
gflagdef.cpp文件
#include <gflags/gflags.h>
DEFINE_int32(port, 9001, “The server port”);
DEFINE_string(host, “127.0.0.1”, “listen port”);
DEFINE_bool(sign, true, “switch mode”);
main.cpp文件
复制代码
#include
#include "gflagdef.h"
using namespace std;
int main(int argc, char** argv) {
google::ParseCommandLineFlags(&argc, &argv, true);
cout << "host = " << FLAGS_host << endl;
cout << "port = " << FLAGS_port << endl;
if (FLAGS_sign) {
cout << "sign is true ..." << endl;
}
else {
cout << "sign is false ..." << endl;
}
google::ShutDownCommandLineFlags();
return 0;
}
复制代码
makefile文件
GFLAGS_DIR = /usr/local/include/gflags/
LIB_DIR = /usr/local/lib/
main: main.o flag.o
g++ main.o flag.o -o main -lgflags
main.o: main.cpp
g++ -c -I${GFLAGS_DIR} -L${LIB_DIR} main.cpp -lgflags -o main.o
flag.o: gflagdef.cpp
g++ -c -I${GFLAGS_DIR} -L${LIB_DIR} gflagdef.cpp -lgflags -o flag.o
clean:
$(RM) -r main *.o
编译&&执行:make&&./main
host = 127.0.0.1
port = 9001
sign is true .
google开源的gflags是很好的可配置参数选项,不但可以代替传统的getopt ,个人觉得最好的地方在于定义一次参数选项,其它需要使用gflags的程序模块可以直接引用,
而引用的方式只需要声明一下对应的参数即可
简单的例子如下,其中标红的就是程序使用某个参数变量的引用方法
(a.cpp)
#include <gflags/gflags.h>
#include …….
DEFINE_string(log_path, “../logs/”,”log path”);
int main(int argc, char **argv) {
::google::ParseCommandLineFlags(&argc, &argv, true);
std::string log_error = FLAGS_log_path + “/error.”;
::google::SetLogDestination(::google::ERROR, (FLAGS_log_path + “/error.”).c_str());
LOG(INFO) « “start process “ « argv[0];
std::tr1::shared_ptr
bool ret_init = pCLS_PROC->_init();
if(!ret_init){
LOG(INFO) << "service break down!" << argv[0];
return EXIT_FAILURE;
}
usleep(100);
LOG(INFO) « “service running…”;
pCLS_PROC->_start();
LOG(INFO) « “exit process” « argv[0];
return EXIT_SUCCESS;
}
(b.cpp)
这里b.cpp也需要使用log_path这个变量,所以只需要一个声明即可
#include <gflags/gflags.h>
#include …..
DECLARE_string(log_path);
/*
这里可以直接像a.cpp中一样用FLAGS_log_path来引用这个参数
*/
google开源的gflags是一套命令行参数解析工具,比getopt功能更强大,使用起来更加方便,gflags还支持从环境变量、配置文件读取参数(可用gflags代替配置文件)。本文简单介绍gflags的使用,内容主要译自http://gflags.googlecode.com/svn/trunk/doc/gflags.html 。
定义参数
使用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,但可看作是以逗号分割的参数列表。
访问参数
当参数被定义后,通过FLAGS_name就可访问到对应的参数,比如上述定义的big_menu、languages两个参数就可通过FLAGS_big_menu、FLAGS_languages访问。
if (FLAGS_languages.find(“english”) != string::npos)
HandleEnglish();
以上的访问方式,仅在参数定义和访问在同一个文件(或是通过头文件包含)时,FLAGS_name才能访问到参数,如果要访问其他文件里定义的参数,则需要使用DECLARE_type。比如在foo.cc中DEFINE_string(color, “red”, “the color you want to use”); 这是如果你需要在foo_test.cc中使用color这个参数,你需要加入DECLARE_string(color, “red”, “the color you want to use”);
参数检查
定义参数后,可以给参数注册一个检查函数(validator),当从命令行指定参数或通过SetCommandLineOption()指定参数时,检查函数就会被调用,两个参数分别为命令行参数名,以及设置的参数值。
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);
建议在定义参数后,立即注册检查函数。RegisterFlagValidator()在检查函数注册成功时返回true;如果参数已经注册了检查函数,或者检查函数类型不匹配,返回false。
初始化参数
在引用程序的main()里通过 google::ParseCommandLineFlags(&argc, &argv, true); 即完成对gflags参数的初始,其中第三个参数为remove_flag,如果为true,gflags会移除parse过的参数,否则gflags就会保留这些参数,但可能会对参数顺序进行调整。 比如 “/bin/foo” “arg1” “-q” “arg2” 会被调整为 “/bin/foo”, “-q”, “arg1”, “arg2”,这样更好理解。
在命令行指定参数
比如要在命令行指定languages参数的值,可通过如下4种方式,int32, int64等类型与string类似。
app_containing_foo –languages=”chinese,japanese,korean”
app_containing_foo -languages=”chinese,japanese,korean”
app_containing_foo –languages “chinese,japanese,korean”
app_containing_foo -languages “chinese,japanese,korean”
对于bool类型,则可通过如下几种方式指定参数
app_containing_foo –big_menu
app_containing_foo –nobig_menu
app_containing_foo –big_menu=true
app_containing_foo –big_menu=false
特殊参数
–help 打印定义过的所有参数的帮助信息
–version 打印版本信息 通过google::SetVersionString()指定
–nodefok 但命令行中出现没有定义的参数时,并不退出(error-exit)
–fromenv 从环境变量读取参数值 –fromenv=foo,bar表明要从环境变量读取foo,bar两个参数的值。通过export FLAGS_foo=xxx; export FLAGS_bar=yyy 程序就可读到foo,bar的值分别为xxx,yyy。
–tryfromenv 与–fromenv类似,当参数的没有在环境变量定义时,不退出(fatal-exit)
–flagfile 从文件读取参数值,–flagfile=my.conf表明要从my.conf文件读取参数的值。在配置文件中指定参数值与在命令行方式类似,另外在flagfile里可进一步通过–flagfile来包含其他的文件。
一、简介
gflags是Google的一个命令行参数处理的开源库,使用C++开发,具备Python接口,可以替代getopt。gflags支持从环境变量、配置文件读取参数。gflags使用起来比getopt方便,但是不支持参数缩写(例如getopt支持–list缩写成-l,gflags不支持)。
gflags不支持列表,用户可通过借助string参数实现:可看作以逗号分隔的参数列表:
DEFINE_string(languages, “english, french, german, chinese”, “comma-separated list of languages to offer in the ‘lang’ menu”);
二、源码获取
可以访问官网下载安装最新版本gflags:
https://code.google.com/p/gflags/
也可以上github获取(对于国内访问更加方便):
https://github.com/gflags/gflags
安装使用过程如下(摘自INSTALL.md):
获取并解压源码;
创建build目录并进入该目录;
运行cmake配置构建树;
使用编译工具编译源码;
验证编译后的库;
安装并使用。
如源码目录下INSTALL.md所述:
The build system of gflags is since version 2.1 based on CMake.
The common steps to build, test, and install software are therefore:
On Unix-like systems with GNU Make as build tool, these build steps can be
summarized by the following sequence of commands executed in a shell,
where $package
and $version
are shell variables which represent
the name of this package and the obtained version of the software.
$ tar xzf gflags-$version-source.tar.gz
$ cd gflags-$version
$ mkdir build && cd build
$ ccmake ..
- Press 'c' to configure the build system and 'e' to ignore warnings.
- Set CMAKE_INSTALL_PREFIX and other CMake variables and options.
- Continue pressing 'c' until the option 'g' is available.
- Then press 'g' to generate the configuration files for GNU Make.
$ make
$ make test (optional)
$ make install (optional)
编译的时候,可以使用ccmake来可视化的修改编译选项和工具,也可以通过cmake –D的方式指定编译选项。常见可用的编译选项如下:
CMake Option Description
CMAKE_INSTALL_PREFIX Installation directory, e.g., “/usr/local” on Unix and “C:\Program Files\gflags” on Windows.
BUILD_SHARED_LIBS Request build of dynamic link libraries.
BUILD_STATIC_LIBS Request build of static link libraries. Implied if BUILD_SHARED_LIBS is OFF.
BUILD_PACKAGING Enable binary package generation using CPack.
BUILD_TESTING Build tests for execution by CTest.
BUILD_NC_TESTS Request inclusion of negative compilation tests (requires Python).
BUILD_CONFIG_TESTS Request inclusion of package configuration tests (requires Python).
BUILD_gflags_LIBS Request build of multi-threaded gflags libraries (if threading library found).
BUILD_gflags_nothreads_LIBS Request build of single-threaded gflags libraries.
GFLAGS_NAMESPACE Name of the C++ namespace to be used by the gflags library. Note that the public source header files are installed in a subdirectory named after this namespace. To maintain backwards compatibility with th
e Google Commandline Flags, set this variable to “google”. The default is “gflags”.
GFLAGS_INTTYPES_FORMAT | String identifying format of built-in integer types.
GFLAGS_INCLUDE_DIR | Name of headers installation directory relative to CMAKE_INSTALL_PREFIX.
LIBRARY_INSTALL_DIR | Name of library installation directory relative to CMAKE_INSTALL_PREFIX.
INSTALL_HEADERS | Request installation of public header files.
三、使用方法
3.1 包含头文件
在使用的源代码中,包含如下头文件:
#include <gflags/gflags.h>
3.2 参数定义
将需要使用的命令行参数使用gflags的如下宏定义的形式全局定义在文档中,注意是全局域:
DEFINE_type(变量名, 默认值, help-string)
gflags支持如下类型(如上type部分):
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
比如分别定义了一个bool和一个string类型的参数:
DEFINE_bool(big_menu, true, “Include ‘advanced’ options in the menu listing”);
DEFINE_string(languages, “english, french, german, chinese”, “comma-separated list of languages to offer in the ‘lang’ menu”);
gflags不支持列表,用户可通过借助string参数实现,比如上面的languages参数,可以看作是以逗号分割的参数列表。
3.3 参数声明
当我们需要在其他文件中使用命令行定义的flags变量时,可以使用gflags的如下宏定义声明一下(就和C++中全局变量使用extern声明一样):
DELCARE_type(变量名)
type部分与前面gflags支持的类型对应。推荐在对应的*.h文件中进行DECLARE_type声明,需要使用的文件直接include即可。
3.4 参数解析
参数解析,也叫参数初始化。在main函数头几行加入如下语句(越早了解用户需求越好么):
google::ParseCommandLineFlags(&argc, &argv, true);
argc和argv就是main主函数传入的参数,想必大家都很了解。第三个参数表示是否释放argv以节约内存:
如果为true,则该函数处理完成后,argv中只保留argv[0]程序名,argc会被设置为1;
如果为false,则argv和argc都会被保留,但解析函数会调整argv中的顺序;
第三个参数的真正含义是remove_flag:如果为true,则gflags会移除parse过的参数,否则gflags就会保留这些参数,但可能会对参数顺序进行调整。
3.5 参数访问
当参数被定义后,在程序中就可以通过FLAGS_name的形式访问对应的flags参数了。FLAGS_是固定的前缀,name为宏定义中使用的名字。比如前面定义的两个参数:
printf(“big_menu=%d\n”, FLAGS_big_menu);
if(FLAGS_languages.find(“english”) != string::npos)
HandleEnglish();
3.6 参数检查
gflags库支持定制自己的输入参数范围检查函数,使用方法如下:
static bool ValidatePort(const char *flagname, int32 value)
{
if(value > 0 && value < 32768)
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);
建议在参数定义之后,立即注册检查函数。RegisterFlagValidator()在检查函数注册成功时返回true;如果参数已经注册了检查函数,或者检查函数类型不匹配,返回false。
3.7 参数传递——命令行
最后,将源码编译成可执行文件之后(编译的时候指定-lgflags),可以使用如下形式来使用命令行参数对flags变量赋值:
executable –参数1=值1 –参数2=值2 . . .
其中的‘=’也可以使用空格‘ ’代替。如果flags变量类型为bool,那么除了使用–xxx=true/false的形式外,还可以使用–xxx和–noxxx后面不加等号的方式指定true和false。比如:
app_containing_foo –languages=”chinese, japanese, korean”
app_containing_foo -languages=” chinese, japanese, korean”
app_containing_foo –languages ”chinese, japanese, korean”
app_containing_foo -languages ”chinese, japanese, korean”
app_containing_foo –big_menu
app_containing_foo –nobig_menu
app_containing_foo –big_menu=true
app_containing_foo –big_menu=false
app_containing_foo –big_menu true
app_containing_foo –big_menu false
==使用–nodefok参数==,可直指定当命令行中出现没有定义的参数时,并不退出(error-exit)。
3.8 参数传递——配置文件
如果参数比较多,那么在执行程序的时候,会显得非常的冗余。可以==使用–flagfile==来指定从文件中读取参数值。比如–flagfile=my.conf表明要从my.conf文件读取参数的值。
在配置文件中指定参数值与在命令行方式类似,另外在flagfile里可进一步通过–flagfile来包含其他的文件。
3.9 参数传递——环境变量
如果我们想让程序直接从环境变量中读取参数值,可以==使用–formenv==来指定。比如:–fromenv=foo,bar表明要从环境变量读取foo,bar两个参数的值。
通过export FLAGS_foo=xxx; export FLAGS_bar=yyy程序就可读到foo,bar的值分别为xxx,yyy。
==参数–tryfromenv==与–fromenv类似,当参数的没有在环境变量定义时,不退出(fatal-exit)。
四、高阶用法
4.1 添加自己的help信息
可以使用google::SetUsageMessage来设定帮助信息。然后在程序中可以使用google::ProgramUsage访问帮助信息,也可在程序外(命令行)通过–help来获取。
【注意】:google::SetUsageMessage必须在google::ParseCommandLineFlags之前执行。
添加自己的version信息
可以使用google::SetVersionString来设定版本信息。然后在程序中可以使用google::VersionString来访问,在程序外(命令行)可以通过–version参数来获取。
google开源的gflags是一套命令行参数解析工具,比getopt功能更强大,使用起来更加方便,gflags还支持从环境变量、配置文件读取参数(可用gflags代替配置文件)。本文简单介绍gflags的使用,内容主要译自 http://gflags.googlecode.com/svn/trunk/doc/gflags.html 。
定义参数
使用flags需要包含头文件 #include
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,但可看作是以逗号分割的参数列表。
访问参数
当参数被定义后,通过FLAGS_name就可访问到对应的参数,比如上述定义的big_menu、languages两个参数就可通过FLAGS_big_menu、FLAGS_languages访问。
if (FLAGS_languages.find(“english”) != string::npos)
HandleEnglish();
以上的访问方式,仅在参数定义和访问在同一个文件(或是通过头文件包含)时,FLAGS_name才能访问到参数,如果要访问其他文件里定义的参数,则需要使用DECLARE_type。比如在foo.cc中DEFINE_string(color, “red”, “the color you want to use”); 这是如果你需要在foo_test.cc中使用color这个参数,你需要加入DECLARE_string(color, “red”, “the color you want to use”);
参数检查
定义参数后,可以给参数注册一个检查函数(validator),当从命令行指定参数或通过SetCommandLineOption()指定参数时,检查函数就会被调用,两个参数分别为命令行参数名,以及设置的参数值。
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);
建议在定义参数后,立即注册检查函数。RegisterFlagValidator()在检查函数注册成功时返回true;如果参数已经注册了检查函数,或者检查函数类型不匹配,返回false。
初始化参数
在引用程序的main()里通过 google::ParseCommandLineFlags(&argc, &argv, true); 即完成对gflags参数的初始,其中第三个参数为remove_flag,如果为true,gflags会移除parse过的参数,否则gflags就会保留这些参数,但可能会对参数顺序进行调整。 比如 “/bin/foo” “arg1” “-q” “arg2” 会被调整为 “/bin/foo”, “-q”, “arg1”, “arg2”,这样更好理解。
在命令行指定参数
比如要在命令行指定languages参数的值,可通过如下4种方式,int32, int64等类型与string类似。
app_containing_foo –languages=”chinese,japanese,korean”
app_containing_foo -languages=”chinese,japanese,korean”
app_containing_foo –languages “chinese,japanese,korean”
app_containing_foo -languages “chinese,japanese,korean”
对于bool类型,则可通过如下几种方式指定参数
app_containing_foo –big_menu
app_containing_foo –nobig_menu
app_containing_foo –big_menu=true
app_containing_foo –big_menu=false
特殊参数
–help 打印定义过的所有参数的帮助信息
–version 打印版本信息 通过google::SetVersionString()指定
–nodefok 但命令行中出现没有定义的参数时,并不退出(error-exit)
–fromenv 从环境变量读取参数值 –fromenv=foo,bar表明要从环境变量读取foo,bar两个参数的值。通过export FLAGS_foo=xxx; export FLAGS_bar=yyy 程序就可读到foo,bar的值分别为xxx,yyy。
–tryfromenv 与–fromenv类似,当参数的没有在环境变量定义时,不退出(fatal-exit)
–flagfile 从文件读取参数值,–flagfile=my.conf表明要从my.conf文件读取参数的值。在配置文件中指定参数值与在命令行方式类似,另外在flagfile里可进一步通过–flagfile来包含其他的文件。
gflags
git clone https://github.com/gflags/gflags.git
cd gflags
mkdir build; cd build
CXXFLAGS=”-fPIC” cmake ..
make
sudo make install
在windows下链接会报错
gflags_static.lib(gflags.obj) : error LNK2001: 无法解析的外部符号 __imp_PathMatchSpecA
#pragma comment(lib, “shlwapi.lib”) 可以解决
glog
git clone https://github.com/google/glog
cd glog
./autogen.sh
./configure –with-gflags=/usr/local/include 如果先安装了gflags这个会自动查找
./configure
make && make install
int main(int argc, char* argv[]) {
FLAGS_log_dir = “./”; //先给个默认位置
google::ParseCommandLineFlags(&argc, &argv, false); //一定要先解析参数。 false表示不删除数组元素.
google::InitGoogleLogging(argv[0]);
//google::SetLogDestination(google::GLOG_INFO, “log/out.log”); //也可用这个设置
LOG(INFO) « “hello world!” « std::endl;
google::ShutdownGoogleLogging(); //要关闭
return 0; } ./test --log_dir=xxxx 即可,不写就默认在当前目录下
https://github.com/gflags/gflags
http://gflags.github.io/gflags/
0、系统环境
Ubuntu 16.04
GCC 5.4
1、安装步骤
1)安装 GFlags
运行如下指令:
git clone https://github.com/gflags/gflags.git
cd gflags
mkdir build && cd build
cmake .. -DGFLAGS_NAMESPACE=google -DCMAKE_CXX_FLAGS=-fPIC ..
make -j4
sudo make install
1
2
3
4
5
6
git clone https://github.com/gflags/gflags.git
cd gflags
mkdir build && cd build
cmake .. -DGFLAGS_NAMESPACE=google -DCMAKE_CXX_FLAGS=-fPIC ..
make -j4
sudo make install
2)安装 GLog:
安装编译工具:
sudo apt-get install autoconf automake libtool
1
sudo apt-get install autoconf automake libtool
运行如下指令安装:
git clone https://github.com/google/glog
./autogen.sh
./configure
make -j8
sudo make install
1
2
3
4
5
git clone https://github.com/google/glog
./autogen.sh
./configure
make -j8
sudo make install
常见问题
1、使用 GLog 报错:libglog.a: error adding symbols: Bad value
在使用 GLog 的工程中遇到了如下错误:
/usr/bin/ld: /usr/local/lib/libglog.a(libglog_la-logging.o): relocation R_X86_64_32 against .rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
.rodata.str1.1’ can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libglog.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
1
2
3
/usr/bin/ld: /usr/local/lib/libglog.a(libglog_la-logging.o): relocation R_X86_64_32 against
/usr/local/lib/libglog.a: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
产生该问题的可能原因是在 64位系统中,不能链接 GLog 生成动态库。修改方法是 GLog 需要使用如下方式编译,加入 -fPIC 编译选项:
./configure CPPFLAGS=”-I/usr/local/include -fPIC” LDFLAGS=”-L/usr/local/lib”
1
./configure CPPFLAGS=”-I/usr/local/include -fPIC” LDFLAGS=”-L/usr/local/lib”
代替:
./configure
1
./configure
2、错误:undefined reference to `google::FlagRegisterer::FlagRegisterer
如果你在编译 GLog 时遇到如下错误:
undefined reference to ‘google::FlagRegisterer::FlagRegisterer’
1
undefined reference to ‘google::FlagRegisterer::FlagRegisterer’
可以尝试先卸载 GFlags:
sudo apt-get purge libgflags-dev
1
sudo apt-get purge libgflags-dev
然后重新编译
另一种可能的解决方案是,在编译 GLog 时请使用:
./configure CPPFLAGS=”-I/usr/local/include” LDFLAGS=”-L/usr/local/lib”
1
./configure CPPFLAGS=”-I/usr/local/include” LDFLAGS=”-L/usr/local/lib”
代替:
./configure
1
./configure
3、错误:Make error: failed to link with libgflags.a
产生该问题的原因有可能是需要使用动态库方式编译 GFlags
将 GFlags 编译时选项改成动态库:
cmake .. -DBUILD_SHARED_LIBS=ON
1
cmake .. -DBUILD_SHARED_LIBS=ON
并重新编译 GFlags 和 GLog。
4、错误:something wrong with flag ‘flagfile’ in file ‘XXX.cc’
请参照 3 中的解决方案重新编译 GFlags 和 GLog。