-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve LibC interface in build.zig #20327
Comments
This would be nice for linking newlib, currently I link it directly with linkLibrary, but then zig doesn't know that libc is linked and stuff like The way you described it with |
Seems related and along the same lines as: I currently manually link in the pre-compiled Something else mentioned in the other issue I ran into is even when I do setup my
Being able to control which libraries are linked in from libc would be nice, as in my case I'm targeting freestanding and don't have |
I think you have a typo there? - libc_file: ?LazyPath = null,
+ libc: ?std.Build.LibC = null, |
|
As a workaround, it is currently possible to use Zig-packaged libc's without hard-coding the paths by using a helper program to dynamically generate a libc.txt file from LazyPaths. Example code: // make-libc-file.zig
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
const allocator = gpa.allocator();
const args = try std.process.argsAlloc(allocator);
defer std.process.argsFree(allocator, args);
var output = std.io.getStdOut();
const valid_keys = .{ "include_dir", "sys_include_dir", "crt_dir", "msvc_lib_dir", "kernel32_lib_dir", "gcc_dir" };
for (args[1..]) |arg| {
var iter = std.mem.splitScalar(u8, arg, '=');
const key = iter.next() orelse return error.InvalidOrMissingKey;
const value = iter.next() orelse return error.InvalidOrMissingValue;
inline for (valid_keys) |valid_key| {
if (std.mem.eql(u8, valid_key, key)) {
try output.writeAll(valid_key ++ "=");
try output.writeAll(value);
try output.writeAll("\n");
}
}
}
} Example usage: const libc_file_builder = b.addExecutable(.{
.name = "libc_file_builder",
.target = b.resolveTargetQuery(.{}), // native
.optimize = .Debug,
.root_source_file = b.path("make-libc-file.zig"),
});
const make_libc_file = b.addRunArtifact(libc_file_builder);
make_libc_file.addArg("include_dir=/hardcoded/example");
make_libc_file.addPrefixedDirectoryArg("sys_include_dir=", b.path("example_sys_include_dir"));
make_libc_file.addPrefixedDirectoryArg("crt_dir=", crt_directory_lazy_path);
b.default_step.dependOn(&make_libc_file.step);
exe.setLibCFile(make_libc_file.captureStdOut()); It would be much simpler if this proposal were implemented. I could take a shot at implementing it if this proposal is accepted. |
There's another problem with |
This problem seems more general than setLibCFile; after all, even optimization and target options have to be manually exposed by libraries. Personally I think it may be reasonable to make custom libc a target option though, passing it down with the usual standardTargetOptions, though that may be a seperate issue. |
Portable libraries written in C often use something like a configure script or CMake to check what headers or symbols exist. If this proposal were implemented, there probably ought to be a way to perform these checks in the Zig build system too. |
Right now, the
--libc [file]
command line argument isn't really well exposed instd.Build.Step.Compile
:zig/lib/std/Build/Step/Compile.zig
Line 87 in 4558996
This implementation doesn't really give us the options to pass down ad-hoc compiled libcs like Foundation libc or newlib inside build.zig.
The fields available in a
libc.txt
file are these:These options could be exposed inside a struct
std.Build.LibC
:which could be used like this then:
Pre-defined libc:
Custom libc:
The text was updated successfully, but these errors were encountered: