Is there any intention for @embedFile to require a string literal argument in future, like @import?
On a project I’m working on, I’m considering generating something like a StaticStringMap to bundle some assets/files, and it’d be quite ergonomic to not have to repeat the file name and/or perform some processing on it before passing it to @embedFile, think something like:
The above is just a quick sketch of the idea, it’s likely going to look very different once implemented.
I’d rather not rely on the existing behaviour though if there is an intention to change it, and would prefer to just do some code generation at build time instead.
I don’t think the ability to do @embedFile(not_a_string_literal) is going away. At the very least there are currently no proposals for making that change, accepted or otherwise.
Making @import() require a string literal was proposed here:
The main motive for making @import() require a string literal appears to be to make it trivially easy for the compiler/tooling to find the full set of files/modules that could possibly be reached by any given source file, without needing to execute comptime code.
It was considered that zig test should automatically find and run all test decls reachable from the root source file instead of requiring explicitly referencing imports containing tests with e.g. comptime { _ = @import("tests.zig"); }, however this idea was never implemented.
Unlike @import(), @embedFile() doesn’t introduce more Zig code that tooling would need to walk and scan for imports recursively, so introducing a similar string literal requirement is less compelling.
I’ve done things like this before, baking executables into another executable so I can have one binary.
I’m not sure if this was part of the decision going into limiting imports and embeds to string literals, but the limit really helps with determining when to put comptime down.
Comptime is an amazing tool, and when you first pick it up, it feels like it’s the ultimate hammer in which all problems become nails. Unfortunately you learn that this is not the case, as a lot of us in the early days experienced by going farther than the bounds of nature, into the echoing halls of madness.
For your particular use-case, the build system is the l right tool. You can create a codegen executable, and save its output as a file in an output directory, and save assets in that output directory. Then you can do @imports to those relative files. I’m quite sure you can make your root assets file into a module as well if you need to wire in dependencies, and hook it up to other modules.
I know what you mean about it feeling like the ultimate hammer, even after three or four years of using Zig for almost all of my personal projects (and a couple of smaller ones at work, actually including one where I also baked an executable into another executable and then shoved it into a memfd to fexecve it), I still often nerd-snipe myself into over-reliance on metaprogramming.
You’re probably right that the build system is a better place for this. I’ve thought about it a bit more and despite needing it to be baked into the binary, I also want this asset/file map to have a well defined in-memory representation, so that it can be reloaded at runtime.
For this, an external tool to generate it would be convenient (and maybe necessary).