@@ -172,6 +172,9 @@ const CustomCase = enum {
172172 generated_graph_200_5 ,
173173 list_builtin_inlined ,
174174 default_platform_linux_disassembly ,
175+ default_platform_build_x64glibc ,
176+ default_platform_build_arm64glibc ,
177+ default_platform_build_wasm32 ,
175178 default_platform_crash_x64musl ,
176179 default_platform_crash_arm64musl ,
177180 default_platform_crash_x64mac ,
@@ -528,6 +531,9 @@ const subcommand_cases = [_]CliCase{
528531 .{ .id = 0 , .suite = .subcommands , .name = "roc check generated module graph handles many imported files" , .body = .{ .custom = .generated_graph_200_5 } },
529532 .{ .id = 0 , .suite = .subcommands , .name = "list builtins inline in native --opt=speed build" , .body = .{ .custom = .list_builtin_inlined } },
530533 .{ .id = 0 , .suite = .subcommands , .name = "roc build default platform x64musl matches direct write assembly" , .skip = .{ .always = "TODO: direct-write default-platform codegen" }, .body = .{ .custom = .default_platform_linux_disassembly } },
534+ .{ .id = 0 , .suite = .subcommands , .name = "roc build default platform x64glibc succeeds" , .body = .{ .custom = .default_platform_build_x64glibc } },
535+ .{ .id = 0 , .suite = .subcommands , .name = "roc build default platform arm64glibc succeeds" , .body = .{ .custom = .default_platform_build_arm64glibc } },
536+ .{ .id = 0 , .suite = .subcommands , .name = "roc build default platform wasm32 archive succeeds" , .body = .{ .custom = .default_platform_build_wasm32 } },
531537 .{ .id = 0 , .suite = .subcommands , .name = "default platform crash prints debug backtrace on x64musl" , .body = .{ .custom = .default_platform_crash_x64musl } },
532538 .{ .id = 0 , .suite = .subcommands , .name = "default platform crash prints debug backtrace on arm64musl" , .body = .{ .custom = .default_platform_crash_arm64musl } },
533539 .{ .id = 0 , .suite = .subcommands , .name = "default platform crash prints debug backtrace on x64mac" , .body = .{ .custom = .default_platform_crash_x64mac } },
@@ -1397,6 +1403,9 @@ fn runCustomCase(
13971403 .generated_graph_200_5 = > customGeneratedModuleGraph (io , allocator , & env , & timer , timeout_ms , .{ .roc_file_count = 200 , .symbols_per_file = 5 }),
13981404 .list_builtin_inlined = > customListBuiltinInlined (io , allocator , & env , & timer , timeout_ms ),
13991405 .default_platform_linux_disassembly = > customDefaultPlatformLinuxDisassembly (io , allocator , & env , & timer , timeout_ms ),
1406+ .default_platform_build_x64glibc = > customDefaultPlatformBuild (io , allocator , & env , & timer , timeout_ms , .x64glibc ),
1407+ .default_platform_build_arm64glibc = > customDefaultPlatformBuild (io , allocator , & env , & timer , timeout_ms , .arm64glibc ),
1408+ .default_platform_build_wasm32 = > customDefaultPlatformBuild (io , allocator , & env , & timer , timeout_ms , .wasm32 ),
14001409 .default_platform_crash_x64musl = > customDefaultPlatformDebugBacktrace (io , allocator , & env , & timer , timeout_ms , .x64musl , .crash ),
14011410 .default_platform_crash_arm64musl = > customDefaultPlatformDebugBacktrace (io , allocator , & env , & timer , timeout_ms , .arm64musl , .crash ),
14021411 .default_platform_crash_x64mac = > customDefaultPlatformDebugBacktrace (io , allocator , & env , & timer , timeout_ms , .x64mac , .crash ),
@@ -1719,20 +1728,30 @@ fn isHexDigit(byte: u8) bool {
17191728const DefaultPlatformTarget = enum {
17201729 x64musl ,
17211730 arm64musl ,
1731+ x64glibc ,
1732+ arm64glibc ,
17221733 x64mac ,
17231734 arm64mac ,
17241735 x64win ,
17251736 arm64win ,
1737+ wasm32 ,
17261738
17271739 fn cliName (self : DefaultPlatformTarget ) []const u8 {
17281740 return @tagName (self );
17291741 }
17301742
1743+ fn canBuildOnHost (self : DefaultPlatformTarget ) bool {
1744+ return switch (self ) {
1745+ .x64glibc , .arm64glibc = > builtin .os .tag == .linux ,
1746+ else = > true ,
1747+ };
1748+ }
1749+
17311750 fn canRunOnHost (self : DefaultPlatformTarget ) bool {
17321751 return switch (builtin .os .tag ) {
17331752 .linux = > switch (builtin .cpu .arch ) {
1734- .x86_64 = > self == .x64musl ,
1735- .aarch64 = > self == .arm64musl ,
1753+ .x86_64 = > self == .x64musl or self == .x64glibc ,
1754+ .aarch64 = > self == .arm64musl or self == .arm64glibc ,
17361755 else = > false ,
17371756 },
17381757 .macos = > switch (builtin .cpu .arch ) {
@@ -1745,6 +1764,7 @@ const DefaultPlatformTarget = enum {
17451764 .aarch64 = > self == .arm64win ,
17461765 else = > false ,
17471766 },
1767+ .freestanding = > false ,
17481768 else = > false ,
17491769 };
17501770 }
@@ -1799,6 +1819,78 @@ const default_platform_stack_overflow_debug_app =
17991819 \\
18001820;
18011821
1822+ const default_platform_echo_app =
1823+ \\main! = |_| {
1824+ \\ echo!("Hello, World!")
1825+ \\ Ok({})
1826+ \\}
1827+ \\
1828+ ;
1829+
1830+ fn customDefaultPlatformBuild (
1831+ io : std.Io ,
1832+ allocator : Allocator ,
1833+ env : * const CaseEnv ,
1834+ timer : * harness.Timer ,
1835+ timeout_ms : u64 ,
1836+ target : DefaultPlatformTarget ,
1837+ ) ? TestResult {
1838+ if (! target .canBuildOnHost ()) {
1839+ const message = std .fmt .allocPrint (
1840+ allocator ,
1841+ "{s} default-platform build requires Linux host support" ,
1842+ .{target .cliName ()},
1843+ ) catch "default-platform build requires Linux host support" ;
1844+ return .{ .status = .skip , .phase = .setup , .duration_ns = timer .read (), .message = message };
1845+ }
1846+
1847+ const app_filename = std .fmt .allocPrint (allocator , "default_platform_build_{s}.roc" , .{target .cliName ()}) catch | err |
1848+ return customInfraFailure (allocator , timer , "failed to allocate default platform app filename: {}" , .{err });
1849+ const app_path = std .fs .path .join (allocator , &.{ env .dirs .work_dir , app_filename }) catch | err |
1850+ return customInfraFailure (allocator , timer , "failed to allocate default platform app path: {}" , .{err });
1851+ const output_path = std .fs .path .join (allocator , &.{ env .dirs .work_dir , "default_platform_build" }) catch | err |
1852+ return customInfraFailure (allocator , timer , "failed to allocate default platform output path: {}" , .{err });
1853+ const target_arg = std .fmt .allocPrint (allocator , "--target={s}" , .{target .cliName ()}) catch | err |
1854+ return customInfraFailure (allocator , timer , "failed to allocate target arg: {}" , .{err });
1855+ const out_arg = outputArg (allocator , output_path ) catch | err |
1856+ return customInfraFailure (allocator , timer , "failed to allocate output arg: {}" , .{err });
1857+
1858+ std .Io .Dir .cwd ().writeFile (io , .{ .sub_path = app_path , .data = default_platform_echo_app }) catch | err |
1859+ return customInfraFailure (allocator , timer , "failed to write default platform app: {}" , .{err });
1860+
1861+ if (runRocAndCheck (io , allocator , env , timer , timeout_ms , .{
1862+ .args = &.{ "build" , "--opt=speed" , "--no-cache" , target_arg , out_arg },
1863+ .roc_file = app_path ,
1864+ .contains = &.{.{ .stream = .stdout , .text = "Built " }},
1865+ })) | failure | return failure ;
1866+
1867+ if (target == .wasm32 ) {
1868+ var file = std .Io .Dir .cwd ().openFile (io , output_path , .{ .mode = .read_only }) catch | err |
1869+ return customInfraFailure (allocator , timer , "failed to open built wasm archive: {}" , .{err });
1870+ defer file .close (io );
1871+
1872+ var magic : [8 ]u8 = undefined ;
1873+ const bytes_read = file .readPositionalAll (io , & magic , 0 ) catch | err |
1874+ return customInfraFailure (allocator , timer , "failed to read built wasm archive: {}" , .{err });
1875+ if (bytes_read != magic .len or ! std .mem .eql (u8 , magic [0.. ], "!<arch>\n " )) {
1876+ return customFailure (allocator , timer , "wasm32 default platform output was not an archive" , .{});
1877+ }
1878+ }
1879+
1880+ if (target .canRunOnHost ()) {
1881+ const executable_path = runnableOutputPath (io , allocator , output_path ) catch | err |
1882+ return customInfraFailure (allocator , timer , "failed to find built executable: {}" , .{err });
1883+
1884+ if (runRawAndCheck (io , allocator , env , timer , timeout_ms , &.{executable_path }, env .dirs .work_dir , .{
1885+ .args = &.{},
1886+ .stdout_exact = "Hello, World!\n " ,
1887+ .stderr_exact = "" ,
1888+ })) | failure | return failure ;
1889+ }
1890+
1891+ return null ;
1892+ }
1893+
18021894fn customDefaultPlatformDebugBacktrace (
18031895 io : std.Io ,
18041896 allocator : Allocator ,
0 commit comments