Skip to content

Guidance for build dependencies #73

@attackgoat

Description

@attackgoat

When [build-dependencies] use profiling it can cause trouble building the target crate. If possible I'm looking for advice and updates that could be made to the documentation.

Background

Recently the image crate was updated to include a dependency on rav1e (via ravif). This dependency uses profiling in the normal way, but fails when image is used from build script of a profiling build. This is somewhat complex so I made a simple repro case.

Sample repository

Problem repo

https://github.com/attackgoat/profiling-test/tree/main

  • my-bin includes foo-lib which uses child-lib in a build script
    • child_lib uses profiling
  • my-bin includes bar-lib which uses profiling

How to reproduce the issue

cargo run
cargo run --features profile-with-puffin

The second run generates:

error[E0433]: failed to resolve: could not find `puffin` in `profiling`
 --> /child-lib/src/lib.rs:1:1
  |
1 | #[profiling::function]
  | ^^^^^^^^^^^^^^^^^^^^^^ could not find `puffin` in `profiling`
  |
  = note: this error originates in the attribute macro `profiling::function`

How to fix:

attackgoat/profiling-test@main...attackgoat:fix

Proposed fix

If I understand what is happening here correctly, the procmacro crate is configured to use puffin, but the profiling crate used by the build is not similarly configured. It's unclear to me if this is a Cargo bug or it is intended that procedural macros are only built once and not separately for the build dependencies.

The fix I used in the sample repository is to expose profile-with-* features in any crate whose dependencies expose such features, and enable them in a pass-through manner. foo-lib does not use profiling but provides the features so that my-bin can enable profiling in child-lib.

This works, in that I can now use the image crate in build scripts and also use profiling on the resulting binary, but the downside is that I'll have to go ask authors of these "middle" crates to expose and maintain these features in their creates too. I also cannot make a build which does not profile rav1e but does profile the code I'm interested in.

Is there a better way to do this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions