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

Add macOS workflow #958

Closed
wants to merge 35 commits into from
Closed

Add macOS workflow #958

wants to merge 35 commits into from

Conversation

valentinegb
Copy link

Adds a workflow which builds and uploads a macOS artifact of Tuba on push or pull request.

@GeopJr
Copy link
Owner

GeopJr commented May 27, 2024

Thanks!

I have a few questions:

  • Is there any way to run the tests? If it's troublesome, it's okay to skip them!
  • Is the way it's packaged 'good enough'? I'm guessing, but since the zip doesn't include the adwaita icon theme then icons are going to be missing(?). FWIW, this is what we do for windows https://github.com/GeopJr/Tuba/blob/main/Makefile#L63-L75 (copying all icons and then attempting to clean up anything we don't need)

@valentinegb
Copy link
Author

Is there any way to run the tests? If it's troublesome, it's okay to skip them!

Pretty sure I can do that, I will next

Is the way it's packaged 'good enough'?

Now that I think about it more, not really ;-;

A Mac user who downloads an artifact from this workflow would, on their machine, needs to make sure they have all the runtime dependencies installed, link the share directory (I don't think you technically need to link bin), and run the post-install commands which, I've just realized, for Mac are only explicitly showed in the Homebrew formula, so it'd be a good idea probably to add something like an install script to do all that for the user and include that in the artifact
I can start working on that next

since the zip doesn't include the adwaita icon theme then icons are going to be missing(?)

If the user has the dependency installed, adwaita-icon-theme, then they should appear fine in the app

this is what we do for windows https://github.com/GeopJr/Tuba/blob/main/Makefile#L63-L75 (copying all icons and then attempting to clean up anything we don't need)

I think this could be done for Mac as well, but should we if we're going to install all of the app's runtime dependencies for users?

@valentinegb valentinegb marked this pull request as draft May 27, 2024 17:55
@valentinegb
Copy link
Author

Okay instead of making an install script, I'm going to focus on getting the minimum working app bundle with dependencies included in the bundle, that way user installation is super easy

@valentinegb
Copy link
Author

valentinegb commented May 27, 2024

There should be some application code to set the XDG_DATA_DIRS environment variable to ../Contents/Resources/share if running on macOS so that it searches for files like settings schemas and icons inside the app bundle and not in /usr/share like is default (I think)
I would really appreciate it if someone else did that since I have never touched Vala before and my editor doesn't even have syntax highlighting for it yet 😅

As of right now though, if you download the app bundle from the macOS workflow on a Mac and set XDG_DATA_DIRS manually + have runtime dependencies (you might also have to run chmod +x Tuba.app/Contents/MacOS/dev.geopjr.Tuba, actions/upload-artifact strips permissions :P), it should work! Next is bundling runtime dependencies, too.

@GeopJr
Copy link
Owner

GeopJr commented May 27, 2024

Bundling the dependencies is very messy... See on windows https://github.com/GeopJr/Tuba/blob/main/Makefile#L46-L57, we go through every single linked dep and straight up copy them and their dependencies to the folder

There should be some application code to set the XDG_DATA_DIRS environment variable to ../Contents/Resources/share if running on macOS so that it searches for files like settings schemas and icons inside the app bundle and not in /usr/share like is default (I think)

I believe, like on windows, it will search locally first, as long as the folders are structured right (see the windows zip package!). Doesn't it do it already for Tuba's own icons since they are included in the artifact? I'll investigate

strips permissions

( 🤫 it keeps them if you zip it yourself)


Honestly, I don't know if it's worth it to bundle everything. Actually, I don't even know if it's worth it to ship it outside of homebrew at all (except for testing)

Windows is a different beast, all dependencies have to be provided from msys2 and you can't really expect users to go through all that. But I suspect that most mac users willing to download an app outside of the appstore, also have homebrew installed 🤷

I'm setting up a Mac KVM and I'll see tmrow!

GNOMies seem to be using https://gitlab.gnome.org/GNOME/gtk-mac-bundler to bundle mac apps, might be worth considering. Actually, taking a look on how gimp and inkscape do it might be helpful too!

@valentinegb
Copy link
Author

Bundling the dependencies is very messy...

Yeah I've realized that now lol
Still, I think I'm making progress on it, so I think I'll keep trying. I learned that macOS app bundles have a Frameworks directory where dynamic libraries are intended to go, so now I'm utilizing that (not pushed yet)

I believe, like on windows, it will search locally first, as long as the folders are structured right

How exactly should they be structured then? Right now it's like:

Tuba.app
    Contents
        MacOS
            dev.geopjr.Tuba
        Resources
            share
                ...
                icons
                ...

Doesn't it do it already for Tuba's own icons since they are included in the artifact? I'll investigate

Not in my testing. But yeah, feel free to download those artifacts and test stuff! ^^

it keeps them if you zip it yourself

Oh nice okay I'll have to add that then

Honestly, I don't know if it's worth it to bundle everything

It would be really nice, and maybe not so far off actually since I've made a ton of progress today

But I suspect that most mac users willing to download an app outside of the appstore, also have homebrew installed 🤷

The thing with that, though, is that Homebrew formulas (compiles a program from source) can't really have app bundles and they're not even actually meant for GUI applications, only CLI and libraries (hence why the current Tuba formula only allows users to open Tuba through Terminal). A Homebrew cask (downloads a release artifact) is really what I'm aiming for, which is intended specifically for GUI applications.

GNOMies seem to be using https://gitlab.gnome.org/GNOME/gtk-mac-bundler to bundle mac apps, might be worth considering. Actually, taking a look on how gimp and inkscape do it might be helpful too!

I have looked at gtk-mac-bundler and GIMP! I learned some stuff from looking at how gtk-mac-bundler works, but I continued implementing things myself, probably mostly because I kinda hate how GIMP is on Mac- it's all kinds of janky

@GeopJr
Copy link
Owner

GeopJr commented May 28, 2024

How exactly should they be structured then?

Not in my testing

My bad, I thought we were still following the original structure (/whatever meson outputted), where the dependencies sit next to the binary and the others on ../share/ ...

The thing with that, though, is that Homebrew formulas (compiles a program from source) can't really have app bundles and they're not even actually meant for GUI applications, only CLI and libraries (hence why the current Tuba formula only allows users to open Tuba through Terminal). A Homebrew cask (downloads a release artifact) is really what I'm aiming for, which is intended specifically for GUI applications.

I see, thanks for the info!


Btw, I'll start pushing to this PR if I have something to push, so don't really worry about the commit history, it will be squashed anyway!

@GeopJr
Copy link
Owner

GeopJr commented May 28, 2024

Okay so, I did more research and what I'd like would be to follow the windows pattern of using a Makefile (can be done after we figure out all the commands):

mac: PREFIX = $(PWD)/tuba_mac/Tuba.app/Contents/Resources
mac: __mac_pre build install # ...

__mac_pre:
	rm -rf $(PREFIX)
	mkdir -p $(PREFIX)/lib/
	mkdir -p $(PREFIX)/../MacOS/
	touch $(PREFIX)/../Info.plist # cp build_aux/...

build_aux can hold mac specific scripts/files/icons

And what we should follow is Kangaroo's guide: https://www.datatable.online/en/blog/004-how-to-deploy-gtk-app-on-mac.html

Kangaroo is a commercial GTK app built using (almost) the same stack as Tuba - Vala, gtk, gtksourceview... So that guide will be on point!

Oh btw, could you add libspelling to the deps? (spelling library, not sure if it will work, but just add it anyway). And maybe webp-pixbuf-loader for webps


So the plan is:

  1. Get it into a working state (incl. icons, gtksourceview langs and themes, webp loader, videos)
  2. Cleanup
  3. Use big sur icon
  4. Create DMG

@valentinegb
Copy link
Author

Oh, actually, I don't even see libpixbifloader-svg.so installed on my machine at all .-.

Screenshot 2024-05-31 at 1 09 38 PM

@GeopJr
Copy link
Owner

GeopJr commented May 31, 2024

://///// try installing librsvg if not already installed

but actually, if they (svgs) work when you run it then I really don't get it

@valentinegb
Copy link
Author

Ah, I have librsvg installed, by coincidence, so that's why it worked on my machine
I'll add it to Brewfile and see how things improve

@valentinegb
Copy link
Author

valentinegb commented May 31, 2024

Currently rewriting the dependency copying stuff to just copy everything in $HOMEBREW_DEPENDENCIES, since brew bundle creates an environment that only has access to packages listed in Brewfile, so it shouldn't really copy any unnecessary libraries I think

@valentinegb valentinegb force-pushed the main branch 7 times, most recently from c17aa06 to 0f8bbfc Compare May 31, 2024 23:32
@GeopJr
Copy link
Owner

GeopJr commented Jun 1, 2024

Update:

  • TLS issue is fixed! I was able to login
  • Icons are still broken (same log as before)
  • Unpacking it results in 800+ MB :(
  • Segfaults right when it's about to finish loading posts, might be pixbuf or qemu related(?), setting up gdb was hellish last time I tried so I don't think I'll thoroughly debug this (last time I had to use self signed certificates and similar)

@valentinegb
Copy link
Author

Icons are still broken (same log as before)

So, for some reason, it looks in subdirectories when looking in /opt/homebrew/lib but it doesn't in $(PREFIX)/lib, it just looks in that directory, so I guess we gotten figure out how to flatten it or something

Unpacking it results in 800+ MB :(

Yeeaaaaah ;-; that's why I said "experiment" in the commit lol. Not really sure if it's viable, but I know that at least a portion of that is actually build dependencies, which don't need to be included. We could probably have two Brewfiles, one with both build and runtime dependencies and one with only runtime dependencies

Segfaults right when it's about to finish loading posts

Oh odd, I thought I had removed most dependencies from my machine and it works mostly fine for me (I am experiencing the icon issue now)

@valentinegb
Copy link
Author

Hah, so, TLS just broke for me for the first time
Did you do something to fix it for yourself or did it just fix itself in 0f8bbfc?

@GeopJr
Copy link
Owner

GeopJr commented Jun 1, 2024

The kangaroo guide is probably our best bet at a minimal and complete bundle but between us only you have a working Mac so the implementation is up to you 😅

did it just fix itself in 0f8bbfc?

Yep, make sure glib-networking was bundled / exists

@valentinegb
Copy link
Author

You know what, I hate to go back on what I said before but trying to get every little thing that the app could possibly need to run correctly bundled in with it is such a pain, takes up way too much space, and Homebrew casks do allow you to specify dependencies (which I kind of forgot about...)
And you're probably right that Mac users that want to use Tuba will probably have Homebrew already anyway, considering Mastodon users are generally more tech savvy I think
In any case, I'm gonna go and say that it's not worth all the effort to keep trying to make the app bundle completely standalone. Sorry for kind of wasting time ;-;
I'll remove all the dependency copying stuff and everything should work perfectly if you run brew bundle in the root of the repository (my fork) and open the app

@valentinegb
Copy link
Author

Just included the Brewfile in distributions, so now you can run brew bundle in the distribution DMG and not download the whole repository

@GeopJr
Copy link
Owner

GeopJr commented Jun 2, 2024

It's ok! Wish I could be of more help :(

I'll give it a try myself too if I get some free time, but for the moment it's good enough! It's not like we can't come back to it in the future anyway

Thank you for taking over this task 🙇

@GeopJr
Copy link
Owner

GeopJr commented Jun 2, 2024

I gave it another try, this is the closest I got to replicating the windows build

It copies over all needed deps, icons, loaders and then cleans up. I did encounter some issues though with the dep loops. Specifically with some icu data stuff and a libwebp dep, maybe we can make otool ignore them if they are not needed? or copy them manually instead

If we can make it work in this state, then we can move on to creating Tuba.app and the installer

(oh I also installed libproxy, not sure if it's needed tbh)

macos: PREFIX = $(PWD)/tuba_macos
macos: MAC_APP = $(PWD)/Tuba.app
macos: __macos_pre build install __macos_copy_deps __macos_schemas __macos_copy_icons __macos_cleanup

__macos_pre:
	rm -rf $(PREFIX)
	mkdir -p $(PREFIX)/lib/

__macos_prepare_app:
	# mkdir -p $(MAC_APP)/Contents/
	# mv $(PREFIX) $(MAC_APP)/Contents/Resources/

	# mkdir -p $(MAC_APP)/Contents/Resources/lib/
	# mkdir -p $(MAC_APP)/Contents/Resources/bin/
	# mkdir -p $(MAC_APP)/Contents/Resources/share/
	# mkdir -p $(MAC_APP)/Contents/Resources/etc/
	# mkdir -p $(MAC_APP)/Contents/Resources/include/
	# mkdir -p $(MAC_APP)/Contents/MacOS/

__macos_copy_deps:
	otool -L $(PREFIX)/bin/dev.geopjr.Tuba | grep "/*.*dylib" -o | grep -v "/usr/lib/*" -o | grep -v "/System/Library/*" -o | xargs -I{} cp -nL "{}" $(PREFIX)/bin

	cp -fL $${HOMEBREW_PREFIX}/opt/webp/lib/libwebp-7.dylib $(PREFIX)/bin
	cp -fL $${HOMEBREW_PREFIX}/opt/librsvg/lib/librsvg-2.2.dylib $(PREFIX)/bin
	cp -fL $${HOMEBREW_PREFIX}/opt/gmp/lib/libgmp.dylib $(PREFIX)/bin
	cp -fL $${HOMEBREW_PREFIX}/opt/gnutls/lib/libgnutls.dylib $(PREFIX)/bin
	cp -fL $${HOMEBREW_PREFIX}/opt/glib/lib/libgthread-*.dylib $(PREFIX)/bin
	cp -fL $${HOMEBREW_PREFIX}/opt/libproxy/lib/libproxy.dylib $(PREFIX)/bin
	cp -frL $${HOMEBREW_PREFIX}/opt/gdk-pixbuf/lib/gdk-pixbuf-2.0 $(PREFIX)/lib/gdk-pixbuf-2.0
	cp -frL $${HOMEBREW_PREFIX}/opt/webp-pixbuf-loader/lib/gdk-pixbuf-2.0 $(PREFIX)/lib/gdk-pixbuf-2.0

	# Let's recursively get all deps of deps 3 levels deep
	for dep in $$(find $(PREFIX)/bin -name \*.dylib -o -name \*.so -type f); do \
		otool -L $$dep | grep "/*.*dylib" -o | grep -v "/usr/lib/*" -o | grep -v "/System/Library/*" -o | xargs -I{} cp -nL "{}" $(PREFIX)/bin; \
	done

	for dep in $$(find $(PREFIX)/bin -name \*.dylib -o -name \*.so -type f); do \
		otool -L $$dep | grep "/*.*dylib" -o | grep -v "/usr/lib/*" -o | grep -v "/System/Library/*" -o | xargs -I{} cp -nL "{}" $(PREFIX)/bin; \
	done

	for dep in $$(find $(PREFIX)/bin -name \*.dylib -o -name \*.so -type f); do \
		otool -L $$dep | grep "/*.*dylib" -o | grep -v "/usr/lib/*" -o | grep -v "/System/Library/*" -o | xargs -I{} cp -nL "{}" $(PREFIX)/bin; \
	done

	cp -f $${HOMEBREW_PREFIX}/opt/gtksourceview5/share/gtksourceview-5/styles/Adwaita.xml $${HOMEBREW_PREFIX}/opt/gtksourceview5/share/gtksourceview-5/styles/Adwaita-dark.xml ${PREFIX}/share/gtksourceview-5/styles/
	cp -f $${HOMEBREW_PREFIX}/opt/gtksourceview5/share/gtksourceview-5/language-specs/xml.lang $${HOMEBREW_PREFIX}/opt/gtksourceview5/share/gtksourceview-5/language-specs/markdown.lang $${HOMEBREW_PREFIX}/opt/gtksourceview5/share/gtksourceview-5/language-specs/html.lang ${PREFIX}/share/gtksourceview-5/language-specs/

__macos_schemas:
	cp -r $${HOMEBREW_PREFIX}/opt/gsettings-desktop-schemas/share/glib-2.0/schemas/*.xml ${PREFIX}/share/glib-2.0/schemas/
	glib-compile-schemas ${PREFIX}/share/glib-2.0/schemas/

__macos_copy_icons:
	cp -r $${HOMEBREW_PREFIX}/opt/adwaita-icon-theme/share/icons/ $(PREFIX)/share/icons/
	cp -r $${HOMEBREW_PREFIX}/opt/hicolor-icon-theme/share/icons/ $(PREFIX)/share/icons/

__macos_cleanup:
	rm -f ${PREFIX}/share/glib-2.0/schemas/*.xml
	rm -rf ${PREFIX}/share/icons/hicolor/scalable/actions/
	find $(PREFIX)/share/icons/ -name *.*.*.svg -not -name *geopjr* -delete
	find $(PREFIX)/lib/gdk-pixbuf-2.0/2.10.0/loaders -name *.a -not -name *geopjr* -delete
	find $(PREFIX)/share/icons/ -name mimetypes -type d  -exec rm -r {} + -depth
	find $(PREFIX)/share/icons/hicolor/ -path */apps/*.png -not -name *geopjr* -delete
	find $(PREFIX) -type d -empty -delete
	gtk4-update-icon-cache $(PREFIX)/share/icons/Adwaita/
	gtk4-update-icon-cache $(PREFIX)/share/icons/hicolor/

@valentinegb
Copy link
Author

Hey, sorry it's been a while

So, I ended up getting really busy with a bunch of other stuff and unfortunately stopped working on this. Right now I'm going through each of the like 30 something different projects I have on my computer and I'm wrapping them up so I can focus on just a few projects. Just wanted to let you know that, yeah, I'm probably not gonna be working on this any more in the near future, sorry -.-'

I will be archiving my fork though, so that the work I've done can be referenced in the future if this is picked up by someone else ^^

@valentinegb valentinegb closed this Sep 6, 2024
@GeopJr
Copy link
Owner

GeopJr commented Sep 6, 2024

That's fine, thanks for moving this so far! Good luck on your other projects :)

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

Successfully merging this pull request may close these issues.

2 participants