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

Implementation Plan for Windows Resource Files (#142) #6939

Open
TravisWhitaker opened this issue Jul 4, 2020 · 8 comments
Open

Implementation Plan for Windows Resource Files (#142) #6939

TravisWhitaker opened this issue Jul 4, 2020 · 8 comments

Comments

@TravisWhitaker
Copy link
Collaborator

RC scripts are quite common for Win32 application development. It'd be nice if Cabal were able to compile and link resource scripts at build time. Since windres.exe comes with mingw-w64, all that's needed is to teach cabal how to use it generate object files from RC files. I'd like to propose the following:

  • Addition of an rc-sources field to the cabal file spec, functioning just like c-sources, asm-sources, etc.
  • Addition of an rc-options (or perhaps windres-options) field to the cabal file spec, functioning just like cc-options, etc.
  • Have cabal call windres.exe on all of the rc-sources with the rc-options, respecting the includes and include-dirs fields, and the --extra-include-dirs flag.
  • Have cabal include the resulting object files when linking, just like object files generated from c-sources.

If this is a reasonable path forward, I'd be happy to tackle the implementation.

@angerman
Copy link
Collaborator

angerman commented Jul 5, 2020

@TravisWhitaker can you come up with a reason why this would be a bad idea? Otherwise, I’d say just go for it.

@phadej
Copy link
Collaborator

phadej commented Jul 5, 2020

Related #142

@phadej
Copy link
Collaborator

phadej commented Jul 5, 2020

c-sources and asm-sources are passed to GHC, which handles them for us, that makes supporting these "easy".

What one will do with rc-sources on non-Windows platforms? Is it immediate install-plan solving error? Is there linux/unix alternative for resource files? Why rc-options should respect includes, aren't there only C-header files? how resource scripts are related to C-headers? What are RC scripts to begin with.


Learned from the bad experiences, I'd want to see first an outline of documentation. (c.f. GHC-proposal.)

@TravisWhitaker
Copy link
Collaborator Author

c-sources and asm-sources are passed to GHC, which handles them for us, that makes supporting these "easy".

Perhaps GHC itself should learn to handle RC files.

What one will do with rc-sources on non-Windows platforms? Is it immediate install-plan solving error? Is there linux/unix alternative for resource files?

In the native case, there is nothing sensible to do with RC files and I suspect it should be a plan error. However, the mingw-w64 toolchain can be used as a cross-toolchain on Linux, so when cross compiling the cross-windres compiler can be used. So whether RC files are supported comes down to whether or not Windows is the target platform, and not necessarily the platform we're building on.

Why rc-options should respect includes, aren't there only C-header files? how resource scripts are related to C-headers?

The C preprocessor is run on RC files before compilation. A common pattern is to assign names/numbers to Win32 resources in a C header file, which gets included in both the RC files (where the names are associated with the binary resources) and C files (where the names are passed to LoadIcon/LoadResource/etc.

What are RC scripts to begin with.

They are a Win32-specific mechanism for including binary resources in a DSO or executable. You can read more about them here https://docs.microsoft.com/en-us/windows/win32/menurc/about-resource-files They are commonly used in the development of graphical Win32 applications. They serve a purpose somewhat similar to the XML files produced by Glade for GTK applications, or the nib files produced by Apple's Interface Builder, so one might ask why they deserve special treatment from the compiler. The key difference is that they are translated into object files at build time that are linked into the final binary, and share the symbol namespace as the other objects in the binary. In the context of their inclusion in a Haskell project, this makes them more like c-sources or asm-sources, rather than GTK XML or nib files, which are simply read at runtime.

@phadej
Copy link
Collaborator

phadej commented Jul 7, 2020

Are resource scripts completely windows specific, or could there in theory be a linux variant of it? The #6096 issue seems related, and RC is windows specific solution for that.

I wonder if https://stackoverflow.com/questions/2627004/embedding-binary-blobs-using-gcc-mingw & http://gareus.org/wiki/embedding_resources_in_executables#architecture_dependent_binary_linking would actually work for other platforms too. I.e. we could have rc-sources for the ones who care about windows only, and embbeded-files (or some other name) for more portable setting (Cabal could generate stub module file with pointers to data).

@phadej
Copy link
Collaborator

phadej commented Jul 7, 2020

EDIT: above means, please go ahead with implementing rc-sources. Your explanations make sense to me. (One way to start is to write a test case in cabal-testsuite)

@TravisWhitaker
Copy link
Collaborator Author

@phadej Do you have any thoughts on which approach might be better:

  • cabal treats rc-sources like c-sources, asm-sources etc., and GHC learns to handle passed in RC files (GHC actually already knows how to call windres).
  • cabal handles rc-sources on its own, and passes the resulting object files to GHC at link time.
    I'm leaning slightly towards the former, since:
  • An rc file might include a C header that (perhaps transitively) includes some header that only GHC knows about, like HsRts.h.
  • This makes for a nice symmetry with the other *-sources flags; otherwise I think this would be the only kind of source file that cabal itself is responsible for building (I could be wrong about this, though).

For a field like embedded-files, how would the Haskell program get access to the symbol/address of the embedded content?

@phadej
Copy link
Collaborator

phadej commented Jul 8, 2020

cabal treats rc-sources like c-sources, asm-sources etc., and GHC learns to handle passed in RC files (GHC actually already knows how to call windres).

Would be easiest to start with

For a field like embedded-files, how would the Haskell program get access to the symbol/address of the embedded content?

Cabal could generate stub module file with pointers to data. (c.f. Paths_packagename.hs)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants