When compiling a program that depends on GTK and GdkPixbuf loaders in msys2 Windows, the loaders.cache generates dlls with an absolute path that is local to the machine it was generated on.
When the resulting compiled program is run on another Windows machine, the local paths of the dlls do not exist and the program crashes.
Example loader.cache snippet
"C:/tools/msys64/mingw64/bin/../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.dll"
"png" 5 "gdk-pixbuf" "PNG" "LGPL"
"image/png" ""
"png" ""
"\211PNG\r\n\032\n" "" 100
The correct output should be
"lib\\gdk-pixbuf\\loaders\\libpixbufloader-png.dll"
"png" 5 "gdk-pixbuf" "PNG" "LGPL"
"image/png" ""
"png" ""
"\211PNG\r\n\032\n" "" 100
The root cause of the bug lies the libdir variable.
libdir = C:/tools/msys64/mingw64/bin
The GdkPixbuf hook generates a loaders.cache file with absolute paths and uses prefix matching to replace the dll paths with relative paths that the program can find. However, this will match none of the prefixes and therefore, the absolute path will not be changed to the relative path in the loaders.cache.
In the code example below, we see that it will try to match the following prefixes:
prefix = "C:/tools/msys64/mingw64/bin/gdk-pixbuf-2.0/2.10.0
win_prefix "\\lib\\gdk-pixbuf-2.0\\2.10.0
This will not work given the line from cachedata
"C:/tools/msys64/mingw64/bin/../lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.dll"
output_lines = []
prefix = '"' + os.path.join(libdir, 'gdk-pixbuf-2.0', '2.10.0')
plen = len(prefix)
win_prefix = '"' + '\\\\'.join(['lib', 'gdk-pixbuf-2.0', '2.10.0'])
win_plen = len(win_prefix)
# For each line in the updated loader cache...
for line in cachedata.splitlines():
if line.startswith('#'):
continue
if line.startswith(prefix):
line = '"@executable_path/' + LOADER_CACHE_DEST_PATH + line[plen:]
elif line.startswith(win_prefix):
line = '"' + LOADER_CACHE_DEST_PATH.replace('/', '\\\\') + line[win_plen:]
output_lines.append(line)
This fix addresses this by accounting for the dll prefix for msys2.
My solution will simplify the line path to be:
"C:/tools/msys64/mingw64/lib/gdk-pixbuf-2.0/2.10.0/loaders/libpixbufloader-png.dll"
which will match my new prefix:
msys2_prefix = "C:/tools/msys64/mingw64/lib/gdk-pixbuf-2.0/2.10.0
And convert the line to be:
line = "lib\\gdk-pixbuf\\loaders\\libpixbufloader-png.dll"
fixes #7838