LLVM 命令行处理
LLVM 命令行处理
以下是一个结合 cl::opt、cl::list、cl::sub 的 复杂命令行接口样例,模拟一个类似 git 的工具,支持子命令、多参数、标志选项和位置参数:
#include "llvm/Support/CommandLine.h"
#include <iostream>
using namespace llvm;
// --- 全局选项(所有子命令共享)---
cl::opt<bool> Verbose(
"verbose",
cl::desc("Enable verbose output"),
cl::init(false)
);
// --- 子命令 'init' ---
cl::opt<std::string> RepoName(
"name",
cl::desc("Repository name"),
cl::value_desc("string"),
cl::init("my_repo") // 默认值
);
cl::SubCommand InitCmd("init", "Initialize a new repository");
// --- 子命令 'commit' ---
cl::list<std::string> Files(
"files",
cl::desc("Files to commit"),
cl::value_desc("filename"),
cl::ZeroOrMore, // 允许零或多个参数
cl::CommaSeparated // 支持逗号分隔
);
cl::opt<std::string> Message(
"m",
cl::desc("Commit message"),
cl::value_desc("string"),
cl::Required // 必须提供
);
cl::SubCommand CommitCmd("commit", "Commit changes");
// --- 子命令 'remote'(嵌套子命令)---
cl::SubCommand RemoteAddCmd("add", "Add a remote repository");
cl::opt<std::string> RemoteName(
"name",
cl::desc("Remote name"),
cl::Required,
cl::sub(RemoteAddCmd) // 仅对 'remote add' 有效
);
cl::opt<std::string> RemoteUrl(
"url",
cl::desc("Remote URL"),
cl::Required,
cl::sub(RemoteAddCmd)
);
cl::SubCommand RemoteCmd("remote", "Manage remote repositories");
int main(int argc, char **argv) {
// 设置帮助信息
cl::ParseCommandLineOptions(argc, argv, "Git-like CLI Example\n");
// 全局选项处理
if (Verbose)
errs() << "Verbose mode enabled\n";
// 子命令分发
if (InitCmd) {
errs() << "Initializing repo: " << RepoName << "\n";
}
else if (CommitCmd) {
errs() << "Committing with message: " << Message << "\n";
for (const auto &file : Files)
errs() << " - " << file << "\n";
}
else if (RemoteCmd) {
if (RemoteAddCmd) {
errs() << "Adding remote: " << RemoteName
<< " -> " << RemoteUrl << "\n";
} else {
errs() << "Unknown remote subcommand\n";
}
}
else {
errs() << "No valid subcommand provided. Use --help for usage.\n";
return 1;
}
return 0;
}
功能说明
1.全局选项
--verbose:所有子命令共享的调试标志。
2.子命令 init
用途:初始化仓库。
选项:
--name <string>:指定仓库名称(默认 my_repo)。
示例:
./cli init --name=my_project
3.子命令 commit
用途:提交文件变更。
选项:
--files <file1,file2>:提交的文件列表(逗号分隔或多次指定)。
-m <message>:必须提供的提交信息。
示例:
./cli commit --files=a.txt,b.txt -m "Fix bugs"
# 或
./cli commit --files a.txt --files b.txt -m "Fix bugs"
4.嵌套子命令 remote add
用途:添加远程仓库地址。
选项:
--name <string>:远程仓库名称(必须提供)。
--url <string>:远程仓库URL(必须提供)。
示例:
./cli remote add --name=origin --url=https://github.com/user/repo.git
运行示例
1. 显示帮助信息
./cli --help
# 输出:
# USAGE: cli [options] <subcommand> [subcommand options]
# OPTIONS:
# --verbose - Enable verbose output
# SUBCOMMANDS:
# init - Initialize a new repository
# commit - Commit changes
# remote - Manage remote repositories
2. 初始化仓库
./cli init --name=my_project --verbose
# 输出:
# Verbose mode enabled
# Initializing repo: my_project
3. 提交文件
./cli commit --files=a.cpp,b.cpp -m "Add features"
# 输出:
# Committing with message: Add features
# - a.cpp
# - b.cpp
4. 添加远程仓库
./cli remote add --name=origin --url=https://github.com/user/repo.git
# 输出:
# Adding remote: origin -> https://github.com/user/repo.git
关键设计点
-
子命令隔离
通过 cl::sub() 将选项绑定到特定子命令,避免命名冲突。
例如 --name 在 init 和 remote add 中含义不同。 -
灵活的参数输入
cl::list 支持多值输入(逗号分隔或重复选项)。
cl::Required 强制用户提供必要参数。 -
嵌套子命令
类似 git remote add 的层级结构,通过嵌套 SubCommand 实现。 -
默认值与校验
cl::init 设置默认值,cl::value_desc 提供类型提示。

浙公网安备 33010602011771号