build, plug-ins: Generate *associations.list automatically at build-time

This is way easier to maintain and creates a bigger list of
associations by following the libraries that GIMP links
(but does not work with more complex code like file-gegl).

Also helps with
https://gitlab.gnome.org/Infrastructure/gimp-macos-build/-/issues/3
This commit is contained in:
Bruno Lopes 2025-05-28 21:35:27 -03:00
parent 3693f90aca
commit 2ce3c604e2
No known key found for this signature in database
43 changed files with 236 additions and 161 deletions

View file

@ -508,6 +508,7 @@ gimp-win:
- _build-$MSYSTEM_PREFIX/done-dll.list
# Needed by dist-installer-weekly and dist-store-weekly
- _build-$MSYSTEM_PREFIX/config.h
- _build-$MSYSTEM_PREFIX/plug-ins/file_associations.list
- _build-$MSYSTEM_PREFIX/build/windows/installer/
- _build-$MSYSTEM_PREFIX/build/windows/store/
expire_in: 2 days

View file

@ -463,7 +463,7 @@ Root: HKA; Subkey: "Software\RegisteredApplications"; ValueType: string; ValueNa
#if Copy(FileLine,1,1)=="#" || FileLine==""
//skip comments and empty lines
#else
#pragma message "Processing data_associations.list: " + FileLine
#pragma message "Processing file_associations.list: " + FileLine
Root: HKA; Subkey: "Software\Classes\.{#FileLine}\OpenWithProgids"; ValueType: string; ValueName: "GIMP{#GIMP_MUTEX_VERSION}.{#FileLine}"; ValueData: ""; Flags: uninsdeletevalue
Root: HKA; Subkey: "Software\Classes\GIMP{#GIMP_MUTEX_VERSION}.{#FileLine}"; ValueType: string; ValueName: ""; ValueData: "GIMP {#CUSTOM_GIMP_VERSION} {#UpperCase(FileLine)}"; Flags: uninsdeletekey
Root: HKA; Subkey: "Software\Classes\GIMP{#GIMP_MUTEX_VERSION}.{#FileLine}\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\bin\gimp-{#GIMP_MUTEX_VERSION}.exe,2"
@ -474,7 +474,7 @@ Root: HKA; Subkey: "Software\GIMP {#GIMP_MUTEX_VERSION}\Capabilities\FileAssocia
#endif
#endsub
#define FileHandle
#for {FileHandle = FileOpen(AddBackslash(SourcePath)+"data_associations.list"); \
#for {FileHandle = FileOpen(AddBackslash(BUILD_DIR)+"plug-ins\file_associations.list"); \
FileHandle && !FileEof(FileHandle); FileLine = FileRead(FileHandle)} \
ProcessAssociation
#if FileHandle

View file

@ -1,80 +0,0 @@
ani
avif
bmp
dds
g3
cel
cur
dcm
dcx
dicom
exr
gif
heif
heic
hej2
icns
jp2
j2k
j2c
jpc
jxl
pcx
pcc
pdf
png
pnm
ppm
pgm
pbm
pfm
pam
ps
eps
psp
tub
pspimage
im1
im8
im24
im32
rs
ras
svg
tga
vda
icb
vst
tif
tiff
webp
wmf
apm
xpm
xwd
fit
fits
fli
flc
jpg
jpeg
jpe
psd
sgi
rgb
rgba
bw
icon
pix
matte
mask
alpha
als
xbm
ora
qoi
wbmp
acbm
iff
ilbm
lbm

View file

@ -241,8 +241,8 @@ foreach ($bundle in $supported_archs)
Foreach-Object {$_ -replace "@CHANNEL_SUFFIX@","$channel_suffix"} | Foreach-Object {$_ -replace "@MUTEX_SUFFIX@","$mutex_suffix"} |
Set-Content $msix_arch\AppxManifest.xml
### Match supported filetypes
$file_types = Get-Content 'build\windows\installer\data_associations.list' | Foreach-Object {" <uap:FileType>." + $_} |
Foreach-Object {$_ + "</uap:FileType>"} | Where-Object {$_ -notmatch 'xcf'}
$file_types = Get-Content "$build_dir\plug-ins\file_associations.list" | Foreach-Object {" <uap:FileType>." + $_} |
Foreach-Object {$_ + "</uap:FileType>"} | Where-Object {$_ -notmatch 'xcf'}
(Get-Content $msix_arch\AppxManifest.xml) | Foreach-Object {$_ -replace "@FILE_TYPES@","$file_types"} |
Set-Content $msix_arch\AppxManifest.xml

