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: Deprecate Step.Compile APIs that mutate the root module #22587

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

castholm
Copy link
Contributor

@castholm castholm commented Jan 23, 2025

Not only are Step.Compile methods like linkLibC() redundant because Module exposes the same APIs, it also might not be immediately obvious to users that these methods modify the underlying root module, which can be a footgun and lead to unintended results if the module is exported to package consumers or shared by multiple compile steps. For example, I personally almost ran in to this:

// module exported to package consumers, doesn't require libc
const mod = b.addModule("mymodule", .{
    .root_source_file = b.path("main.zig"),
    .target = target,
    .optimize = optimize,
});

// some unit tests require libc
const tests = b.addTest(.{ .root_module = mod });
tests.linkLibC(); // uh-oh! now the exported module requires libc!

const run_tests = b.addRunArtifact(tests);

const test_step = b.step("test", "Run tests");
test_step.dependOn(&run_tests.step);

Using compile.root_module.link_libc = true or compile.root_module.linkLibrary(lib) makes it more clear to users which of the compile step and the module owns which options.

Suggested release notes (if you think deprecation notices are relevant):

Deprecated std.Build.Step.Compile APIs

The following std.Build.Step.Compile methods have been deprecated in favor of their std.Build.Module equivalents and are slated for removal during the next release cycle:

  • addAfterIncludePath
  • addAssemblyFile
  • addCSourceFile
  • addCSourceFiles
  • addConfigHeader
  • addFrameworkPath
  • addIncludePath
  • addLibraryPath
  • addObject
  • addObjectFile
  • addRPath
  • addSystemFrameworkPath
  • addSystemIncludePath
  • addWin32ResourceFile
  • linkFramework
  • linkLibC
  • linkLibCpp
  • linkLibrary
  • linkSystemLibrary
  • linkSystemLibrary2

Upgrade guide:

 // Most uses can be migrated by inserting `root_module` before the method call
-exe.linkLibrary(lib);
+exe.root_module.linkLibrary(lib);

 // Set the corresponding field directly
-exe.linkLibC();
-exe.linkLibCpp();
+exe.root_module.link_libc = true;
+exe.root_module.link_libcpp = true;

 // Pass '.{}' as the second argument
-exe.linkSystemLibrary("foo");
+exe.root_module.linkSystemLibrary("foo", .{});

 // Omit the '2' from the method name
-exe.linkSystemLibrary2("foo", .{ .needed = false });
+exe.root_module.linkSystemLibrary("foo", .{ .needed = false });

@alexrp alexrp added this to the 0.14.0 milestone Jan 30, 2025
@alexrp alexrp added the release notes This PR should be mentioned in the release notes. label Feb 9, 2025
@alexrp alexrp requested a review from mlugg February 9, 2025 03:21
@alexrp
Copy link
Member

alexrp commented Feb 9, 2025

@mlugg would you mind reviewing this (considering #20388/#18752)? Also @BratishkaErik.

Copy link
Member

@andrewrk andrewrk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, let's make this depend on #22822 yeah?

@castholm
Copy link
Contributor Author

@andrewrk Updating these APIs to make use of @deprecated is blocked by the fact that @deprecated does not seem to work as envisioned. I opened a topic on Zulip with more details but the gist of the problem is that if you have a function marked with @deprecated, it becomes an error if the context in which it is declared forbids deprecations, when it should be the context from which it is called. Because Compile.linkLibrary etc. reside in the std module, which is configured with fno-allow-deprecated by default, this means that it becomes a compile error to use them even from a dependency's build.zig module which is configured with -fallow-deprecated. This makes it painful to depend on "legacy packages" that haven't been updated to use the module APIs and seems contrary to the spirit of soft-deprecating the APIs in the first place (instead of simply removing them right here and now).

@castholm castholm force-pushed the deprecate-compile-apis branch from fcea7b0 to 67ecb65 Compare February 28, 2025 03:03
Not only are `Step.Compile` methods like `linkLibC()` redundant because
`Module` exposes the same APIs, it also might not be immediately obvious
to users that these methods modify the underlying root module, which can
be a footgun and lead to unintended results if the module is exported to
package consumers or shared by multiple compile steps.

Using `compile.root_module.link_libc = true` makes it more clear to
users which of the compile step and the module owns which options.
@castholm castholm force-pushed the deprecate-compile-apis branch from 67ecb65 to a8cfdb5 Compare February 28, 2025 03:05
@castholm castholm force-pushed the deprecate-compile-apis branch from a8cfdb5 to 8d7acbe Compare February 28, 2025 04:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release notes This PR should be mentioned in the release notes.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants