草庐IT

c++ - 如何避免 LLVM 的 Support CommandLine 泄漏库参数?

coder 2024-02-01 原文

我一直在为我的一种语言开发编译器,想利用 LLVM 支持库 CommandLine处理参数解析。

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

static cl::opt<std::string>
OutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));

static cl::list<std::string> 
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=<function name>        - Specify the name of the generated function
  -cppfor=<string>                 - 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=<uint>                   - Global Pointer Addressing Size.  The default size is 8.
  -i=<filenames>                   - Input files
  -imp-null-check-page-size=<uint> - The page size of the target in bytes
  -join-liveintervals              - Coalesce copies (default=true)
  -limit-float-precision=<uint>    - 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=<filename>                    - Output filename
  -print-after-all                 - Print IR after each pass
  -print-before-all                - Print IR before each pass
  -print-machineinstrs=<pass-name> - 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=<filename>     - Symbol Rewrite Map
  -rng-seed=<seed>                 - Seed for the random number generator
  -stackmap-version=<int>          - 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实用程序正在利用全局变量和 template metaprogramming我的问题可能是由于静态链接 LLVM。

我发现了几个似乎涉及该问题的链接,但除了可能动态链接到 LLVM 之外,没有其他具体的解决方案。



我在 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 $@

最佳答案

Geoff Reedy 的回答对我来说非常有用,所以我接受了他的回答,但是,我想提供有关您如何设置它的更多详细信息,以及我找到的其他一些信息。

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

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

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

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

然后我在 main 中调用 HideUnrelatedOptions 就在 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=<filenames> - Input files
  -o=<filename>  - 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<cl::Option*> 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");
  ...
}

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

关于c++ - 如何避免 LLVM 的 Support CommandLine 泄漏库参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34147464/

有关c++ - 如何避免 LLVM 的 Support CommandLine 泄漏库参数?的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  3. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  4. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  5. ruby-on-rails - 如何验证 update_all 是否实际在 Rails 中更新 - 2

    给定这段代码defcreate@upgrades=User.update_all(["role=?","upgraded"],:id=>params[:upgrade])redirect_toadmin_upgrades_path,:notice=>"Successfullyupgradeduser."end我如何在该操作中实际验证它们是否已保存或未重定向到适当的页面和消息? 最佳答案 在Rails3中,update_all不返回任何有意义的信息,除了已更新的记录数(这可能取决于您的DBMS是否返回该信息)。http://ar.ru

  6. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  7. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  8. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  9. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  10. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

随机推荐