Reputation: 91
Closed - see the end of the entry
I want to make a C callable library using the zig language. I decided to start with the two examples in the Zig documentation. "Exporting a C Library" and "Mixing Object Files". In each case I copied the three relevant files(from 0.6.0 docs).
Both examples fail to build.
The Exporting a C Library example fails to compile test.c with a message cannot find mathtest.h
The Mixing Object Files example fails to compile test.c with cannot find base64.h
Here are the three files for the Exporting C Libary example:
mathtest.zig
export fn add(a: i32, b: i32) i32 {
return a + b;
}
test.c
// This header is generated by zig from mathtest.zig
#include "mathtest.h"
#include <stdio.h>
int main(int argc, char **argv) {
int32_t result = add(42, 1337);
printf("%d\n", result);
return 0;
}
build.zig
const Builder = @import("std").build.Builder;
pub fn build(b: *Builder) void {
const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
const exe = b.addExecutable("test", null);
exe.addCSourceFile("test.c", &[_][]const u8{"-std=c99"});
exe.linkLibrary(lib);
exe.linkSystemLibrary("c");
b.default_step.dependOn(&exe.step);
const run_cmd = exe.run();
const test_step = b.step("test", "Test the program");
test_step.dependOn(&run_cmd.step);
}
Part of the error message
~/Projects/zig/z-c-lib $ zig build test
/home/robert/Projects/zig/z-c-lib/test.c:2:10: fatal error: 'mathtest.h' file not found
#include "mathtest.h"
^~~~~~~~~~~~
1 error generated.
The following command failed:
/home/robert/zig/zig clang -c -nostdinc -fno-spell-checking -target x86_64-unknown-linux-gnu -isystem /home/robert/zig/lib/zig/include -isystem /home/robert/zig/lib/zig/libc/include/x86_64-linux-gnu -isystem /home/robert/zig/lib/zig/libc/include/generic-glibc -isystem /home/robert/zig/lib/zig/libc/include/x86_64-linux-any -isystem /home/robert/zig/lib/zig/libc/include/any-linux-any -Xclang -target-cpu -Xclang znver2 -Xclang -target-feature -Xclang -3dnow -Xclang -target-feature -Xclang -3dnowa -Xclang -target-feature -Xclang +64bit -Xclang -target-feature -Xclang +adx -Xclang -target-feature -Xclang +aes -Xclang -target-feature -Xclang +avx -Xclang -target-feature -Xclang +avx2 -Xclang -target-feature -Xclang -avx512bf16 -Xclang -target-feature -Xclang -avx512b
I cannot find a file named mathtest.h
on my system so I assume it was not generated, contrary to the claim in the test.c file.
What am I missing ? Help gratefully accepted.
Answers and More questions
I discovered the -femit-h
options:
zig build-lib mathtest.zig -femit-h
will create a mathtest.h
file and then
zig build
will be successful.
I further discovered that
these lines in the build.zig
files
const lib = b.addSharedLibrary('mathtest', 'mathtest.zig', b.version(1, 0, 0));
lib.femit_h = true;
will ensure that
zig build test
will be successful and generate the answer 1379 as indicated in the docs.
BUT - this mod to the build.zig file does not leave a mathtest.h
file around after it runs.
That seems to be the final hurdle to generating a usable C library from a Zig code.
Final piece in the puzzle
If I add
lib.setOutputDir("build");
to the build.zig
file. The mathtest.h
and libmathtest.a
(or .so) files will be saved into a build
dir.
Call this one close
Upvotes: 2
Views: 3793
Reputation: 91
Ok so part of the answer is simple, but maybe obscure, the -femit-h options. The command
zig build-lib mathtest.zig -femit-h
will generate a mathtest.h
file.
But how do I add that options to the
const lib = b.addSharedLibrary("mathtest", "mathtest.zig", b.version(1, 0, 0));
line in the build.zig file.
Upvotes: 5