Compile a static c library (archive .a)

I have a make files that generates a library like the following

> file libdevelutils.a && ar -t libdevelutils.a
libdevelutils.a: current ar archive
nonstd.o
testing.o
threads.o
loadingbarPretty.o
loadingbar.o
typecast.o
stream.o

The recipe in my make file looks like this (summarized for showing purposes)

$(STATIC): $(RELEASE_OBJ)
	@echo "[$(CC)] $@"
	ar rcs $@ $(RELEASE_OBJ)

I have been trying to generate a build.zig that generates the equivalent .a output but I instead generate something that looks like this

> zig build && file zig-out/lib/libstringcore.a  && nm zig-out/lib/libstringcore.a
zig-out/lib/libstringcore.a: current ar archive
bfd plugin: LLVM gold plugin has failed to create LTO module: Opaque pointers are only supported in -opaque-pointers mode (Producer: 'LLVM21.1.0' Reader: 'LLVM 14.0.6')

.zig-cache/o/06a7d78b2967e1e869062b95f9907b95/stringCore.o:
nm: .zig-cache/o/06a7d78b2967e1e869062b95f9907b95/stringCore.o: no symbols

When i try to use this output, the linker fails giving me this message

/usr/bin/ld: /usr/lib/nonstd/libstringcore.a: error adding symbols: file format not recognized
collect2: error: ld returned 1 exit status
make: *** [makefile:25: blt] Error 1

This is the part of my build.zig that I thought was supposed to make my archive but it is not working

    const source_files = collectSourceFiles(
        b,
        "src",
        ".c",
        .initComptime(.{.{ "tester.c", 0 }}),
    ) catch @panic("Failed to collect source files\n");

    const lib = b.addLibrary(.{
        .name = lib_name,
        .linkage = .static,
        .root_module = b.createModule(.{
            .link_libc = true,
            .optimize = optimize,
            .target = target,
        }),
    });
    lib.root_module.addCSourceFiles(
        .{ .files = source_files, .flags = flags, .language = .c },
    );
    b.installArtifact(lib);

I know I don’t fully understand the modules part of the build system. Am i wrong to use a module when creating a static library to be used with c?

1 Like

i wasn’t able to reproduce this on my machine (Fedora 43), could you give some details about your system?

my best guess is that this is caused by zig enabling lto by default and the version of llvm used by your machine is too old, you can try to work around this using lib.lto = .none;.

This is the information from my system

> nm --version && cat /etc/os-release && gcc --version && zig version
GNU nm (GNU Binutils for Debian) 2.40
Copyright (C) 2023 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

PRETTY_NAME="Debian GNU/Linux 12 (bookworm)"
NAME="Debian GNU/Linux"
VERSION_ID="12"
VERSION="12 (bookworm)"
VERSION_CODENAME=bookworm
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

gcc (Debian 12.2.0-14+deb12u1) 12.2.0
Copyright (C) 2022 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

0.16.0 // zig version

I set the options you suggested

lib.lto = .none

but it produced the same output. I have a feeling your are right. I have Debian 13 on my other machine. I will try it there

I finally got around to running the build.zig on my other machine. I didn’t have much luck

zig build && file zig-out/lib/libstringcore.a  && nm zig-out/lib/libstringcore.a
zig-out/lib/libstringcore.a: current ar archive
nm: .zig-cache/o/59272a80cff41070f41ed2d86b05dfc3/stringCore.o: file format not recognized

This is my other system

> nm --version && cat /etc/os-release && gcc --version && zig version
GNU nm (GNU Binutils for Debian) 2.44
Copyright (C) 2025 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
VERSION_ID="13"
VERSION="13 (trixie)"
VERSION_CODENAME=trixie
DEBIAN_VERSION_FULL=13.5
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

gcc (Debian 14.2.0-19) 14.2.0
Copyright (C) 2024 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

0.16.0

This might just be a Deiban issue. I will post a solutions here if i find one.