命令行参数仅在单一文件内使用
所需头文件
#include <llvm/Support/CommandLine.h>
在cpp文件中声明变量类型
static cl::opt<bool>
PInfoFlag("p", cl::desc("是否选择打印某些内容 "), cl::init(false), cl::Optional);
上面的代码为声明一个bool类型的命令行参数捕获器。如果该程序是testCM。调用如下
$ test -p
命令行参数上有-p那么变量PInfoFlag的值就是true,如果没有那么PInfoFlag的值就是false。
参数含义:
-
“p”:这个为第一个参数,表示命令行调用时应该写什么。
如果第一个参数写printf,那么调用就需要这样:testCM -printf,这样变量PInfoFlag才是true。 -
cl::desc参数,说明该命令行选项的作用是什么。如果是单独写一个程序,在main函数的开头写如下代码:
cl::ParseCommandLineOptions(argc, argv,);
则可以在执行testCM -help时将cl::desc对应的描述输出出来。
-
cl::init():设定初始值。
-
cl::Optional表明该选项是可选的。
可以设置的其他捕获参数类型
例如:
捕获string
static cl::opt<string> OutputFileName("o", cl::desc("Spectify output filename"), cl::value_desc("file name"));
命令行参数:
$ testCM -o=test.cpp
捕获后OutputFileName的值就是test.cpp
更多类型与用法参考官方文档:CommandLine
命令行参数在多个文件中使用
先写一个单独的文件,存放所有变量
/* commandLineArgConf.h */
/*
用于配置Pass的命令行参数,决定是否启用那些功能的。
如果该变量跨越多个文件要这样写。
使用方法:
先在此处声明变量,然后在
*/
extern bool PinfoFlag;
然后在需要使用该选项的地方引用该头文件。就可以直接使用了。
但是在使用之前需要先进行捕获
在某个cpp中,比如运行runOnFunction的cpp中进行捕获。
/* main.cc *//
#include <llvm/Support/CommandLine.h>// 需要包含头commandline文件
#include "commandLineArgConf.h" // 需要包含变量定义的头文件。
bool PinfoFlag; // 对变量进行声明。
static cl::opt<bool, true>
PInfo("p",cl::desc("决定运行是否打印printf的一些内容。"), cl::location(PinfoFlag)); // 进行捕获,cl::location()作用是指明捕获后的存放位置。
这样可以做到在main.cc或者某个cpp捕获,然后在其他文件中使用。
比如说在vmprotect/cvmprotect.cpp中使用:
/* cvmprotect.cpp */
#include "../commandLineArgConf.h"
...
if(PinfoFlag == false){
printf("\n*********\n*********\nprintf 在createCVMInterpreter 中起作用\n*******\n*********\n");
}
...
在llvmPass中使用方法
在llvm Pass中,使用clang加载时,需要在参数前加-mllvm 再添加Pass的参数。
实例:
$ clang -Xclang -load -Xclang <Pass.so> -mllvm -p
最后的-p参数不会传递给clang,而是传递给Pass
更详细的内容请参考官方文档
https://www.llvm.org/docs/CommandLine.html
里面包含命令行参数数组的使用,有关顺序的规定。还有可自定义选项前缀。给选项分组等。还有获取选项在命令行中的绝对位置的getPosition等。还有类似 ls -lrt 这种多个简短选项组合该怎么设置。