1

I am writing an OpenGL app which runs on windows, OSX and linux.

I have some free-for-commercial-use truetype fonts that I'm packaging with the app, so the user can choose their preferred font for the text part of my renders.

I have some glsl shaders of my own making, so that my rendering does just the right thing. I need to package these with the app, too

I build with cmake and build an installer with cpack. I use the install command to control where the fonts and shaders go, on the target machine.

I have C++ code which, given a path to a font file, will give me just the right font in the rendered image. Similarly, I have OpenGL code which needs to know where the shaders are, at runtime.

On the build machine I've used configure_file to handle OS/user variations. The fonts and shaders are relative to a directory where the code resides, so I can put their location into a header file as a namespace variable, and the shading and font code can always find them.

Now I'm trying to get the installed app to work I've hit a problem: I can put my fonts and shaders anywhere I like on the target machine, at install time, but am struggling to see how the runtime (installed) executable, on the target machine, can be made to understand where that location is.

Compiler flag? Environment variable? Target property? None of them seems to quite fit the bill. Or is that wrong? Any thoughts would be very much appreciated.

Neil Gatenby
  • 419
  • 6
  • 21
  • 3
    On windows if the font and shader set is not meant to be user-supplementable I would simply use the relative path from wherever the executable is installed. Install the executable to "\Program Files (x86)\MyName\MyProgram\MyProgram.exe" and resources to MyProgram\Resources (possibly with locale-awareness if that matters). And then use ".\Resources\" as a path – SoronelHaetir Jan 16 '18 at 17:34
  • Linux must have an equivalent to `GetModuleFileName` that will return you the path of your executable, which you can then use to build path name(s) for your resources. https://msdn.microsoft.com/en-us/library/windows/desktop/ms683197(v=vs.85).aspx – Richard Critten Jan 16 '18 at 17:40
  • 2
    @RichardCritten: On linux the executable and the data they use are usually installed into completely different locations. – Yakov Galka Jan 16 '18 at 19:11
  • @RichardCritten: [Nothing so easy, no](https://stackoverflow.com/questions/1023306/finding-current-executables-path-without-proc-self-exe). – genpfault Jan 16 '18 at 23:51
  • 1
    Can't you use a relative path convention and always put them on a subdirectory under your executable installation? – Makogan Jan 17 '18 at 04:22
  • Thanks for the replies, all. I can (and do) use a relative path convention on the target machine, and be unable to run the app on the build machine, where the hierarchy is markedly different ... I suspect I'll pursue that approach in further depth. I can't install into "\Program Files ..." on windows as the user choses install location at install time ... also, I really need a x-platform approach, including working on old linux machines :( Hopefully I can get the fonts and shaders into the app, as resources – Neil Gatenby Jan 17 '18 at 09:40

2 Answers2

3

You have two possibilities here:

  • The application is installed to a directory chosen by the user, but you control everything within that directory (what CMake calls the install tree). Because of this, you know where all of the external files are located relatively to the executable, so you can use relative paths for addressing them (as was also suggested in the comments). This approach is very common for OS X and Windows, where each application is typically installed to its own distinct directory. It's a bit less common for Unix-y systems, where stuff is typically just dumped to /usr/bin.
  • If you are not comfortable with relative paths, you can always package all resources into the executable itself. This is typically done using a resource compiler, but CMake has built-in support for those. This approach is particularly popular with GUI applications that package their fonts and icons into the executable itself. Qt offers a cross-platform resource compiler for this purpose, that is also supported by CMake.
ComicSansMS
  • 51,484
  • 14
  • 155
  • 166
1

Linux has a really different installation philosophy. Resources are installed in standard locations, which are not at a fixed relative location from the binary itself (windows in somewhat moving in this direction with ProgramData and .AppData)

The Linux approach would be to use fontconfig to locate fonts, and then install your fonts system-wide in /usr/share/fonts/myapp or in the user directory (~/.fonts/myapp or even better the new XDG location)

For shaders it would be similar with /usr/share/myapp system-wide and XDG locations user-side (https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html)

Of course you can force whatever you want in your code, and install in /opt, it will never feel like an integrated linux app from the user POW though

nim
  • 2,345
  • 14
  • 13