Hello many applications, when they are downloaded have an icon embedded.
is this available in zig? (i’d assume it’s something handled by the build system?)
Hello many applications, when they are downloaded have an icon embedded.
is this available in zig? (i’d assume it’s something handled by the build system?)
It depends on operating system you using.
For example on linux icons are specified in .desktop file separately from executable. Im less familiar with windows but it seems like they are indeed embeded.
You can of course integrate it with build system but i would assume most of the time it would be left for people packaging your software for distribution.
It also depends on the framework/libraries you are using for the app. For example, DVUI lets you set the icon and you could do it either with @embedFile into the binary or load it from the filesystem. With the later, you could use the build system to place the file where you expect it.
For final packaging, it will depend on the OS like AndrewKraevskii said.
so for linux: this seems like a tech-debt issue?
my main target is windows though.
Not tech debt, just how the system is designed. You have given very little for us to work with. Without more details on what you are trying to accomplish and what barriers you are running into, we won’t be able to help very well.
i’m just writing a simple image viewer using sdl3
This article may be of service.
Thanks, that seems like a great resource!
I recall that Bun, which has a way to bundle a web app into a single platform-specific executable, only allows including an icon for Windows .exes when compiling on Windows, and not when cross-compiling (I think the wording was that they’re relying on native system APIs?). Wonder why that is, considering the article claims the Windows resource bundler merged into Zig is cross-platform.
the key point is “windows resource bundler”, the bundler may run on any platform, but it is bundling specifically for windows.
Different platforms have different ways to bundle resources and allow bundling different things. AFAIK windows is the only (major) platform that allows embedding the icon into the executable.
Linux has a very different system, you don’t associate resources with an executable directly. Instead, you have a separate .desktop entry (this is what application launchers use), that describes the icon, the name, description, mime-types it can open, search keywords and supports multiple languages for each. It isn’t bound to an executable, instead it has a command that it runs, multiple even for right click menu.
macOS has .app bundles, a zip file (i think) which contain the icon, the executable and any other resources an application needs, I think there is a special manifest aswell, idk I havent used mac in a long time. A lone executable is in the same situation as it would be on Linux.
I really wish that idea (of embedded resources) would have taken off and across all platforms… theoretically in Windows it would be even possible to bundle an entire many-gigabytes-game into a single self-contained .exe file and run it without prior installation.
Technically this wouldn’t be a problem since only the parts of the exe file that are currently needed are mapped into RAM. The embedded resources could be accessed through some sort of virtual filesystem and that would be infinitely faster than accessing individual files.
macOS has
.appbundles, a zip file (i think) which contain the icon, the executable and any other resources an application needs, I think there is a special manifest aswell
Yes, that manifest file is the Info.plist file (essentially an XML file with tons of configuration options and hints). I was actually wondering recently whether Zig (or the build system) supports creating macOS/iOS app bundles (like cmake does), because the key/value pairs in Info.plist sometimes have essential information that cannot be provided programmatically.
You can ofc do this with smaller programs, but perhaps some linker shenanigans (I am not an expert!!) would let you lazily load data from the exe and have a user land virtual file system?
Yes I think that should work, the basic Win32 API is FindResource => LoadResource => LockResource, the last function returns a pointer to the resource data in memory. E.g. if one resource maps to one asset file this could be used to implement a virtual file system…
But yeah, the linker is probably not happy with creating a 100GB game executable ![]()
i can’t wait for counter_strike_2028.exe ~180GiB ![]()
the key point is “windows resource bundler”, the bundler may run on any platform, but it is bundling specifically for windows.
That was my expectation too! But no, see the docs for the --windows-icon flag. Like the note says, you get the following error when using it on Linux with Bun 1.3.9:
error: Using --windows-icon is only available when compiling on Windows
Zig itself is great for cross-compilation.
How unfortunate that bun appears to have chosen to be dependent on building on the target.
That is bun-the-program not supporting cross-compilation for its feature of bundling a JavaScript application into a .exe. It uses a library called rescle that uses Win32 APIs to modify the resources of an existing .exe file. If they wanted cross-compilation support, they’d need to get a cross-platform implementation of those APIs, which is not something that Zig provides*.
From what I can tell, though, bun avoids using Zig’s resource compilation for compiling bun itself and instead lets CMake handle it, so that introduces a dependency on an external resource compiler like windres/rc.exe/resinator/zig rc and maybe also a linker that can handle .res → .obj conversion (see here for some context, been meaning to write something more substantial about this). I’m unsure if bun supports or intends to support cross-compilation of bun itself (this note in the Windows build instructions seems to suggest cross-compilation is not a concern).
To hopefully clarify some stuff generally:
.exe is the first icon in the resource table of the file, which is a convention dictated by the behavior of the OS.rsrc section within the PE/COFF file format, which is the executable format that Windows uses
*Zig provides cross-platform .rc → .res compilation, which involves a C preprocessor in the mix (some details about that here), and then also supports linking .res files via LLD which does internal .res → .obj conversion (although Zig can do .res → .obj conversion via zig rc for use cases where that’s necessary)
Technically there’s a (non-standard) extension for it (Elficon), but practically nobody really uses it.
You can embed any data into ELF mapping the section from /proc/exe/self for VFS access for example would be possible too. It would be cool if Elficon was more supported, .desktop files just for icons is kinda weird.
I’m working on a platform which uses custom random access archive format to bundle the binary, assets and metadata. Under the hood there indeed is VFS that can both access stuff from the archive and real file system. https://cloudef.pw/sorvi/#supertux.sorvi is example running on browser, it loads 300+MB file with the binary and assets. (You need JSPI enabled if trying that on firefox, javascript.options.wasm_js_promise_integration)