Přemysl Eric Janouch
72bf913f3d
It works well for my Nikon. Note that hot pixels can be eliminated in the camera itself, when you run sensor cleaning immediately after a very long exposure of darkness.
381 lines
13 KiB
Meson
381 lines
13 KiB
Meson
# vim: noet ts=4 sts=4 sw=4:
|
|
project('fiv', 'c',
|
|
default_options : ['c_std=gnu99', 'warning_level=2'],
|
|
version : '0.1.0',
|
|
meson_version : '>=0.57')
|
|
|
|
cc = meson.get_compiler('c')
|
|
add_project_arguments(
|
|
cc.get_supported_arguments('-Wno-cast-function-type'), language : 'c')
|
|
|
|
# This, annoyingly, enables the leak sanitizer by default,
|
|
# which requires some tuning to not stand in the way.
|
|
# Use -Db_sanitize=address,undefined and adjust LSAN_OPTIONS yourself.
|
|
#if get_option('buildtype').startswith('debug')
|
|
# flags = cc.get_supported_arguments('-fsanitize=address,undefined')
|
|
# add_project_arguments(flags, language : ['c'])
|
|
# add_project_link_arguments(flags, language : ['c'])
|
|
#endif
|
|
|
|
win32 = host_machine.system() == 'windows'
|
|
|
|
# The likelihood of this being installed is nearly zero. Enable the wrap.
|
|
libjpegqs = dependency('libjpegqs', required : get_option('libjpegqs'),
|
|
allow_fallback : true)
|
|
|
|
lcms2 = dependency('lcms2', required : get_option('lcms2'))
|
|
# Note that only libraw_r is thread-safe, but we'll just run it out-of process.
|
|
libraw = dependency('libraw', required : get_option('libraw'))
|
|
# This is a direct runtime dependency, but its usage may be disabled for images.
|
|
librsvg = dependency('librsvg-2.0', required : get_option('librsvg'))
|
|
xcursor = dependency('xcursor', required : get_option('xcursor'))
|
|
libheif = dependency('libheif', required : get_option('libheif'))
|
|
libtiff = dependency('libtiff-4', required : get_option('libtiff'))
|
|
# This is a direct dependency of GTK+, but its usage may be disabled for images.
|
|
gdkpixbuf = dependency('gdk-pixbuf-2.0', required : get_option('gdk-pixbuf'))
|
|
dependencies = [
|
|
dependency('gtk+-3.0'),
|
|
dependency('pixman-1'),
|
|
|
|
dependency('libjpeg'),
|
|
dependency('libturbojpeg'),
|
|
dependency('libwebp'),
|
|
dependency('libwebpdemux'),
|
|
dependency('libwebpdecoder', required : false),
|
|
dependency('libwebpmux'),
|
|
# Wuffs is included as a submodule.
|
|
|
|
lcms2,
|
|
libjpegqs,
|
|
libraw,
|
|
librsvg,
|
|
xcursor,
|
|
libheif,
|
|
libtiff,
|
|
|
|
cc.find_library('m', required : false),
|
|
]
|
|
|
|
# As of writing, no pkg-config file is produced, and the plugin is not installed
|
|
# by default. The library can be built statically, but it's a bit of a hassle.
|
|
have_lcms2_fast_float = false
|
|
if not get_option('lcms2fastfloat').disabled()
|
|
lcms2ff = dependency('lcms2_fast_float', required : false)
|
|
if not lcms2ff.found()
|
|
lcms2ff = cc.find_library(
|
|
'lcms2_fast_float', required : get_option('lcms2fastfloat'))
|
|
if lcms2ff.found() and not cc.has_header('lcms2_fast_float.h')
|
|
error('lcms2_fast_float.h not found')
|
|
endif
|
|
endif
|
|
if lcms2ff.found()
|
|
dependencies += lcms2ff
|
|
have_lcms2_fast_float = true
|
|
endif
|
|
endif
|
|
|
|
# As of writing, the API is unstable, and no pkg-config file is produced.
|
|
# Trying to wrap Cargo in Meson is a recipe for pain, so no version pinning.
|
|
have_resvg = false
|
|
if not get_option('resvg').disabled()
|
|
resvg = dependency('resvg', required : false)
|
|
if not resvg.found()
|
|
resvg = cc.find_library('resvg', required : get_option('resvg'))
|
|
if resvg.found() and not cc.has_header('resvg.h')
|
|
error('resvg.h not found')
|
|
endif
|
|
endif
|
|
if resvg.found()
|
|
dependencies += resvg
|
|
have_resvg = true
|
|
endif
|
|
endif
|
|
|
|
# XXX: https://github.com/mesonbuild/meson/issues/825
|
|
docdir = get_option('datadir') / 'doc' / meson.project_name()
|
|
application_ns = 'name.janouch.'
|
|
application_url = 'https://janouch.name/p/' + meson.project_name()
|
|
|
|
conf = configuration_data()
|
|
conf.set_quoted('PROJECT_NAME', meson.project_name())
|
|
conf.set_quoted('PROJECT_VERSION', '@VCS_TAG@')
|
|
conf.set_quoted('PROJECT_NS', application_ns)
|
|
conf.set_quoted('PROJECT_URL', application_url)
|
|
conf.set_quoted('PROJECT_DOCDIR', get_option('prefix') / docdir)
|
|
if win32
|
|
conf.set_quoted('PROJECT_DOCDIR', docdir)
|
|
endif
|
|
|
|
conf.set('HAVE_JPEG_QS', libjpegqs.found())
|
|
conf.set('HAVE_LCMS2', lcms2.found())
|
|
conf.set('HAVE_LCMS2_FAST_FLOAT', have_lcms2_fast_float)
|
|
conf.set('HAVE_LIBRAW', libraw.found())
|
|
conf.set('HAVE_RESVG', have_resvg)
|
|
conf.set('HAVE_LIBRSVG', librsvg.found())
|
|
conf.set('HAVE_XCURSOR', xcursor.found())
|
|
conf.set('HAVE_LIBHEIF', libheif.found())
|
|
conf.set('HAVE_LIBTIFF', libtiff.found())
|
|
conf.set('HAVE_GDKPIXBUF', gdkpixbuf.found())
|
|
|
|
config = vcs_tag(
|
|
command : ['git', 'describe', '--always', '--dirty=+'],
|
|
input : configure_file(output : 'config.h.in', configuration : conf),
|
|
output : 'config.h',
|
|
)
|
|
|
|
rc = []
|
|
if win32
|
|
windows = import('windows')
|
|
rsvg_convert = find_program('rsvg-convert')
|
|
icotool = find_program('icotool')
|
|
|
|
# Meson is brain-dead and retarded, so these PNGs cannot be installed,
|
|
# only because they must all have the same name when installed.
|
|
# The largest size is mainly for an appropriately sized Windows icon.
|
|
icon_png_list = []
|
|
foreach size : ['16', '32', '48', '256']
|
|
icon_dimensions = size + 'x' + size
|
|
icon_png_list += custom_target(icon_dimensions + ' icon',
|
|
input : 'fiv.svg',
|
|
output : 'fiv.' + icon_dimensions + '.png',
|
|
command : [rsvg_convert, '--output', '@OUTPUT@',
|
|
'--width', size, '--height', size, '@INPUT@'])
|
|
endforeach
|
|
|
|
icon_ico = custom_target('fiv.ico',
|
|
output : 'fiv.ico', input : icon_png_list,
|
|
command : [icotool, '-c', '-o', '@OUTPUT@', '@INPUT@'])
|
|
rc += windows.compile_resources('fiv.rc', depends : icon_ico)
|
|
endif
|
|
|
|
gnome = import('gnome')
|
|
gresources = gnome.compile_resources('resources',
|
|
'resources/resources.gresource.xml',
|
|
source_dir : 'resources',
|
|
c_name : 'resources',
|
|
)
|
|
|
|
tiff_tables = custom_target('tiff-tables.h',
|
|
output : 'tiff-tables.h',
|
|
input : 'tiff-tables.db',
|
|
# Meson 0.56 chokes on files() as well as on a relative path.
|
|
command : [meson.current_source_dir() / 'tiff-tables.awk', '@INPUT@'],
|
|
capture : true,
|
|
)
|
|
|
|
desktops = ['fiv.desktop', 'fiv-browse.desktop']
|
|
iolib = static_library('fiv-io', 'fiv-io.c', 'xdg.c', tiff_tables,
|
|
dependencies : dependencies).extract_all_objects(recursive : true)
|
|
exe = executable('fiv', 'fiv.c', 'fiv-view.c', 'fiv-context-menu.c',
|
|
'fiv-browser.c', 'fiv-sidebar.c', 'fiv-thumbnail.c', 'fiv-collection.c',
|
|
'fiv-io-model.c', gresources, rc, config,
|
|
objects : iolib,
|
|
dependencies : dependencies,
|
|
install : true,
|
|
win_subsystem : 'windows',
|
|
)
|
|
|
|
desktops += 'fiv-jpegcrop.desktop'
|
|
jpegcrop = executable('fiv-jpegcrop', 'fiv-jpegcrop.c', rc, config,
|
|
install : true,
|
|
dependencies : [
|
|
dependency('gtk+-3.0'),
|
|
dependency('libturbojpeg'),
|
|
],
|
|
win_subsystem : 'windows',
|
|
)
|
|
|
|
if get_option('tools').enabled()
|
|
# libjq has only received a pkg-config file in version 1.7.
|
|
# libjq >= 1.6 is required.
|
|
tools_dependencies = [
|
|
cc.find_library('jq'), dependency('libpng'), dependency('libraw')]
|
|
tools_c_args = cc.get_supported_arguments(
|
|
'-Wno-unused-function', '-Wno-unused-parameter')
|
|
foreach tool : ['info', 'pnginfo', 'rawinfo', 'hotpixels']
|
|
executable(tool, 'tools/' + tool + '.c', tiff_tables,
|
|
dependencies : tools_dependencies,
|
|
c_args: tools_c_args)
|
|
endforeach
|
|
|
|
if gdkpixbuf.found()
|
|
executable('benchmark-io', 'tools/benchmark-io.c',
|
|
objects : iolib,
|
|
dependencies : [dependencies, gdkpixbuf])
|
|
endif
|
|
endif
|
|
|
|
# Copying the files to the build directory makes GSettings find them in devenv.
|
|
gsettings_schemas = ['fiv.gschema.xml']
|
|
foreach schema : gsettings_schemas
|
|
configure_file(
|
|
input : schema,
|
|
output : application_ns + schema,
|
|
copy : true,
|
|
install: true,
|
|
install_dir : get_option('datadir') / 'glib-2.0' / 'schemas')
|
|
endforeach
|
|
|
|
# For the purposes of development: make the program find its GSettings schemas.
|
|
gnome.compile_schemas(depend_files : files(gsettings_schemas))
|
|
gnome.post_install(glib_compile_schemas : true, gtk_update_icon_cache : true)
|
|
|
|
# Meson is broken on Windows and removes the backslashes, so this ends up empty.
|
|
symbolics = run_command(find_program('sed', required : false, disabler : true),
|
|
'-n', 's@.*>\\([^<>]*[.]svg\\)<.*@resources/\\1@p',
|
|
configure_file(
|
|
input : 'resources/resources.gresource.xml',
|
|
output : 'resources.gresource.xml.stamp',
|
|
copy : true,
|
|
), capture : true, check : true).stdout().strip()
|
|
|
|
# Validate various files, if there are tools around to do it.
|
|
xmls = ['fiv.svg', 'fiv.manifest', 'resources/resources.gresource.xml'] + \
|
|
gsettings_schemas
|
|
if symbolics != ''
|
|
xmls += symbolics.split('\n')
|
|
endif
|
|
|
|
xmlwf = find_program('xmlwf', required : false, disabler : true)
|
|
xmllint = find_program('xmllint', required : false, disabler : true)
|
|
foreach xml : xmls
|
|
test('xmlwf ' + xml, xmlwf, args : files(xml))
|
|
test('xmllint ' + xml, xmllint, args : ['--noout', files(xml)])
|
|
endforeach
|
|
|
|
dfv = find_program('desktop-file-validate', required : false, disabler : true)
|
|
foreach desktop : desktops
|
|
test(desktop, dfv, args : files(desktop))
|
|
endforeach
|
|
|
|
# Finish the installation.
|
|
install_data('fiv.svg',
|
|
install_dir : get_option('datadir') / 'icons/hicolor/scalable/apps')
|
|
install_subdir('docs',
|
|
install_dir : docdir, strip_directory : true)
|
|
|
|
if not win32
|
|
asciidoctor = find_program('asciidoctor', required : false)
|
|
a2x = find_program('a2x', required : false)
|
|
if not asciidoctor.found() and not a2x.found()
|
|
warning('Neither asciidoctor nor a2x were found, ' +
|
|
'falling back to a substandard manual page generator')
|
|
endif
|
|
foreach page : [meson.project_name()]
|
|
man_capture = false
|
|
if asciidoctor.found()
|
|
command = [asciidoctor, '-b', 'manpage',
|
|
'-a', 'release-version=' + meson.project_version(),
|
|
'-o', '@OUTPUT@', '@INPUT@']
|
|
elif a2x.found()
|
|
command = [a2x, '--doctype', 'manpage', '--format', 'manpage',
|
|
'-a', 'release-version=' + meson.project_version(),
|
|
'-D', '@OUTDIR@', '@INPUT@']
|
|
else
|
|
command = ['env', 'LC_ALL=C',
|
|
'asciidoc-release-version=' + meson.project_version(),
|
|
'awk', '-f', files('submodules/liberty/tools/asciiman.awk'),
|
|
'@INPUT@']
|
|
man_capture = true
|
|
endif
|
|
custom_target('manpage for ' + page,
|
|
input : 'docs' / page + '.adoc',
|
|
output : page + '.1',
|
|
capture : man_capture,
|
|
command : command,
|
|
install : true,
|
|
install_dir : get_option('mandir') / 'man1')
|
|
endforeach
|
|
|
|
foreach desktop : desktops
|
|
install_data(desktop,
|
|
rename : application_ns + desktop,
|
|
install_dir : get_option('datadir') / 'applications')
|
|
endforeach
|
|
|
|
# TODO(p): Consider moving this to /usr/share or /usr/lib.
|
|
install_data('fiv-reverse-search',
|
|
install_dir : get_option('bindir'))
|
|
|
|
# As usual, handling generated files in Meson is a fucking pain.
|
|
updatable_desktops = [application_ns + 'fiv.desktop']
|
|
foreach name, uri : {
|
|
'Google' : 'https://lens.google.com/uploadbyurl?url=',
|
|
'Bing' : 'https://www.bing.com/images/searchbyimage?cbir=sbi&imgurl=',
|
|
'Yandex' : 'https://yandex.com/images/search?rpt=imageview&url=',
|
|
'TinEye' : 'https://tineye.com/search?url=',
|
|
'SauceNAO' : 'https://saucenao.com/search.php?url=',
|
|
'IQDB' : 'https://iqdb.org/?url=',
|
|
}
|
|
desktop = 'fiv-reverse-search-' + name.to_lower() + '.desktop'
|
|
updatable_desktops += application_ns + desktop
|
|
|
|
test(desktop, dfv, args : configure_file(
|
|
input : 'fiv-reverse-search.desktop.in',
|
|
output : application_ns + desktop,
|
|
configuration : {'NAME' : name, 'URL' : uri},
|
|
install : true,
|
|
install_dir : get_option('datadir') / 'applications',
|
|
))
|
|
endforeach
|
|
|
|
# With gdk-pixbuf, fiv.desktop depends on currently installed modules;
|
|
# the package manager needs to be told to run this script as necessary.
|
|
dynamic_desktops = gdkpixbuf.found()
|
|
|
|
updater = configure_file(
|
|
input : 'fiv-update-desktop-files.in',
|
|
output : 'fiv-update-desktop-files',
|
|
configuration : {
|
|
'FIV' : get_option('prefix') / get_option('bindir') / exe.name(),
|
|
'DESKTOPDIR' : get_option('prefix') /
|
|
get_option('datadir') / 'applications',
|
|
'DESKTOPS' : ' \\\n\t'.join(updatable_desktops),
|
|
},
|
|
install : dynamic_desktops,
|
|
install_dir : get_option('bindir'))
|
|
if not meson.is_cross_build()
|
|
meson.add_install_script(updater, skip_if_destdir : dynamic_desktops)
|
|
endif
|
|
|
|
# Quick and dirty package generation, lacking dependencies.
|
|
packaging = configuration_data({
|
|
'name' : meson.project_name(),
|
|
'version' : meson.project_version(),
|
|
'summary' : 'Image viewer',
|
|
'author' : 'Přemysl Eric Janouch',
|
|
})
|
|
|
|
subdir('submodules/liberty/meson/packaging')
|
|
elif meson.is_cross_build()
|
|
# Note that even compiling /from within MSYS2/ can still be a cross-build.
|
|
msys2_root = meson.get_external_property('msys2_root')
|
|
meson.add_install_script('msys2-install.sh', msys2_root)
|
|
|
|
wxs = configure_file(
|
|
input : 'fiv.wxs.in',
|
|
output : 'fiv.wxs',
|
|
configuration : configuration_data({
|
|
'ProjectName' : meson.project_name(),
|
|
'ProjectVersion' : meson.project_version(),
|
|
'ProjectURL' : application_url,
|
|
}),
|
|
)
|
|
custom_target('package',
|
|
output : 'fiv.msi',
|
|
command : [meson.current_source_dir() / 'msys2-package.sh',
|
|
host_machine.cpu(), 'fiv.msi', wxs],
|
|
env : ['MESON_BUILD_ROOT=' + meson.current_build_dir(),
|
|
'MESON_SOURCE_ROOT=' + meson.current_source_dir()],
|
|
console : true,
|
|
build_always_stale : true,
|
|
build_by_default : false,
|
|
)
|
|
|
|
# This is the minimum to run targets from msys2-configure.sh builds.
|
|
meson.add_devenv({
|
|
'WINEPATH' : msys2_root / 'bin',
|
|
'XDG_DATA_DIRS' : msys2_root / 'share',
|
|
})
|
|
endif
|