Skip to content

Commit

Permalink
feat(libmain): add zig build
Browse files Browse the repository at this point in the history
  • Loading branch information
RossComputerGuy committed Feb 21, 2025
1 parent 64cf493 commit b991176
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 80 deletions.
165 changes: 165 additions & 0 deletions src/libmain/build.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
const std = @import("std");

fn readFile(b: *std.Build, path: []const u8) []const u8 {
var file = b.build_root.handle.openFile(path, .{}) catch |err| std.debug.panic("Failed to open {s}: {}", .{ path, err });
defer file.close();

const meta = file.metadata() catch |err| std.debug.panic("Failed to get metadata for {s}: {}", .{ path, err });

return file.readToEndAlloc(b.allocator, meta.size()) catch @panic("OOM");
}

pub fn build(b: *std.Build) void {
const optimize = b.standardOptimizeOption(.{});
const target = b.standardTargetOptions(.{});
const linkage = b.option(std.builtin.LinkMode, "linkage", "The link mode of binaries");
const fsys_libutil = b.systemIntegrationOption("nix-util", .{});
const fsys_libstore = b.systemIntegrationOption("nix-store", .{});
const use_meson_libs = std.mem.eql(u8, b.graph.env_map.get("USE_MESON_LIBS") orelse "0", "1");

const config = b.addConfigHeader(.{
.include_path = "config-main.hh",
}, .{
.HAVE_PUBSETBUF = 1,
});

const libmain = std.Build.Step.Compile.create(b, .{
.name = "nixmain",
.kind = .lib,
.linkage = linkage,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
.link_libc = true,
.link_libcpp = true,
}),
});

libmain.addConfigHeader(config);
libmain.addIncludePath(b.path("."));

libmain.root_module.addCMacro("SYSTEM", b.fmt("\"{s}-{s}\"", .{
@tagName(target.result.cpu.arch),
@tagName(target.result.os.tag),
}));

libmain.addCSourceFiles(.{
.files = &.{
"common-args.cc",
"loggers.cc",
"plugin.cc",
"progress-bar.cc",
"shared.cc",
},
.flags = &.{
"--std=c++2a",
b.fmt("-I{s}", .{std.mem.trimRight(u8, b.run(&.{ "pkg-config", "--variable=includedir", "boost" }), "\n")}),
},
});

if (target.result.os.tag == .windows) {
libmain.addCSourceFile(.{
.file = b.path("unix/stack.cc"),
.flags = &.{
"--std=c++2a",
b.fmt("-I{s}", .{std.mem.trimRight(u8, b.run(&.{ "pkg-config", "--variable=includedir", "boost" }), "\n")}),
},
});
}

libmain.installHeader(config.getOutput(), "nix/config-main.hh");

if (fsys_libutil) {
if (use_meson_libs) {
libmain.linkSystemLibrary("nixutil");

for (b.search_prefixes.items) |prefix| {
const path = b.pathJoin(&.{ prefix, "include", "nix" });

var dir = std.fs.cwd().openDir(path, .{}) catch continue;
defer dir.close();

libmain.root_module.addSystemIncludePath(.{ .cwd_relative = path });
}

libmain.linkSystemLibrary("libarchive");
libmain.linkSystemLibrary("boost");
libmain.linkSystemLibrary("nlohmann_json");
} else {
libmain.linkSystemLibrary("nix-util");
}
} else {
const libutil = b.dependency("nix-util", .{
.target = target,
.optimize = optimize,
.linkage = linkage orelse .static,
});

libmain.linkLibrary(libutil.artifact("nixutil"));

for (libutil.artifact("nixutil").root_module.include_dirs.items) |hdr| {
libmain.root_module.include_dirs.append(b.allocator, hdr) catch @panic("OOM");
}

libmain.linkSystemLibrary("libarchive");
libmain.linkSystemLibrary("boost");
libmain.linkSystemLibrary("nlohmann_json");
}

if (fsys_libstore) {
if (use_meson_libs) {
libmain.linkSystemLibrary("nixstore");

for (b.search_prefixes.items) |prefix| {
const path = b.pathJoin(&.{ prefix, "include", "nix" });

var dir = std.fs.cwd().openDir(path, .{}) catch continue;
defer dir.close();

libmain.root_module.addSystemIncludePath(.{ .cwd_relative = path });
}
} else {
libmain.linkSystemLibrary("nix-store");
}
} else {
const libstore = b.dependency("nix-store", .{
.target = target,
.optimize = optimize,
.linkage = linkage orelse .static,
});

libmain.linkLibrary(libstore.artifact("nixstore"));

for (libstore.artifact("nixstore").root_module.include_dirs.items) |hdr| {
libmain.root_module.include_dirs.append(b.allocator, hdr) catch @panic("OOM");
}
}

inline for (&.{
"common-args.hh",
"loggers.hh",
"plugin.hh",
"progress-bar.hh",
"shared.hh",
}) |hdr| {
libmain.installHeader(b.path(hdr), "nix/" ++ hdr);
}

b.installArtifact(libmain);

