Can't build to android

I am trying to build to android.

Files like these:

build.zig

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addLibrary(.{
        .name = "testso",
        .linkage = .dynamic,
        .root_module = b.createModule(.{
            .target = target,
            .optimize = optimize,
            .link_libc = true,
        }),
    });

    lib.addCSourceFile(.{ .file = b.path("test.c") });

    b.installArtifact(lib);
}

test.c

#include <string.h>

int func1()
{
    printf("hello world!");
    return 0;
}

android libc file

# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\include

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.

sys_include_dir=E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\include\aarch64-linux-android

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

Build command line:
zig build -Dtarget=aarch64-linux-android --libc "android.conf"

But the compiler report error:

install
└─ install testso
   └─ zig build-lib testso Debug aarch64-linux-android 6 errors
F:\test\zigbug\test.c:1:10: error: 'string.h' file not found
#include <string.h>
         ^~~~~~~~~~~
\crtbegin_so.o: BadPathNameKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34
\crtbegin_so.oe parsing E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34
\crtend_so.o: BadPathNameSDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34
\crtend_so.oile parsing E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34
error: failed to parse shared library: BadPathName
\libm.so: while parsing E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34
error: failed to parse shared library: BadPathName
\libc.so: while parsing E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34
error: failed to parse shared library: BadPathName
\libdl.so while parsing E:\SDKs\AndroidSDK\ndk\27.0.12077973\toolchains\llvm\prebuilt\windows-x86_64\sysroot\usr\lib\aarch64-linux-android\34
error: warning(compilation): failed to delete 'F:\test\zigbug\.zig-cache\tmp\1a580fc7f6c24c8e-test.o.d': FileNotFound

error: the following command failed with 6 compilation errors:
F:\test\zig\zig-windows-x86_64-0.14.0\zig.exe build-lib F:\test\zigbug\test.c -ODebug -target aarch64-linux-android -mcpu baseline -Mroot -lc --libc android.conf --cache-dir F:\test\zi
gbug\.zig-cache --global-cache-dir C:\Users\Administrator\AppData\Local\zig --name testso -dynamic --zig-lib-dir F:\code2\tools\zig\zig-windows-x86_64-0.14.0\lib\ --listen=-
Build Summary: 0/3 steps succeeded; 1 failed
install transitive failure
└─ install testso transitive failure
   └─ zig build-lib testso Debug aarch64-linux-android 6 errors
error: the following build command failed with exit code 1:
F:\test\zigbug\.zig-cache\o\6778774e7813522235bc965053f6bb7f\build.exe F:\code2\tools\zig\zig-windows-x86_64-0.14.0\zig.exe F:\code2\tools\zig\zig-windows-x86_64-0.14.0\lib F:\test\zigbug F:\
test\zigbug\.zig-cache C:\Users\Administrator\AppData\Local\zig --seed 0x71da49d0 -Z1bf269ed2b04bbcc -Dtarget=aarch64-linux-android --libc android.conf

What did I make a mistake?

You probably need to link lib c.
In build.zig

    lib.linkLibC();

You tell zig build where to find libc, but you never ask it to link it for your artifact.

I have set ‘root_module.link_libc = true’

Write file is ok:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const lib = b.addLibrary(.{
        .name = "testso",
        .linkage = .dynamic,
        .root_module = b.createModule(.{
            .target = target,
            .optimize = optimize,
        }),
    });

    lib.linkLibC();

    const system_target = getAndroidTriple(lib.rootModuleTarget()) catch |err| @panic(@errorName(err));

    const android_api_version: u32 = 34;

    const libc = createLibC(b, system_target, android_api_version, "E:\\SDKs\\AndroidSDK\\ndk\\27.0.12077973\\toolchains\\llvm\\prebuilt\\windows-x86_64\\sysroot", "27.0.12077973");

    lib.setLibCFile(libc);

    lib.root_module.addCSourceFile(.{ .file = b.path("test.c") });

    b.installArtifact(lib);
}

fn getAndroidTriple(target: std.Target) error{InvalidAndroidTarget}![]const u8 {
    if (target.abi != .android) return error.InvalidAndroidTarget;
    return switch (target.cpu.arch) {
        .x86 => "i686-linux-android",
        .x86_64 => "x86_64-linux-android",
        .arm => "arm-linux-androideabi",
        .aarch64 => "aarch64-linux-android",
        .riscv64 => "riscv64-linux-android",
        else => error.InvalidAndroidTarget,
    };
}

fn createLibC(b: *std.Build, system_target: []const u8, android_api_version: u32, ndk_sysroot_path: []const u8, ndk_version: []const u8) std.Build.LazyPath {
    const libc_file_format =
        \\# Generated by zig-android-sdk. DO NOT EDIT.
        \\
        \\# The directory that contains `stdlib.h`.
        \\# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
        \\include_dir={[include_dir]s}
        \\
        \\# The system-specific include directory. May be the same as `include_dir`.
        \\# On Windows it's the directory that includes `vcruntime.h`.
        \\# On POSIX it's the directory that includes `sys/errno.h`.
        \\sys_include_dir={[sys_include_dir]s}
        \\
        \\# The directory that contains `crt1.o`.
        \\# On POSIX, can be found with `cc -print-file-name=crt1.o`.
        \\# Not needed when targeting MacOS.
        \\crt_dir={[crt_dir]s}
        \\
        \\# The directory that contains `vcruntime.lib`.
        \\# Only needed when targeting MSVC on Windows.
        \\msvc_lib_dir=
        \\
        \\# The directory that contains `kernel32.lib`.
        \\# Only needed when targeting MSVC on Windows.
        \\kernel32_lib_dir=
        \\
        \\gcc_dir=
    ;

    const include_dir = b.fmt("{s}/usr/include", .{ndk_sysroot_path});
    const sys_include_dir = b.fmt("{s}/usr/include/{s}", .{ ndk_sysroot_path, system_target });
    const crt_dir = b.fmt("{s}/usr/lib/{s}/{d}", .{ ndk_sysroot_path, system_target, android_api_version });

    const libc_file_contents = b.fmt(libc_file_format, .{
        .include_dir = include_dir,
        .sys_include_dir = sys_include_dir,
        .crt_dir = crt_dir,
    });

    const filename = b.fmt("android-libc_target-{s}_version-{d}_ndk-{s}.conf", .{ system_target, android_api_version, if (ndk_version.len > 0) ndk_version else "unknown" });

    const write_file = b.addWriteFiles();
    const android_libc_path = write_file.add(filename, libc_file_contents);
    return android_libc_path;
}

seems --libc [file] command line argument isn’t work.

1 Like

Ahh, didn’t see that sorry. I’m too used to using the method to linkLibC.

It seems like you were able to find a way around it.