当前位置:  开发笔记 > 编程语言 > 正文

如何避免LLVM的支持CommandLine泄漏库参数?

如何解决《如何避免LLVM的支持CommandLine泄漏库参数?》经验,为你挑选了1个好方法。

我一直在为我的语言编写一个编译器,并希望利用LLVM支持库CommandLine来处理参数解析.

我只添加了两个简单的声明:

static cl::opt
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::list 
InputFilenames("i", cl::desc("Input files"), cl::value_desc("filenames"), cl::OneOrMore);

然后我在main中添加通常的调用:

int main(int argc, char *argv[])
{
    cl::ParseCommandLineOptions(argc, argv, " My compiler\n");

...

传递-help给我的程序时问题非常明显:

General options:

  -aarch64-neon-syntax             - Choose style of NEON code to emit from AArch64 backend:
    =generic                       -   Emit generic NEON assembly
    =apple                         -   Emit Apple-style NEON assembly
  -cppfname=        - Specify the name of the generated function
  -cppfor=                 - Specify the name of the thing to generate
  -cppgen                          - Choose what kind of output to generate
    =program                       -   Generate a complete program
    =module                        -   Generate a module definition
    =contents                      -   Generate contents of a module
    =function                      -   Generate a function definition
    =functions                     -   Generate all function definitions
    =inline                        -   Generate an inline function
    =variable                      -   Generate a variable definition
    =type                          -   Generate a type definition
  -debugger-tune                   - Tune debug info for a particular debugger
    =gdb                           -   gdb
    =lldb                          -   lldb
    =sce                           -   SCE targets (e.g. PS4)
  -disable-spill-fusing            - Disable fusing of spill code into instructions
  -enable-implicit-null-checks     - Fold null checks into faulting memory operations
  -enable-load-pre                 - 
  -enable-objc-arc-opts            - enable/disable all ARC Optimizations
  -enable-scoped-noalias           - 
  -enable-tbaa                     - 
  -exhaustive-register-search      - Exhaustive Search for registers bypassing the depth and interference cutoffs of last chance recoloring
  -gpsize=                   - Global Pointer Addressing Size.  The default size is 8.
  -i=                   - Input files
  -imp-null-check-page-size= - The page size of the target in bytes
  -join-liveintervals              - Coalesce copies (default=true)
  -limit-float-precision=    - Generate low-precision inline sequences for some float libcalls
  -merror-missing-parenthesis      - Error for missing parenthesis around predicate registers
  -merror-noncontigious-register   - Error for register names that aren't contigious
  -mfuture-regs                    - Enable future registers
  -mips16-constant-islands         - Enable mips16 constant islands.
  -mips16-hard-float               - Enable mips16 hard float.
  -mno-compound                    - Disable looking for compound instructions for Hexagon
  -mno-ldc1-sdc1                   - Expand double precision loads and stores to their single precision counterparts
  -mno-pairing                     - Disable looking for duplex instructions for Hexagon
  -mwarn-missing-parenthesis       - Warn for missing parenthesis around predicate registers
  -mwarn-noncontigious-register    - Warn for register names that arent contigious
  -mwarn-sign-mismatch             - Warn for mismatching a signed and unsigned value
  -nvptx-sched4reg                 - NVPTX Specific: schedule for register pressue
  -o=                    - Output filename
  -print-after-all                 - Print IR after each pass
  -print-before-all                - Print IR before each pass
  -print-machineinstrs= - Print machine instrs
  -regalloc                        - Register allocator to use
    =default                       -   pick register allocator based on -O option
    =fast                          -   fast register allocator
    =greedy                        -   greedy register allocator
    =pbqp                          -   PBQP register allocator
  -rewrite-map-file=     - Symbol Rewrite Map
  -rng-seed=                 - Seed for the random number generator
  -stackmap-version=          - Specify the stackmap encoding version (default = 1)
  -stats                           - Enable statistics output from program (available with Asserts)
  -time-passes                     - Time each pass, printing elapsed time for each on exit
  -verify-debug-info               - 
  -verify-dom-info                 - Verify dominator info (time consuming)
  -verify-loop-info                - Verify loop info (time consuming)
  -verify-regalloc                 - Verify during register allocation
  -verify-region-info              - Verify region info (time consuming)
  -verify-scev                     - Verify ScalarEvolution's backedge taken counts (slow)
  -x86-asm-syntax                  - Choose style of code to emit from X86 backend:
    =att                           -   Emit AT&T-style assembly
    =intel                         -   Emit Intel-style assembly

Generic Options:

  -help                            - Display available options (-help-hidden for more)
  -help-list                       - Display list of available options (-help-list-hidden for more)
  -version                         - Display the version of this program

我显然希望减少噪音,只显示我暴露的相关命令行选项.

我意识到CommandLine实用程序正在利用全局变量和模板元编程,我的问题可能是由于静态链接LLVM.

我找到了几个似乎触及这个问题的链接,但没有什么具体的解决方案,除了可能动态链接到LLVM之外.


LLVM CommandLine:如何重置参数?

LLVMdev:命令行选项放在Target后端库中

Bugzilla 8860:命令行参数解析器在使用--enable-shared构建时提供了太多选项


我在OS X El Capitan版本10.11.1上运行

我按如下方式安装了llvm:

git clone http://llvm.org/git/llvm.git
git clone http://llvm.org/git/clang.git llvm/tools/clang
git clone http://llvm.org/git/clang-tools-extra.git llvm/tools/clang/tools/extra
git clone http://llvm.org/git/compiler-rt.git llvm/projects/compiler-rt
git clone http://llvm.org/git/libcxx.git llvm/projects/libcxx
git clone http://llvm.org/git/libcxxabi.git llvm/projects/libcxxabi

mkdir build_llvm
cd build_llvm && cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=prefix=/usr/local/llvm ../llvm
make

我的Makefile的相关部分:

LLVMCONFIG = llvm-config
CPPFLAGS = `$(LLVMCONFIG) --cxxflags` -std=c++11
LDFLAGS = `$(LLVMCONFIG) --ldflags` -lpthread -ldl -lz -lncurses -rdynamic
LIBS = `$(LLVMCONFIG) --libs`

%.o: %.cpp
    clang++ -I /usr/local/llvm/include -c $(CPPFLAGS) $< -o $@

mycompiler: $(OBJECTS)
    clang++ -I /usr/local/llvm/include -g $^ $(LIBS) $(LDFLAGS) -o $@

Matthew Sand.. 6

Geoff Reedy的回答对我很有帮助所以我接受了他的答案,但是,我想提供更多关于你如何设置的细节,以及我发现的其他一些信息.

和以前一样,我在声明形式上面选择了我的main函数,但是我添加了一个声明,OptionCategory并将其包含在该类别中每个选项的声明中:

cl::OptionCategory 
CompilerCategory("Compiler Options", "Options for controlling the compilation process.");

static cl::opt
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::cat(CompilerCategory));

