CommandLine库功能介绍
CommandLine库用于定制命令行选项。它可以使用声明性的方法来指定程序采用的命令行选项。
1、快速入门指南
-
在程序中包含CommandLine头文件。
#include "llvm/Support/CommandLine.h"
-
在main函数中调用命名空间cl中的函数ParseCommandLineOptions,对输入的命令行进行解析。
cl::ParseCommandLineOptions(argc,argv);
-
全局定义cl::opt类型的变量,用于接收命令行匹配的参数。在如下示例中,outputFilename接收命令行-o选项后的参数,并以string类型进行存储。
static cl::opt<string> outputFilename("o",cl::desc("Specify output filename"), cl::value_desc("filename"));
-
此外,CommandLine库默认支持-h及-help选项。在上述示例中,使用-h选项将打印对应的命令行帮助信息。
下图展示了示例使用-h命令执行的结果,可以清楚的看到cl::opt对象的初始化参数与创建的命令行规则的对应关系。
完整代码及运行结果如下
#include<iostream>
#include<cstring>
#include "llvm/Support/CommandLine.h"
using namespace std;
using namespace llvm;
static cl::opt<string> outputFilename("o",cl::desc("Specify output filename"), cl::value_desc("filename"));
int main(int argc,char **argv)
{
cl::ParseCommandLineOptions(argc,argv);
cout << outputFilename << endl;
}
2、opt对象初始化额外配置
opt可配置非选项形式的命令行参数,此时须设置初始化参数cl::Positional。
- 非选项形式的命令行参数可设置默认值。下面的示例中给InputFilename设置默认值
input.txt。
cl::opt<string> InputFilename(cl::Positional, cl::desc("<input file>"), cl::init("input.txt"));
- 通过添加opt的初始化参数cl::Required,可要求在命令行中必须显示的指定该参数。
cl::opt<string> InputFilename(cl::Positional, cl::Required, cl::desc("<input file>"));
- 命令行参数的顺序与opt对象定义的顺序相同。
完整代码及运行结果如下
#include<iostream>
#include<cstring>
#include "llvm/Support/CommandLine.h"
using namespace std;
using namespace llvm;
static cl::opt<string> outputFilename("o",cl::desc("Specify output filename"), cl::value_desc("filename"));
static cl::opt<string> inputFilename1(cl::Positional, cl::desc("<input file>"), cl::init("-"));
static cl::opt<string> inputFilename2(cl::Positional, cl::desc("<input file>"), cl::Required);
static cl::opt<string> inputFilename3(cl::Positional, cl::desc("<input file>"), cl::init("@"));
int main(int argc,char **argv)
{
cl::ParseCommandLineOptions(argc,argv);
cout << outputFilename << endl;
cout << inputFilename1 << endl;
cout << inputFilename2 << endl;
cout << inputFilename3 << endl;
}
3、Boolean型参数
CommandLine库除了支持string类型的命令行参数,也支持boolean型的参数。下图定义了三个bool型的命令行参数,其中Quiet2初始化中的cl::Hidden表示在-h中隐藏该参数的信息。
static cl::opt<bool> Force ("f", cl::desc("Enable binary output on terminals"));
static cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
static cl::opt<bool> Quiet2("q", cl::desc("Don't print informational messages"), cl::Hidden);
完整代码及运行结果如下图所示
#include<iostream>
#include "llvm/Support/CommandLine.h"
using namespace std;
using namespace llvm;
static cl::opt<bool> Force ("f", cl::desc("Enable binary output on terminals"));
static cl::opt<bool> Quiet ("quiet", cl::desc("Don't print informational messages"));
static cl::opt<bool> Quiet2("q", cl::desc("Don't print informational messages"), cl::Hidden);
int main(int argc,char **argv)
{
cl::ParseCommandLineOptions(argc,argv);
cout << Force << endl;
cout << Quiet << endl;
cout << Quiet2 << endl;
}
4、枚举类型参数
在下图代码的场景下,OptimizationLevel表示代码优化的级别,它有四种可选项:g、O1、O2、O3。
完整代码及运行结果如下图所示
#include<iostream>
#include "llvm/Support/CommandLine.h"
using namespace std;
using namespace llvm;
enum OptLevel {
g, O1, O2, O3
};
cl::opt<OptLevel> OptimizationLevel(cl::desc("Choose optimization level:"),
cl::values(
clEnumVal(g , "No optimizations, enable debugging"),
clEnumVal(O1, "Enable trivial optimizations"),
clEnumVal(O2, "Enable default optimizations"),
clEnumVal(O3, "Enable expensive optimizations")));
int main(int argc,char **argv)
{
cl::ParseCommandLineOptions(argc,argv);
cout << OptimizationLevel << endl;
}
5、列表参数
定制命令行的过程中可能需要一次指定一系列的同类参数,比如在上图的场景下,可能需要指定多个优化级别,比如./testDemo -g -O2。想要实现该功能,需要使用命令空间cl的模板类list。
完整代码及运行结果如下图所示
#include<iostream>
#include "llvm/Support/CommandLine.h"
using namespace std;
using namespace llvm;
enum Opts {
dce, instsimplify, inlining, strip
};
cl::list<Opts> OptimizationList(cl::desc("Available Optimizations:"),
cl::values(
clEnumVal(dce, "Dead Code Elimination"),
clEnumVal(instsimplify, "Instruction Simplification"),
clEnumValN(inlining,"inline", "Procedure Integration"),
clEnumVal(strip, "Strip Symbols")));
int main(int argc,char **argv)
{
cl::ParseCommandLineOptions(argc,argv);
for(unsigned int i = 0 ; i < OptimizationList.size();i++){
cout << OptimizationList[i] << endl;
}
}