MacOS App Contents

Hello, I am working on a GTK app build for MacOS, that while it initialises some things on start up , shows a splash screen. For that splash screen I have used a png file, that I just moved into the project folder and referenced it so far without any “file-structure”…

img := gtk.NewImageFromFile("Morti.png")

This works fine with go run Morti.go and go build Morti.go - ./Morti,
but when i create the app with:

mkdir -p Morti.app/Contents/MacOS
go build -o Morti.app/Contents/Morti

The png is not located and does not show. How can i solve this ?

You can use os.Args[0] which always is the path relative or absolute to the executing file and then use filepath.Dir to get folder and go from there.

1 Like

That works, so anybody who has the same problem, here is how you find files in the contents folder of your golang “app”. Thank you Johan !

imgpath:=filepath.Dir(os.Args[0])+"/Image.png"
img := gtk.NewImageFromFile(imgpath)

@Locust that won’t work as soon as your application is properly installed and lives in the PATH.

Your best option is to adhere to the “file system hirarchy” standard as described.

@NobbZ I just compiled the app and moved it onto another mac in the network with no problems. What do you mean by properly installed in the path??

Well, as soon as you build and distribute the application in a way, that you do not need to qualify the binary path anymore (eg. beeing able to start it using foo rather than ./foo), then your current approach wont work anymore.

Now I understand your concern. But like I said, it is a MacOS “app” not a single binary. The app is distributed in a packed dmg file. On installation it gets copied to the users application folder and is launched via double click only. Any MacOS app is basically just a link to the binary and a hidden folder “contents” with the binary and resources like icons etc. In my case it consists apart from the binary and icon also of a splash screen image.

Okay… Basically naming the packages d(a)m(a)g(e) tells me everything I need to know about Mac OS :wink:

Feels a weird way if distribution, but if that’s the way to go, then that’s the way to go… Even Microsoft started to discourage relying on the fact that you can infer the data dir from the binaries place in the filesystem…

A good practice to run your programs on various operating systems and from various locations is to use something like this:

path, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
    log.Fatal(err)
}
imgpath = filepath.Join(path, "Image.png")

Use join which care about slash (or backslash). path variable can be global and will be the reference for your program files.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.