Reproduce command
Some checks failed
CI / ci (MinSizeRel, ubuntu-latest) (pull_request) Failing after 32s
CI / ci (RelWithDebInfo, ubuntu-latest) (pull_request) Failing after 31s
CI / ci (Release, ubuntu-latest) (pull_request) Failing after 31s
CI / ci (Debug, ubuntu-latest) (pull_request) Failing after 1m5s

This commit is contained in:
David Gonzalez Martin 2025-06-21 07:58:19 -06:00
parent 03aa714a51
commit 2bfc16c662
5 changed files with 100 additions and 3 deletions

View File

@ -34,3 +34,4 @@ jobs:
./generate.sh
./build.sh
./build/bb test
./build/bb reproduce

View File

@ -984,6 +984,7 @@ CompilerCommand = enum
{
compile,
test,
reproduce,
}
BuildMode = enum
@ -18283,7 +18284,7 @@ compile_file = fn (arena: &Arena, compile_options: CompileFile, envp: &&u8) []u8
{
>builder: ArgumentBuilder = zero;
add_argument(&builder, "/home/david/dev/llvm/install/llvm_20.1.3_x86_64-linux-Release/bin/llvm-config");
add_argument(&builder, arena_join_string(module.arena, [ CMAKE_PREFIX_PATH, "/bin/llvm-config"][..]);
add_argument(&builder, "--libdir");
add_argument(&builder, "--libs");
add_argument(&builder, "--system-libs");
@ -18558,7 +18559,10 @@ names: [_][]u8 =
return 1;
}
>debug_info_array: [_]u1 = [1, 0];
>command = command_string_to_enum.enum_value;
switch (command)
{
.compile =>
@ -18620,7 +18624,6 @@ names: [_][]u8 =
report_error();
}
>debug_info_array: [_]u1 = [1, 0];
for (name: names)
{
for (build_mode: #enum_values(BuildMode))
@ -18656,6 +18659,43 @@ names: [_][]u8 =
}
}
},
.reproduce =>
{
for (build_mode: #enum_values(BuildMode))
{
for (has_debug_info: debug_info_array)
{
>position = arena.position;
// Produce the compiler
>relative_file_path = "src/compiler.bbb";
>executable_path = compile_file(arena, {
.relative_file_path = relative_file_path,
.build_mode = build_mode,
.has_debug_info = has_debug_info,
.silent = 1,
}, envp);
// Test the compiler
>arguments: [_]&u8 = [
executable_path.pointer,
"test",
zero,
];
>args = arguments[..arguments.length - 1];
>execution = os_execute(arena, args, envp, zero);
>success = execution.termination_kind == .exit and execution.termination_code == 0;
if (!success)
{
#trap();
}
arena.position = position;
}
}
},
}
return 0;

View File

@ -93,6 +93,7 @@ fn void compile(Arena* arena, Options options)
.name = options.name,
.path = options.path,
.executable = options.executable,
.definitions = options.definitions,
.objects = options.objects,
.library_directories = options.library_directories,
.library_names = options.library_names,
@ -174,6 +175,13 @@ fn String compile_file(Arena* arena, Compile options)
auto file_content = file_read(arena, relative_file_path);
auto file_path = path_absolute(arena, relative_file_path);
Slice<Definition> definitions = {};
auto cmake_prefix_path = string_literal(CMAKE_PREFIX_PATH);
auto cmake_prefix_path_definition = Definition{
.name = string_literal("CMAKE_PREFIX_PATH"),
.value = cmake_prefix_path,
};
String objects[] = {
output_object_path,
};
@ -190,9 +198,11 @@ fn String compile_file(Arena* arena, Compile options)
if (is_compiler)
{
definitions = { .pointer = &cmake_prefix_path_definition, .length = 1 };
ArgBuilder builder = {};
String llvm_config_parts[] = {
string_literal(CMAKE_PREFIX_PATH),
cmake_prefix_path,
string_literal("/bin/llvm-config"),
};
builder.add(arena, arena_join_string(arena, array_to_slice(llvm_config_parts)));
@ -300,6 +310,7 @@ fn String compile_file(Arena* arena, Compile options)
.path = file_path,
.executable = output_executable_path,
.name = base_name,
.definitions = definitions,
.objects = object_slice,
.library_paths = library_paths,
.library_names = library_names,
@ -619,6 +630,24 @@ void entry_point(Slice<char* const> arguments, Slice<char* const> envp)
print(compiler_has_debug_info ? string_literal(" with debug info\n") : string_literal(" with no debug info\n"));
bb_fail();
}
char* const reproduce_arguments[] =
{
(char*)compiler.pointer,
(char*)"reproduce",
0,
};
arg_slice = array_to_slice(reproduce_arguments);
arg_slice.length -= 1;
execution = os_execute(arena, arg_slice, environment, {});
success = execution.termination_kind == TerminationKind::exit && execution.termination_code == 0;
if (!success)
{
print(string_literal("Self-hosted reproduction failed: "));
print(build_mode_to_string(compiler_build_mode));
print(compiler_has_debug_info ? string_literal(" with debug info\n") : string_literal(" with no debug info\n"));
bb_fail();
}
}
}
} break;

View File

@ -1296,6 +1296,12 @@ struct ModuleLLVM
u32 debug_tag;
};
struct Definition
{
String name;
String value;
};
struct Module
{
Arena* arena;
@ -1330,6 +1336,7 @@ struct Module
String path;
String executable;
Slice<Definition> definitions;
Slice<String> objects;
Slice<String> library_directories;
Slice<String> library_names;
@ -1408,6 +1415,7 @@ struct Options
String path;
String executable;
String name;
Slice<Definition> definitions;
Slice<String> objects;
Slice<String> library_paths;
Slice<String> library_names;

View File

@ -3166,6 +3166,25 @@ fn Block* parse_block(Module* module, Scope* parent_scope)
void parse(Module* module)
{
auto scope = &module->scope;
for (auto definition: module->definitions)
{
auto definition_global = new_global(module);
auto definition_value = new_value(module);
*definition_value = {
.string_literal = definition.value,
.id = ValueId::string_literal,
};
*definition_global = Global{
.variable = {
.initial_value = definition_value,
.type = get_slice_type(module, uint8(module)),
.scope = scope,
.name = definition.name,
},
};
}
while (1)
{
skip_space(module);