blob: 27353f337218b6e7abd0dd453538c9f6d78ce8a2 [file] [log] [blame]
Mathieu Duponchelle920efc02018-05-17 01:28:53 +02001project('harfbuzz', 'c', 'cpp',
Mathieu Duponchelle07cadc92018-06-18 17:18:05 +02002 meson_version: '>= 0.47.0',
Ebrahim Byagowi31218b42020-03-11 22:27:32 +03303 default_options : ['cpp_std=c++11'],
Ebrahim Byagowi1c3f80b2020-03-11 19:29:47 +03304 version: '2.6.4')
Mathieu Duponchelle920efc02018-05-17 01:28:53 +02005
Tim-Philipp Müller535186f2018-12-03 20:51:06 +01006hb_version_arr = meson.project_version().split('.')
7hb_version_major = hb_version_arr[0].to_int()
8hb_version_minor = hb_version_arr[1].to_int()
9hb_version_micro = hb_version_arr[2].to_int()
10
11# libtool versioning
12hb_version_int = hb_version_major*10000 + hb_version_minor*100 + hb_version_micro
13if hb_version_minor % 2 == 1
14 hb_libtool_revision = 0 # for unstable releases
15else
16 hb_libtool_revision = hb_version_micro # for stable releases
17endif
18hb_libtool_age = hb_version_int - hb_libtool_revision
19hb_libtool_current = hb_libtool_age
20hb_libtool_version_info = '@0@:@1@:@2@'.format(hb_libtool_current, hb_libtool_revision, hb_libtool_age)
21
Mathieu Duponchelle484313f2018-06-05 02:15:43 +020022pkgmod = import('pkgconfig')
Mathieu Duponchelle920efc02018-05-17 01:28:53 +020023cpp = meson.get_compiler('cpp')
24
Tim-Philipp Müller4a47f1a2018-12-01 11:05:27 +000025if cpp.get_id() == 'msvc'
26 # Ignore several spurious warnings for things HarfBuzz does very commonly.
27 # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
28 # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
29 # NOTE: Only add warnings here if you are sure they're spurious
30 msvc_args = [
31 '/wd4018', # implicit signed/unsigned conversion
32 '/wd4146', # unary minus on unsigned (beware INT_MIN)
33 '/wd4244', # lossy type conversion (e.g. double -> int)
34 '/wd4305', # truncating type conversion (e.g. double -> float)
35 cpp.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
36 ]
37 add_project_arguments(msvc_args, language : 'c')
38 add_project_arguments(msvc_args, language : 'cpp')
39 # Disable SAFESEH with MSVC for libs that use external deps that are built with MinGW
40 # noseh_link_args = ['/SAFESEH:NO']
41endif
42
Ebrahim Byagowi365d2d32020-03-11 20:16:36 +033043add_global_arguments(cpp.get_supported_arguments([
44 '-fno-rtti',
45 '-fno-exceptions',
46 '-fno-threadsafe-statics',
47 '-fvisibility-inlines-hidden', # maybe shouldn't be applied for mingw
48]), language : 'cpp')
49
50if host_machine.cpu_family() == 'arm' and cpp.alignment('struct { char c; }') != 1
51 if cpp.has_argument('-mstructure-size-boundary=8')
52 add_global_arguments('-mstructure-size-boundary=8', language : 'cpp')
53 endif
54endif
55
Mathieu Duponchelle920efc02018-05-17 01:28:53 +020056python3 = import('python').find_installation('python3')
57
58check_headers = [
59 ['unistd.h'],
60 ['sys/mman.h'],
61 ['xlocale.h'],
62 ['stdbool.h'],
63]
64
65check_funcs = [
66 ['atexit'],
67 ['mprotect'],
68 ['sysconf'],
69 ['getpagesize'],
70 ['mmap'],
71 ['isatty'],
72 ['newlocale'],
73 ['strtod_l'],
Ebrahim Byagowi1c3f80b2020-03-11 19:29:47 +033074 ['roundf'],
Mathieu Duponchelle920efc02018-05-17 01:28:53 +020075]
76
Chun-wei Fan733414b2020-03-13 16:15:21 +080077freetype_dep = dependency('freetype2', required: false)
78
79if not freetype_dep.found() and cpp.get_id() == 'msvc'
80 if cpp.has_header('ft2build.h')
81 freetype_dep = cpp.find_library('freetype', required: false)
82 endif
83endif
84
85if not freetype_dep.found() and get_option('freetype').enabled()
86 freetype_dep = dependency('freetype2', fallback: ['freetype2', 'freetype_dep'])
87endif
88
Tim-Philipp Müller49ba2112018-11-12 15:36:27 +000089glib_dep = dependency('glib-2.0', required: get_option('glib'),
Nirbheek Chauhanf65def42018-10-12 19:41:49 +053090 fallback: ['glib', 'libglib_dep'])
Tim-Philipp Müller49ba2112018-11-12 15:36:27 +000091gobject_dep = dependency('gobject-2.0', required: get_option('gobject'),
Nirbheek Chauhanf65def42018-10-12 19:41:49 +053092 fallback: ['glib', 'libgobject_dep'])
Tim-Philipp Müller49ba2112018-11-12 15:36:27 +000093cairo_dep = dependency('cairo', required: get_option('cairo'),
Nirbheek Chauhanf65def42018-10-12 19:41:49 +053094 fallback: ['cairo', 'libcairo_dep'])
Tim-Philipp Müller49ba2112018-11-12 15:36:27 +000095fontconfig_dep = dependency('fontconfig', required: get_option('fontconfig'),
Nirbheek Chauhanf65def42018-10-12 19:41:49 +053096 fallback: ['fontconfig', 'fontconfig_dep'])
Tim-Philipp Müller49ba2112018-11-12 15:36:27 +000097graphite2_dep = dependency('graphite2', required: get_option('graphite'))
Chun-wei Fan5efce602020-03-13 16:40:20 +080098icu_dep = dependency('icu-uc', required: get_option('icu').enabled() and cpp.get_id() != 'msvc')
Mathieu Duponchellefce88f92018-05-17 16:20:10 +020099m_dep = cpp.find_library('m', required: false)
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200100
Chun-wei Fan5efce602020-03-13 16:40:20 +0800101if not icu_dep.found() and cpp.get_id() == 'msvc'
102 if cpp.has_header('unicode/uchar.h') and \
103 cpp.has_header('unicode/unorm2.h') and \
104 cpp.has_header('unicode/ustring.h') and \
105 cpp.has_header('unicode/utf16.h') and \
106 cpp.has_header('unicode/uversion.h') and \
107 cpp.has_header('unicode/uscript.h')
108 if get_option('buildtype') == 'debug'
109 icu_dep = cpp.find_library('icuucd', required: get_option('icu'))
110 else
111 icu_dep = cpp.find_library('icuuc', required: get_option('icu'))
112 endif
113 else
114 if get_option('icu').enabled()
115 error('ICU headers and libraries must be present to build ICU support')
116 endif
117 endif
118endif
119
Nirbheek Chauhanf65def42018-10-12 19:41:49 +0530120# Ensure that cairo-ft is fetched from the same library as cairo itself
121if cairo_dep.found()
122 if cairo_dep.type_name() == 'pkgconfig'
Tim-Philipp Müller49ba2112018-11-12 15:36:27 +0000123 cairo_ft_dep = dependency('cairo-ft', required: get_option('cairo'))
Nirbheek Chauhanf65def42018-10-12 19:41:49 +0530124 else
125 cairo_ft_dep = cairo_dep
126 endif
127else
128 # Not-found dependency
129 cairo_ft_dep = dependency('', required: false)
130endif
131
Mathieu Duponchellefce88f92018-05-17 16:20:10 +0200132deps = []
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200133
134conf = configuration_data()
Tim-Philipp Müller618584e2018-11-14 20:19:36 +0000135incconfig = include_directories('.')
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200136cpp_args = ['-DHAVE_CONFIG_H']
137
138warn_cflags = [
139 '-Wno-non-virtual-dtor',
140]
141
142cpp_args += cpp.get_supported_arguments(warn_cflags)
143
Mathieu Duponchellefce88f92018-05-17 16:20:10 +0200144if m_dep.found()
145 deps += [m_dep]
146endif
147
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200148if glib_dep.found()
149 conf.set('HAVE_GLIB', 1)
150 deps += [glib_dep]
151endif
152
153if gobject_dep.found()
154 conf.set('HAVE_GOBJECT', 1)
155 deps += [gobject_dep]
156endif
157
158if cairo_dep.found()
159 conf.set('HAVE_CAIRO', 1)
160 deps += [cairo_dep]
161endif
162
163if cairo_ft_dep.found()
164 conf.set('HAVE_CAIRO_FT', 1)
165 deps += [cairo_ft_dep]
166endif
167
168if graphite2_dep.found()
169 conf.set('HAVE_GRAPHITE2', 1)
170 deps += [graphite2_dep]
171endif
172
173if icu_dep.found()
174 conf.set('HAVE_ICU', 1)
175 conf.set('HAVE_ICU_BUILTIN', 1)
176 deps += [icu_dep]
177endif
178
179if freetype_dep.found()
180 conf.set('HAVE_FREETYPE', 1)
181 deps += [freetype_dep]
Mathieu Duponchelle04bcdb92018-06-05 20:59:29 +0200182 check_freetype_funcs = [
183 ['FT_Get_Var_Blend_Coordinates', {'deps': freetype_dep}],
184 ['FT_Set_Var_Blend_Coordinates', {'deps': freetype_dep}],
185 ['FT_Done_MM_Var', {'deps': freetype_dep}],
186 ]
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200187
188 if freetype_dep.type_name() == 'internal'
189 foreach func: check_freetype_funcs
190 name = func[0]
191 conf.set('HAVE_@0@'.format(name.to_upper()), 1)
192 endforeach
193 else
194 check_funcs += check_freetype_funcs
195 endif
196endif
197
198if fontconfig_dep.found()
199 conf.set('HAVE_FONTCONFIG', 1)
200 deps += [fontconfig_dep]
201endif
202
Chun-wei Fan7baa8e02020-03-13 16:21:25 +0800203# uniscribe (windows)
Tim-Philipp Müllerb7796a52018-11-12 16:56:56 +0000204if host_machine.system() == 'windows' and not get_option('uniscribe').disabled()
205 # TODO: make nicer once we have https://github.com/mesonbuild/meson/issues/3940
206 if cpp.has_header('usp10.h') and cpp.has_header('windows.h')
207 foreach usplib : ['usp10', 'gdi32', 'rpcrt4']
208 deps += [cpp.find_library(usplib, required: true)]
209 endforeach
210 conf.set('HAVE_UNISCRIBE', 1)
211 elif get_option('uniscribe').enabled()
212 error('uniscribe was enabled explicitly, but some required headers are missing.')
213 endif
214endif
215
Chun-wei Fan7baa8e02020-03-13 16:21:25 +0800216# DirectWrite (windows)
Tim-Philipp Müller83ebbe42018-11-12 16:56:56 +0000217if host_machine.system() == 'windows' and not get_option('directwrite').disabled()
Chun-wei Fan7baa8e02020-03-13 16:21:25 +0800218 if cpp.has_header('dwrite_1.h')
Tim-Philipp Müller83ebbe42018-11-12 16:56:56 +0000219 deps += [cpp.find_library('dwrite', required: true)]
220 conf.set('HAVE_DIRECTWRITE', 1)
221 elif get_option('directwrite').enabled()
222 error('DirectWrite was enabled explicitly, but required header is missing.')
223 endif
224endif
225
Tim-Philipp Müller4840c822018-11-12 16:56:56 +0000226# CoreText (macOS) - FIXME: untested
227if host_machine.system() == 'darwin' and not get_option('coretext').disabled()
228 app_services_dep = dependency('appleframeworks', modules : ['ApplicationServices'], required: false)
229 if cpp.has_type('CTFontRef', prefix: '#include <ApplicationServices/ApplicationServices.h>', dependencies: app_services_dep)
230 deps += [app_services_dep]
231 conf.set('HAVE_CORETEXT', 1)
232 # On iOS CoreText and CoreGraphics are stand-alone frameworks
233 # Check for a different symbol to avoid getting cached result
234 else
235 coretext_dep = dependency('appleframeworks', modules : ['CoreText'], required: false)
236 coregraphics_dep = dependency('appleframeworks', modules : ['CoreGraphics'], required: false)
237 corefoundation_dep = dependency('appleframeworks', modules : ['CoreFoundation'], required: false)
238 if cpp.has_type('CTRunRef', prefix: '#include <CoreText/CoreText.h>', dependencies: [coretext_dep, coregraphics_dep, corefoundation_dep])
239 deps += [coretext_dep, coregraphics_dep, corefoundation_dep]
240 conf.set('HAVE_CORETEXT', 1)
241 elif get_option('coretext').enabled()
242 error('CoreText was enabled explicitly, but required headers or frameworks are missing.')
243 endif
244 endif
245endif
246
Tim-Philipp Müllerb7796a52018-11-12 16:56:56 +0000247# threads
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200248if host_machine.system() != 'windows'
249 thread_dep = dependency('threads', required: false)
250
251 if thread_dep.found()
252 conf.set('HAVE_PTHREAD', 1)
253 deps += [thread_dep]
254 else
255 check_headers += ['sched.h']
256 check_funcs += ['sched_yield', {'link_with': 'rt'}]
257 endif
258endif
259
Mathieu Duponchelle04bcdb92018-06-05 20:59:29 +0200260conf.set('HAVE_OT', 1)
261conf.set('HAVE_FALLBACK', 1)
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200262conf.set_quoted('PACKAGE_NAME', 'HarfBuzz')
263conf.set_quoted('PACKAGE_VERSION', meson.project_version())
264
265foreach check : check_headers
266 name = check[0]
267
268 if cpp.has_header(name)
269 conf.set('HAVE_@0@'.format(name.to_upper().underscorify()), 1)
270 endif
271endforeach
272
273foreach check : check_funcs
274 name = check[0]
Mathieu Duponchelle04bcdb92018-06-05 20:59:29 +0200275 opts = check.get(1, {})
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200276 link_withs = opts.get('link_with', [])
Mathieu Duponchelle04bcdb92018-06-05 20:59:29 +0200277 check_deps = opts.get('deps', [])
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200278 extra_deps = []
279 found = true
280
281 # First try without linking
282
Mathieu Duponchelle04bcdb92018-06-05 20:59:29 +0200283 found = cpp.has_function(name, dependencies: check_deps)
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200284
285 if not found and link_withs.length() > 0
286 found = true
287
288 foreach link_with : link_withs
289 dep = cpp.find_library(link_with, required: false)
290 if dep.found()
291 extra_deps += dep
292 else
293 found = false
294 endif
295 endforeach
296
297 if found
Mathieu Duponchelle04bcdb92018-06-05 20:59:29 +0200298 found = cpp.has_function(name, dependencies: check_deps + extra_deps)
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200299 endif
300 endif
301
302 if found
303 deps += extra_deps
304 conf.set('HAVE_@0@'.format(name.to_upper()), 1)
305 endif
306endforeach
307
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200308if cpp.links(files('meson-cc-tests/intel-atomic-primitives-test.c'), name: 'Intel atomics')
309 conf.set('HAVE_INTEL_ATOMIC_PRIMITIVES', 1)
310endif
311
312if cpp.links(files('meson-cc-tests/solaris-atomic-operations.c'), name: 'Solaris atomic ops')
313 conf.set('HAVE_SOLARIS_ATOMIC_OPS', 1)
314endif
315
316subdir('src')
317subdir('util')
Tim-Philipp Müller6147df32018-11-14 10:12:40 +0000318
319if not get_option('tests').disabled()
320 subdir('test')
321endif
Mathieu Duponchelle920efc02018-05-17 01:28:53 +0200322
323configure_file(output: 'config.h', configuration: conf)