summaryrefslogtreecommitdiff
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/windows.md342
1 files changed, 342 insertions, 0 deletions
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.