feat: add support for python3(pypy3) and rust
This commit is contained in:
parent
204b61a867
commit
864696c70c
@ -14,6 +14,11 @@ import (
|
||||
)
|
||||
|
||||
func (s *service) Compile(meta *JudgeMeta) (*JudgeStatus, e.Status) {
|
||||
// 0. maybe we can skip compile
|
||||
if v, ok := AllowedLanguages[meta.Cfg.Lang.Lang]; !ok || v.Interpreter != "" {
|
||||
return &JudgeStatus{}, e.Success
|
||||
}
|
||||
|
||||
// 1. prepare judge environment
|
||||
workDir := filepath.Join(UserDir, meta.Run.User)
|
||||
judgeDir := filepath.Join(ProblemDir, fmt.Sprintf("%d", meta.Run.Version), "judge")
|
||||
@ -104,5 +109,8 @@ func (s *service) Compile(meta *JudgeMeta) (*JudgeStatus, e.Status) {
|
||||
utils.If(status == e.Success, e.RunnerUserCompileFailed, status)
|
||||
}
|
||||
|
||||
// 5. grant permission
|
||||
_ = os.Chmod(targetFile, 0755)
|
||||
|
||||
return &JudgeStatus{CompileMessage: msgText}, e.Success
|
||||
}
|
||||
|
@ -9,6 +9,18 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var (
|
||||
AllowedLanguages = map[string]struct {
|
||||
Interpreter string
|
||||
}{
|
||||
"c": {""},
|
||||
"cpp": {""},
|
||||
"rust": {""},
|
||||
"python3": {"/usr/bin/python3"},
|
||||
"pypy3": {"/usr/bin/pypy3"},
|
||||
}
|
||||
)
|
||||
|
||||
type ConfigRuntime struct {
|
||||
TimeLimit int `json:"TimeLimit"`
|
||||
MemoryLimit int `json:"MemoryLimit"`
|
||||
@ -19,17 +31,17 @@ var (
|
||||
DefaultPrebuildRuntime = ConfigRuntime{
|
||||
TimeLimit: 300000,
|
||||
MemoryLimit: 256,
|
||||
NProcLimit: 64,
|
||||
NProcLimit: 128,
|
||||
}
|
||||
DefaultCompileRuntime = ConfigRuntime{
|
||||
TimeLimit: 60000,
|
||||
MemoryLimit: 256,
|
||||
NProcLimit: 64,
|
||||
NProcLimit: 128,
|
||||
}
|
||||
DefaultCheckRuntime = ConfigRuntime{
|
||||
TimeLimit: 60000,
|
||||
MemoryLimit: 128,
|
||||
NProcLimit: 64,
|
||||
NProcLimit: 128,
|
||||
}
|
||||
)
|
||||
|
||||
@ -96,6 +108,10 @@ func (l *ConfigLanguage) JudgeScript() string {
|
||||
}
|
||||
}
|
||||
|
||||
func (l *ConfigLanguage) JudgeInterpreter() string {
|
||||
return AllowedLanguages[l.Lang].Interpreter
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Languages []ConfigLanguage `json:"Languages"`
|
||||
Prebuild ConfigRuntime `json:"Prebuild,omitempty"`
|
||||
@ -106,18 +122,9 @@ type Config struct {
|
||||
}
|
||||
|
||||
func (c *Config) Validate(base string) error {
|
||||
allowedLang := map[string]struct{}{
|
||||
"c": {},
|
||||
"cpp": {},
|
||||
"go": {},
|
||||
"rust": {},
|
||||
"python3": {},
|
||||
"pypy3": {},
|
||||
}
|
||||
|
||||
// check per language config
|
||||
for _, lang := range c.Languages {
|
||||
if _, ok := allowedLang[lang.Lang]; !ok {
|
||||
if _, ok := AllowedLanguages[lang.Lang]; !ok {
|
||||
return fmt.Errorf("language %s is not allowed", lang.Lang)
|
||||
}
|
||||
|
||||
|
@ -20,13 +20,23 @@ func (s *service) SandboxArgsBuilder(meta *JudgeMeta, id int) string {
|
||||
args = append(args, fmt.Sprintf("--nproc_limit=%d", meta.Cfg.Lang.Runtime.Run.NProcLimit))
|
||||
args = append(args, fmt.Sprintf("--time_limit=%d", meta.Cfg.Lang.Runtime.Run.TimeLimit))
|
||||
args = append(args, fmt.Sprintf("--sandbox_template=%s", meta.Cfg.Lang.Lang))
|
||||
args = append(args, fmt.Sprintf("--sandbox_action=ret"))
|
||||
args = append(args, fmt.Sprintf("--uid=1000"))
|
||||
args = append(args, fmt.Sprintf("--gid=1000"))
|
||||
args = append(args, fmt.Sprintf("--sandbox_action=%s", "ret"))
|
||||
args = append(args, fmt.Sprintf("--uid=%d", 1000))
|
||||
args = append(args, fmt.Sprintf("--gid=%d", 1000))
|
||||
args = append(args, fmt.Sprintf("--file_input=/woj/problem/data/input/%d.input", id))
|
||||
args = append(args, fmt.Sprintf("--file_output=/woj/user/%d.out.usr", id))
|
||||
args = append(args, fmt.Sprintf("--file_info=/woj/user/%d.info", id))
|
||||
|
||||
if meta.Cfg.Lang.JudgeInterpreter() != "" {
|
||||
sourceFile := fmt.Sprintf("%s.%s", meta.Run.User, meta.Run.Lang)
|
||||
|
||||
args = append(args, fmt.Sprintf("--program=%s", meta.Cfg.Lang.JudgeInterpreter()))
|
||||
args = append(args, fmt.Sprintf("--program_arg=/woj/user/%s", sourceFile))
|
||||
} else {
|
||||
args = append(args, fmt.Sprintf("--program=/woj/user/%s.out", meta.Run.User))
|
||||
}
|
||||
|
||||
s.log.Debug("[run] sandbox args", zap.Strings("args", args))
|
||||
|
||||
return strings.Join(args, " ")
|
||||
}
|
||||
@ -49,10 +59,14 @@ func (s *service) ProblemRun(meta *JudgeMeta) {
|
||||
f := func(id int) func() error {
|
||||
return func() error {
|
||||
testCase := filepath.Join(dataDir, fmt.Sprintf("%d.input", id))
|
||||
targetFile := filepath.Join(workDir, fmt.Sprintf("%s.out", meta.Run.User))
|
||||
ansFile := filepath.Join(workDir, fmt.Sprintf("%d.out.usr", id))
|
||||
ifoFile := filepath.Join(workDir, fmt.Sprintf("%d.info", id))
|
||||
|
||||
targetFile := fmt.Sprintf("%s.out", meta.Run.User)
|
||||
targetPath := filepath.Join(workDir, targetFile)
|
||||
sourceFile := fmt.Sprintf("%s.%s", meta.Run.User, meta.Run.Lang)
|
||||
sourcePath := filepath.Join(workDir, sourceFile)
|
||||
|
||||
args := &RunArgs{
|
||||
Program: ProgramArgs{
|
||||
Args: []string{
|
||||
@ -71,8 +85,8 @@ func (s *service) ProblemRun(meta *JudgeMeta) {
|
||||
Options: []string{"rbind", "ro"},
|
||||
},
|
||||
{
|
||||
Source: targetFile,
|
||||
Destination: fmt.Sprintf("/woj/user/%s.out", meta.Run.User),
|
||||
Source: utils.If(meta.Cfg.Lang.JudgeInterpreter() != "", sourcePath, targetPath),
|
||||
Destination: fmt.Sprintf("/woj/user/%s", utils.If(meta.Cfg.Lang.JudgeInterpreter() != "", sourceFile, targetFile)),
|
||||
Type: "bind",
|
||||
Options: []string{"rbind", "ro"},
|
||||
},
|
||||
|
@ -0,0 +1,7 @@
|
||||
include ${TEMPLATE}/pypy3.mk ${TEMPLATE}/Judger.mk
|
||||
|
||||
compile:
|
||||
@echo no need to compile
|
||||
|
||||
judge:
|
||||
$($(CMP)) $(PREFIX)/problem/data/input/$(TEST_NUM).input $(PREFIX)/user/$(TEST_NUM).out.usr $(PREFIX)/problem/data/output/$(TEST_NUM).output $(PREFIX)/user/$(TEST_NUM).judge -appes
|
@ -0,0 +1,7 @@
|
||||
include ${TEMPLATE}/python3.mk ${TEMPLATE}/Judger.mk
|
||||
|
||||
compile:
|
||||
@echo no need to compile
|
||||
|
||||
judge:
|
||||
$($(CMP)) $(PREFIX)/problem/data/input/$(TEST_NUM).input $(PREFIX)/user/$(TEST_NUM).out.usr $(PREFIX)/problem/data/output/$(TEST_NUM).output $(PREFIX)/user/$(TEST_NUM).judge -appes
|
7
resource/runner/framework/template/default/rust.Makefile
Normal file
7
resource/runner/framework/template/default/rust.Makefile
Normal file
@ -0,0 +1,7 @@
|
||||
include ${TEMPLATE}/rust.mk ${TEMPLATE}/Judger.mk
|
||||
|
||||
compile:
|
||||
@$(RUSTC) $(RUSTFLAGS) -o $(PREFIX)/user/$(USER_PROG).out $(PREFIX)/user/$(USER_PROG).$(LANG)
|
||||
|
||||
judge:
|
||||
$($(CMP)) $(PREFIX)/problem/data/input/$(TEST_NUM).input $(PREFIX)/user/$(TEST_NUM).out.usr $(PREFIX)/problem/data/output/$(TEST_NUM).output $(PREFIX)/user/$(TEST_NUM).judge -appes
|
1
resource/runner/framework/template/pypy3.mk
Normal file
1
resource/runner/framework/template/pypy3.mk
Normal file
@ -0,0 +1 @@
|
||||
PYTHON=/usr/bin/pypy3
|
1
resource/runner/framework/template/python3.mk
Normal file
1
resource/runner/framework/template/python3.mk
Normal file
@ -0,0 +1 @@
|
||||
PYTHON=/usr/bin/python3
|
2
resource/runner/framework/template/rust.mk
Normal file
2
resource/runner/framework/template/rust.mk
Normal file
@ -0,0 +1,2 @@
|
||||
RUSTC = /root/.cargo/bin/rustc
|
||||
RUSTFLAGS = -C opt-level=2 -W warnings
|
@ -51,6 +51,28 @@
|
||||
"Runtime": {
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Lang" : "python3",
|
||||
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
|
||||
"Runtime": {
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Lang" : "pypy3",
|
||||
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
|
||||
"Runtime": {
|
||||
// pypy3 运行时内存常数开销大,A+B 问题内存至少给到 80 MB
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 80, "NProcLimit": 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Lang" : "rust",
|
||||
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
|
||||
"Runtime": {
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
|
||||
}
|
||||
}
|
||||
],
|
||||
// 题目构建阶段,用于生成测试数据等,可选,默认值见下
|
||||
@ -69,7 +91,7 @@
|
||||
### 评测脚本
|
||||
|
||||
1. 默认评测脚本目前只支持 `c` 语言和 `cpp`,参见 `../../framework/template/default/{c,cpp}.Makefile`
|
||||
2. 自定义评测脚本参见 `./judge/XYZ.Makefile`
|
||||
2. 自定义评测脚本参见 `./judge/custom.Makefile`
|
||||
3. `prebuild.Makefile`: 题目初始化脚本,用于编译辅助程序、生成数据等。如果存在该文件,系统会在题目分发到判机后自动执行,否则跳过该步骤
|
||||
|
||||
## 注意事项
|
||||
|
@ -15,6 +15,27 @@
|
||||
"Runtime": {
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Lang" : "python3",
|
||||
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
|
||||
"Runtime": {
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Lang" : "pypy3",
|
||||
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
|
||||
"Runtime": {
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 80, "NProcLimit": 1}
|
||||
}
|
||||
},
|
||||
{
|
||||
"Lang" : "rust",
|
||||
"Judge" : {"Type": "default", "Script": "", "Cmp": "NCMP"},
|
||||
"Runtime": {
|
||||
"Run": {"TimeLimit": 1000, "MemoryLimit": 16, "NProcLimit": 1}
|
||||
}
|
||||
}
|
||||
],
|
||||
"Prebuild" : {"TimeLimit": 300000, "MemoryLimit": 256, "NProcLimit": 64},
|
||||
|
@ -1,6 +1,10 @@
|
||||
FROM git.0x7f.app/woj/ubuntu-full:latest AS builder
|
||||
FROM docker.io/library/ubuntu:22.04
|
||||
|
||||
RUN apt-get update && apt-get upgrade -y \
|
||||
&& apt-get install -y python3 pypy3 \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists
|
||||
|
||||
WORKDIR /woj
|
||||
RUN mkdir -p /woj/framework/scripts
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user