# How to export a function named "main" accepting no arguments?

**URL:** <https://ziggit.dev/t/how-to-export-a-function-named-main-accepting-no-arguments/3750>\
**Category:** Help\
**Tags:** language\
**Created:** [March 29, 2024, 2:20pm UTC](https://ziggit.dev/t/how-to-export-a-function-named-main-accepting-no-arguments/3750 "2024-03-29T14:20:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [March 29, 2024, 2:20pm UTC](https://ziggit.dev/t/how-to-export-a-function-named-main-accepting-no-arguments/3750/1 "2024-03-29T14:20:53Z")

</div>

I’m trying to link libc into a wasm project. The library seems to expect `main` even though `lib.entry` is set to `.disabled`. Oh well, just need to stick an empty function in there I guess. If I put the following in a zig file:

```zig
export fn main() callconv(.C) c_int {
    return 0;
}

```

The linker pulls in an additional function from `__main_void.c`:

```c
// If the user's `main` function expects arguments, the compiler will rename
// it to `__main_argc_argv`, and this version will get linked in, which
// initializes the argument data and calls `__main_argc_argv`.
__attribute__ (( __weak__ , nodebug))
int __main_void(void) {

```

wasm-objdump indicates that `main` has the following signiture:

```zig
- type[2] (i32, i32) -> i32

```

So `argc` and `argv` are still there somehow. If I add the through a C file instead, I get the correct behavior:

```c
int main(void) { 
    return 0; 
}

```

---

<div class="post-metadata">

**Author:** ![castholm](https://ziggit.dev/user_avatar/ziggit.dev/castholm/32/1330_2.png) [@castholm](https://ziggit.dev/u/castholm)\
**Post date:** [March 29, 2024, 3:51pm UTC](https://ziggit.dev/t/how-to-export-a-function-named-main-accepting-no-arguments/3750/2 "2024-03-29T15:51:31Z")

</div>

It’s not clear what `lib` is from your description. Is it your wasm artifact? Is it an external library you’re linking your wasm artifact with?  
Could you post your full build.zig script for context?

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [March 29, 2024, 4:01pm UTC](https://ziggit.dev/t/how-to-export-a-function-named-main-accepting-no-arguments/3750/3 "2024-03-29T16:01:29Z")

</div>

```zig
const std = @import("std");
const cfg = @import("./build-cfg.zig");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});
    const arch = if (@hasDecl(@TypeOf(target), "getCpuArch")) target.getCpuArch() else target.result.cpu.arch;
    const is_wasm = switch (arch) {
        .wasm32, .wasm64 => true,
        else => false,
    };
    const lib = b.addSharedLibrary(.{
        .name = cfg.module_name,
        .root_source_file = .{ .path = cfg.stub_path },
        .target = target,
        .optimize = optimize,
    });
    if (is_wasm) {
        lib.rdynamic = true;
    }
    const imports = .{};
    if (@hasDecl(std.Build.Step.Compile, "addModule")) {
        // Zig 0.11.0
        lib.addModule("exporter", b.createModule(.{
            .source_file = .{ .path = cfg.exporter_path },
        }));
        lib.addModule("module", b.createModule(.{
            .source_file = .{ .path = cfg.module_path },
            .dependencies = &imports,
        }));
    } else if (@hasField(std.Build.Step.Compile, "root_module")) {
        // Zig 0.12.0
        lib.root_module.addImport("exporter", b.createModule(.{
            .root_source_file = .{ .path = cfg.exporter_path },
        }));
        lib.root_module.addImport("module", b.createModule(.{
            .root_source_file = .{ .path = cfg.module_path },
            .imports = &imports,
        }));
        if (is_wasm) {
            // WASM needs to be compiled as exe
            lib.kind = .exe;
            lib.linkage = .static;
            lib.entry = .disabled;
        }
    }
    if (cfg.use_libc) {
        lib.linkLibC();
        if (is_wasm) {
            // add empty function expected by libc
            lib.addCSourceFile(.{ .file = .{ .path = "./main.c" }, .flags = &.{} });
        }
    }
    const wf = b.addWriteFiles();
    wf.addCopyFileToSource(lib.getEmittedBin(), cfg.output_path);
    wf.step.dependOn(&lib.step);
    b.getInstallStep().dependOn(&wf.step);
}

```

---

<div class="post-metadata">

**Author:** ![castholm](https://ziggit.dev/user_avatar/ziggit.dev/castholm/32/1330_2.png) [@castholm](https://ziggit.dev/u/castholm)\
**Post date:** [March 29, 2024, 4:33pm UTC](https://ziggit.dev/t/how-to-export-a-function-named-main-accepting-no-arguments/3750/4 "2024-03-29T16:33:33Z")

</div>

If you’re targeting `wasm32-wasi`, you can set `lib.wasi_exec_model = .reactor`. This will export a small `_initialize` function which must be called before any other exported symbols are accessed, but not require your artifact to export any `main` symbol.

---

<div class="post-metadata">

**Author:** ![chung-leong](https://ziggit.dev/user_avatar/ziggit.dev/chung-leong/32/999_2.png) [@chung-leong](https://ziggit.dev/u/chung-leong)\
**Post date:** [March 29, 2024, 7:22pm UTC](https://ziggit.dev/t/how-to-export-a-function-named-main-accepting-no-arguments/3750/5 "2024-03-29T19:22:54Z")

</div>

That was it. Thanks!
