前言
服务端有两个大模块,第一个是编译运行CompileServer,第二个是OJServer。
CompileServer分为编译模块Compiler,运行模块Runner,最后还需要一个CompileRun对前两个进行整合,并且打包成网络服务。
本文实现编译模块,并且引入日志功能
一.思路
编译模块仅仅用于提供编译服务,所以前提是我们已经有了要编译的源文件。我们先让提供编译运行服务的进程fork创建子进程,然后再让子进程程序替换成g++,去编译源文件。父进程则等待子进程退出,检查子进程是否完成编译任务。要检查编译是否完成,可以分析g++的退出码,但有更简单的方式——检查当前目录下是否有对应的可执行程序
子进程编译代码,要么编译成功,形成可执行程序,要么代码有语法错误,向标准错误输出错误信息,然后退出进程。
我们不应该让g++向屏幕打印信息,这样会很混乱。并且编译出错的信息将来是要返回给用户的,所以我们应该用文件来保存。因此,在子进程程序替换成g++之前,应该将标准错误重定向到compileError文件。
二.接口设计
compile函数:
返回值:bool -> true则编译成功,生成可执行程序,否则失败(我们写的代码有问题或者用户提供的代码有语法错误)
参数:const string& fileName -> fileName是源文件的文件名,不带路径和后缀,需要我们在函数内部自己补充路径和后缀,以定位该文件。
三.日志组件
一条日志的信息包含日志等级,调用日志函数处所在的文件,所在代码行,调用时间,最后是信息。文件名和代码函数可以使用C语言中的__FILE__和__LINE__两个预定义的宏。
Log.hpp:
#pragma once
#include <iostream>
#include <string>
#include "Util.hpp"
namespace ns_log
{
using namespace n