Skip to content

Commit

Permalink
Merge pull request #176 from aherrmann/dynamic-linker
Browse files Browse the repository at this point in the history
feat: Support custom dynamic linker
  • Loading branch information
aherrmann authored Dec 30, 2023
2 parents f4476c2 + a00ffea commit 4d41d5f
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 3 deletions.
4 changes: 2 additions & 2 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import %workspace%/.bazelrc.remote
# To update these lines, execute
# `bazel run @rules_bazel_integration_test//tools:update_deleted_packages`
# docs: https://bazel.build/reference/command-line-reference#flag--deleted_packages
build --deleted_packages=e2e/workspace,e2e/workspace/c-sources,e2e/workspace/configure-mode,e2e/workspace/configure-target,e2e/workspace/configure-threaded,e2e/workspace/data-dependencies,e2e/workspace/embed-file,e2e/workspace/include-dependencies,e2e/workspace/include-dependencies/zig-include,e2e/workspace/include-dependencies/zig-include-define,e2e/workspace/include-dependencies/zig-include-isystem,e2e/workspace/include-dependencies/zig-std-include,e2e/workspace/link-dependencies,e2e/workspace/link-dependencies/static-library,e2e/workspace/linker-script,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-shared-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace
query --deleted_packages=e2e/workspace,e2e/workspace/c-sources,e2e/workspace/configure-mode,e2e/workspace/configure-target,e2e/workspace/configure-threaded,e2e/workspace/data-dependencies,e2e/workspace/embed-file,e2e/workspace/include-dependencies,e2e/workspace/include-dependencies/zig-include,e2e/workspace/include-dependencies/zig-include-define,e2e/workspace/include-dependencies/zig-include-isystem,e2e/workspace/include-dependencies/zig-std-include,e2e/workspace/link-dependencies,e2e/workspace/link-dependencies/static-library,e2e/workspace/linker-script,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-shared-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace
build --deleted_packages=e2e/workspace,e2e/workspace/c-sources,e2e/workspace/configure-mode,e2e/workspace/configure-target,e2e/workspace/configure-threaded,e2e/workspace/data-dependencies,e2e/workspace/embed-file,e2e/workspace/include-dependencies,e2e/workspace/include-dependencies/zig-include,e2e/workspace/include-dependencies/zig-include-define,e2e/workspace/include-dependencies/zig-include-isystem,e2e/workspace/include-dependencies/zig-std-include,e2e/workspace/link-dependencies,e2e/workspace/link-dependencies/static-library,e2e/workspace/linker-script,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-shared-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace,zig/tests/integration_tests/workspace/custom_interpreter
query --deleted_packages=e2e/workspace,e2e/workspace/c-sources,e2e/workspace/configure-mode,e2e/workspace/configure-target,e2e/workspace/configure-threaded,e2e/workspace/data-dependencies,e2e/workspace/embed-file,e2e/workspace/include-dependencies,e2e/workspace/include-dependencies/zig-include,e2e/workspace/include-dependencies/zig-include-define,e2e/workspace/include-dependencies/zig-include-isystem,e2e/workspace/include-dependencies/zig-std-include,e2e/workspace/link-dependencies,e2e/workspace/link-dependencies/static-library,e2e/workspace/linker-script,e2e/workspace/multiple-sources-and-packages-test,e2e/workspace/multiple-sources-binary,e2e/workspace/simple-binary,e2e/workspace/simple-library,e2e/workspace/simple-shared-library,e2e/workspace/simple-test,e2e/workspace/transitive-zig-packages-binary,e2e/workspace/transitive-zig-packages-binary/hello-world,e2e/workspace/transitive-zig-packages-binary/hello-world/data,e2e/workspace/transitive-zig-packages-binary/hello-world/data/hello,e2e/workspace/transitive-zig-packages-binary/hello-world/data/world,e2e/workspace/transitive-zig-packages-binary/hello-world/io,e2e/workspace/zig-package-binary,e2e/workspace/zig-package-binary/data,e2e/workspace/zig-package-binary/io,zig/tests/integration_tests/workspace,zig/tests/integration_tests/workspace/custom_interpreter

# Load any settings specific to the current user.
# .bazelrc.user should appear in .gitignore so that settings are not shared with team members
Expand Down
3 changes: 2 additions & 1 deletion docs/toolchains.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions zig/private/providers/zig_target_info.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Defines the compiler configuration for a target platform.
FIELDS = {
"target": "The Zig target platform",
"triple": "The components of the Zig target platform triple",
"dynamic_linker": "optional; A custom dynamic linker path",
"args": "The collected compiler arguments for the target platform",
}

Expand Down
10 changes: 10 additions & 0 deletions zig/private/zig_target_toolchain.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ ATTRS = {
doc = "The value of the -target flag.",
mandatory = True,
),
"dynamic_linker": attr.string(
doc = "The value of the --dynamic-linker flag.",
mandatory = False,
),
}

def _zig_target_toolchain(ctx):
Expand All @@ -58,9 +62,14 @@ def _zig_target_toolchain(ctx):
target = ctx.attr.target
args.extend(["-target", target])

dynamic_linker = ctx.attr.dynamic_linker
if dynamic_linker:
args.extend(["--dynamic-linker", dynamic_linker])