static cl::list 
InputFilenames("i", cl::desc("Input files"), cl::value_desc("filenames"), cl::OneOrMore, cl::cat(CompilerCategory));

然后我就HideUnrelatedOptionsmain之前接到电话ParseCommandLineOptions:

int main(int argc, char *argv[])
{
    cl::HideUnrelatedOptions( CompilerCategory );
    cl::ParseCommandLineOptions(argc, argv, " My compiler\n");

... 

现在我的OPTIONS输出看起来好多了:

OPTIONS:

Compiler Options:
Options for controlling the compilation process.

  -i= - Input files
  -o=  - Output filename

Generic Options:

  -help          - Display available options (-help-hidden for more)
  -help-list     - Display list of available options (-help-list-hidden for more)
  -version       - Display the version of this program

这基本上标志着所有选项,cl::ReallyHidden因此他们甚至没有出现-help-hidden:).

我发现的其他有用信息在CommandLine Library Manual上.

我知道LLVM处于不断变化的状态,以防万一以后页面不见了以下是示例:

using namespace llvm;
int main(int argc, char **argv) {
  cl::OptionCategory AnotherCategory("Some options");

  StringMap Map;
  cl::getRegisteredOptions(Map);

  //Unhide useful option and put it in a different category
  assert(Map.count("print-all-options") > 0);
  Map["print-all-options"]->setHiddenFlag(cl::NotHidden);
  Map["print-all-options"]->setCategory(AnotherCategory);

  //Hide an option we don't want to see
  assert(Map.count("enable-no-infs-fp-math") > 0);
  Map["enable-no-infs-fp-math"]->setHiddenFlag(cl::Hidden);

  //Change --version to --show-version
  assert(Map.count("version") > 0);
  Map["version"]->setArgStr("show-version");

  //Change --help description
  assert(Map.count("help") > 0);
  Map["help"]->setDescription("Shows help");

  cl::ParseCommandLineOptions(argc, argv, "This is a small program to demo the LLVM CommandLine API");
  ...
}

