meson, desktop, plug-ins: Generate MIMEtypes var dynamically

This way, we avoid divergence with MIMEs declared on the
plug-ins .c and .py files and we eliminate duplicate work.

See also: 2ce3c604
This commit is contained in:
Bruno Lopes 2025-06-13 12:36:38 -03:00
parent a2bd03a471
commit d56676a2fa
No known key found for this signature in database
4 changed files with 93 additions and 118 deletions

View file

@ -5,7 +5,7 @@ desktop_conf.set('GIMP_COMMAND', gimp_command)
desktop_conf.set('GIMP_VERSION', gimp_version)
desktop_conf.set('GIMP_APP_VERSION', gimp_app_version)
desktop_conf.set('GIMP_DESKTOP_NAME', gimp_desktop_name)
desktop_conf.set('MIME_TYPES', ';'.join(MIMEtypes))
desktop_conf.set('MIME_TYPES', 'image/x-xcf;' + MIMEtypes_dep.get_variable('MIMEtypes'))
desktop_conf.set('BUG_REPORT_URL', bug_report_url)
desktopfilein = configure_file(

View file

@ -742,44 +742,12 @@ have_doc_shooter= x11_target
################################################################################
# Plugins (optional dependencies)
# The list of MIME types that are supported by plug-ins
MIMEtypes = [
'image/bmp',
'image/g3fax',
'image/gif',
'image/svg+xml',
'image/x-compressed-xcf',
'image/x-fits',
'image/x-gimp-gbr',
'image/x-gimp-gih',
'image/x-gimp-pat',
'image/x-pcx',
'image/x-portable-anymap',
'image/x-portable-bitmap',
'image/x-portable-graymap',
'image/x-portable-pixmap',
'image/x-psd',
'image/x-sgi',
'image/x-sun-raster',
'image/x-tga',
'image/x-xbitmap',
'image/x-xcf',
'image/x-xwindowdump',
]
libtiff_minver = '4.0.0'
libtiff = dependency('libtiff-4', version: '>=' + libtiff_minver)
MIMEtypes += 'image/tiff'
libjpeg = dependency('libjpeg')
MIMEtypes += 'image/jpeg'
zlib = dependency('zlib')
MIMEtypes += 'image/x-psp'
# Compiler-provided headers can't be found in crossroads environment
if not meson.is_cross_build()
@ -793,15 +761,12 @@ liblzma = dependency('liblzma', version: '>='+liblzma_minver)
ghostscript = cc.find_library('gs', required: get_option('ghostscript'))
if ghostscript.found()
MIMEtypes += 'application/postscript'
else
if not ghostscript.found()
ghostscript = disabler()
endif
libpng_minver = '1.6.25'
libpng = dependency('libpng', version: '>='+libpng_minver)
MIMEtypes += [ 'image/png', 'image/x-icon']
libmng = dependency('libmng', required: get_option('mng'))
@ -821,14 +786,8 @@ endif
libaa = cc.find_library('aa', required: get_option('aa'))
libxpm = dependency('xpm', required: get_option('xpm'))
if libxpm.found()
MIMEtypes += 'image/x-xpixmap'
endif
have_qoi = cc.has_header('qoi.h')
if have_qoi
MIMEtypes += 'image/qoi'
endif
libiff = dependency('libiff', required: get_option('ilbm'))
libilbm = dependency('libilbm', required: get_option('ilbm'))
@ -837,17 +796,11 @@ if libiff.found() and libilbm.found()
else
have_ilbm = cc.has_header('libilbm/ilbm.h', required: get_option('ilbm'))
endif
if have_ilbm
MIMEtypes += 'image/x-ilbm'
endif
openexr_minver = '1.6.1'
openexr = dependency('OpenEXR', version: '>='+openexr_minver,
required: get_option('openexr')
)
if openexr.found()
MIMEtypes += 'image/x-exr'
endif
webp_minver = '0.6.0'
webp_libs = [
@ -860,13 +813,6 @@ foreach lib : webp_libs
webp_found = webp_found and lib.found()
endforeach
if webp_found
MIMEtypes += [
'image/x-webp',
'image/webp'
]
endif
libheif_minver = '1.15.1'
libheif = dependency('libheif', version: '>='+libheif_minver,
required: get_option('heif')
@ -960,17 +906,6 @@ if have_heif
if not can_import_heic and not can_import_avif
have_heif = false
endif
if have_heif
# Listing support for both HEIC and AVIF if we build with HEIF support,
# because codecs can be added at any time later and we won't be able to edit
# the desktop file once it's installed. See discussion in #9080.
MIMEtypes += [
'image/heif',
'image/heic',
'image/avif'
]
endif
endif
have_vala = add_languages('vala', required: get_option('vala'), native: false)
@ -1014,24 +949,15 @@ cairopdf = dependency('cairo-pdf', version: '>='+cairopdf_minver,
required: get_option('cairo-pdf')
)
# PDF import support is a granted feature.
MIMEtypes += 'application/pdf'
wmf_minver = '0.2.8'
wmf = dependency('libwmf', version: '>='+wmf_minver,
required: get_option('wmf')
)
if wmf.found()
MIMEtypes += 'image/x-wmf'
endif
openjpeg_minver = '2.1.0'
openjpeg = dependency('libopenjp2', version: '>='+openjpeg_minver,
required: get_option('jpeg2000')
)
if openjpeg.found()
MIMEtypes += [ 'image/jp2', 'image/jpeg2000', 'image/jpx', ]
endif
jpegxl_minver = '0.7.0'
libjxl = dependency('libjxl',
@ -1042,14 +968,8 @@ libjxl_threads = dependency('libjxl_threads',
version: '>='+jpegxl_minver,
required: get_option('jpeg-xl')
)
if libjxl.found() and libjxl_threads.found()
MIMEtypes += 'image/jxl'
endif
xmc = dependency('xcursor', required: get_option('xcursor'))
if xmc.found()
MIMEtypes += 'image/x-xcursor'
endif
alsa = dependency('alsa', version: '>=1.0.0', required: get_option('alsa'))
@ -1093,9 +1013,6 @@ endif
conf.set('HAVE_DX_DINPUT', directx.found())
cfitsio_dep = dependency('cfitsio', required: get_option('fits'))
if cfitsio_dep.found()
MIMEtypes += 'image/fits'
endif
################################################################################
@ -1176,8 +1093,6 @@ if not pygobject_found
error('PyGObject is required.')
endif
MIMEtypes += 'image/openraster'
## Javascript
gjs = find_program('gjs', required: false)
@ -1930,9 +1845,8 @@ subdir('po-python')
subdir('po-script-fu')
subdir('po-tags')
subdir('po-tips')
# Data / Desktop / xml files
# Data / xml files
subdir('data')
subdir('desktop')
subdir('etc')
subdir('menus')
subdir('themes')
@ -1957,6 +1871,9 @@ subdir('plug-ins')
subdir('app')
subdir('app-tools')
# Desktop files
subdir('desktop')
################################################################################
# Make GIMP runnable without being installed for unit-testing or as a build
# tool.

View file

@ -0,0 +1,54 @@
#!/usr/bin/env python3
import sys
import os
import re
types_associations_list = set()
#Read file loading plug-ins sourcecode
source_files = sys.argv[3:]
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 MIME types or extensions declared in the sourcecode
mode = sys.argv[1]
if mode == "--mime":
function_suffix = 'set_mime_types'
elif mode == "--association":
function_suffix = 'set_extensions'
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 = (fr'gimp_file_procedure_{function_suffix}\s*'
fr'\(\s*GIMP_FILE_PROCEDURE\s*\(\s*procedure\s*\)\s*,\s*"([^"]+)"')
elif source_file_ext == '.py':
if "LoadProcedure" not in content:
continue
regex = fr'procedure\.{function_suffix}\s*\(\s*"([^"]+)"\s*\)'
else:
continue
for match in re.findall(regex, content, re.DOTALL):
#(Take care of extensions separated by commas)
for mime_extension in match.split(','):
trimmed = mime_extension.strip()
if trimmed:
types_associations_list.add(trimmed)
if mode == "--mime":
#Output string with the parsed MIME types
print(";".join(sorted(types_associations_list)))
elif mode == "--association":
#Create list with the parsed extensions
output_file = sys.argv[2]
try:
with open(output_file, 'w', encoding='utf-8') as outf:
outf.writelines(f"{assoc}\n" for assoc in sorted(types_associations_list))
except Exception as e:
sys.stderr.write(f"(ERROR): When writing output file {output_file}: {e}\n")
sys.exit(1)

View file

@ -1,13 +1,11 @@
subdir('common')
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
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
complex_plugins_list = [
@ -72,41 +70,47 @@ 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
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
endforeach
endif
endif
endforeach
endforeach
subdir('python')
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
foreach plugin : python_plugins
if plugin.get('name').startswith('file-')
all_plugins_sources += [ meson.current_source_dir() / 'python' / plugin.get('name') + '.py' ]
endif
endforeach
#Dynamically created list of supported files with the plugins lists above
MIMEtypes_output = run_command(
python,
meson.current_source_dir() / 'generate_mime_ext.py',
'--mime',
meson.current_build_dir() / 'file_mimetypes.list',
all_plugins_sources
).stdout().strip()
MIMEtypes_dep = declare_dependency(variables : {'MIMEtypes': MIMEtypes_output})
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@'
meson.current_source_dir() / 'generate_mime_ext.py',
'--association',
'@OUTPUT@',
] + all_plugins_sources,
build_by_default: true
)