target_info = ZigTargetInfo(
target = target,
triple = triple.from_string(target),
dynamic_linker = dynamic_linker,
args = args,
)

Expand All @@ -69,6 +78,7 @@ def _zig_target_toolchain(ctx):

template_variables = platform_common.TemplateVariableInfo({
"ZIG_TARGET": target,
"ZIG_DYNAMIC_LINKER": dynamic_linker,
})
default = DefaultInfo(
files = depset([target_json]),
Expand Down
36 changes: 36 additions & 0 deletions zig/tests/integration_tests/integration_tests_runner.zig
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,39 @@ test "zig_binary result should not contain the output base path in release_fast

try testBinaryShouldNotContainOutputBase("release_fast");
}

test "zig_target_toolchain attribute dynamic_linker configures the interpreter" {
const ctx = try BitContext.init();

const result = try ctx.exec_bazel(.{
.argv = &[_][]const u8{
"build",
"//custom_interpreter:binary-custom_interpreter",
"--extra_toolchains=//custom_interpreter:x86_64-linux-custom_interpreter_toolchain",
"--extra_toolchains=//custom_interpreter:cc_x86_64-linux-custom_interpreter_toolchain",
},
});
defer result.deinit();

try std.testing.expect(result.success);

var workspace = try std.fs.cwd().openDir(ctx.workspace_path, .{});
defer workspace.close();

const file = try workspace.openFile("bazel-bin/custom_interpreter/binary-custom_interpreter", .{});
defer file.close();

const elf_header = try std.elf.Header.read(file);
var ph_iter = elf_header.program_header_iterator(file);
var interp = std.ArrayList(u8).init(std.testing.allocator);
defer interp.deinit();
while (try ph_iter.next()) |phdr| {
if (phdr.p_type == std.elf.PT_INTERP) {
try file.seekableStream().seekTo(phdr.p_offset);
try file.reader().streamUntilDelimiter(interp.writer(), 0, null);
break;
}
}

try std.testing.expectEqualStrings("/custom/loader.so", interp.items);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
load("@rules_zig//zig:defs.bzl", "zig_binary", "zig_configure_binary")
load("@rules_zig//zig:toolchain.bzl", "zig_target_toolchain")
load(":cc.bzl", "cc_config")

constraint_setting(
name = "interpreter",
)

constraint_value(
name = "custom_interpreter",
constraint_setting = ":interpreter",
)

platform(
name = "x86_64-linux-custom_interpreter",
constraint_values = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":custom_interpreter",
],
)

zig_target_toolchain(
name = "x86_64-linux-custom_interpreter_target",
dynamic_linker = "/custom/loader.so",
target = "x86_64-linux-gnu",
)

toolchain(
name = "x86_64-linux-custom_interpreter_toolchain",
target_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
":custom_interpreter",
],
toolchain = ":x86_64-linux-custom_interpreter_target",
toolchain_type = "@rules_zig//zig/target:toolchain_type",
)

cc_config(
name = "cc_x86_64-linux-custom_interpreter_toolchain",
target_compatible_with = [
"@platforms//os:linux",
"@platforms//cpu:x86_64",
],
)

zig_binary(
name = "binary",
cdeps = ["@rules_zig//zig/lib:libc"],
main = "main.zig",
tags = ["manual"],
)

zig_configure_binary(
name = "binary-custom_interpreter",
actual = ":binary",
tags = ["manual"],
target = ":x86_64-linux-custom_interpreter",
)
46 changes: 46 additions & 0 deletions zig/tests/integration_tests/workspace/custom_interpreter/cc.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
"""Dummy CC toolchain for custom-interpreter test.
Provides a dummy CC toolchain such that the custom_interpreter test also works
on other platforms than Linux without having to supply a proper C/C++
cross-compilation toolchain.
"""

def _cc_toolchain_config_impl(ctx):
return cc_common.create_cc_toolchain_config_info(
ctx = ctx,
toolchain_identifier = "cc-dummy-toolchain",
host_system_name = "dummy",
target_system_name = "dummy",
target_cpu = "dummy",
target_libc = "gnu",
compiler = "dummy",
abi_version = "unknown",
abi_libc_version = "unknown",
)

_cc_toolchain_config = rule(
implementation = _cc_toolchain_config_impl,
attrs = {},
provides = [CcToolchainConfigInfo],
)

def cc_config(*, name, target_compatible_with):
_cc_toolchain_config(name = name + "_cc_config")
native.cc_toolchain(
name = name + "_cc_toolchain",
toolchain_identifier = "dummy-toolchain",
toolchain_config = ":" + name + "_cc_config",
all_files = ":empty",
compiler_files = ":empty",
dwp_files = ":empty",
linker_files = ":empty",
objcopy_files = ":empty",
strip_files = ":empty",
supports_param_files = 0,
)
native.toolchain(
name = name,
target_compatible_with = target_compatible_with,
toolchain = ":" + name + "_cc_toolchain",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const c = @cImport({
@cInclude("stdio.h");
});

pub fn main() void {
_ = c.puts("Hello world!");
}

0 comments on commit 4d41d5f

Please sign in to comment.