add support to use zig as a linker driver
closes #243 I also added --grep to ./run_tests if you want to single out some specific testsmaster
parent
8c10b6dcbd
commit
d65cd73a8b
|
@ -1462,6 +1462,7 @@ struct CodeGen {
|
|||
ConstExprValue panic_msg_vals[PanicMsgIdCount];
|
||||
|
||||
Buf global_asm;
|
||||
ZigList<Buf *> link_objects;
|
||||
};
|
||||
|
||||
enum VarLinkage {
|
||||
|
|
|
@ -3743,6 +3743,18 @@ static void do_code_gen(CodeGen *g) {
|
|||
char *error = nullptr;
|
||||
LLVMVerifyModule(g->module, LLVMAbortProcessAction, &error);
|
||||
#endif
|
||||
|
||||
char *err_msg = nullptr;
|
||||
Buf *out_file_o = buf_create_from_buf(g->root_out_name);
|
||||
const char *o_ext = target_o_file_ext(&g->zig_target);
|
||||
buf_append_str(out_file_o, o_ext);
|
||||
if (LLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(out_file_o),
|
||||
LLVMObjectFile, &err_msg))
|
||||
{
|
||||
zig_panic("unable to write object file: %s", err_msg);
|
||||
}
|
||||
|
||||
g->link_objects.append(out_file_o);
|
||||
}
|
||||
|
||||
static const size_t int_sizes_in_bits[] = {
|
||||
|
@ -4550,6 +4562,10 @@ void codegen_add_root_assembly(CodeGen *g, Buf *src_dir, Buf *src_basename, Buf
|
|||
do_code_gen(g);
|
||||
}
|
||||
|
||||
void codegen_add_object(CodeGen *g, Buf *object_path) {
|
||||
g->link_objects.append(object_path);
|
||||
}
|
||||
|
||||
|
||||
static const char *c_int_type_names[] = {
|
||||
[CIntTypeShort] = "short",
|
||||
|
|
|
@ -48,6 +48,7 @@ void codegen_set_omit_zigrt(CodeGen *g, bool omit_zigrt);
|
|||
PackageTableEntry *new_package(const char *root_src_dir, const char *root_src_path);
|
||||
void codegen_add_root_code(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
|
||||
void codegen_add_root_assembly(CodeGen *g, Buf *source_dir, Buf *source_basename, Buf *source_code);
|
||||
void codegen_add_object(CodeGen *g, Buf *object_path);
|
||||
|
||||
void codegen_parseh(CodeGen *g, Buf *src_dirname, Buf *src_basename, Buf *source_code);
|
||||
void codegen_render_ast(CodeGen *g, FILE *f, int indent_size);
|
||||
|
|
36
src/link.cpp
36
src/link.cpp
|
@ -16,7 +16,6 @@ struct LinkJob {
|
|||
Buf out_file;
|
||||
ZigList<const char *> args;
|
||||
bool link_in_crt;
|
||||
Buf out_file_o;
|
||||
HashMap<Buf *, bool, buf_hash, buf_eql_buf> rpath_table;
|
||||
};
|
||||
|
||||
|
@ -32,14 +31,6 @@ static const char *get_libc_static_file(CodeGen *g, const char *file) {
|
|||
return buf_ptr(out_buf);
|
||||
}
|
||||
|
||||
static const char *get_o_file_extension(CodeGen *g) {
|
||||
if (g->zig_target.env_type == ZigLLVM_MSVC) {
|
||||
return ".obj";
|
||||
} else {
|
||||
return ".o";
|
||||
}
|
||||
}
|
||||
|
||||
static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
||||
Buf *source_basename = buf_sprintf("%s.zig", oname);
|
||||
|
||||
|
@ -78,7 +69,7 @@ static Buf *build_o(CodeGen *parent_gen, const char *oname) {
|
|||
}
|
||||
|
||||
codegen_add_root_code(child_gen, parent_gen->zig_std_special_dir, source_basename, &source_code);
|
||||
const char *o_ext = get_o_file_extension(child_gen);
|
||||
const char *o_ext = target_o_file_ext(&child_gen->zig_target);
|
||||
Buf *o_out = buf_sprintf("%s%s", oname, o_ext);
|
||||
codegen_link(child_gen, buf_ptr(o_out));
|
||||
|
||||
|
@ -274,7 +265,9 @@ static void construct_linker_job_elf(LinkJob *lj) {
|
|||
}
|
||||
|
||||
// .o files
|
||||
lj->args.append((const char *)buf_ptr(&lj->out_file_o));
|
||||
for (size_t i = 0; i < g->link_objects.length; i += 1) {
|
||||
lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
|
||||
}
|
||||
|
||||
if (g->is_test_build) {
|
||||
Buf *test_runner_o_path = build_o(g, "test_runner");
|
||||
|
@ -417,7 +410,9 @@ static void construct_linker_job_coff(LinkJob *lj) {
|
|||
lj->args.append(buf_ptr(g->libc_static_lib_dir));
|
||||
}
|
||||
|
||||
lj->args.append((const char *)buf_ptr(&lj->out_file_o));
|
||||
for (size_t i = 0; i < g->link_objects.length; i += 1) {
|
||||
lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
|
||||
}
|
||||
|
||||
if (g->is_test_build) {
|
||||
Buf *test_runner_o_path = build_o(g, "test_runner");
|
||||
|
@ -681,7 +676,9 @@ static void construct_linker_job_macho(LinkJob *lj) {
|
|||
lj->args.append(lib_dir);
|
||||
}
|
||||
|
||||
lj->args.append((const char *)buf_ptr(&lj->out_file_o));
|
||||
for (size_t i = 0; i < g->link_objects.length; i += 1) {
|
||||
lj->args.append((const char *)buf_ptr(g->link_objects.at(i)));
|
||||
}
|
||||
|
||||
if (g->is_test_build) {
|
||||
Buf *test_runner_o_path = build_o(g, "test_runner");
|
||||
|
@ -776,19 +773,6 @@ void codegen_link(CodeGen *g, const char *out_file) {
|
|||
buf_append_str(&lj.out_file, get_exe_file_extension(g));
|
||||
}
|
||||
}
|
||||
buf_init_from_buf(&lj.out_file_o, &lj.out_file);
|
||||
|
||||
if (g->out_type != OutTypeObj || !override_out_file) {
|
||||
const char *o_ext = get_o_file_extension(g);
|
||||
buf_append_str(&lj.out_file_o, o_ext);
|
||||
}
|
||||
|
||||
char *err_msg = nullptr;
|
||||
if (LLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(&lj.out_file_o),
|
||||
LLVMObjectFile, &err_msg))
|
||||
{
|
||||
zig_panic("unable to write object file: %s", err_msg);
|
||||
}
|
||||
|
||||
if (g->out_type == OutTypeObj) {
|
||||
if (g->want_h_file) {
|
||||
|
|
86
src/main.cpp
86
src/main.cpp
|
@ -24,6 +24,8 @@ static int usage(const char *arg0) {
|
|||
" build_exe [source] create executable from source\n"
|
||||
" build_lib [source] create library from source\n"
|
||||
" build_obj [source] create object from source\n"
|
||||
" link_exe [objects] create executable from objects\n"
|
||||
" link_lib [objects] create library from objects\n"
|
||||
" parseh [source] convert a c header file to zig extern declarations\n"
|
||||
" targets list available compilation targets\n"
|
||||
" test [source] create and run a test build\n"
|
||||
|
@ -108,6 +110,7 @@ enum Cmd {
|
|||
CmdParseH,
|
||||
CmdTargets,
|
||||
CmdAsm,
|
||||
CmdLink,
|
||||
};
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -147,6 +150,7 @@ int main(int argc, char **argv) {
|
|||
const char *linker_script = nullptr;
|
||||
ZigList<const char *> rpath_list = {0};
|
||||
bool each_lib_rpath = false;
|
||||
ZigList<const char *> objects = {0};
|
||||
|
||||
if (argc >= 2 && strcmp(argv[1], "build") == 0) {
|
||||
const char *zig_exe_path = arg0;
|
||||
|
@ -304,6 +308,12 @@ int main(int argc, char **argv) {
|
|||
} else if (strcmp(arg, "build_lib") == 0) {
|
||||
cmd = CmdBuild;
|
||||
out_type = OutTypeLib;
|
||||
} else if (strcmp(arg, "link_lib") == 0) {
|
||||
cmd = CmdLink;
|
||||
out_type = OutTypeLib;
|
||||
} else if (strcmp(arg, "link_exe") == 0) {
|
||||
cmd = CmdLink;
|
||||
out_type = OutTypeExe;
|
||||
} else if (strcmp(arg, "version") == 0) {
|
||||
cmd = CmdVersion;
|
||||
} else if (strcmp(arg, "parseh") == 0) {
|
||||
|
@ -330,6 +340,9 @@ int main(int argc, char **argv) {
|
|||
return usage(arg0);
|
||||
}
|
||||
break;
|
||||
case CmdLink:
|
||||
objects.append(arg);
|
||||
break;
|
||||
case CmdVersion:
|
||||
case CmdTargets:
|
||||
return usage(arg0);
|
||||
|
@ -344,11 +357,24 @@ int main(int argc, char **argv) {
|
|||
case CmdParseH:
|
||||
case CmdTest:
|
||||
case CmdAsm:
|
||||
case CmdLink:
|
||||
{
|
||||
if (!in_file)
|
||||
return usage(arg0);
|
||||
bool one_source_input = (cmd == CmdBuild || cmd == CmdParseH || cmd == CmdTest || cmd == CmdAsm);
|
||||
if (one_source_input) {
|
||||
if (!in_file) {
|
||||
fprintf(stderr, "Expected source file argument.\n");
|
||||
return usage(arg0);
|
||||
}
|
||||
} else if (cmd == CmdLink) {
|
||||
if (objects.length == 0) {
|
||||
fprintf(stderr, "Expected one or more object arguments.\n");
|
||||
return usage(arg0);
|
||||
}
|
||||
} else {
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
assert(cmd != CmdBuild || out_type != OutTypeUnknown);
|
||||
assert((cmd != CmdBuild && cmd != CmdLink) || out_type != OutTypeUnknown);
|
||||
|
||||
init_all_targets();
|
||||
|
||||
|
@ -379,10 +405,9 @@ int main(int argc, char **argv) {
|
|||
}
|
||||
}
|
||||
|
||||
bool need_name = (cmd == CmdBuild || cmd == CmdAsm);
|
||||
bool need_name = (cmd == CmdBuild || cmd == CmdAsm || cmd == CmdLink);
|
||||
|
||||
Buf in_file_buf = BUF_INIT;
|
||||
buf_init_from_str(&in_file_buf, in_file);
|
||||
|
||||
Buf root_source_dir = BUF_INIT;
|
||||
Buf root_source_code = BUF_INIT;
|
||||
|
@ -390,26 +415,35 @@ int main(int argc, char **argv) {
|
|||
|
||||
Buf *buf_out_name = (cmd == CmdTest) ? buf_create_from_str("test") :
|
||||
(out_name == nullptr) ? nullptr : buf_create_from_str(out_name);
|
||||
if (buf_eql_str(&in_file_buf, "-")) {
|
||||
|
||||
if (one_source_input) {
|
||||
buf_init_from_str(&in_file_buf, in_file);
|
||||
|
||||
if (buf_eql_str(&in_file_buf, "-")) {
|
||||
os_get_cwd(&root_source_dir);
|
||||
if ((err = os_fetch_file(stdin, &root_source_code))) {
|
||||
fprintf(stderr, "unable to read stdin: %s\n", err_str(err));
|
||||
return 1;
|
||||
}
|
||||
buf_init_from_str(&root_source_name, "");
|
||||
|
||||
} else {
|
||||
os_path_split(&in_file_buf, &root_source_dir, &root_source_name);
|
||||
if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) {
|
||||
fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (need_name && buf_out_name == nullptr) {
|
||||
buf_out_name = buf_alloc();
|
||||
Buf ext_name = BUF_INIT;
|
||||
os_path_extname(&root_source_name, buf_out_name, &ext_name);
|
||||
}
|
||||
}
|
||||
} else if (cmd == CmdLink) {
|
||||
os_get_cwd(&root_source_dir);
|
||||
if ((err = os_fetch_file(stdin, &root_source_code))) {
|
||||
fprintf(stderr, "unable to read stdin: %s\n", err_str(err));
|
||||
return 1;
|
||||
}
|
||||
buf_init_from_str(&root_source_name, "");
|
||||
|
||||
} else {
|
||||
os_path_split(&in_file_buf, &root_source_dir, &root_source_name);
|
||||
if ((err = os_fetch_file_path(buf_create_from_str(in_file), &root_source_code))) {
|
||||
fprintf(stderr, "unable to open '%s': %s\n", in_file, err_str(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (need_name && buf_out_name == nullptr) {
|
||||
buf_out_name = buf_alloc();
|
||||
Buf ext_name = BUF_INIT;
|
||||
os_path_extname(&root_source_name, buf_out_name, &ext_name);
|
||||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
if (need_name && buf_out_name == nullptr) {
|
||||
|
@ -484,6 +518,12 @@ int main(int argc, char **argv) {
|
|||
codegen_add_root_code(g, &root_source_dir, &root_source_name, &root_source_code);
|
||||
codegen_link(g, out_file);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (cmd == CmdLink) {
|
||||
for (size_t i = 0; i < objects.length; i += 1) {
|
||||
codegen_add_object(g, buf_create_from_str(objects.at(i)));
|
||||
}
|
||||
codegen_link(g, out_file);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (cmd == CmdAsm) {
|
||||
codegen_add_root_assembly(g, &root_source_dir, &root_source_name, &root_source_code);
|
||||
codegen_link(g, out_file);
|
||||
|
|
16
src/os.hpp
16
src/os.hpp
|
@ -54,4 +54,20 @@ int os_delete_file(Buf *path);
|
|||
|
||||
int os_file_exists(Buf *full_path, bool *result);
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#define ZIG_OS_DARWIN
|
||||
#elif defined(_WIN32)
|
||||
#define ZIG_OS_WINDOWS
|
||||
#elif defined(__linux__)
|
||||
#define ZIG_OS_LINUX
|
||||
#else
|
||||
#define ZIG_OS_UNKNOWN
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__)
|
||||
#define ZIG_ARCH_X86_64
|
||||
#else
|
||||
#define ZIG_ARCH_UNKNOWN
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -527,3 +527,12 @@ int get_c_type_size_in_bits(const ZigTarget *target, CIntType id) {
|
|||
}
|
||||
zig_unreachable();
|
||||
}
|
||||
|
||||
const char *target_o_file_ext(ZigTarget *target) {
|
||||
if (target->env_type == ZigLLVM_MSVC) {
|
||||
return ".obj";
|
||||
} else {
|
||||
return ".o";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -72,4 +72,6 @@ void resolve_target_object_format(ZigTarget *target);
|
|||
|
||||
int get_c_type_size_in_bits(const ZigTarget *target, CIntType id);
|
||||
|
||||
const char *target_o_file_ext(ZigTarget *target);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -18,6 +18,7 @@ enum TestSpecial {
|
|||
TestSpecialNone,
|
||||
TestSpecialSelfHosted,
|
||||
TestSpecialStd,
|
||||
TestSpecialLinkStep,
|
||||
};
|
||||
|
||||
struct TestSourceFile {
|
||||
|
@ -36,6 +37,7 @@ struct TestCase {
|
|||
ZigList<TestSourceFile> source_files;
|
||||
ZigList<const char *> compile_errors;
|
||||
ZigList<const char *> compiler_args;
|
||||
ZigList<const char *> linker_args;
|
||||
ZigList<const char *> program_args;
|
||||
bool is_parseh;
|
||||
TestSpecial special;
|
||||
|
@ -89,6 +91,37 @@ static TestCase *add_simple_case(const char *case_name, const char *source, cons
|
|||
return test_case;
|
||||
}
|
||||
|
||||
static TestCase *add_asm_case(const char *case_name, const char *source, const char *output) {
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = case_name;
|
||||
test_case->output = output;
|
||||
test_case->special = TestSpecialLinkStep;
|
||||
|
||||
test_case->source_files.resize(1);
|
||||
test_case->source_files.at(0).relative_path = ".tmp_source.s";
|
||||
test_case->source_files.at(0).source_code = source;
|
||||
|
||||
test_case->compiler_args.append("asm");
|
||||
test_case->compiler_args.append(".tmp_source.s");
|
||||
test_case->compiler_args.append("--name");
|
||||
test_case->compiler_args.append("test");
|
||||
test_case->compiler_args.append("--color");
|
||||
test_case->compiler_args.append("on");
|
||||
|
||||
test_case->linker_args.append("link_exe");
|
||||
test_case->linker_args.append("test.o");
|
||||
test_case->linker_args.append("--name");
|
||||
test_case->linker_args.append("test");
|
||||
test_case->linker_args.append("--output");
|
||||
test_case->linker_args.append(tmp_exe_path);
|
||||
test_case->linker_args.append("--color");
|
||||
test_case->linker_args.append("on");
|
||||
|
||||
test_cases.append(test_case);
|
||||
|
||||
return test_case;
|
||||
}
|
||||
|
||||
static TestCase *add_simple_case_libc(const char *case_name, const char *source, const char *output) {
|
||||
TestCase *tc = add_simple_case(case_name, source, output);
|
||||
tc->compiler_args.append("--library");
|
||||
|
@ -129,46 +162,23 @@ static TestCase *add_compile_fail_case(const char *case_name, const char *source
|
|||
}
|
||||
|
||||
static void add_debug_safety_case(const char *case_name, const char *source) {
|
||||
{
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->is_debug_safety = true;
|
||||
test_case->case_name = buf_ptr(buf_sprintf("%s (debug)", case_name));
|
||||
test_case->source_files.resize(1);
|
||||
test_case->source_files.at(0).relative_path = tmp_source_path;
|
||||
test_case->source_files.at(0).source_code = source;
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->is_debug_safety = true;
|
||||
test_case->case_name = buf_ptr(buf_sprintf("%s", case_name));
|
||||
test_case->source_files.resize(1);
|
||||
test_case->source_files.at(0).relative_path = tmp_source_path;
|
||||
test_case->source_files.at(0).source_code = source;
|
||||
|
||||
test_case->compiler_args.append("build_exe");
|
||||
test_case->compiler_args.append(tmp_source_path);
|
||||
test_case->compiler_args.append("build_exe");
|
||||
test_case->compiler_args.append(tmp_source_path);
|
||||
|
||||
test_case->compiler_args.append("--name");
|
||||
test_case->compiler_args.append("test");
|
||||
test_case->compiler_args.append("--name");
|
||||
test_case->compiler_args.append("test");
|
||||
|
||||
test_case->compiler_args.append("--output");
|
||||
test_case->compiler_args.append(tmp_exe_path);
|
||||
test_case->compiler_args.append("--output");
|
||||
test_case->compiler_args.append(tmp_exe_path);
|
||||
|
||||
test_cases.append(test_case);
|
||||
}
|
||||
{
|
||||
TestCase *test_case = allocate<TestCase>(1);
|
||||
test_case->case_name = buf_ptr(buf_sprintf("%s (release)", case_name));
|
||||
test_case->source_files.resize(1);
|
||||
test_case->source_files.at(0).relative_path = tmp_source_path;
|
||||
test_case->source_files.at(0).source_code = source;
|
||||
test_case->output = "";
|
||||
|
||||
test_case->compiler_args.append("build_exe");
|
||||
test_case->compiler_args.append(tmp_source_path);
|
||||
|
||||
test_case->compiler_args.append("--name");
|
||||
test_case->compiler_args.append("test");
|
||||
|
||||
test_case->compiler_args.append("--output");
|
||||
test_case->compiler_args.append(tmp_exe_path);
|
||||
|
||||
test_case->compiler_args.append("--release");
|
||||
|
||||
test_cases.append(test_case);
|
||||
}
|
||||
test_cases.append(test_case);
|
||||
}
|
||||
|
||||
static TestCase *add_parseh_case(const char *case_name, AllowWarnings allow_warnings,
|
||||
|
@ -1865,9 +1875,7 @@ pub fn panic(message: []const u8) -> noreturn {
|
|||
while (true) {}
|
||||
}
|
||||
pub fn main() -> %void {
|
||||
if (!@compileVar("is_release")) {
|
||||
@panic("oh no");
|
||||
}
|
||||
@panic("oh no");
|
||||
}
|
||||
)SOURCE");
|
||||
|
||||
|
@ -2375,6 +2383,32 @@ static void add_std_lib_tests(void) {
|
|||
}
|
||||
}
|
||||
|
||||
static void add_asm_tests(void) {
|
||||
#if defined(ZIG_OS_LINUX) && defined(ZIG_ARCH_X86_64)
|
||||
add_asm_case("assemble and link hello world linux x86_64", R"SOURCE(
|
||||
.text
|
||||
.globl _start
|
||||
|
||||
_start:
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
lea rsi, msg
|
||||
mov rdx, 14
|
||||
syscall
|
||||
|
||||
mov rax, 60
|
||||
mov rdi, 0
|
||||
syscall
|
||||
|
||||
.data
|
||||
|
||||
msg:
|
||||
.ascii "Hello, world!\n"
|
||||
)SOURCE", "Hello, world!\n");
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void print_compiler_invocation(TestCase *test_case) {
|
||||
printf("%s", zig_exe);
|
||||
|
@ -2384,6 +2418,15 @@ static void print_compiler_invocation(TestCase *test_case) {
|
|||
printf("\n");
|
||||
}
|
||||
|
||||
static void print_linker_invocation(TestCase *test_case) {
|
||||
printf("%s", zig_exe);
|
||||
for (size_t i = 0; i < test_case->linker_args.length; i += 1) {
|
||||
printf(" %s", test_case->linker_args.at(i));
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
|
||||
static void print_exe_invocation(TestCase *test_case) {
|
||||
printf("%s", tmp_exe_path);
|
||||
for (size_t i = 0; i < test_case->program_args.length; i += 1) {
|
||||
|
@ -2470,6 +2513,23 @@ static void run_test(TestCase *test_case) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (test_case->special == TestSpecialLinkStep) {
|
||||
Buf link_stderr = BUF_INIT;
|
||||
Buf link_stdout = BUF_INIT;
|
||||
int err;
|
||||
Termination term;
|
||||
if ((err = os_exec_process(zig_exe, test_case->linker_args, &term, &link_stderr, &link_stdout))) {
|
||||
fprintf(stderr, "Unable to exec %s: %s\n", zig_exe, err_str(err));
|
||||
}
|
||||
|
||||
if (term.how != TerminationIdClean || term.code != 0) {
|
||||
printf("\nLink failed:\n");
|
||||
print_linker_invocation(test_case);
|
||||
printf("%s\n", buf_ptr(&zig_stderr));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
Buf program_stderr = BUF_INIT;
|
||||
Buf program_stdout = BUF_INIT;
|
||||
os_exec_process(tmp_exe_path, test_case->program_args, &term, &program_stderr, &program_stdout);
|
||||
|
@ -2520,9 +2580,13 @@ static void run_test(TestCase *test_case) {
|
|||
}
|
||||
}
|
||||
|
||||
static void run_all_tests(void) {
|
||||
static void run_all_tests(const char *grep_text) {
|
||||
for (size_t i = 0; i < test_cases.length; i += 1) {
|
||||
TestCase *test_case = test_cases.at(i);
|
||||
if (grep_text != nullptr && strstr(test_case->case_name, grep_text) == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("Test %zu/%zu %s...", i + 1, test_cases.length, test_case->case_name);
|
||||
fflush(stdout);
|
||||
run_test(test_case);
|
||||
|
@ -2538,13 +2602,24 @@ static void cleanup(void) {
|
|||
}
|
||||
|
||||
static int usage(const char *arg0) {
|
||||
fprintf(stderr, "Usage: %s\n", arg0);
|
||||
fprintf(stderr, "Usage: %s [--grep text]\n", arg0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const char *grep_text = nullptr;
|
||||
for (int i = 1; i < argc; i += 1) {
|
||||
return usage(argv[0]);
|
||||
const char *arg = argv[i];
|
||||
if (i + 1 >= argc) {
|
||||
return usage(argv[0]);
|
||||
} else {
|
||||
i += 1;
|
||||
if (strcmp(arg, "--grep") == 0) {
|
||||
grep_text = argv[i];
|
||||
} else {
|
||||
return usage(argv[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
add_compiling_test_cases();
|
||||
add_debug_safety_test_cases();
|
||||
|
@ -2552,6 +2627,7 @@ int main(int argc, char **argv) {
|
|||
add_parseh_test_cases();
|
||||
add_self_hosted_tests();
|
||||
add_std_lib_tests();
|
||||
run_all_tests();
|
||||
add_asm_tests();
|
||||
run_all_tests(grep_text);
|
||||
cleanup();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue