What first comes to mind is that functions that should be exposed to a C interface should be defined with export fn, not pub fn. I’m not sure if that solves your problem, though.
Also, with -O ReleaseSmall (or ReleaseFast) the size of the C file will be much smaller.
I’ve just tried this myself (0.14.0-dev.2545+e2e363361/macos aarch64). I think the problem may be that you’re specifying a target (you look like you’re building on Windows, but asking the output C to be for x86_64-linux).
zig build-obj -ofmt=c src/main.zig
zig cc -o main main.c -I...
./main
Sum is 5
First, -O ReleaseSmall helps make it from 123000 lines to 4000. Thanks for that.
Second, I hopped over to my Ubuntu WSL instance with zig version 0.14.0-dev.2639+15fe99957 to try to compile there.
zig build-obj -ofmt=c ./src/main.zig
zig cc -o main main.c -I/home/draco/zig/lib
ld.lld: error: duplicate symbol: _start
>>> defined at /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crt1.o:(_start)
>>> defined at main.c:794
>>> /mnt/c/Users/Draco/Documents/Projects/zig/zig-c/.zig-cache/o/e23adaa98d1cff462ecd7bdc927a78e1/main.o:(.text+0x0)
There are two ways you can solve the duplicate _start error. The issue is that, the way you’re currently doing it, both Zig and the C standard library/runtime are trying to provide their own executable entry point (_start) and conflicting with each other.
Tell Zig to link libc when building the initial C output file (add -lc to the first command):
$ zig build-obj -ofmt=c -lc main.zig
$ zig cc -o main main.c -I$HOME/src/zig/lib
$ ./main
Sum is 5
This also fixes the issue from your original message, which appears to be present in the code Zig is generating for its _start implementation. Given that fact, I’d recommend going with this option.
Tell the C compiler not to use the standard library when building the executable from the C output file (add -nostdlib to the second command):
$ zig build-obj -ofmt=c -OReleaseSmall main.zig
$ zig cc -o main main.c -I$HOME/src/zig/lib -nostdlib
$ ./main
Sum is 5
Now, given you’re using zig build-obj and not zig build-exe, I’m not entirely sure of the rationale for Zig still exporting _start (that is, the reason for the @hasDecl(root, "main") check here: zig/lib/std/start.zig at fb43e91b226a9cde51967455c57989c0371d4b0a · ziglang/zig · GitHub). If that condition weren’t there, then I would expect it to work fine just by adding export to your main function.