Skip to content

Commit

Permalink
generated zig-cc wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
kassane committed Jan 17, 2025
1 parent d420ca1 commit 3e53abc
Show file tree
Hide file tree
Showing 2 changed files with 146 additions and 78 deletions.
156 changes: 146 additions & 10 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -628,14 +628,10 @@ pub fn ldcBuildStep(b: *Build, options: DCompileStep) !*std.Build.Step.InstallDi
installdir.step.dependOn(&ldc_exec.step);

if (options.zig_cc) {
const zcc = buildZigCC(b);
const install = b.addInstallArtifact(zcc, .{ .dest_dir = .{ .override = .{ .custom = "tools" } } });
const zcc_path = b.pathJoin(&.{ b.install_prefix, "tools", if (options.target.result.os.tag == .windows) "zcc.exe" else "zcc" });
const zcc_exists = !std.meta.isError(std.fs.accessAbsolute(zcc_path, .{}));
if (!zcc_exists)
ldc_exec.step.dependOn(&install.step);
ldc_exec.addArg(b.fmt("--gcc={s}", .{zcc_path}));
ldc_exec.addArg(b.fmt("--linker={s}", .{zcc_path}));
const target_options = try buildOptions(b, options.target);
const zcc = buildZigCC(b, target_options);
ldc_exec.addPrefixedFileArg("--gcc=", zcc.getEmittedBin());
ldc_exec.addPrefixedFileArg("--linker=", zcc.getEmittedBin());
}

const example_run = b.addSystemCommand(&.{b.pathJoin(&.{ b.install_path, outputDir, options.name })});
Expand Down Expand Up @@ -738,16 +734,156 @@ pub fn path(b: *std.Build, sub_path: []const u8) std.Build.LazyPath {
// -------------------------- Others Configuration --------------------------

// zig-cc wrapper for ldc2
pub fn buildZigCC(b: *Build) *CompileStep {
pub fn buildZigCC(b: *std.Build, options: *std.Build.Step.Options) *std.Build.Step.Compile {
const zigcc = b.addWriteFiles();

const exe = b.addExecutable(.{
.name = "zcc",
.target = b.graph.host,
.optimize = .ReleaseSafe,
.root_source_file = b.path("tools/zigcc.zig"),
.root_source_file = zigcc.add("zcc.zig", generated_zcc),
});
exe.root_module.addOptions("build_options", options);
return exe;
}

pub fn buildOptions(b: *std.Build, target: std.Build.ResolvedTarget) !*std.Build.Step.Options {
const zigcc_options = b.addOptions();

// Native target, zig can read 'zig libc' contents and also link system libraries.
const native = if (target.query.isNative()) switch (target.result.abi) {
.msvc => "native-native-msvc",
else => "native-native",
} else try target.result.zigTriple(b.allocator);
zigcc_options.addOption(
?[]const u8,
"triple",
native,
);
zigcc_options.addOption(
?[]const u8,
"cpu",
target.result.cpu.model.name,
);
return zigcc_options;
}

const generated_zcc =
\\ const std = @import("std");
\\ const builtin = @import("builtin");
\\ const build_options = @import("build_options");
\\ // [NOT CHANGE!!] => skip flag
\\ // replace system-provider resources to zig provider resources
\\
\\ pub fn main() !void {
\\ var gpa = std.heap.GeneralPurposeAllocator(.{}){};
\\ defer _ = std.debug.assert(gpa.deinit() == .ok); // ok or leak
\\ const allocator = gpa.allocator();
\\
\\ var args = try std.process.argsWithAllocator(allocator);
\\ defer args.deinit();
\\
\\ _ = args.skip(); // skip arg[0]
\\
\\ var cmds = std.ArrayList([]const u8).init(allocator);
\\ defer cmds.deinit();
\\
\\ try cmds.append("zig");
\\ try cmds.append("cc");
\\
\\ while (args.next()) |arg| {
\\ // HACK: ldmd2 emit '-target' flag for Darwin, but zigcc already have it
\\ if (std.mem.startsWith(u8, arg, "arm64-apple-") or
\\ std.mem.startsWith(u8, arg, "x86_64-apple-"))
\\ {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "-target")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "-group")) {
\\ try cmds.appendSlice(&.{
\\ "-Wl,--start-group",
\\ "-Wl,--end-group",
\\ });
\\ } else if (std.mem.endsWith(u8, arg, "-dynamic")) {
\\ try cmds.append("-Wl,--export-dynamic");
\\ } else if (std.mem.eql(u8, arg, "--exclude-libs") or std.mem.eql(u8, arg, "ALL")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "rv64gc") or
\\ std.mem.endsWith(u8, arg, "rv32i_zicsr_zifencei"))
\\ {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "--hash-style")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "--build-id")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "whole-archive")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "--eh-frame-hdr")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "as-needed")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "gcc") or
\\ std.mem.endsWith(u8, arg, "gcc_s"))
\\ {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "-lFortran")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "linkonceodr-outlining")) {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "aarch64linux") or
\\ std.mem.startsWith(u8, arg, "elf"))
\\ {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "/lib/ld-") or
\\ std.mem.startsWith(u8, arg, "-dynamic-linker"))
\\ {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "crtendS.o") or
\\ std.mem.endsWith(u8, arg, "crtn.o"))
\\ {
\\ // NOT CHANGE!!
\\ } else if (std.mem.endsWith(u8, arg, "crtbeginS.o") or
\\ std.mem.endsWith(u8, arg, "crti.o") or
\\ std.mem.endsWith(u8, arg, "Scrt1.o"))
\\ {
\\ // NOT CHANGE!!
\\ } else if (std.mem.startsWith(u8, arg, "-m") or
\\ std.mem.startsWith(u8, arg, "elf_"))
\\ {
\\ // NOT CHANGE!!
\\ } else {
\\ try cmds.append(arg);
\\ }
\\ }
\\
\\ if (build_options.triple) |triple_target| {
\\ try cmds.append("-target");
\\ try cmds.append(triple_target);
\\ }
\\ if (build_options.cpu) |cpu| {
\\ try cmds.append(std.fmt.comptimePrint("-mcpu={s}", .{cpu}));
\\ }
\\
\\ if (builtin.os.tag != .windows) {
\\ try cmds.append("-lunwind");
\\ }
\\
\\ var proc = std.process.Child.init(cmds.items, allocator);
\\
\\ try std.io.getStdOut().writer().print("[zig cc] flags: \"", .{});
\\ for (cmds.items) |cmd| {
\\ if (std.mem.startsWith(u8, cmd, "zig")) continue;
\\ if (std.mem.startsWith(u8, cmd, "cc")) continue;
\\ try std.io.getStdOut().writer().print("{s} ", .{cmd});
\\ }
\\ try std.io.getStdOut().writer().print("\"\n", .{});
\\
\\ _ = try proc.spawnAndWait();
\\ }
;

// -------------------------- Build Steps --------------------------

// a separate step to compile shaders, expects the shader compiler in ../sokol-tools-bin/
fn buildShaders(b: *Build, target: Build.ResolvedTarget) void {
if (b.lazyDependency("shdc", .{})) |dep| {
Expand Down
68 changes: 0 additions & 68 deletions tools/zigcc.zig

This file was deleted.

0 comments on commit 3e53abc

Please sign in to comment.