From f56922975ef293c68ecdfac74a65454ceb8ff0b2 Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Sat, 18 Mar 2023 22:51:02 +0100 Subject: how to develop for windows from linux --- content/windows.md | 342 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 342 insertions(+) create mode 100644 content/windows.md diff --git a/content/windows.md b/content/windows.md new file mode 100644 index 0000000..e3704de --- /dev/null +++ b/content/windows.md @@ -0,0 +1,342 @@ +Title: Support Windows not supporting Windows +Date: 2023-03-18 +Category: +Tags: +Slug: windows +Lang: en +Summary: + About the possibility of having Windows users as clients being a software + developer that doesn't use Windows, and how to solve that technically. + +I hate Windows. I don't like it, I don't support the software practices of +Microsoft and I probably never will. That doesn't mean I don't live in this +world, where unfortunately most of the people uses Windows. Many people have no +other choice than using Windows and they still deserve to have some good free +software in their computers. + +Of course, I always try to encourage my clients (and everyone around me!) to +use free software and stop using Windows, but sometimes it's impossible, and +it's always better for them to use Windows with some free software made by +me[^money] than using Windows with more proprietary bloatware done by any +garbage corporation that doesn't care about their freedom. + +[^money]: And I can earn some money in the process. + +Since I started with ElenQ Technology I always had this issue in mind, and the +time to tackle it has come, so: + +> How could I make software for Windows users if I don't use Windows, I don't +> have any machine that runs Windows and I don't support Windows in any way? + +Until recently, most of my clients asked me for Web based tools, so I dodged +that ball without even realizing it, but I always had that the impression I +would have to tackle the issue someday and I was just delaying the moment to +make some research. + +During the last couple of weeks, in my spare time, I made that research a +little bit and this is a simple high-level result of that research. + +Needless to say this research is for myself and I have a very strong +background to take in consideration (read the blog and you'll see!), so it +probably won't fit your needs in any way, but it does fit mine and probably +some of my near colleagues'. + +1. [Web-based](#web) + 1. [Web Extensions](#webext) +2. [Java Virtual Machine](#jvm) + 1. [GUIs](#jvmgui) + 2. [Interesting JVM languages](#jvmlangs) + 1. [Clojure](#clojure) + 2. [Kawa](#kawa) + 3. [Distribution: JAR files and UberJAR](#jar) +3. [Native Binaries](#native) + 1. [MinGW](#mingw) + 2. [Zig](#zig) + 3. [Distribution: statically built binaries](#staticbin) + 4. [GUIs](#guilibs) +4. [Distribution with Windows Installers](#wininst) +5. [Conclusion](#conclusion) +6. [Final words](#finalwords) + +### Web-based {#web} + +Most of the times I am asked to do Web stuff, because most of the people just +use Webs for everything[^ask-vs-need]. + +[^ask-vs-need]: Often times what the clients want or they ask for is not what + they need, so be careful with that. + +Clients are used to work with websites, the UIs are easy to make, they work in +any device... They are cool for many things, but when you need to make any +interesting native operation they don't make any sense (i.e. reading or +creating files locally) and they require deployment, one way or another, and +that may carry extra costs or efforts and maintenance. + +#### Web Extensions {#webext} + +Another interesting option are Web Extensions (browser extensions). They are +kinda easy to make and making them work in several browsers[^web-ext] is almost +no effort, they don't require deployment (no servers, no pain) and they have +more permissions than a regular website. + +[^web-ext]: API support in all the browsers is not the same, be careful with + that. + +The problem they have is the browser is still a constrained environment, and +you might not be able to do anything you'd like in there and they force the +users to have the browser open in order to run them. + + +### JVM runs everywhere! {#jvm} + +I've never been a Java fan. I don't really like the language and the fact that +it supposes you are using an IDE to code in it, but I have to say the JVM is a +really interesting environment. + +The main problem it has is it's pretty large, but it's not a huge deal to tell +my clients to install it (if they don't have it already) and it provides most +of the functionality I'd ever need out of the box. + +#### GUI {#jvmgui} + +It comes with GUI stuff by default (Swing and AWT[^swing]) and there are more +modern ways to make GUIs like JavaFX, which I didn't manage to make it work in +my Guix machine. + +[^swing]: Welcome back to 2001. + +#### Interesting JVM languages {#jvmlangs} + +The best thing about the Java Virtual Machine is you don't need to use Java for +it. There are some cool languages full of parenthesis you can use in it. + +##### Clojure {#clojure} + +I have some Clojure past. It's a language I love. It had a couple of things I +didn't like about it though: + +- The startup time of Clojure made me feel uncomfortable. +- I was worried about the size of the JVM. +- Most of my code relied too heavily in Leiningen for everything and I didn't + know very well what was going on internally or which libraries were being + used (a little bit of an NPM effect), and I was worried about the maintenance + of the software if I was asked to make changes in the + future[^maintenance-future]. +- The Java interaction is really well designed at a language level, but + integrating Clojure's functional programming with heavily imperative Java + code (like GUIs) feels uncomfortable. + +I have to say I don't code in Clojure for a long time and I wasn't that good +programmer at the time I played around with it. Probably I would make a way +better use of it right now, and things that I felt weird may feel way more +comfortable. + +None of this issues is a big deal anyway. For these kind of projects for +Windows, it might be a great choice, as most of the problems don't mean a lot +any more in this context. I may give Clojure another go. + +[^maintenance-future]: Guix can help here! + +##### Kawa {#kawa} + +Recently I discovered Kawa, and it looks great. +Kawa programs are easy to build with no additional tools, it's a scheme, it's +**fast**, and its Java interaction feels natural. + +Of course, there are almost no libraries written in Kawa, no tutorials, no +learning resources further than the documentation (which is very good, by the +way). + +It's minimalistic, it's easy to set up and is really fast: it might be a good +choice for many projects. + +#### Distribution: JAR files and UberJARs {#jar} + +The Java world might be "too enterprisey" for someone like me, but it has +interesting features. The `jar` files are just zip files that have Java +bytecode and resources inside. + +In any machine with Java installed they are launched automatically when they +are clicked. There's no need to unpack them or anything like that. + +There are several ways to make those `jar` files, and one is simply insert all +the dependencies of the Java application inside of the `jar`. That's called the +UberJAR. + +Doing this makes you sure to have all the dependencies and resource files (such +as icons and stuff like that) inside of a file that you can distribute and will +always run if there's a JVM installed in the target machine. Simple +distribution! + +The only problem they have is they are not located in the correct system folder +to appear in the application launchers[^jpackage]. + +[^jpackage]: The Java ecosystem provides a tool to solve this [called + `javapackage`](https://openjdk.org/jeps/343) but unfortunately it doesn't + cross-compile (Wine for the win?) and it would add a full Java runtime to the + installer. Maybe it's too much. + +### Native binaries {#native} + +Sharing prebuilt binaries is also feasible if you are using the right tools, +but it might be tricky to distribute. + +The first thing you have to do if you want to share binaries is cross-compile +them for windows. I found a couple of tools that fit very well with my style +here: MinGW and Zig. + +#### MinGW {#mingw} + +Recently I discovered this and it happens to be great. Simply put, MinGW a +cross-compiler toolchain for Windows. It has everything you need to build your +C/C++ software for Windows: gcc, binutils, libraries and header files. + +Pretty straightforward. + +Guix also supports this as a target so I can even `guix build --target=` with +it and have all the fun. + +#### Zig {#zig} + +Zig is a great programming language and the tooling around it is absolutely +fantastic. It's designed to be easy to cross-compile and don't need anything +else than the Zig compiler itself to be able to build your Zig, C or C++ +software for a Windows machine. Just change the target and boom, works! + +Zig also comes with a build-system, that lets you describe how to build your +whole project and build it with a simple command. No need to use external tools +like GNU Autotools, Make, CMake, Meson or anything like that. One Zig +installation comes with everything you need. + +> Another advantage of Zig is that I love the language and I'm looking for an +> excuse to learn it. I think it's very well designed and I love the community +> it has. I don't like the syntax that much but I think I'll get used to it. + +#### Distribution: statically built binaries {#staticbin} + +In order to distribute the binaries, there only obvious choice is to statically +link everything and give it in one `.exe` file to my clients. I can't really +trust non-tech users to install all the dependencies in place and I can't guide +them in the process of how to do it because I don't know how to do it myself, +and I can't try as I don't own any Windows machine. + +Statically built binaries require no installation so that's great, but they are +not set in the correct folder of the system and they don't support resources as +icons and stuff like that[^resources-bin]. They might be ok for many things but +they are not a perfect solution either. + +[^resources-bin]: The problem with the resources can be bypassed by a + self-expanding executable: a program that unpacks its binary contents in the + current folder. They can be made by 7zip and other tools like this, but I + don't really like it, as they pollute the current folder and you might not + expect that to happen. Some games are distributed like this. + +#### GUIs {#guilibs} + +This kind of clients require GUIs most of the time. I don't imagine them +running a script from the shell. + +There are many GUI libraries I could use but I'd like to use anything that is +small and easy to build for any target. That leaves most of them out. + +- I tried to build [IUP](https://www.tecgraf.puc-rio.br/iup/) myself but the + build process is basically broken. It looks good and uses native GUI + components, but if the build process is broken I can't really trust it. I + could just use the binaries they provide but I don't like that. + +- I built [FLTK](https://www.fltk.org/index.php) successfully without problems + and I even [packaged it in my personal Guix + channel](http://git.elenq.tech/guix-packages/commit/?id=b952e7778843adbebae0d12d6f1601e4594313eb). + It's not beautiful, but it works, and I don't expect it to be hard to build + for Windows either. + +- I could go for something like Dear ImGUI, but ImGUIs are better suited for + programs that are being rendered continuously like games and such. + +- Qt, GTK, wxWidgets and those are great too, but probably too much for a + simple man like me[^kde]. + +[^kde]: Probably you didn't know but my first free software contribution was + for KDE and I had to deal with Qt. It was right in the migration from Qt4 to + Qt5. Good times. + + +### Distribution with Windows installers {#wininst} + +Software distribution can be eased using a Windows Installer like MSI or MSIX. +Those packages know where to install everything and they do automagically, as +Windows users are used to. + +They require extra tools but they might be simple enough to deal with and help +a lot removing the downsides of the distribution methods described previously. + +- GNOME project has a tool called `msitools`, which exposes a similar interface + to WixToolset, a popular Windows installer generator. I can use that to build + and inspect MSI installers. + +- Microsoft also provides [a tool for MSIX + installers](https://github.com/microsoft/msix-packaging) that is Open Source + but it happens to insert + [telemetry](https://github.com/microsoft/msix-packaging/issues/569) (what a + surprise!). + +- There's a [Python package called + `msicreator`](https://github.com/jpakkane/msicreator) that simplifies the use + of `msitools` with a simpler approach that might be more than enough for my + needs. + +There are also some language-specific tools like PyInstaller but that forces me +to use Python, which I like but I don't know if I want to keep using for +everything. Also, it includes the interpreter in the installer, which feels +like a little bit too much. + +### Conclusion + +Each choice comes with its downsides and shines in specific scenarios. Working +in a classic C/C++ setup with MinGW might be great but I have to make sure I +don't use a complex dependency tree, as everything might fail to compile or +distribute for Windows. + +I want to learn Zig. It's really cool and I think it will ease the process +significantly. I'm not sure about the C integration but I need to give it a go +first. It might become my go-to language for these kind of applications. + +On these cases I need still to find the best GUI library to use (suggestions +welcome!). + +The JVM case is also interesting. It comes batteries included and has Swing by +default, which is horrible but it's something. For faster development I could +use some flexible language like Clojure or Kawa there, being the second way +faster than the first but also way less know (which shouldn't be a problem as I +don't want to rely in many external libraries). + +All these options look feasible so I could just go for any of them. Obviously, +some have way better performance than others (C/C++/Zig vs Clojure) but the +ease of development is also something I have to take in account. That I'd need +to think about when the projects come. + +We'll see...[^chicken] + +[^chicken]: I can always chicken out and go for PyInstaller + PyQt when the + projects come. 😐 + +### Final words {#finalwords} + +It's obvious that I left many options out and I can't wait to get some emails +of people recommending me to learn Go or Rust[^rust], but this non-exhaustive +research is mostly based on my personal (and current) preference. + +Surely you'll think I'm making it way more difficult than it actually is: +*"just install a virtual machine and build there! Buy a Windows machine if you +really want to solve this issue!!"* and you'd probably be right, but it doesn't +feel right to me. So I won't. + +If you have other ideas or success stories that fit this line of thinking don't +hesitate to [contact me](https://ekaitz.elenq.tech/pages/about.html). + +Stay safe! + +[^rust]: I don't like Go but I'm open to learn Rust even if its a little bit + more complex than I'd like it to be (and I don't like the syntax). It would + require me to allocate a long time for it, which is not a problem, but I need + to be sure that I will be able to get some benefit from it. -- cgit v1.2.3