cairo/meson.build
Benjamin Gilbert 7a780896a1 win32: Fix MSVC build with dwrite disabled
We now require at least Windows Vista.  When dwrite is disabled, declare
WINVER accordingly so we get the defines we no longer carry ourselves.
The default dwrite-enabled path already has a new-enough WINVER.

Fixes: d0ee67a142 ("Win32: Remove unused code and defines for old toolchains")
2025-07-14 12:17:27 -07:00

867 lines
26 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')
d2d_dep = cpp_compiler.find_library('d2d1', required: get_option('dwrite'))
dwrite_dep = cpp_compiler.find_library('dwrite', required: get_option('dwrite'))
d2d_header = cpp_compiler.has_header('d2d1.h')
d2d_3_header = cpp_compiler.has_header('d2d1_3.h')
dwrite_header = cpp_compiler.has_header('dwrite.h')
wincodec_dep = cpp_compiler.find_library('windowscodecs', required: get_option('dwrite'))
wincodec_header = cpp_compiler.has_header('wincodec.h')
if d2d_dep.found() and dwrite_dep.found() and d2d_header and dwrite_header and wincodec_dep.found() and wincodec_header
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]
if cpp_compiler.has_header('d2d1_3.h')
conf.set('HAVE_D2D1_3_H', 1)
endif
add_project_arguments('-DWINVER=_WIN32_WINNT_WIN10', '-D_WIN32_WINNT=_WIN32_WINNT_WIN10', '-DNTDDI_VERSION=NTDDI_WIN10_RS3', 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
# Atomics are an optional feature in C11. Also need to check that C11 atomics are lock free.
# On Windows we use the Interlocked family of functions
if host_machine.system() != 'windows'
if cc.links(files('meson-cc-tests/atomic-ops-c11.c'), name: 'Atomic ops: c11')
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 cc.has_header('atomic_ops.h')
conf.set('HAVE_LIB_ATOMIC_OPS', 1)
elif cc.has_header('libkern/OSAtomic.h')
conf.set('HAVE_OS_ATOMIC_OPS', 1)
else
warning('Atomic ops not supported.')
endif
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
if not ['x86', 'x86_64'].contains(host_machine.cpu_family())
conf.set('ATOMIC_OP_NEEDS_MEMORY_BARRIER', 1)
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)