Skip to content
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

std.build.Builder.addObject does not copy artifacts by default #14079

Closed
Jarred-Sumner opened this issue Dec 27, 2022 · 9 comments
Closed

std.build.Builder.addObject does not copy artifacts by default #14079

Jarred-Sumner opened this issue Dec 27, 2022 · 9 comments
Labels
question No questions on the issue tracker, please. zig build system std.Build, the build runner, `zig build` subcommand, package management
Milestone

Comments

@Jarred-Sumner
Copy link
Contributor

Zig Version

0.11.0-dev.947+cf822c6dd

Steps to Reproduce and Observed Behavior

  1. zig init-exe
  2. Copy the following into build.zig:
const std = @import("std");

pub fn build(b: *std.build.Builder) void {
    // Standard target options allows the person running `zig build` to choose
    // what target to build for. Here we do not override the defaults, which
    // means any target is allowed, and the default is native. Other options
    // for restricting supported target set are available.
    const target = b.standardTargetOptions(.{});

    // Standard release options allow the person running `zig build` to select
    // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
    const mode = b.standardReleaseOptions();

    const exe = b.addObject("zls-missing-root-obj", "src/main.zig");
    exe.setTarget(target);
    exe.setBuildMode(mode);
    b.default_step.dependOn(&exe.step);
    // exe.output_dir = b.pathFromRoot("bin");
    const exe_tests = b.addTest("src/main.zig");
    exe_tests.setTarget(target);
    exe_tests.setBuildMode(mode);

    const test_step = b.step("test", "Run unit tests");
    test_step.dependOn(&exe_tests.step);
}
  1. Run zig build
  2. The following directory tree, which does not have an object file in zig-out:
tree
.
├── build.zig
├── src
│   └── main.zig
└── zig-cache
    [ ... ]
16 directories, 24 files

Expected Behavior

zls-missing-root-obj.o should exist in zig-out/lib/zls-missing-root-obj.o or otherwise somewhere in zig-out.

@Jarred-Sumner Jarred-Sumner added the bug Observed behavior contradicts documented or intended behavior label Dec 27, 2022
@Vexu Vexu added the zig build system std.Build, the build runner, `zig build` subcommand, package management label Dec 27, 2022
@Vexu Vexu added this to the 0.11.0 milestone Dec 27, 2022
@Jarred-Sumner
Copy link
Contributor Author

I'm not sure what changed, but the -femit-bin hack we've been relying on no longer works.

The exact shell command is:

zig build-obj <project>/root.zig -lc -femit-bin=<project>/packages/debug-bun-darwin-aarch64/bun-debug.o -fno-strip --cache-dir <project>/zig-cache --global-cache-dir /Users/jarred/.cache/zig --name bun-debug -fno-compiler-rt -fno-omit-frame-pointer -target native-native.11 -mcpu apple_m1 --mod build_options::<project>/zig-cache/c/85f8bbe9bf69b61d1147ff5eb7fce805/options.zig --mod async_io::<project>/src/io/io_darwin.zig --deps async_io,build_options -I <project>/src/deps -I <project>/src/deps --main-pkg-path /Users/jarred/Code/bun --enable-cache

The .o files are in the zig-cache directory, but they're never copied out of the cache.

@nektro
Copy link
Contributor

nektro commented May 14, 2023

you might need b.installArtifact(exe);

edit: relevant pr + issue #15245

@Jarred-Sumner
Copy link
Contributor Author

❯ zig build obj --verbose
Build darwin-aarch64 v11 - v13.2.1 (apple_m1)
Output: /Users/jarred/Code/bun/packages/debug-bun-darwin-aarch64/bun-debug

thread 40542 panic: Cannot install a .obj build artifact.
/Users/jarred/zig/0.11.0-dev.2371+a31450375/files/lib/std/Build/InstallArtifactStep.zig:34:21: 0x10443d8d3 in create (build)
            .obj => @panic("Cannot install a .obj build artifact."),
                    ^
/Users/jarred/zig/0.11.0-dev.2371+a31450375/files/lib/std/Build.zig:1173:38: 0x1043fe60f in addInstallArtifact (build)
    return InstallArtifactStep.create(self, artifact);
                                     

Unfortunately it refuses

@Inve1951
Copy link
Contributor

Workaround:

    const obj = b.addObject(.{
        .name = "obj-name",
        // ...
    });

    obj.override_dest_dir = std.Build.InstallDir{ .custom = "obj" };
    b.installArtifact(obj);

Will output to zig-out/obj/obj-name.o.

@kassane
Copy link
Contributor

kassane commented Jun 16, 2023

Workaround:

    const obj = b.addObject(.{
        .name = "obj-name",
        // ...
    });

    obj.override_dest_dir = std.Build.InstallDir{ .custom = "obj" };
    b.installArtifact(obj);

Will output to zig-out/obj/obj-name.o.

Thanks! it works.

@andrewrk andrewrk added question No questions on the issue tracker, please. and removed bug Observed behavior contradicts documented or intended behavior labels Jul 22, 2023
@andrewrk
Copy link
Member

This is working as designed. Not only are objects not installed by default, neither are executables, libraries, or tests. You need to add install steps into your build graph in order to install things.

InstallArtifact is for installing binaries in standard ways, and there is no standard way to install object files. Therefore, you should use getOutputSource like this:

const install_object = b.addInstallFile(obj.getOutputSource(), "my_object_path.o");
b.getInstallStep().dependOn(&install_object.step);

Note that you might want a different extension than .o depending the target. There are some helpers for this you can call into if you need it, but first you should reconsider why you are installing object files. I can't think of any reason to do that.

Related: #16351

@andrewrk andrewrk closed this as not planned Won't fix, can't repro, duplicate, stale Jul 22, 2023
@Inve1951
Copy link
Contributor

@andrewrk

..., but first you should reconsider why you are installing object files. I can't think of any reason to do that.

My reason for installing an object file is to get it into a known location where it can then be linked together with other object files as part of an existing Makefile project.
The codebase I'm doing this for depends on now unsupported gcc-9 behavior so I couldn't compile/link it from Zig.

Do you think this is a bad reason? Is there a better path?

@mlugg
Copy link
Member

mlugg commented Jul 24, 2023

Zig's build system allows you to run external commands using a Step.Run. As such, I'd suggest using the Zig build system as the "root", and do one of the following to use gcc-9:

  • If it's a single command, directly trigger it through a std.Build.Step.Run
  • If it's more complex, write a shell script and trigger that through a std.Build.Step.Run, passing the paths to the relevant object fields as arguments

In either case, you need to pass the path to the object file to a Step.Run. Use getOutputSource to get the FileSource corresponding to the object file, and use std.Build.Step.Run.addFileSourceArg.

@andrewrk
Copy link
Member

@mlugg beat me to the punch, but I'll finish what I was typing up too:


For that use case, either zig build calls make, or vice versa.

If zig build is driving, then you should use std.Build.Step.Run.addArtifactArg(obj) in order to pass it as an argument to make, for example, make ZIG_OBJ=<path>.

If make is driving, then I think "installing" the objects is indeed the right way to go. In this case you treat the installation prefix not as a standard file system hierarchy but the file layout that your make system expects to see. However, that means that InstallArtifact is still correct in refusing to install object files, because you need to use getOutputSource (soon to be renamed to getOutputBin as part of #16353) and an InstallFile step to manually put that file exactly where make expects it to be relative to the installation prefix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question No questions on the issue tracker, please. zig build system std.Build, the build runner, `zig build` subcommand, package management
Projects
None yet
Development

No branches or pull requests

7 participants