View file

@ -10,12 +10,12 @@ huffman = custom_target('huffman.h',
command: [gen_huffman, '@OUTPUT@'],
)
plugin_sources = [
plugin_sourcecode = [
'bmp-load.c',
'bmp-export.c',
'bmp.c',
huffman,
]
plugin_sources = plugin_sourcecode + huffman
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,6 +1,6 @@
plugin_name = 'file-dds'
plugin_sources = [
plugin_sourcecode = [
'bc7.c',
'dds.c',
'ddsread.c',
@ -10,6 +10,7 @@ plugin_sources = [
'misc.c',
'formats.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -2,10 +2,11 @@ if openexr.found()
plugin_name = 'file-exr'
plugin_sources = [
plugin_sourcecode = [
'file-exr.c',
'openexr-wrapper.cc',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,9 +1,10 @@
plugin_name = 'file-faxg3'
plugin_sources = [
plugin_sourcecode = [
'faxg3.c',
'g3.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,9 +1,10 @@
if cfitsio_dep.found()
plugin_name = 'file-fits'
plugin_sources = [
plugin_sourcecode = [
'fits.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,9 +1,10 @@
plugin_name = 'file-fli'
plugin_sources = [
plugin_sourcecode = [
'fli-gimp.c',
'fli.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,11 +1,12 @@
plugin_name = 'file-icns'
plugin_sources = [
plugin_sourcecode = [
'file-icns-data.c',
'file-icns-load.c',
'file-icns-export.c',
'file-icns.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,11 +1,12 @@
plugin_name = 'file-ico'
plugin_sources = [
plugin_sourcecode = [
'ico-dialog.c',
'ico-load.c',
'ico-export.c',
'ico.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,6 +1,6 @@
plugin_name = 'file-jpeg'
plugin_sources = [
plugin_sourcecode = [
'jpeg-icc.c',
'jpeg-load.c',
'jpeg-quality.c',
@ -8,6 +8,7 @@ plugin_sources = [
'jpeg-settings.c',
'jpeg.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,6 +1,6 @@
plugin_name = 'file-psd'
plugin_sources = [
plugin_sourcecode = [
'psd-image-res-load.c',
'psd-layer-res-load.c',
'psd-load.c',
@ -9,6 +9,7 @@ plugin_sources = [
'psd-util.c',
'psd.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -8,10 +8,11 @@ file_raw_exes = [
foreach plugin_name : file_raw_exes
plugin_sources = [
plugin_sourcecode = [
plugin_name +'.c',
'file-raw-utils.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_rc = configure_file(

View file

@ -1,9 +1,10 @@
plugin_name = 'file-sgi'
plugin_sources = [
plugin_sourcecode = [
'sgi-lib.c',
'sgi.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,11 +1,12 @@
plugin_name = 'file-tiff'
plugin_sources = [
plugin_sourcecode = [
'file-tiff-io.c',
'file-tiff-export.c',
'file-tiff.c',
'file-tiff-load.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -2,12 +2,13 @@ if webp_found
plugin_name = 'file-webp'
plugin_sources = [
plugin_sourcecode = [
'file-webp-dialog.c',
'file-webp-load.c',
'file-webp-export.c',
'file-webp.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,11 +1,12 @@
plugin_name = 'flame'
plugin_sources = [
plugin_sourcecode = [
'cmap.c',
'flame.c',
'libifs.c',
'rect.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -2,10 +2,11 @@ subdir('examples')
plugin_name = 'fractal-explorer'
plugin_sources = [
plugin_sourcecode = [
'fractal-explorer-dialogs.c',
'fractal-explorer.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -0,0 +1,45 @@
#!/usr/bin/env python3
import sys
import os
import re
associations = set()
#Read file loading plug-ins sourcecode
source_files = sys.argv[2:]
for source_file in source_files:
try:
with open(source_file, 'r', encoding='utf-8') as f:
content = f.read()
except Exception as e:
sys.stderr.write(f"(WARNING): Unable to open file {source_file}: {e}\n")
continue
#Parse extensions declared in the sourcecode
source_file_ext = os.path.splitext(source_file)[1].lower()
if source_file_ext == '.c':
if "LOAD_PROC" not in content and "load_procedure" not in content:
continue
regex = (r'gimp_file_procedure_set_extensions\s*'
r'\(\s*GIMP_FILE_PROCEDURE\s*\(\s*procedure\s*\)\s*,\s*"([^"]+)"')
elif source_file_ext == '.py':
if "LoadProcedure" not in content:
continue
regex = r'procedure\.set_extensions\s*\(\s*"([^"]+)"\s*\)'
else:
continue
for match in re.findall(regex, content, re.DOTALL):
#(Take care of extensions separated by commas)
for extension in match.split(','):
trimmed = extension.strip()
if trimmed:
associations.add(trimmed)
#Create list of associations with the parsed extensions
output_file = sys.argv[1]
try:
with open(output_file, 'w', encoding='utf-8') as outf:
outf.writelines(f"{assoc}\n" for assoc in sorted(associations))
except Exception as e:
sys.stderr.write(f"(ERROR): When writing output file {output_file}: {e}\n")
sys.exit(1)

View file

@ -3,7 +3,7 @@ subdir('images')
plugin_name = 'gfig'
plugin_sources = [
plugin_sourcecode = [
'gfig-arc.c',
'gfig-bezier.c',
'gfig-circle.c',
@ -20,8 +20,8 @@ plugin_sources = [
'gfig-star.c',
'gfig-style.c',
'gfig.c',
gfig_icon_sources,
]
plugin_sources = plugin_sourcecode + gfig_icon_sources
plugin_sources += gnome.compile_resources(
'gfig-menus',

View file

@ -4,7 +4,7 @@ subdir('Presets')
plugin_name = 'gimpressionist'
plugin_sources = [
plugin_sourcecode = [
'brush.c',
'color.c',
'general.c',
@ -24,6 +24,7 @@ plugin_sources = [
'sizemap.c',
'utils.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -2,9 +2,10 @@ subdir('flares')
plugin_name = 'gradient-flare'
plugin_sources = [
plugin_sourcecode = [
'gradient-flare.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -2,11 +2,12 @@ if get_option('webkit-unmaintained')
plugin_name = 'help-browser'
plugin_sources = [
plugin_sourcecode = [
'dialog.c',
'help-browser.c',
'uri.c',
]
plugin_sources = plugin_sourcecode
plugin_sources += gnome.compile_resources(
'help-menus',

View file

@ -1,6 +1,6 @@
plugin_name = 'help'
plugin_sources = [
plugin_sourcecode = [
# 'gimp-help-lookup.c',
'gimphelp.c',
'gimphelpdomain.c',
@ -8,6 +8,7 @@ plugin_sources = [
'gimphelplocale.c',
'gimphelpprogress.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,10 +1,11 @@
plugin_name = 'ifs-compose'
plugin_sources = [
plugin_sourcecode = [
'ifs-compose-storage.c',
'ifs-compose-utils.c',
'ifs-compose.c',
]
plugin_sources = plugin_sourcecode
plugin_sources += gnome.compile_resources(
'ifs-menus',

View file

@ -2,7 +2,7 @@ subdir('images')
plugin_name = 'imagemap'
plugin_sources = [
plugin_sourcecode = [
'imap_about.c',
'imap_browse.c',
'imap_circle.c',
@ -60,8 +60,8 @@ plugin_sources = [
'imap_string.c',
'imap_taglist.c',
'imap_ui_grid.c',
imagemap_icon_sources,
]
plugin_sources = plugin_sourcecode + imagemap_icon_sources
plugin_sources += gnome.compile_resources(
'imagemap-menus',

View file

@ -2,7 +2,7 @@ subdir('images')
plugin_name = 'lighting'
plugin_sources = [
plugin_sourcecode = [
'lighting-apply.c',
'lighting-icons.c',
'lighting-image.c',
@ -10,8 +10,8 @@ plugin_sources = [
'lighting-preview.c',
'lighting-shade.c',
'lighting-ui.c',
lighting_icon_sources,
]
plugin_sources = plugin_sourcecode + lighting_icon_sources
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,6 +1,6 @@
plugin_name = 'map-object'
plugin_sources = [
plugin_sourcecode = [
'arcball.c',
'map-object-apply.c',
'map-object-icons.c',
@ -9,8 +9,8 @@ plugin_sources = [
'map-object-preview.c',
'map-object-shade.c',
'map-object-ui.c',
lighting_icon_sources,
]
plugin_sources = plugin_sourcecode + lighting_icon_sources
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,34 +1,113 @@
subdir('common')
subdir('file-bmp')
subdir('file-dds')
subdir('file-exr')
subdir('file-faxg3')
subdir('file-fits')
subdir('file-fli')
subdir('file-icns')
subdir('file-ico')
subdir('file-jpeg')
subdir('file-psd')
subdir('file-raw')
subdir('file-sgi')
subdir('file-tiff')
subdir('file-webp')
subdir('flame')
subdir('fractal-explorer')
subdir('gfig')
subdir('gimpressionist')
subdir('gradient-flare')
subdir('help')
subdir('help-browser')
subdir('ifs-compose')
subdir('imagemap')
subdir('lighting')
subdir('map-object')
subdir('metadata')
subdir('pagecurl')
subdir('print')
if get_option('windows-installer') or get_option('ms-store')
all_plugins_sources = []
foreach plugin : common_plugins_list
if plugin.get('name').startswith('file-') and plugin.get('name') != 'file-desktop-link' and plugin.get('name') != 'file-lnk'
all_plugins_sources += [ meson.current_source_dir() / 'common' / plugin.get('name') + '.c' ]
endif
endforeach
endif
complex_plugins_list = [
{ 'name': 'file-bmp', },
{ 'name': 'file-dds', },
{ 'name': 'file-faxg3', },
{ 'name': 'file-fli', },
{ 'name': 'file-icns', },
{ 'name': 'file-ico', },
{ 'name': 'file-jpeg', },
{ 'name': 'file-psd', },
{ 'name': 'file-raw', },
{ 'name': 'file-sgi', },
{ 'name': 'file-tiff', },
{ 'name': 'flame', },
{ 'name': 'fractal-explorer', },
{ 'name': 'gfig', },
{ 'name': 'gimpressionist', },
{ 'name': 'gradient-flare', },
{ 'name': 'help', },
{ 'name': 'ifs-compose', },
{ 'name': 'imagemap', },
{ 'name': 'lighting', },
{ 'name': 'map-object', },
{ 'name': 'metadata', },
{ 'name': 'pagecurl', },
{ 'name': 'print', },
{ 'name': 'screenshot', },
{ 'name': 'script-fu', },
{ 'name': 'selection-to-path', }
]
if openexr.found()
complex_plugins_list += {
'name': 'file-exr',
}
endif
if cfitsio_dep.found()
complex_plugins_list += {
'name': 'file-fits',
}
endif
if webp_found
complex_plugins_list += {
'name': 'file-webp',
}
endif
if get_option('webkit-unmaintained')
complex_plugins_list += {
'name': 'help-browser',
}
endif
if platform_windows and host_cpu_family == 'x86'
complex_plugins_list += {
'name': 'twain',
}
endif
foreach plugin : complex_plugins_list
subdir(plugin.get('name'))
if get_option('windows-installer') or get_option('ms-store')
foreach sourcecode : plugin_sourcecode
if plugin.get('name').startswith('file-')
#.ico files are handled in a special way by installer and msix scripts
if plugin.get('name') == 'file-ico' and platform_windows
continue
else
all_plugins_sources += [ meson.current_source_dir() / plugin.get('name') / sourcecode ]
endif
endif
endforeach
endif
endforeach
subdir('python')
subdir('screenshot')
subdir('script-fu')
subdir('selection-to-path')
subdir('twain')
#if get_option('windows-installer') or get_option('ms-store')
# foreach plugin : python_plugins
# if plugin.get('name').startswith('file-')
# all_plugins_sources += [ meson.current_source_dir() / python/ plugin.get('name') + '.py' ]
# endif
# endforeach
#endif
if get_option('windows-installer') or get_option('ms-store')
#List of file associations dynamically created with the plugins lists above
custom_target('file_associations',
input : all_plugins_sources,
output : 'file_associations.list',
command : [
python,
meson.current_source_dir() / 'generate_associations.py',
'@OUTPUT@'
] + all_plugins_sources,
build_by_default: true
)
endif

View file

@ -1,12 +1,13 @@
plugin_name = 'metadata-editor'
plugin_sources = [
plugin_sourcecode = [
'metadata-editor.c',
'metadata-impexp.c',
'metadata-tags.c',
'metadata-xml.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_rc = configure_file(
@ -42,10 +43,11 @@ plugin_executables += [plugin_exe.full_path()]
plugin_name = 'metadata-viewer'
plugin_sources = [
plugin_sourcecode = [
'metadata-viewer.c',
'metadata-tags.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_rc = configure_file(

View file

@ -1,8 +1,9 @@
plugin_name = 'pagecurl'
plugin_sources = [
plugin_sourcecode = [
'pagecurl.c',
]
plugin_sources = plugin_sourcecode
pagecurl_icons_images = [
'curl0.png',

View file

@ -3,7 +3,7 @@ if have_print
plugin_name = 'print'
plugin_sources = [
plugin_sourcecode = [
'print-draw-page.c',
'print-page-layout.c',
'print-page-setup.c',
@ -12,6 +12,7 @@ plugin_sources = [
'print-utils.c',
'print.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -1,4 +1,4 @@
plugins = [
python_plugins = [
{ 'name': 'colorxhtml' },
{ 'name': 'file-openraster' },
{ 'name': 'foggify' },
@ -13,7 +13,7 @@ plugins = [
]
if not stable or not release
plugins += [
python_plugins += [
{ 'name': 'test-dialog' },
]
endif
@ -21,7 +21,7 @@ endif
subdir('python-console')
subdir('tests')
foreach plugin : plugins
foreach plugin : python_plugins
name = plugin.get('name')
srcs = plugin.get('srcs', [name + '.py'])

View file

@ -1,5 +1,5 @@
plugins += {
python_plugins += {
'name': 'python-console',
'srcs': [ 'python-console/pyconsole.py', 'python-console/python-console.py' ],
}

View file

@ -1,7 +1,7 @@
if not stable or not release or gimp_version.endswith('+git') or get_option('file-plug-ins-test')
# This does not get installed for releases
plugins += {
python_plugins += {
'name': 'test-file-plug-ins',
'srcs': [
# modules

View file

@ -1,12 +1,13 @@
plugin_name = 'screenshot'
plugin_sources = [
plugin_sourcecode = [
'screenshot-freedesktop.c',
'screenshot-osx.c',
'screenshot-win32.c',
'screenshot-x11.c',
'screenshot.c',
]
plugin_sources = plugin_sourcecode
screenshot_icons_images = [
'screenshot-icon.png',

View file

@ -3,10 +3,11 @@ scriptfuInclude = include_directories('..')
executable_name = 'gimp-script-fu-interpreter-' + gimp_api_version
plugin_sources = [
plugin_sourcecode = [
'script-fu-interpreter.c',
'script-fu-interpreter-plugin.c',
]
plugin_sources = plugin_sourcecode
if not meson.is_cross_build()
if platform_windows

View file

@ -23,13 +23,14 @@ executable_name = 'script-fu'
# Several source files implement the PDB procedures of type PLUGIN, of similar names.
# script-fu.c also implements PDB procedure of type EXTENSION "extension-script-fu"
plugin_sources = [
plugin_sourcecode = [
'script-fu-eval.c',
'script-fu-text-console.c',
'script-fu-refresh.c',
'script-fu.c',
]
plugin_sources = plugin_sourcecode
if not meson.is_cross_build()
if platform_windows

View file

@ -3,10 +3,11 @@ scriptfuInclude = include_directories('..')
executable_name = 'script-fu-server'
plugin_sources = [
plugin_sourcecode = [
'script-fu-server.c',
'script-fu-server-plugin.c',
]
plugin_sources = plugin_sourcecode
if not meson.is_cross_build()
if platform_windows

View file

@ -1,6 +1,6 @@
plugin_name = 'selection-to-path'
plugin_sources = [
plugin_sourcecode = [
'curve.c',
'edge.c',
'fit.c',
@ -10,6 +10,7 @@ plugin_sources = [
'spline.c',
'vector.c',
]
plugin_sources = plugin_sourcecode
if platform_windows
plugin_sources += windows.compile_resources(

View file

@ -4,12 +4,13 @@ endif
plugin_name = 'twain'
plugin_sources = [
plugin_sourcecode = [
'tw_func.c',
'tw_util.c',
'tw_win.c',
'twain.c',
]
plugin_sources = plugin_sourcecode
plugin_sources += windows.compile_resources(
gimp_plugins_rc,