b.getInstallStep().dependOn(&b.addInstallFileWithDir(b.addWriteFile("nix-main.pc", b.fmt(
\\prefix={s}
\\libdir={s}
\\includedir={s}
\\
\\Name: Nix
\\Description: Nix Package Manager
\\Version: 0.1.0
\\Cflags: -I${{includedir}}/nix -std=c++2a
\\Libs: -L${{libdir}} -lnixmain
, .{
b.getInstallPath(.prefix, ""),
b.getInstallPath(.lib, ""),
b.getInstallPath(.header, ""),
})).getDirectory().path(b, "nix-main.pc"), .lib, "pkgconfig/nix-main.pc").step);
}
13 changes: 13 additions & 0 deletions src/libmain/build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.{
.name = "nix-main",
.version = "0.1.0",
.paths = .{"."},
.dependencies = .{
.@"nix-util" = .{
.path = "../libutil",
},
.@"nix-store" = .{
.path = "../libstore",
},
},
}
125 changes: 47 additions & 78 deletions src/libmain/meson.build
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
project('nix-main', 'cpp',
project('nix-main',
version : files('.zix-version'),
default_options : [
'cpp_std=c++2a',
# TODO(Qyriad): increase the warning level
'warning_level=1',
'errorlogs=true', # Please print logs for tests that fail
Expand All @@ -10,88 +9,58 @@ project('nix-main', 'cpp',
license : 'LGPL-2.1-or-later',
)

cxx = meson.get_compiler('cpp')
fs = import('fs')

subdir('nix-meson-build-support/deps-lists')
subdir('nix-meson-build-support/zig')

configdata = configuration_data()
zig_prefix = meson.current_build_dir() / 'zig-out'

deps_private_maybe_subproject = [
]
deps_public_maybe_subproject = [
dependency('nix-util'),
dependency('nix-store'),
]
subdir('nix-meson-build-support/subprojects')
deps = []

pubsetbuf_test = '''
#include <iostream>
using namespace std;
char buf[1024];
int main() {
cerr.rdbuf()->pubsetbuf(buf, sizeof(buf));
}
'''

configdata.set(
'HAVE_PUBSETBUF',
cxx.compiles(pubsetbuf_test).to_int(),
description: 'Optionally used for buffering on standard error'
)

config_h = configure_file(
configuration : configdata,
output : 'config-main.hh',
)

add_project_arguments(
# TODO(Qyriad): Yes this is how the autoconf+Make system did it.
# It would be nice for our headers to be idempotent instead.
'-include', 'config-util.hh',
'-include', 'config-store.hh',
'-include', 'config-main.hh',
language : 'cpp',
)

subdir('nix-meson-build-support/common')

sources = files(
'common-args.cc',
'loggers.cc',
'plugin.cc',
'progress-bar.cc',
'shared.cc',
)

if host_machine.system() != 'windows'
sources += files(
'unix/stack.cc',
)
libutil = dependency('nix-util', required: false)
if libutil.found()
deps += libutil
zig_build_args += [
'-fsys=nix-util',
'--search-prefix', libutil.get_variable('prefix'),
'--search-prefix', fs.parent(libutil.get_variable('includedir')),
'--search-prefix', fs.parent(libutil.get_variable('libdir')),
]
endif

include_dirs = [include_directories('.')]

headers = [config_h] + files(
'common-args.hh',
'loggers.hh',
'plugin.hh',
'progress-bar.hh',
'shared.hh',
)
libstore = dependency('nix-store', required: false)
if libstore.found()
deps += libstore
zig_build_args += [
'-fsys=nix-store',
'--search-prefix', libstore.get_variable('prefix'),
'--search-prefix', fs.parent(libstore.get_variable('includedir')),
'--search-prefix', fs.parent(libstore.get_variable('libdir')),
]
endif

this_library = library(
'nixmain',
sources,
dependencies : deps_public + deps_private + deps_other,
prelink : true, # For C++ static initializers
install : true,
zig_target = custom_target('zig build',
output: ['zig-out'],
command: [zig, 'build', zig_build_args, '--prefix', zig_prefix, '--build-file', meson.project_source_root() / 'build.zig'],
env: {
'USE_MESON_LIBS': '1',
},
)

install_headers(headers, subdir : 'nix', preserve_path : true)

libraries_private = []

subdir('nix-meson-build-support/export')
includedir = zig_prefix / 'include' / 'nix'
compile_args = ['-I' + includedir]

install_subdir(zig_prefix / 'lib', install_dir: get_option('libdir'), strip_directory: true)
install_subdir(zig_prefix / 'include', install_dir: get_option('includedir'), strip_directory: true)

meson.override_dependency('nix-main', declare_dependency(
compile_args: compile_args,
link_args: ['-L' + zig_prefix / 'lib', '-lnixmain'],
sources: [zig_target],
dependencies: deps,
variables: {
'prefix': zig_prefix,
'includedir': zig_prefix / 'include',
'libdir': zig_prefix / 'lib'
}
))
11 changes: 9 additions & 2 deletions src/libmain/package.nix
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
lib,
mkMesonLibrary,
mkZigLibrary,

nix-util,
nix-store,
Expand All @@ -15,7 +15,7 @@ let
inherit (lib) fileset;
in

mkMesonLibrary (finalAttrs: {
mkZigLibrary (finalAttrs: {
pname = "zix-main";
inherit version nixVersion;

Expand All @@ -31,13 +31,20 @@ mkMesonLibrary (finalAttrs: {
./meson.options
(fileset.fileFilter (file: file.hasExt "cc") ./.)
(fileset.fileFilter (file: file.hasExt "hh") ./.)
(fileset.fileFilter (file: file.hasExt "zig") ./.)
(fileset.fileFilter (file: file.hasExt "zon") ./.)
];

propagatedBuildInputs = [
nix-util
nix-store
];

postInstall = ''
substituteInPlace $out/lib/pkgconfig/nix-main.pc \
--replace-fail "includedir=$out" "includedir=$dev"
'';

meta = {
platforms = lib.platforms.unix ++ lib.platforms.windows;
};
Expand Down

0 comments on commit b991176

Please sign in to comment.