mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-04-21 21:40:40 +02:00
Relaxed atomics really benefit from volatile access since otherwise
the compiler can hoist loads / stores out of loops. For example, in
the typical spin scenario:
while (!_cairo_atomic_int_get_relaxed (&done));
The optimizer can do:
val = _cairo_atomic_int_get_relaxed (&done);
if (!val) {
for (;;);
}
Unless told otherwise, e.g. with volatile or _Atomic, the optimizer
assumes that variables are only accessed by a single thread of execution.
That's also why data races are undefined behaviour in C11.
For GCC and CLang we use an intermediate volatile cast. This works
because GCC and CLang support the Linux Kernel Memory Model (LKMM) [1],
ensuring that:
1. volatile can be applied to single accesses and not necessarily
to the variable itself
2. volatile accesses are atomic for aligned and machine-word sized
variables
For MSVC we use the newer __iso_volatile intrinsics which are recommended
over volatile accesses [2].
Mutex-based fallbacks must all go under the mutex, even relaxed ones,
so we drop the ATOMIC_OP_NEEDS_MEMORY_BARRIER macro.
References:
1. https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0124r6.html
2. https://learn.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-c4746
896 lines
27 KiB
Meson
896 lines
27 KiB
Meson
project('cairo', 'c',
|
|
meson_version: '>= 1.3.0',
|
|
version: run_command(find_program('version.py'), check: true).stdout().strip(),
|
|
default_options: ['c_std=gnu11,c11',
|
|
'cpp_std=gnu++11,c++11',
|
|
'warning_level=2'],
|
|
)
|
|
|
|
freetype_required_version = '>= 23.0.17' # Release version 2.10
|
|
freetype_colrv1_required_version = '>= 25.0.19' # Release version 2.13
|
|
fontconfig_required_version = '>= 2.13.0'
|
|
libpng_required_version = '>= 1.4.0'
|
|
xrender_required_version = '>= 0.6'
|
|
xcb_required_version = '>= 1.6'
|
|
xcb_render_required_version = '>= 1.6'
|
|
libudev_required_version = '>= 136'
|
|
glib_required_version = '>= 2.14'
|
|
|
|
# library versioning
|
|
version_arr = meson.project_version().split('.')
|
|
cairo_version_major = version_arr[0].to_int()
|
|
cairo_version_minor = version_arr[1].to_int()
|
|
cairo_version_micro = version_arr[2].to_int()
|
|
|
|
# The libtool shared library version stuff.
|
|
# Try and maintain compatibility with the previous library versioning.
|
|
cairo_version_sonum = cairo_version_major + 1
|
|
cairo_version = cairo_version_major * 10000 + cairo_version_minor * 100 + cairo_version_micro
|
|
|
|
if cairo_version_minor % 2 == 1
|
|
# unstable release
|
|
cairo_libversion = '@0@.@1@.0'.format(cairo_version_sonum, cairo_version)
|
|
else
|
|
# stable release
|
|
cairo_libversion = '@0@.@1@.@2@'.format(cairo_version_sonum, cairo_version, cairo_version_micro)
|
|
endif
|
|
|
|
conf = configuration_data()
|
|
|
|
cc = meson.get_compiler('c')
|
|
|
|
# Compiler flags
|
|
cflags = []
|
|
if cc.get_id() != 'msvc'
|
|
cflags += [
|
|
'-Wmissing-declarations',
|
|
'-Werror-implicit-function-declaration',
|
|
'-Wpointer-arith',
|
|
'-Wwrite-strings',
|
|
'-Wsign-compare',
|
|
'-Wpacked',
|
|
'-Wswitch-enum',
|
|
'-Wmissing-format-attribute',
|
|
'-Wvolatile-register-var',
|
|
'-Wstrict-aliasing=2',
|
|
'-Winit-self',
|
|
'-Wunsafe-loop-optimizations',
|
|
'-Wno-missing-field-initializers',
|
|
'-Wno-unused-parameter',
|
|
'-Wno-attributes',
|
|
'-Wno-long-long',
|
|
'-Winline'
|
|
]
|
|
|
|
cflags += ['-Wno-unused-but-set-variable',
|
|
'-Wno-enum-conversion'
|
|
]
|
|
|
|
cflags += [
|
|
'-fno-strict-aliasing',
|
|
'-fno-common'
|
|
]
|
|
|
|
if get_option('optimization') in ['1', '2', '3']
|
|
cflags += '-Wp,-D_FORTIFY_SOURCE=2'
|
|
endif
|
|
|
|
supported_cflags = cc.get_supported_arguments(cflags)
|
|
add_project_arguments(supported_cflags, language: ['c', 'cpp'])
|
|
|
|
# We only wish to enable attribute(warn_unused_result) if we can prevent
|
|
# gcc from generating thousands of warnings about the misapplication of the
|
|
# attribute to void functions and variables.
|
|
warn_unused_result = ''
|
|
if supported_cflags.contains('-Wno-attributes')
|
|
if cc.compiles(files('meson-cc-tests/check-unused-result.c'), args : ['-Wno-attributes', '-Werror'])
|
|
warn_unused_result = '__attribute__((__warn_unused_result__))'
|
|
endif
|
|
endif
|
|
conf.set('WARN_UNUSED_RESULT', warn_unused_result)
|
|
endif
|
|
|
|
if cc.get_id() == 'msvc'
|
|
# Basic usage in the cairo type system that causes spammy and useless warnings
|
|
add_project_arguments('/wd4244', '/wd4146',
|
|
# Don't warn about double -> float truncation
|
|
'/wd4305',
|
|
# Don't warn about _cairo_status -> _cairo_int_status conversion
|
|
'/wd5286',
|
|
language : ['c', 'cpp'])
|
|
add_project_arguments('-D_CRT_SECURE_NO_WARNINGS', language : ['c', 'cpp'])
|
|
endif
|
|
|
|
add_project_arguments('-D_GNU_SOURCE', language: ['c', 'cpp'])
|
|
|
|
pkgmod = import('pkgconfig')
|
|
python3 = import('python').find_installation()
|
|
|
|
check_sizeofs = [
|
|
['void *', {'conf-name': 'SIZEOF_VOID_P'}],
|
|
['int'],
|
|
['long'],
|
|
['long long'],
|
|
['size_t'],
|
|
]
|
|
|
|
check_headers = [
|
|
['stdint.h'],
|
|
['inttypes.h'],
|
|
['sys/int_types.h'],
|
|
['fcntl.h'],
|
|
['unistd.h'],
|
|
['signal.h'],
|
|
['sys/stat.h'],
|
|
['sys/socket.h'],
|
|
['poll.h'],
|
|
['sys/poll.h'],
|
|
['sys/un.h'],
|
|
['sched.h', {'check-funcs': ['sched_getaffinity']}],
|
|
['sys/mman.h', {'check-funcs': ['mmap']}],
|
|
['time.h', {'check-funcs': ['clock_gettime']}],
|
|
['libgen.h'],
|
|
['byteswap.h'],
|
|
['signal.h'],
|
|
['setjmp.h'],
|
|
['fenv.h'],
|
|
['sys/wait.h'],
|
|
['sys/stat.h'],
|
|
['io.h'],
|
|
['fenv.h', {'check-funcs': ['feenableexcept', 'fedisableexcept', 'feclearexcept']}],
|
|
['xlocale.h'],
|
|
['sys/ioctl.h'],
|
|
['intsafe.h'],
|
|
['alloca.h'],
|
|
['termios.h'],
|
|
]
|
|
|
|
check_types = [
|
|
['uint64_t', {'headers': ['stdint.h']}],
|
|
['uint128_t', {'headers': ['stdint.h']}],
|
|
['__uint128_t']
|
|
]
|
|
|
|
check_funcs = [
|
|
'alarm',
|
|
'ctime_r',
|
|
'localtime_r',
|
|
'gmtime_r',
|
|
'drand48',
|
|
'flockfile',
|
|
'funlockfile',
|
|
'getline',
|
|
'link',
|
|
'fork',
|
|
'waitpid',
|
|
'raise',
|
|
'newlocale',
|
|
'strtod_l',
|
|
]
|
|
|
|
check_thread_flags = [
|
|
[['-D_REENTRANT'], ['-lpthread']],
|
|
[['-pthread'], []],
|
|
[['-D_REENTRANT'], [], {'real': false}],
|
|
]
|
|
|
|
m_dep = cc.find_library('m', required: false)
|
|
# Used in util
|
|
gtk_dep = dependency('gtk+-2.0', required: get_option('gtk2-utils'))
|
|
|
|
deps = [m_dep]
|
|
test_deps = []
|
|
internal_deps = []
|
|
extra_link_args = []
|
|
|
|
extra_link_args += cc.get_supported_link_arguments([
|
|
'-Wl,-Bsymbolic-functions',
|
|
])
|
|
|
|
if host_machine.endian() == 'big'
|
|
conf.set('WORDS_BIGENDIAN', 1)
|
|
endif
|
|
|
|
float_order = cc.get_define('__FLOAT_WORD_ORDER__')
|
|
if float_order != ''
|
|
if float_order == cc.get_define('__ORDER_BIG_ENDIAN__')
|
|
conf.set('FLOAT_WORDS_BIGENDIAN', 1)
|
|
endif
|
|
else
|
|
# Assume same as platform endian
|
|
if host_machine.endian() == 'big'
|
|
conf.set('FLOAT_WORDS_BIGENDIAN', 1)
|
|
endif
|
|
endif
|
|
|
|
lzo_dep = dependency('lzo2', required: get_option('lzo'))
|
|
if lzo_dep.found()
|
|
conf.set('HAVE_LZO', 1)
|
|
endif
|
|
|
|
dl_dep = cc.find_library('dl', required: false)
|
|
if dl_dep.found() and cc.has_function('dlsym', dependencies: [dl_dep])
|
|
deps += [dl_dep]
|
|
conf.set('CAIRO_HAS_DLSYM', 1)
|
|
elif cc.has_function('dlsym')
|
|
conf.set('CAIRO_HAS_DLSYM', 1)
|
|
elif cc.has_function('dlsym', prefix: '#include <dlfcn.h>')
|
|
conf.set('CAIRO_HAS_DLSYM', 1)
|
|
endif
|
|
|
|
feature_conf = configuration_data()
|
|
|
|
# Array of dictionaries, used to generate per-feature pc files
|
|
# Mandatory keys: name, description
|
|
# Optional keys: requires, libs
|
|
built_features = []
|
|
|
|
zlib_dep = dependency('zlib',
|
|
required: get_option('zlib'),
|
|
fallback : ['zlib', 'zlib_dep'],
|
|
)
|
|
if zlib_dep.found()
|
|
if zlib_dep.type_name() == 'internal'
|
|
internal_deps += [zlib_dep]
|
|
else
|
|
deps += [zlib_dep]
|
|
endif
|
|
conf.set('HAVE_ZLIB', 1)
|
|
endif
|
|
|
|
png_dep = dependency('libpng',
|
|
required: get_option('png'),
|
|
version: libpng_required_version,
|
|
fallback: ['libpng', 'libpng_dep']
|
|
)
|
|
if png_dep.found()
|
|
feature_conf.set('CAIRO_HAS_SVG_SURFACE', 1)
|
|
feature_conf.set('CAIRO_HAS_PNG_FUNCTIONS', 1)
|
|
built_features += [
|
|
{
|
|
'name': 'cairo-png',
|
|
'description': 'PNG functions',
|
|
'deps': [png_dep],
|
|
},
|
|
{
|
|
'name': 'cairo-svg',
|
|
'description': 'SVG surface backend',
|
|
'deps': [png_dep],
|
|
}
|
|
]
|
|
|
|
if png_dep.type_name() == 'internal'
|
|
internal_deps += [png_dep]
|
|
else
|
|
deps += [png_dep]
|
|
endif
|
|
endif
|
|
|
|
# Disable fontconfig by default on platforms where it is optional
|
|
fontconfig_option = get_option('fontconfig')
|
|
fontconfig_required = host_machine.system() not in ['windows', 'darwin']
|
|
fontconfig_option = fontconfig_option.disable_auto_if(not fontconfig_required)
|
|
|
|
fontconfig_dep = dependency('fontconfig',
|
|
required: fontconfig_option,
|
|
version: fontconfig_required_version,
|
|
fallback: ['fontconfig', 'fontconfig_dep'],
|
|
)
|
|
if fontconfig_dep.found()
|
|
fc_check_funcs = [
|
|
'FcInit',
|
|
'FcFini'
|
|
]
|
|
|
|
if fontconfig_dep.type_name() == 'internal'
|
|
foreach func : fc_check_funcs
|
|
conf.set('HAVE_@0@'.format(func.to_upper()), 1)
|
|
endforeach
|
|
internal_deps += [fontconfig_dep]
|
|
else
|
|
check_funcs += fc_check_funcs
|
|
deps += [fontconfig_dep]
|
|
endif
|
|
|
|
feature_conf.set('CAIRO_HAS_FC_FONT', 1)
|
|
built_features += [{
|
|
'name': 'cairo-fc',
|
|
'description': 'Fontconfig font backend',
|
|
'deps': [fontconfig_dep],
|
|
}]
|
|
endif
|
|
|
|
ttx = find_program('ttx', required: false)
|
|
|
|
# Disable FreeType by default on platforms where it is optional
|
|
freetype_option = get_option('freetype')
|
|
freetype_required = host_machine.system() not in ['windows', 'darwin']
|
|
freetype_option = freetype_option.disable_auto_if(not freetype_required)
|
|
|
|
freetype_dep = dependency('freetype2',
|
|
required: freetype_option,
|
|
version: freetype_required_version,
|
|
fallback: ['freetype2', 'freetype_dep'],
|
|
)
|
|
if freetype_dep.found()
|
|
feature_conf.set('CAIRO_HAS_FT_FONT', 1)
|
|
built_features += [{
|
|
'name': 'cairo-ft',
|
|
'description': 'FreeType font backend',
|
|
'deps': [freetype_dep],
|
|
# cairo-ft.h includes fontconfig.h so it needs its cflags
|
|
'compile-deps': [fontconfig_dep.partial_dependency(compile_args: true, includes: true)],
|
|
}]
|
|
|
|
if freetype_dep.type_name() == 'internal'
|
|
if freetype_dep.version().version_compare(freetype_colrv1_required_version)
|
|
conf.set('HAVE_FT_SVG_DOCUMENT', 1)
|
|
conf.set('HAVE_FT_LOAD_NO_SVG', 1)
|
|
conf.set('HAVE_FT_COLR_V1', 1)
|
|
endif
|
|
internal_deps += [freetype_dep]
|
|
else
|
|
if png_dep.found() and \
|
|
cc.has_type('FT_SVG_Document', dependencies: freetype_dep, prefix: '#include <freetype/otsvg.h>')
|
|
conf.set('HAVE_FT_SVG_DOCUMENT', 1)
|
|
if ttx.found()
|
|
conf.set('CAIRO_CAN_TEST_TTX_FONT', 1)
|
|
endif
|
|
endif
|
|
if cc.has_define('FT_LOAD_NO_SVG', dependencies: freetype_dep, prefix: '#include <freetype/freetype.h>')
|
|
conf.set('HAVE_FT_LOAD_NO_SVG', 1)
|
|
endif
|
|
if freetype_dep.version().version_compare(freetype_colrv1_required_version) and \
|
|
cc.has_function('FT_Get_Color_Glyph_Paint', dependencies: freetype_dep)
|
|
conf.set('HAVE_FT_COLR_V1', 1)
|
|
endif
|
|
deps += [freetype_dep]
|
|
endif
|
|
endif
|
|
|
|
x11_dep = dependency('x11', required: get_option('xlib'))
|
|
xext_dep = dependency('xext', required: get_option('xlib'))
|
|
if x11_dep.found() and xext_dep.found()
|
|
feature_conf.set('CAIRO_HAS_XLIB_SURFACE', 1)
|
|
built_features += [{
|
|
'name': 'cairo-xlib',
|
|
'description': 'Xlib surface backend',
|
|
'deps': [x11_dep, xext_dep],
|
|
}]
|
|
|
|
extra_headers = ['X11/Xlibint.h', 'X11/Xproto.h']
|
|
check_headers += [
|
|
['X11/extensions/XShm.h', {'extra-headers': extra_headers}],
|
|
['X11/extensions/shmproto.h', {'extra-headers': extra_headers}],
|
|
['X11/extensions/shmstr.h', {'extra-headers': extra_headers}],
|
|
]
|
|
deps += [x11_dep, xext_dep]
|
|
|
|
# Can skip the run check by providing the result in a cross file or
|
|
# native file as bool property value.
|
|
prop = meson.get_external_property('ipc_rmid_deferred_release', meson.is_cross_build() ? 'false' : 'auto')
|
|
# We don't know the type of prop (bool, string) but need to differentiate
|
|
# between a set value (bool) or the fallback value (string), so convert to
|
|
# a string and check the string value.
|
|
prop_str = '@0@'.format(prop)
|
|
if prop_str in ['true', 'false']
|
|
ipc_rmid_deferred_release = (prop_str == 'true')
|
|
message('IPC_RMID_DEFERRED_RELEASE:', ipc_rmid_deferred_release)
|
|
elif prop_str == 'auto'
|
|
res = cc.run(files('meson-cc-tests/ipc_rmid_deferred_release.c'),
|
|
dependencies: [x11_dep, xext_dep],
|
|
name: 'shmctl IPC_RMID allowes subsequent attaches')
|
|
|
|
ipc_rmid_deferred_release = (res.returncode() == 0)
|
|
else
|
|
error('Unexpected value for external property ipc_rmid_deferred_release: @0@'.format(prop_str))
|
|
endif
|
|
|
|
conf.set10('IPC_RMID_DEFERRED_RELEASE', ipc_rmid_deferred_release)
|
|
endif
|
|
|
|
if feature_conf.get('CAIRO_HAS_XLIB_SURFACE', 0) == 1
|
|
xrender_dep = dependency('xrender', required: get_option('xlib'),
|
|
version: xrender_required_version)
|
|
|
|
if xrender_dep.found()
|
|
check_funcs += [
|
|
'XRenderCreateSolidFill',
|
|
'XRenderCreateLinearGradient',
|
|
'XRenderCreateRadialGradient',
|
|
'XRenderCreateConicalGradient',
|
|
]
|
|
|
|
deps += [xrender_dep]
|
|
|
|
built_features += [{
|
|
'name': 'cairo-xlib-xrender',
|
|
'description': 'Xlib Xrender surface backend',
|
|
'deps': [xrender_dep],
|
|
}]
|
|
feature_conf.set('CAIRO_HAS_XLIB_XRENDER_SURFACE', 1)
|
|
endif
|
|
endif
|
|
|
|
xcb_dep = dependency('xcb', required: get_option('xcb'),
|
|
version: xcb_required_version)
|
|
xcb_render_dep = dependency('xcb-render', required: get_option('xcb'),
|
|
version: xcb_render_required_version)
|
|
if xcb_dep.found() and xcb_render_dep.found()
|
|
feature_conf.set('CAIRO_HAS_XCB_SURFACE', 1)
|
|
built_features += [{
|
|
'name': 'cairo-xcb',
|
|
'description': 'XCB surface backend',
|
|
'deps': [xcb_dep, xcb_render_dep],
|
|
}]
|
|
|
|
deps += [xcb_dep, xcb_render_dep]
|
|
endif
|
|
|
|
if feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1 and feature_conf.get('CAIRO_HAS_XLIB_SURFACE', 0) == 1
|
|
x11xcb_dep = dependency('x11-xcb', required: get_option('xlib-xcb'))
|
|
if x11xcb_dep.found()
|
|
deps += [x11xcb_dep]
|
|
feature_conf.set('CAIRO_HAS_XLIB_XCB_FUNCTIONS', 1)
|
|
built_features += [{
|
|
'name': 'cairo-xlib-xcb',
|
|
'description': 'Xlib/XCB functions',
|
|
'deps': [x11xcb_dep],
|
|
}]
|
|
endif
|
|
endif
|
|
|
|
if feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1
|
|
xcbshm_dep = dependency('xcb-shm', required: get_option('xcb'))
|
|
if xcbshm_dep.found()
|
|
feature_conf.set('CAIRO_HAS_XCB_SHM_FUNCTIONS', 1)
|
|
deps += [xcbshm_dep]
|
|
built_features += [{
|
|
'name': 'cairo-xcb-shm',
|
|
'description': 'XCB/SHM functions',
|
|
'deps': [xcbshm_dep],
|
|
}]
|
|
endif
|
|
endif
|
|
|
|
if host_machine.system() == 'darwin' and not get_option('quartz').disabled()
|
|
quartz_deps = dependency('appleframeworks', modules : ['CoreFoundation', 'ApplicationServices'], required: get_option('quartz'))
|
|
|
|
if quartz_deps.found()
|
|
deps += [quartz_deps]
|
|
|
|
feature_conf.set('CAIRO_HAS_QUARTZ_SURFACE', 1)
|
|
feature_conf.set('CAIRO_HAS_QUARTZ_IMAGE_SURFACE', 1)
|
|
|
|
built_features += [
|
|
{
|
|
'name': 'cairo-quartz',
|
|
'description': 'Quartz surface backend',
|
|
'deps': quartz_deps,
|
|
},
|
|
{
|
|
'name': 'cairo-quartz-image',
|
|
'description': 'Quartz Image surface backend',
|
|
'deps': quartz_deps,
|
|
}]
|
|
compiler = meson.get_compiler('c')
|
|
if compiler.has_function('CTFontDrawGlyphs', prefix: '#include <ApplicationServices/ApplicationServices.h>',
|
|
dependencies: quartz_deps)
|
|
built_features += [
|
|
{
|
|
'name': 'cairo-quartz-font',
|
|
'description': 'Quartz font backend',
|
|
'deps': quartz_deps,
|
|
}]
|
|
feature_conf.set('CAIRO_HAS_QUARTZ_FONT', 1)
|
|
endif
|
|
endif
|
|
endif
|
|
|
|
if host_machine.system() == 'windows'
|
|
add_languages('cpp', native: false)
|
|
|
|
add_project_arguments('-DWIN32_LEAN_AND_MEAN', '-DNOMINMAX', language: ['c', 'cpp'])
|
|
|
|
win32_extra_deps = [
|
|
cc.find_library('gdi32'),
|
|
cc.find_library('msimg32'),
|
|
]
|
|
|
|
deps += win32_extra_deps
|
|
|
|
feature_conf.set('CAIRO_HAS_WIN32_SURFACE', 1)
|
|
feature_conf.set('CAIRO_HAS_WIN32_FONT', 1)
|
|
|
|
built_features += [
|
|
{
|
|
'name': 'cairo-win32',
|
|
'description': 'Microsoft Windows surface backend',
|
|
'deps': win32_extra_deps,
|
|
},
|
|
{
|
|
'name': 'cairo-win32-font',
|
|
'description': 'Microsoft Windows font backend',
|
|
'deps': win32_extra_deps,
|
|
}
|
|
]
|
|
|
|
cpp_compiler = meson.get_compiler('cpp')
|
|
|
|
if get_option('dwrite').allowed()
|
|
d2d_dep = cpp_compiler.find_library('d2d1')
|
|
dwrite_dep = cpp_compiler.find_library('dwrite')
|
|
wincodec_dep = cpp_compiler.find_library('windowscodecs')
|
|
|
|
feature_conf.set('CAIRO_HAS_DWRITE_FONT', 1)
|
|
built_features += [{
|
|
'name': 'cairo-dwrite-font',
|
|
'description': 'Microsoft Windows DWrite font backend',
|
|
'deps': [dwrite_dep, d2d_dep, wincodec_dep],
|
|
}]
|
|
deps += [dwrite_dep, d2d_dep, wincodec_dep]
|
|
|
|
sdk_version_args = [
|
|
'-DWINVER=_WIN32_WINNT_WIN10',
|
|
'-D_WIN32_WINNT=_WIN32_WINNT_WIN10',
|
|
# DWrite / D2D headers define types conditionally on the value of NTDDI_VERSION.
|
|
# Use an high version to avoid including definitions in-tree. 0x0A000010 ==
|
|
# NTDDI_WIN11_GE; using the number to stay compatible with not bleeding-edge SDK
|
|
# headers.
|
|
'-DNTDDI_VERSION=0x0A000010',
|
|
]
|
|
|
|
foreach i : range(8, 9)
|
|
if cpp_compiler.has_type('IDWriteFactory' + i.to_string(),
|
|
prefix: ['#include <windows.h>', '#include <dwrite_3.h>'],
|
|
args: sdk_version_args)
|
|
conf.set('HAVE_IDWRITEFACTORY' + i.to_string(), 1)
|
|
endif
|
|
endforeach
|
|
|
|
if cpp_compiler.has_header('d2d1_2.h')
|
|
conf.set('HAVE_D2D1_2_H', 1)
|
|
endif
|
|
|
|
if cpp_compiler.has_header('d2d1_3.h')
|
|
conf.set('HAVE_D2D1_3_H', 1)
|
|
|
|
foreach i : range(2, 8)
|
|
if cpp_compiler.has_type('ID2D1DeviceContext' + i.to_string(),
|
|
prefix: ['#include <windows.h>', '#include <d2d1_3.h>'],
|
|
args: sdk_version_args)
|
|
conf.set('HAVE_ID2D1DEVICECONTEXT' + i.to_string(), 1)
|
|
endif
|
|
endforeach
|
|
endif
|
|
|
|
add_project_arguments(sdk_version_args, language: ['c', 'cpp'])
|
|
else
|
|
add_project_arguments('-DWINVER=_WIN32_WINNT_VISTA', '-D_WIN32_WINNT=_WIN32_WINNT_VISTA', language: ['c', 'cpp'])
|
|
endif
|
|
endif
|
|
|
|
gobject_dep = dependency('gobject-2.0',
|
|
required: get_option('glib'),
|
|
fallback: ['glib', 'libgobject_dep']
|
|
)
|
|
glib_dep = dependency('glib-2.0',
|
|
required: get_option('glib'),
|
|
version: glib_required_version,
|
|
fallback: ['glib', 'libglib_dep'],
|
|
)
|
|
if gobject_dep.found() and glib_dep.found()
|
|
feature_conf.set('CAIRO_HAS_GOBJECT_FUNCTIONS', 1)
|
|
endif
|
|
|
|
if zlib_dep.found()
|
|
feature_conf.set('CAIRO_HAS_SCRIPT_SURFACE', 1)
|
|
built_features += [{
|
|
'name': 'cairo-script',
|
|
'description': 'script surface backend',
|
|
'deps': [zlib_dep],
|
|
}]
|
|
endif
|
|
|
|
if zlib_dep.found()
|
|
feature_conf.set('CAIRO_HAS_PS_SURFACE', 1)
|
|
built_features += [{
|
|
'name': 'cairo-ps',
|
|
'description': 'PostScript surface backend',
|
|
'deps': [zlib_dep],
|
|
}]
|
|
endif
|
|
|
|
if zlib_dep.found()
|
|
feature_conf.set('CAIRO_HAS_PDF_SURFACE', 1)
|
|
built_features += [{
|
|
'name': 'cairo-pdf',
|
|
'description': 'PDF surface backend',
|
|
'deps': [zlib_dep],
|
|
}]
|
|
endif
|
|
|
|
if zlib_dep.found()
|
|
conf.set('CAIRO_HAS_INTERPRETER', 1)
|
|
endif
|
|
|
|
bfd_dep = cc.find_library('bfd', has_headers: ['bfd.h'], required: get_option('symbol-lookup'))
|
|
if bfd_dep.found() and \
|
|
cc.has_function('bfd_openr', dependencies: [bfd_dep]) and \
|
|
cc.links(files('meson-cc-tests/bfd-section-flags.c'), name: 'bfd_section_flags', dependencies: bfd_dep)
|
|
conf.set('HAVE_BFD', 1)
|
|
deps += [bfd_dep]
|
|
elif get_option('symbol-lookup').enabled()
|
|
error('symbol lookup via bfd was enabled via options but is not available (bfd might be too old)')
|
|
endif
|
|
|
|
if conf.get('HAVE_BFD', 0) == 1
|
|
conf.set('CAIRO_HAS_SYMBOL_LOOKUP', 1)
|
|
endif
|
|
|
|
if feature_conf.get('CAIRO_HAS_PS_SURFACE', 0) == 1
|
|
gs = find_program('gs', required: get_option('tests'))
|
|
libspectre_dep = dependency('libspectre', version: '>= 0.2.0',
|
|
required: get_option('spectre'))
|
|
if gs.found() and libspectre_dep.found()
|
|
conf.set('CAIRO_CAN_TEST_PS_SURFACE', 1)
|
|
endif
|
|
|
|
if libspectre_dep.found()
|
|
conf.set('CAIRO_HAS_SPECTRE', 1)
|
|
test_deps += [libspectre_dep]
|
|
endif
|
|
endif
|
|
|
|
if feature_conf.get('CAIRO_HAS_PDF_SURFACE', 0) == 1
|
|
poppler_dep = dependency('poppler-glib', version: '>= 0.17.4',
|
|
required: get_option('tests'))
|
|
if poppler_dep.found() and cc.has_function('poppler_page_render', dependencies: [poppler_dep])
|
|
conf.set('CAIRO_CAN_TEST_PDF_SURFACE', 1)
|
|
test_deps += [poppler_dep]
|
|
endif
|
|
endif
|
|
|
|
if feature_conf.get('CAIRO_HAS_SVG_SURFACE', 0) == 1
|
|
librsvg_dep = dependency('librsvg-2.0', version: '>= 2.35.0',
|
|
required: get_option('tests'))
|
|
if librsvg_dep.found()
|
|
conf.set('CAIRO_CAN_TEST_SVG_SURFACE', 1)
|
|
test_deps += [librsvg_dep]
|
|
endif
|
|
endif
|
|
|
|
pixman_dep = dependency('pixman-1',
|
|
version: '>= 0.40.0',
|
|
fallback: ['pixman', 'idep_pixman'],
|
|
)
|
|
if pixman_dep.found()
|
|
feature_conf.set('CAIRO_HAS_IMAGE_SURFACE', 1)
|
|
conf.set('HAS_PIXMAN_GLYPHS', 1)
|
|
if pixman_dep.version().version_compare('>= 0.42.3')
|
|
conf.set('HAS_PIXMAN_r8g8b8_sRGB', 1)
|
|
endif
|
|
if pixman_dep.type_name() == 'internal'
|
|
internal_deps += [pixman_dep]
|
|
else
|
|
deps += [pixman_dep]
|
|
endif
|
|
endif
|
|
|
|
feature_conf.set('CAIRO_FEATURES_H', true)
|
|
feature_conf.set('CAIRO_HAS_USER_FONT', 1)
|
|
|
|
feature_conf.set('CAIRO_HAS_MIME_SURFACE', 1)
|
|
feature_conf.set('CAIRO_HAS_RECORDING_SURFACE', 1)
|
|
feature_conf.set('CAIRO_HAS_OBSERVER_SURFACE', 1)
|
|
|
|
if not get_option('tee').disabled()
|
|
feature_conf.set('CAIRO_HAS_TEE_SURFACE', 1)
|
|
built_features += [{
|
|
'name': 'cairo-tee',
|
|
'description': 'Tee surface backend',
|
|
}]
|
|
endif
|
|
|
|
incbase = include_directories('.')
|
|
|
|
foreach check : check_sizeofs
|
|
type = check[0]
|
|
opts = check.length() > 1 ? check[1] : {}
|
|
|
|
conf_name = opts.get('conf-name', 'SIZEOF_@0@'.format(type.underscorify().to_upper()))
|
|
|
|
conf.set(conf_name, cc.sizeof(type))
|
|
endforeach
|
|
|
|
foreach check : check_headers
|
|
name = check[0]
|
|
opts = check.length() > 1 ? check[1] : {}
|
|
prefix = ''
|
|
|
|
foreach header : opts.get('extra-headers', [])
|
|
prefix += '#include <@0@>\n'.format(header)
|
|
endforeach
|
|
|
|
if cc.has_header(name, prefix: prefix)
|
|
conf.set('HAVE_@0@'.format(name.to_upper().underscorify()), 1)
|
|
check_funcs += check.length() > 1 ? check[1].get('check-funcs', []) : []
|
|
endif
|
|
endforeach
|
|
|
|
foreach check : check_types
|
|
name = check[0]
|
|
opts = check.length() > 1 ? check[1] : {}
|
|
prefix = ''
|
|
|
|
foreach header : opts.get('headers', [])
|
|
prefix += '#include <@0@>\n'.format(header)
|
|
endforeach
|
|
|
|
if cc.has_type(name, prefix: prefix)
|
|
conf.set('HAVE_@0@'.format(name.to_upper()), 1)
|
|
endif
|
|
endforeach
|
|
|
|
foreach name : check_funcs
|
|
if cc.has_function(name, dependencies: deps)
|
|
conf.set('HAVE_@0@'.format(name.to_upper()), 1)
|
|
endif
|
|
endforeach
|
|
|
|
conf.set('HAVE_STRNDUP', cc.has_function('strndup', prefix : '#include <string.h>'))
|
|
|
|
pthread_c_args = []
|
|
pthread_link_args = []
|
|
|
|
foreach thread_flags : check_thread_flags
|
|
if not conf.has('CAIRO_HAS_PTHREAD')
|
|
cflags = thread_flags[0]
|
|
lflags = thread_flags[1]
|
|
real_pthread = thread_flags.length() > 2 ? thread_flags[2].get('real', true) : true
|
|
|
|
if cc.links(files('meson-cc-tests/pthread.c'), args: cflags + lflags, name: 'pthreads')
|
|
conf.set('CAIRO_HAS_PTHREAD', 1)
|
|
if real_pthread
|
|
conf.set('CAIRO_HAS_REAL_PTHREAD', 1)
|
|
endif
|
|
pthread_c_args = cflags
|
|
pthread_link_args = lflags
|
|
endif
|
|
endif
|
|
endforeach
|
|
|
|
extra_link_args += pthread_link_args
|
|
|
|
cpp_enabled = host_machine.system() == 'windows'
|
|
|
|
if not cpp_enabled and cc.links(files('meson-cc-tests/atomic-ops-c11.c'), name: 'Atomic ops: c11')
|
|
# Currently we avoid C11 atomics when using both C and C++. The standards
|
|
# do not guarantee compatibility between C11 atomics and C++11 std::atomic
|
|
# (though effort is underway, see C++/N2741). We can enable this for selected
|
|
# compilers over time.
|
|
#
|
|
# When not using C++, check if C11 atomics are available and whether atomic
|
|
# ints and pointers are lock-free.
|
|
conf.set('HAVE_C11_ATOMIC_PRIMITIVES', 1)
|
|
elif cc.links(files('meson-cc-tests/atomic-ops-cxx11.c'), name: 'Atomic ops: cxx11')
|
|
conf.set('HAVE_CXX11_ATOMIC_PRIMITIVES', 1)
|
|
elif cc.links(files('meson-cc-tests/atomic-ops-gcc-legacy.c'), name: 'Atomic ops: gcc legacy')
|
|
conf.set('HAVE_GCC_LEGACY_ATOMICS', 1)
|
|
elif host_machine.system() != 'windows' and dependency('atomic_ops', required: false).found()
|
|
internal_deps += [dependency('atomic_ops')]
|
|
conf.set('HAVE_LIB_ATOMIC_OPS', 1)
|
|
elif host_machine.system() == 'darwin' and cc.has_header('libkern/OSAtomic.h')
|
|
conf.set('HAVE_OS_ATOMIC_OPS', 1)
|
|
elif not cc.has_define('_MSC_VER')
|
|
warning('Atomic ops not supported.')
|
|
endif
|
|
|
|
test_mkdir_c_args = []
|
|
if conf.get('HAVE_SYS_STAT_H', 0) == 1
|
|
test_mkdir_c_args += ['-DHAVE_SYS_STAT_H']
|
|
endif
|
|
|
|
if conf.get('HAVE_IO_H', 0) == 1
|
|
test_mkdir_c_args += ['-DHAVE_IO_H']
|
|
endif
|
|
|
|
if cc.links(files('meson-cc-tests/mkdir-variant-1.c'), args: test_mkdir_c_args)
|
|
conf.set('HAVE_MKDIR', 1)
|
|
elif cc.links(files('meson-cc-tests/mkdir-variant-2.c'), args: test_mkdir_c_args)
|
|
conf.set('HAVE_MKDIR', 2)
|
|
else
|
|
conf.set('HAVE_MKDIR', 0)
|
|
endif
|
|
|
|
have_ld_preload = ['linux', 'freebsd', 'darwin', 'dragonfly', 'sunos'].contains(host_machine.system())
|
|
|
|
if have_ld_preload and zlib_dep.found() and conf.get('CAIRO_HAS_REAL_PTHREAD', 0) == 1 and conf.get('CAIRO_HAS_DLSYM', 0) == 1
|
|
conf.set('CAIRO_HAS_TRACE', 1)
|
|
endif
|
|
|
|
rt_dep = cc.find_library('rt', required: false)
|
|
have_shm = false
|
|
if rt_dep.found() and cc.has_function('shm_open', dependencies: [rt_dep])
|
|
have_shm = true
|
|
endif
|
|
|
|
# This to make sure we don't run checks against internal deps
|
|
deps += internal_deps
|
|
|
|
subdir('src')
|
|
|
|
if feature_conf.get('CAIRO_HAS_PNG_FUNCTIONS', 0) == 1
|
|
subdir('boilerplate')
|
|
else
|
|
cairoboilerplate_dep = dependency('', required: false)
|
|
endif
|
|
|
|
subdir('util')
|
|
|
|
if not get_option('tests').disabled() and feature_conf.get('CAIRO_HAS_PNG_FUNCTIONS', 0) == 1
|
|
subdir('test')
|
|
subdir('perf')
|
|
endif
|
|
|
|
if get_option('gtk_doc')
|
|
doc_srcdir = include_directories('src')
|
|
subdir('doc/public')
|
|
endif
|
|
|
|
configure_file(output: 'config.h', configuration: conf)
|
|
|
|
foreach feature: built_features
|
|
feature_deps = feature.get('deps', [])
|
|
feature_libs = feature.get('libs', [])
|
|
feature_compile_deps = feature.get('compile-deps', [])
|
|
pkgmod.generate(libraries: [libcairo, feature_deps, feature_libs],
|
|
name: feature['name'],
|
|
description: feature['description'] + ' for cairo graphics library',
|
|
)
|
|
meson.override_dependency(feature['name'],
|
|
declare_dependency(dependencies: [libcairo_dep, feature_deps, feature_compile_deps],
|
|
link_args: feature_libs,
|
|
)
|
|
)
|
|
endforeach
|
|
|
|
# summary
|
|
summary({
|
|
'Image': true,
|
|
'Recording': true,
|
|
'Observer': true,
|
|
'Mime': true,
|
|
'Tee': feature_conf.get('CAIRO_HAS_TEE_SURFACE', 0) == 1,
|
|
'Xlib': feature_conf.get('CAIRO_HAS_XLIB_SURFACE', 0) == 1,
|
|
'Xlib Xrender': feature_conf.get('CAIRO_HAS_XLIB_XRENDER_SURFACE', 0) == 1,
|
|
'Quartz': feature_conf.get('CAIRO_HAS_QUARTZ_SURFACE', 0) == 1,
|
|
'Quartz-image': feature_conf.get('CAIRO_HAS_QUARTZ_IMAGE_SURFACE', 0) == 1,
|
|
'XCB': feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1,
|
|
'Win32': feature_conf.get('CAIRO_HAS_WIN32_SURFACE', 0) == 1,
|
|
'CairoScript': feature_conf.get('CAIRO_HAS_SCRIPT_SURFACE', 0) == 1,
|
|
'PostScript': feature_conf.get('CAIRO_HAS_PS_SURFACE', 0) == 1,
|
|
'PDF': feature_conf.get('CAIRO_HAS_PDF_SURFACE', 0) == 1,
|
|
'SVG': feature_conf.get('CAIRO_HAS_SVG_SURFACE', 0) == 1,
|
|
}, section: 'Surface Backends', bool_yn: true)
|
|
|
|
summary({
|
|
'User': true,
|
|
'FreeType': feature_conf.get('CAIRO_HAS_FT_FONT', 0) == 1,
|
|
'Fontconfig': feature_conf.get('CAIRO_HAS_FC_FONT', 0) == 1,
|
|
'Win32': feature_conf.get('CAIRO_HAS_WIN32_FONT', 0) == 1,
|
|
'Win32 DWrite': feature_conf.get('CAIRO_HAS_DWRITE_FONT', 0) == 1,
|
|
'Quartz': feature_conf.get('CAIRO_HAS_QUARTZ_FONT', 0) == 1,
|
|
}, section: 'Font Backends', bool_yn: true)
|
|
|
|
summary({
|
|
'PNG functions': feature_conf.get('CAIRO_HAS_PNG_FUNCTIONS', 0) == 1,
|
|
'X11-xcb': feature_conf.get('CAIRO_HAS_XLIB_XCB_FUNCTIONS', 0) == 1,
|
|
'XCB-shm': feature_conf.get('CAIRO_HAS_XCB_SHM_FUNCTIONS', 0) == 1,
|
|
}, section: 'Functions', bool_yn: true)
|
|
|
|
summary({
|
|
'cairo-trace:': conf.get('CAIRO_HAS_TRACE', 0) == 1,
|
|
'cairo-script-interpreter': conf.get('CAIRO_HAS_INTERPRETER', 0) == 1,
|
|
'API reference': get_option('gtk_doc'),
|
|
}, section: 'Features and Utilities', bool_yn: true)
|