这基本上显示了系统的强大功能,并演示了如何根据需要修改特定选项.



1> Matthew Sand..:

Geoff Reedy的回答对我很有帮助所以我接受了他的答案,但是,我想提供更多关于你如何设置的细节,以及我发现的其他一些信息.

和以前一样,我在声明形式上面选择了我的main函数,但是我添加了一个声明,OptionCategory并将其包含在该类别中每个选项的声明中:

cl::OptionCategory 
CompilerCategory("Compiler Options", "Options for controlling the compilation process.");

static cl::opt
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"), cl::cat(CompilerCategory));

static cl::list 
InputFilenames("i", cl::desc("Input files"), cl::value_desc("filenames"), cl::OneOrMore, cl::cat(CompilerCategory));

然后我就HideUnrelatedOptionsmain之前接到电话ParseCommandLineOptions:

int main(int argc, char *argv[])
{
    cl::HideUnrelatedOptions( CompilerCategory );
    cl::ParseCommandLineOptions(argc, argv, " My compiler\n");

... 

现在我的OPTIONS输出看起来好多了:

OPTIONS:

Compiler Options:
Options for controlling the compilation process.

  -i= - Input files
  -o=  - Output filename

Generic Options:

  -help          - Display available options (-help-hidden for more)
  -help-list     - Display list of available options (-help-list-hidden for more)
  -version       - Display the version of this program

这基本上标志着所有选项,cl::ReallyHidden因此他们甚至没有出现-help-hidden:).

我发现的其他有用信息在CommandLine Library Manual上.

我知道LLVM处于不断变化的状态,以防万一以后页面不见了以下是示例:

using namespace llvm;
int main(int argc, char **argv) {
  cl::OptionCategory AnotherCategory("Some options");

  StringMap Map;
  cl::getRegisteredOptions(Map);

  //Unhide useful option and put it in a different category
  assert(Map.count("print-all-options") > 0);
  Map["print-all-options"]->setHiddenFlag(cl::NotHidden);
  Map["print-all-options"]->setCategory(AnotherCategory);

  //Hide an option we don't want to see
  assert(Map.count("enable-no-infs-fp-math") > 0);
  Map["enable-no-infs-fp-math"]->setHiddenFlag(cl::Hidden);

  //Change --version to --show-version
  assert(Map.count("version") > 0);
  Map["version"]->setArgStr("show-version");

  //Change --help description
  assert(Map.count("help") > 0);
  Map["help"]->setDescription("Shows help");

  cl::ParseCommandLineOptions(argc, argv, "This is a small program to demo the LLVM CommandLine API");
  ...
}

这基本上显示了系统的强大功能,并演示了如何根据需要修改特定选项.

推荐阅读
郑小蒜9299_941611_G
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有