Distributing a GTK+ based application on Linux
Distributing a GTK+ based application on Linux
Recently I tried to build a cross platform GUI. It uses native widgets on Windows and GTK+ on Linux. The windows version worked like a charm, the Linux version did not.
On WIndows GTK+ based applications tend to distribute the GTK+ dlls' used when building the application. That's the only way to make sure the right GTK+ version is used.
To make sure Windows uses the dlls' that come with the application these are put in the same directory as the application. As Windows looks there first for the dlls needed by an application there is no chance of Windows using the wrong dlls' (there might be a different version of GTK+ sitting on the HDD somewhere).
But that's windows. On Linux the situation is...? Is it enough to put dlls in the same directory as the application to ensure the program uses the GTK+ dlls provided by me? I've read something about using patchelf to make sure the right dlls' are used but patching a binary to make sure the right dlls' are used sounds a bit over the top to me.
On WIndows GTK+ based applications tend to distribute the GTK+ dlls' used when building the application. That's the only way to make sure the right GTK+ version is used.
To make sure Windows uses the dlls' that come with the application these are put in the same directory as the application. As Windows looks there first for the dlls needed by an application there is no chance of Windows using the wrong dlls' (there might be a different version of GTK+ sitting on the HDD somewhere).
But that's windows. On Linux the situation is...? Is it enough to put dlls in the same directory as the application to ensure the program uses the GTK+ dlls provided by me? I've read something about using patchelf to make sure the right dlls' are used but patching a binary to make sure the right dlls' are used sounds a bit over the top to me.
linux
I don't think Linux does uses .dlls. They use .so that are in the /usr/lib directory. I think you might be able to use one that is on 80% of every linux distro. As a try find a gtk lib and put the line "include /usr/lib/assafafd.so" or something like that. It might not work.
When I make cross plattform apps with GUI, the LINUX version works like a charme and the windows version needs some finetuning. It depends on your productive system.
I think it isn't wise to distribute the GTK library within a linux package. The package installer can do a check whether GTK is installed and if the library version fulfil your needs.
If you'll not create a package, there is a way to check the GTK version from your app, using code like (from GTK+tobac2):
Also on windows it isn't wise to install GTK libraries in the program folder (and host them 20 times on the same system). I'm used to install at C:\opt\GTK-x.x.x\ folder and set the PATH-variable, so the libs are usable system wide. (Make sure to have just one GTK version into the PATH-variable.)
In most cases you do not need the latest version of GTK. Actually I try to code for the 2.16 version.
I think it isn't wise to distribute the GTK library within a linux package. The package installer can do a check whether GTK is installed and if the library version fulfil your needs.
If you'll not create a package, there is a way to check the GTK version from your app, using code like (from GTK+tobac2):
Code: Select all
IF gtk_check_version(2, 12, 0) THEN
?"Fehler/Error: GTK-version too old, please update!"
END -1
END IF
In most cases you do not need the latest version of GTK. Actually I try to code for the 2.16 version.
Re: Distributing a GTK+ based application on Linux
No support for binary files at all. If cross distro binaries keep working it is sheer coincidence.AGS wrote:
But that's windows. On Linux the situation is...?
Libraries in Linux are quite different in Windows. There is a path for executables (PATH environment variable), path for libraries (LIBPATH environment variable), etc. You need permission to be able to add libraries to this path. It is not recommended to include libraries with applications for Linux since adding library files into /usr/lib or other paths in LIBPATH may damage the packaging system of the distro (Deb, RPM, PET, etc.). Adding libraries where the executable resides will not work without using some shell scripts, which I think is not a good idea. On the other hand, GTK+ is installed by default in many distros so you don't need to worry about them. It is good if you will base your program to use the stable major release, which is currently 2.16, because most distros have it installed. Also, many distros are updated to the newest GTK+ libraries, one of them is Ubuntu which always have the latest version of GTK+ in its repositories. Most distros use GNOME as desktop environment so usually there is only one copy of GTK+ in those distros. That possibility is maximized even more because distros tend to use one prefix for path when installing all libraries, executables, etc., i.e. /usr, /usr/local, /opt . This will only have problems if the user recompiled GTK+ other than using package management of his distro. And GTK+ is also much backward-compatible with older releases.
Cross platform development (of the GUI kind) seems to be a bit more difficult then I had expected.
The bottom line seems to be this: if your application depends upon the availability of version x of library y on the system where the application gets installed there is no way of making sure it's there unless you provide it. I simply cannot assume the user to have a certain version of GTK+ installed.
Supplying all the dependencies (GTK+ dlls) myself would work on Windows (no problem). Most GTK+ applications on Windows actually come with the needed dlls' as developers are not taking any chances when it comes to the version of GTK+ that might (or might not) already be installed on a computer. It's 'the way things are' on Windows right now.
I'm going to take all the tips and information provided by all of you and think this cross platform development thing through a bit more (I obviously need to read a LOT more about development on the Linux platform).
The bottom line seems to be this: if your application depends upon the availability of version x of library y on the system where the application gets installed there is no way of making sure it's there unless you provide it. I simply cannot assume the user to have a certain version of GTK+ installed.
Supplying all the dependencies (GTK+ dlls) myself would work on Windows (no problem). Most GTK+ applications on Windows actually come with the needed dlls' as developers are not taking any chances when it comes to the version of GTK+ that might (or might not) already be installed on a computer. It's 'the way things are' on Windows right now.
I'm going to take all the tips and information provided by all of you and think this cross platform development thing through a bit more (I obviously need to read a LOT more about development on the Linux platform).
It's not easy, particularly at the beginning. But with FreeBasic you have one of the best compilers to do that kind of programming.AGS wrote:Cross platform development (of the GUI kind) seems to be a bit more difficult then I had expected.
Making your application depend upon the availability of version x of library y isn't the best programming style for cross platform applications. You'll allways have to make compromizes.AGS wrote:The bottom line seems to be this: if your application depends upon the availability of version x of library y on the system where the application gets installed there is no way of making sure it's there unless you provide it. I simply cannot assume the user to have a certain version of GTK+ installed.
You can make sure a functionality is there by checking the version (see above). If a basic functionality isn't available (ie. like GtkGuilder) you must stop your app. If a minor functionality isn't available, you can switch it off.
No problem for you as the programmer.AGS wrote:Supplying all the dependencies (GTK+ dlls) myself would work on Windows (no problem). ...
What about the users, spending a lot of disk space for different versions, getting confused by them?
What about the internet trafic? (I'm not sure if you are allowed to serve GTK without the source - LGPL?).
There are some reasons why it is done in a different manner in LINUX.
I agree with Galeon: At the bottom line you can assume that all users have GTK-2.16 on LINUX. On windows they may have nothing. A NSIS installer can check if GTK is installed and witch version it is. And the installer may download and install (system wide) the desired version.
For me, it is easier to create GTK+ libraries for Linux since most distros have it already installed. Actually I don't know one that don't have it except Kubuntu (which uses Qt). You could assume that at least version 2.16 is there since the user might be using other GTK+ programs. And you could create packages of your program, like DEB's (Debian, [K/X]Ubuntu), PET's (Puppy Linux), RPM's (Red Hat, Fedora), etc., which could list GTK+ as dependency. And most distros have good repositories, many Linux users know how to install GTK+ and other libraries themselves, very different from pampered Windows users :).AGS wrote:The bottom line seems to be this: if your application depends upon the availability of version x of library y on the system where the application gets installed there is no way of making sure it's there unless you provide it. I simply cannot assume the user to have a certain version of GTK+ installed.
In Windows, you have to include GTK+ with the installer. You should decide which files should be added, for example, certain GDK-Pixbuff modules are needed to load PNG, BMP, SVG, etc. There are needed additional options like installing translations of GTK+ and other libraries. You need to tweak the theme that will be used or add a theme changing application. Some GTK+-related libraries are not available as compiled in Windows. Last but not the least, just like what TJF had said, it will use up a lot of disk space, since GTK+ is a large set of libraries. Checking if GTK+ is installed is installed is also not good (imagine checking each folders in the path!).
GTK+ is backward compatible. If you would not use functions from newer versions (which is commonly what happens), you shouldn't have a problem with those versions.
Using NSIS it's easy to check if GTK is installed and witch version it is, using code like:Galeon wrote:... Checking if GTK+ is installed is installed is also not good (imagine checking each folders in the path!).
Depending on $0 you mayFunction .onInit
GetDllVersion "libgtk-win32-2.0-0.dll" $R0 $R1
IntOp $R2 $R0 / 0x00010000
IntOp $R3 $R0 & 0x0000FFFF
IntOp $R4 $R1 / 0x00010000
IntOp $R5 $R1 & 0x0000FFFF
StrCpy $0 "$R2.$R3.$R4.$R5"
...
FunctionEnd
- * install GTK if nothing was found
* install a newer version if the installed GTK version is too old
* tell the user that a matching GTK version was fount
The following installer could be embedded to NSIS installers: http://gtk-win.sourceforge.net
Currently it has 2.16.6. There are instructions in that website on how to embed it.
Currently it has 2.16.6. There are instructions in that website on how to embed it.
As far as I understand, this will generate installers with GTK+ on board. You'll have to ship GTK+ at each download.Galeon wrote:The following installer could be embedded to NSIS installers: http://gtk-win.sourceforge.net
Currently it has 2.16.6. There are instructions in that website on how to embed it.
From my point of view it's better to let our installer download the GTK+ installer from the internet, if it doesn't find a matching version on the system. Today we can assume that every FB user has an internet connection, can't we?
Only if our installer cannot connect to the internet, it can make the user choose an GTK+ installer from a local directory.
Download and start of the GTK+ installer can be controlled by our installer (starting similar to the above link, app-specific and system wide installation).
This way our installer will stay pretty small - we'll save disc space and time when uploading. And it's very easy to change to another GTK+ version by just changing the name of the download file.
I know, all this is possible using NSIS. But sorry, I haven't time to code it yet. (@Galeon: I know you make better installers than I do.)
@AGS
BTW, to answer your first question: It is obviously possible to use local copies of a certain library in LINUX. You can copy your local installation (shared library files ending with .so) into some folder and tell the linker ld where to find them, before the app starts. You may use a short bash-shript to start your app, e.g.
BTW, to answer your first question: It is obviously possible to use local copies of a certain library in LINUX. You can copy your local installation (shared library files ending with .so) into some folder and tell the linker ld where to find them, before the app starts. You may use a short bash-shript to start your app, e.g.
export LD_LIBRARY_PATH="./lib"
./MyApp
Good point (very good point actually).TJF wrote:Making your application depend upon the availability of version x of library y isn't the best programming style for cross platform applications. You'll allways have to make compromizes.AGS wrote:The bottom line seems to be this: if your application depends upon the availability of version x of library y on the system where the application gets installed there is no way of making sure it's there unless you provide it. I simply cannot assume the user to have a certain version of GTK+ installed.
You can make sure a functionality is there by checking the version (see above). If a basic functionality isn't available (ie. like GtkGuilder) you must stop your app. If a minor functionality isn't available, you can switch it off.
I agree with you (totally). Check this out: I've got 12!!!! copies of libgtk-win32-2.0-0.dll sitting on my Windows PC. 12..... some of those are my own mistake butTJF wrote:No problem for you as the programmer.AGS wrote:Supplying all the dependencies (GTK+ dlls) myself would work on Windows (no problem). ...
What about the users, spending a lot of disk space for different versions, getting confused by them?
What about the internet trafic? (I'm not sure if you are allowed to serve GTK without the source - LGPL?).
==> Dia
==> Gimp
==> Gnumeric
==> graphviz
==> Vala IDE (don't ask...)
==> Denemo
==> Evince
==> Geany
==> Pike (again, don't ask...)
==> Frama-C
have all, upon installation, installed a version of GTK+. That's 12 copies of GTK+ sitting on the HDD of my PC. That´s not good.
Okay then, GTK-2.16 on Linux it will be. On Windows a check for available versions and install if needed sounds like the way to go.TJF wrote: There are some reasons why it is done in a different manner in LINUX.
I agree with Galeon: At the bottom line you can assume that all users have GTK-2.16 on LINUX. On windows they may have nothing. A NSIS installer can check if GTK is installed and witch version it is. And the installer may download and install (system wide) the desired version.
Okay then, so we need an windows installer (NSIS?!) that canAGS wrote:Okay then, GTK-2.16 on Linux it will be. On Windows a check for available versions and install if needed sounds like the way to go.
- A) check the GTK installation
B) download an GTK installer
C) run the GTK installation process
D) install our application