r/dartlang 27d ago

Am I the only one absolutely frustrated by Build Hooks?

I'm sorry, but how is any non-expert supposed to understand how to use hooks? Have any of you, after studying the rather sparse documentation and complex Hooks API, actually felt like you understood any of this? I have been sitting here for hours, just trying to call a simple function from a pre-compiled dll, but the non-helpful documentation and error messages make even the simplest things a daunting task.

But what I find most unpleasent is that even the basic example code (which hasn't helped me at all) looks quite complex and build hooks can just execute any arbitrary code, be that downloading files, executing some other script, or whatever. Not only does that stink of a huge security risk, but there will be so many packages with completely broken hooks on pub, which will then also start to depend on each other. This will be really fun...

Edit: Heureka, it finally worked! But what a frustrating ride it was...

Upvotes

24 comments sorted by

u/raman4183 27d ago

What is so complicated and which part is giving you a hard time?

You have to digest it in separate parts. As you have mentioned that you already have a compiled dll then you don’t need an intermediary package for compilation such as ‘c_builder’ and etc. You can directly use ‘code_asset’ package to include the compiled dll into the final bundle which will automatically be loaded when you call your function.

Just make sure to create proper bindings.

u/randomguy4q5b3ty 27d ago

I got to that part already. But they do a really bad job explaining what it even is that you are supposed to build, how these assets work, etc. Why not just have me declare native resources in pubspec instead of this whole coding ceremony?

u/mraleph 26d ago

Why not just have me declare native resources in pubspec instead of this whole coding ceremony?

Because these native resources are not just something that exists (like an image or an icon in your asset folder), they are something that can be produced in many different ways (e.g. compiled with make, cmake, ninja, scons, cargo, zig, downloaded from the internet or simply present as part of the OS installation). Not to mention that what goes into these native resources can depend on which parts of your Dart code is used.

Any sort of simple YAML based declarative description would be too limiting - hence decision to use code based hooks.

u/randomguy4q5b3ty 26d ago

Well yes, in many cases they do already exist or need just be downloaded and the devs don't need any build script. But this is a minor point. The bigger one is: This system is just terrible for the common case and completey unmanageable for actually complex ones. You know what I really enjoyed working with Node.js? Nice task runners like Jake.

u/mraleph 26d ago

This system is just terrible for the common case and completey unmanageable for actually complex ones.

Well, it would help if you explained what you think is terrible and how you think it could be done better (in other worlds make it more actionable for us).

Lets say your common use case is download a prebuilt library. All you need to write is this:

void main(List<String> args) async {
  await build(args, (input, output) async {
    final fileUri = await downloadPrebuiltLibraryTo(
      input.outputDirectory,
      input.config.code.targetOS,
      input.config.code.targetArchitecture
    ); 

    output.assets.code.add(
      CodeAsset(
        package: input.packageName,
        name: 'lib.dart',
        linkMode: DynamicLoadingBundled(),
        file: fileUri,
      ),
    );
  });
}

Maybe you could abstract it further, but the actual complexity (and variability) is in the downloadPrebuiltLibraryTo not in this glue code.

So what would you prefer to be different here? What exactly makes this terrible?

You know what I really enjoyed working with Node.js? Nice task runners like Jake.

Well, you can build on this experience and offer a package.

Hooks API and things like Jake are different things. You can build hooks using some task runner package, if you so wish. Hooks API is an integration surface between your package and Dart's / Flutter's building&packaging tooling and the execution environment.

u/randomguy4q5b3ty 26d ago

Well, it would help if you explained what you think is terrible and how you think it could be done better

Your example relies on the fact that every library can be treated the same and that no action depends on another one. But as soon as that isn't the case anymore and you have to write some guard clauses, this has to become a mess. Why cram everything into a single callback?

Hooks API and things like Jake are different things. You can build hooks using some task runner package, if you so wish.

Okay, whatever. Hooks are meant to build things, yes? But somehow they are completely different from a build tool?

u/mraleph 26d ago

Your example relies on the fact that every library can be treated the same and that no action depends on another one.

This was based on you saying "in many cases they do already exist or need just be downloaded and the devs don't need any build script." and that "this system is just terrible for the common case". So I assumed that the common case you are talking about is to simply download prebuilt libraries - and tried to illustrate it.

If dynamic library depends on other dynamic libraries you just need to add those as assets as well. It is true that doing it manually can be cumbersome, so there are some open issues around automating it.

It will greatly help if you write down your concrete feedback (e.g. "I tried to wrap native library X into a Dart package and here is where hooks system failed me: 1) I expected X to do Y but it did Z instead 2) an error I got "ABC is FOO" is completely unactionable 3) ...") and file and issue at http://github.com/dart-lang/native .

We tried to collect as much feedback as possible from early adopters of hooks (they have been in preview for a while now) and we have done a bunch of improvements to the overall APIs based on that feedback.

But I would not claim that the system is without issues - it can be that you tried to use the system in a way that that never tried before, and consequently a bunch of rough edges were overlooked. It would be nice to smoothen them out if that is possible.

Hooks are meant to build things, yes? But somehow they are completely different from a build tool?

Yes, they are intended to be an intermediary between build tools. They are not intended to be a full fledged build system themselves - because there are already way too many build systems in the world. We did consider different designs (e.g. should a hook just be an arbitrary program with defined interface? should a hook be a some fixed build system that everybody is forced to use? etc) - but settled on the current design which we consider optimal in terms of flexibility and maintenance costs.

u/randomguy4q5b3ty 26d ago

I really appreciate your effort and like to apologize for sounding so combative. I was just frustrated that I couldn't properly wrap my head around what exactly hooks are, not realizing they are more than just another automation tool. And I was really just stumbling through it, not even knowing what to expect, and at some point I finally figured it out. I'm afraid that's not really helpful feedback.

Your explanation of hooks as an intermediate really helps closing the gap. But I think that's pretty unclear in the documentation, just like the whole stuff being generated in the background, which is the acutal "glue", if I understand correctly. It would be really helpful to explain all that stuff in more (technical) detail and to guide the user step by step through the whole process rather than just throwing some examples and technical jargon at them so they can figure it out themselves.

And beyond that, I think some guidelines about dos and don'ts, more security oriented interfaces, letting the user decide what code they allow hooks to run, and indeed a task runner would be really appreciated. Being able to just run arbitrary code really worries me, and while one author may actually check the signature of a downloaded library, another one doesn't.

Don't get me wrong, I know how much work all this is and I really appreciate the work of the Dart team, and I love Dart as a programming language.

u/airflow_matt 26d ago

Hooks are orthogonal to calling functions from pre-compiled dll (ffi).

u/loic-sharma-google 26d ago

Hello, I'm from the Flutter team at Google. Thanks for the feedback!

Could you provide specific details on your experience? For example, for each task:

  • What actions did you try?
  • What error messages did you see that were unclear?
  • What docs did you find confusing?

The more specific the feedback, the better! That'll help us iron out those kinks :)

u/randomguy4q5b3ty 26d ago

Well, even after reading everything for the fifth time, I barely understood what any of these parts do exactly or what this ominous assetId is and how it gets connected to a dynamic library that was already sitting in the project directory.

And for somebody who has no clue what exactly these hooks are supposed to build when the dll is already there, the error messages about some assetId that wasn't found (still had no clue what that was supposed to be) weren't particularly helpful.

Just through trial and error I got it working and a superficial understanding of what I was doing.

And let's just say the API is not nice and even the example code looks hideous. It's there any reason we can't have a nice, clean task runner like Jake.js?

u/DigiProductive 27d ago edited 27d ago

I assume you are talking about Dart Hooks. To be honest, hooks are for seasoned developers. If you are a newbie, you probably want to leave it alone because you probably don’t even need them.

u/randomguy4q5b3ty 27d ago edited 27d ago

I am seasoned and have been using Dart right from the beginning. Even before they stabalized the FFI, I had been working with VM Native Extensions, and even those were hard to use. But this? It's 100% a documentation issue and I don't have to feel dumb for not understanding any of this.

u/autognome 26d ago

Maybe write up your "falling down" and suggest where documentation could be clearer?

u/DigiProductive 27d ago

And that is exactly why you figured it out, because you are seasoned!👌🏾

u/Luc-redd 26d ago

Hooks is for the middle of the bell curve, beginners should stay away, and experts prefer not to use them.

u/Bachihani 26d ago

I m not particularly advanced but i didn't find hooks that hard to understand or write, especially with some explanation from an llm

u/goopa-troopa-bazooka 27d ago

It's simple to understand. Read the official documentation.

u/randomguy4q5b3ty 27d ago

Geez, why didn't I think of that...

u/ralphbergmann 27d ago

Claude did it for me and it works :)

u/randomguy4q5b3ty 27d ago

And here come the broken hooks and security flaws 😆 Seriously, when we don't even understand how our software is build anymore... Then some AI/bad faith actor will just smuggle in some rogue code or telemetrics.

u/ralphbergmann 26d ago

Whether or not you understand how the AI built something is irrelevant. The important thing is testing. If you already know how something works, why use AI at all? I might as well just do it myself.

Dart Hooks was set up by the AI once. Since then, it has run automatically with every build. It doesn't matter if I've changed anything in the Dart or Rust code — it just works.

It was a one-off setup task for Claude. So it’s perfect for AI. Why should I spend days getting to grips with something that I’ll only do once and then forget about?

u/randomguy4q5b3ty 26d ago

I can see why it has become so easy to smuggle malware into software projects...