手写g++编译命令行工具笔记
基本想法
为什么要写 CPPRUN:
- 如果要开警告开关,敲完整的编译代码还挺麻烦的
- 想要编译与运行一次性完成
- Windows 的控制台本来是 cmd,后来有了 Powershell,但是后者不能用
<指定输入文件,比较麻烦
所以可以直接用 C++ 写一个类似于脚本的命令行程序。
功能
- 编译单个源代码。
- 默认情况下若编译成功,则运行程序,可以指定输入输出文件。
- 毫秒级计算实际运行时间。
基本用法:
.\run <源程序文件名,不包括.cpp扩展> <其他指令>
指令列表:
\i <文件名>指定输入文件\o <文件名>指定输出文件\f <文件名,不带扩展名>指定exe文件名,默认与源文件相同\std <c++/c++11/c++14>设置C++版本,默认 C++14\u取消警告,默认开启-Wall -Wextra -Wconversion -Wshadow\cmd回显编译命令,默认不开启\comp只编译不运行,默认编译后立即运行
代码实现
命令行程序添加参数
以 CPPRUN 为例,.\run <...> 中的 <...> 就是参数。在 C++ 中 main 函数其实是有两个参数的(只是竞赛的时候从来不会用到,也可以不写),即
// 参数随便命名,这里举个例子
int main(int argc, char** argv) {
}
其中 argc 是 ”参数数量“ + 1,注意命令行中不同参数用若干空格隔开;argv[1 ~ argc - 1] 是字符串形式的参数。
在程序中形成编译命令并执行
C风格字符串的拼接还挺麻烦,可以直接用 iostream 中的 string,通过 +, += 可以完成字符串与字符、字符串与字符串的拼接。
执行需要用到 system 函数,但是 system 的参数是C风格字符串,string 类型需要用到内置的 c_str() 转化。另外一提,在 system 中是可以使用 <, > 指定输入输出文件的,因为其本质是在 cmd 中执行了指令。相当于免去了在 Powershell 中打开 cmd 执行指令再关闭 cmd 的这种繁琐的操作。
system 函数是有返回值的,就是执行的该条指令的返回值。这样可以获取程序的返回值判断程序是否正常结束,也可以通过 g++ 的返回值判断是否有编译错误。
Tab. g++ 返回 0 是编译成功(包括有编译警告),其余返回值是有编译错误。
其他的小细节
如果想要在命令行中输出中文,一定保证你的源文件是在 GBK(或者其他中文) 的编码下编写并保存的!
源代码
/* Lucky_Glass */
// 2022-6-21 modified
#include <windows.h>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <iostream>
int getOption(char *_str) {
std::string str(_str);
if (str == "\\i") return 1;
if (str == "\\o") return 2;
if (str == "\\f") return 3;
if (str == "\\std") return 4;
if (str == "\\u") return 5;
if (str == "\\cmd") return 6;
if (str == "\\comp") return 7;
return 0;
}
void somethingError() {
std::cerr << "<fail> CPPRUN发生了未知错误" << std::endl;
exit(1);
}
bool isopt[50];
int main(int num, char *opt[]) {
std::string cmd("g++ ");
if (num == 1) {
std::cerr << "<fail> 请指定编译文件" << std::endl;
return 0;
}
std::string fil(opt[1]), inp, oup, gver("c++14");
cmd += fil, cmd += ".cpp";
for (int i = 2; i < num; ++i) {
int optid = getOption(opt[i]);
isopt[optid] = true;
if (optid <= 4) {
std::string ext(opt[++i]);
switch (optid) {
case 1: inp = ext; break;
case 2: oup = ext; break;
case 3: fil = ext; break;
case 4: gver = ext; break;
default: somethingError();
}
}
}
cmd += " -o ", cmd += fil;
if (gver == "c++14") cmd += " -std=c++14";
else if (gver == "c++11") cmd += " -std=c++11";
else if (gver != "c++") {
std::cerr << "<fail> C++版本只能为 c++/c++11/c++14" << std::endl;
return 0;
}
if (!isopt[5])
cmd += " -Wall -Wextra -Wconversion -Wshadow";
if (isopt[6])
std::cerr << cmd << std::endl;
if(!system(cmd.c_str()))
std::cerr << "<success> 编译完成" << std::endl;
else {
std::cerr << "<fail> 编译失败" << std::endl;
return 0;
}
if (!isopt[7]) {
cmd = ".\\", cmd += fil, cmd += ".exe";
if (isopt[1]) cmd += " < ", cmd += inp;
if (isopt[2]) cmd += " > ", cmd += oup;
DWORD stt, edt;
stt = GetTickCount();
int ret = system(cmd.c_str());
edt = GetTickCount();
std::cerr.precision(3);
std::cerr << "<success> 运行结束,返回值 " << ret
<< ",运行时间 " << (edt - stt) / 1000.0
<< std::endl;
}
return 0;
}
THE END
手写g++编译命令行工具笔记的更多相关文章
- 通过npm写一个cli命令行工具
前言 如果你想写一个npm插件,如果你想通过命令行来简化自己的操作,如果你也是个懒惰的人,那么这篇文章值得一看. po主的上一篇文章介绍了定制自己的模版,但这样po主还是不满足啊,项目中我们频繁的需要 ...
- 如何用Node编写命令行工具
0. 命令行工具 当全局安装模块之后,我们可以在控制台下执行指定的命令来运行操作,如果npm一样.我把这样的模块称之为命令行工具模块(如理解有偏颇,欢迎指正) 1.用Node编写命令行工具 在Node ...
- 吻逗死(windows)系统下自动部署脚本(for java spring*)及linux命令行工具
转载请注明出处:https://www.cnblogs.com/funnyzpc/p/10051647.html (^^)(^^)自動部署腳本原本在上個公司就在使用,由於近期同事需要手動部署一個Spr ...
- 如何创建一个基于命令行工具的跨平台的 NuGet 工具包
命令行可是跨进程通信的一种非常方便的手段呢,只需启动一个进程传入一些参数即可完成一些很复杂的任务.NuGet 为我们提供了一种自动导入 .props 和 .targets 的方法,同时还是一个 .NE ...
- Windows 编程,程序编译使用的命令行工具。
Windows 编程,程序编译使用的命令行工具. 1.cl.exe文件是Visual C\C++的编译器,它将程序源代码文件编译为obj文件. 2.rc.exe文件是资源编译器.工程项目中的.rc文件 ...
- 用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具
用 nodejs 写一个命令行工具 :创建 react 组件的命令行工具 前言 上周,同事抱怨说 react 怎么不能像 angular 那样,使用命令行工具来生成一个组件.对呀,平时工作时,想要创建 ...
- python笔记42-http请求命令行工具(httpie)
前言 通常我们需要快速的测试某个接口通不通,一般linux上用curl去发http请求,但是这个命令行工具语法有点复杂了,不够直观. python有一个给人类使用的requests库,非常的简单方便. ...
- Gitbook 命令行工具
1.Gitbook 简介 1.1 Gitbook GitBook 是一个基于 Node.js 开发的命令行工具,使用它可以很方便的管理电子书,GitBook 是目前最流行的开源书籍写作方案. 使用 G ...
- react.js 之 create-react-app 命令行工具系统讲解
react.js 教程之 create-react-app 命令行工具系统讲解 快速开始 npm install -g create-react-app create-react-app my-app ...
- FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑
FFmpeg_Tutorial FFmpeg工具和sdk库的使用demo 一.使用FFmpeg命令行工具和批处理脚本进行简单的音视频文件编辑 1.基本介绍 对于每一个从事音视频技术开发的工程师,想必没 ...
随机推荐
- UICC Send USSD 加密信息解析
已以下指令为例 已知发送 USSD 的格式为:Send USSD aaaxxxxxxxxxxxx*yyyyyyy# ;Fetch:==:SEND USSD SEND 801200001F ASSERT ...
- 线程基础知识05 synchronized类锁和对象锁演示
1 简介 synchronized在方法内,同步代码块,传入对象,使用的是对象锁,传入class对象,使用的是类锁 作用于普通方法,也是对象锁,当前对象 作用于静态方法,是类锁 2 同步方法示例 2. ...
- MySQL 常用函数一览
本文选取一些mysql函数进行具体举例介绍,从功能.语法等多方面做个记录说明,附上执行截图 1.IP处理函数INET_ATON()和INET_NTOA() 1)INET_ATON(expr) 功能:给 ...
- VS Code windows系统C/C++环境配置_添加路径
1.安装cygwin 2.配置VS Code 按ctrl + shift + p ,选择 c/c++:Edit configuration(json) { "configurations&q ...
- Spring(AOP的认识、实现)
2:Spring AOP AOP (Aspect Oriented Programming) 面向切面编程 OOP(Object Oriented Programming)面向对象编程,用对象的思想来 ...
- pandas连接msyql报(1115, "Unknown character set: 'utf8mb4'")错误
代码如下: 报错如下: 首先,为什么会出现这个错误: 分析如下: 随着智能手机的普及,我们开始经常使用表情符号.��更好的帮助我们进行交流.但是mysql的utf8编码只支持3字节的数据,而移动端的表 ...
- sqllabs:less18-22
在利用抓包工具进行抓包的时候,我们能看到很多的项,下面详细讲解每一项. HTTP 头部详解 1. Accept:告诉 WEB 服务器自己接受什么介质类型,/ 表示任何类型,type/* 表示该类型下的 ...
- JZOJ 4296. 有趣的有趣的家庭菜园
[NOIP2015模拟11.2]有趣的有趣的家庭菜园 题面 思路一 暴力 \(30\) 分! 很容易打,但是要注意: 开 \(\texttt{long long}\) 是非严格高于(等于是被允许的) ...
- Balanced Team
https://vjudge.net/problem/CodeForces-1133C 题意:在数组中找出一段 每两个元素差值不大于5的这段元素个数的最大值. 1 #include <iost ...
- K8S Pod Sidecar 应用场景之一-加入 NGINX Sidecar 做反代和 web 服务器
Kubernetes Pod Sidecar 简介 Sidecar 是一个独立的容器,与 Kubernetes pod 中的应用容器一起运行,是一种辅助性的应用. Sidecar 的常见辅助性功能有这 ...