meson.build (13948B)
1 project( 2 'anastasis', 3 'c', 4 license: 'AGPLv3', 5 meson_version: '>=1.1.0', 6 version: run_command('sh', 'scripts/get_version.sh', check: true).stdout().strip(), 7 # PIE is a built-in option, so it has to be set here rather than under the 8 # 'hardening' option below; -Db_pie=false still turns it off. 9 # 'debugoptimized' (-O2 -g) rather than Meson's 'debug' default: without 10 # optimisation _FORTIFY_SOURCE does nothing, so a plain developer build 11 # would never exercise the fortified code paths that releases ship with. 12 # -Dbuildtype=debug still gives an unoptimised build. 13 default_options: ['b_pie=true', 'buildtype=debugoptimized'], 14 ) 15 16 cc = meson.get_compiler('c') 17 incdir = include_directories('src/include') 18 19 # Used to populate gnunet_private_config.h 20 private_config = configuration_data() 21 22 23 plugindir = get_option('libdir') / 'anastasis' 24 pkgdatadir = get_option('datadir') / 'anastasis' 25 pkgcfgdir = pkgdatadir / 'config.d' 26 docdir = get_option('datadir') / 'doc' / 'anastasis' 27 28 if get_option('install-rpath') 29 rpath_option = get_option('prefix') / get_option('libdir') 30 else 31 rpath_option = '' 32 endif 33 34 install_emptydir(docdir) 35 install_data('README', 'COPYING', install_dir: docdir) 36 37 gnunet_user = false 38 dpkg_architecture_bin = find_program( 39 'dpkg-architecture', 40 '/usr/bin/dpkg-architecture', 41 required: false, 42 ) 43 if dpkg_architecture_bin.found() 44 private_config.set( 45 'MULTIARCH', 46 dpkg_architecture_bin.full_path() + ' -qDEB_HOST_MULTIARCH', 47 ) 48 endif 49 50 TALER_PLUGIN_LDFLAGS = [ 51 '-export-dynamic', 52 '-avoid-version', 53 '-module', 54 '--no-undefined', 55 ] 56 57 cdata = configuration_data() 58 if not get_option('only-doc') 59 add_project_arguments( 60 '-Wall', 61 '-Wno-address-of-packed-member', 62 language: 'c', 63 ) 64 65 # Source builds get no hardening from anywhere else: distribution packaging 66 # passes its own flags, but ./configure && make does not. For a key backup 67 # tool that is worth having on by default. 68 if get_option('hardening') 69 hardening_cflags = cc.get_supported_arguments( 70 '-fstack-protector-strong', 71 '-fstack-clash-protection', 72 ) 73 # _FORTIFY_SOURCE needs optimisation to do anything and warns without 74 # it, so only set it when the build is actually optimised -- which the 75 # default buildtype above ensures, so this skips only for an explicit 76 # -Dbuildtype=debug. 'plain' is excluded as well: it means the 77 # packager supplies the flags, and distributions that pass their own 78 # -D_FORTIFY_SOURCE would then get a "redefined" warning in every 79 # translation unit. 80 if get_option('optimization') not in ['0', 'g', 'plain'] 81 # The obvious test, '#if _FORTIFY_SOURCE < 3', can never fail: it 82 # reads back the value just put on the command line. glibc does 83 # not lower _FORTIFY_SOURCE when it cannot honour the level, it 84 # clamps __USE_FORTIFY_LEVEL and emits a #warning -- hence both the 85 # macro tested here and the -Werror that turns that warning into 86 # the failure it should be. A libc that defines neither is treated 87 # as not supporting level 3. 88 if cc.compiles( 89 '''#include <string.h> 90 #if !defined(__USE_FORTIFY_LEVEL) || __USE_FORTIFY_LEVEL < 3 91 #error no level 3 92 #endif 93 int main(void) { return 0; }''', 94 args: ['-O2', '-Werror', '-D_FORTIFY_SOURCE=3'], 95 name: '_FORTIFY_SOURCE=3', 96 ) 97 hardening_cflags += '-D_FORTIFY_SOURCE=3' 98 else 99 hardening_cflags += '-D_FORTIFY_SOURCE=2' 100 endif 101 endif 102 add_project_arguments(hardening_cflags, language: 'c') 103 add_project_link_arguments( 104 cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now'), 105 language: 'c', 106 ) 107 endif 108 taler_lib_ldflags = '-export-dynamic -no-undefined' 109 110 check_headers = ['stdint.h', 'stdlib.h', 'string.h', 'unistd.h'] 111 112 foreach h : check_headers 113 if cc.check_header(h) 114 define = 'HAVE_' + h.underscorify().to_upper() 115 message(define) 116 private_config.set(define, 1) 117 endif 118 endforeach 119 120 # Gettext 121 i18n = import('i18n') 122 123 gettext_package = 'anastasis' 124 add_project_arguments('-DGETTEXT_PACKAGE=' + gettext_package, language: 'c') 125 add_project_arguments('-DENABLE_NLS=1', language: 'c') 126 127 subdir('po') 128 129 zlib_dep = dependency('zlib', required: false) 130 if not zlib_dep.found() 131 zlib_dep = cc.find_library('z', required: true) 132 endif 133 m_dep = cc.find_library('m', required: false) 134 if m_dep.found() 135 private_config.set('HAVE_LIBM', 1) 136 endif 137 138 139 mhd_dep = dependency('libmicrohttpd', required: false) 140 if not mhd_dep.found() 141 mhd_dep = cc.find_library('microhttpd', required: true) 142 endif 143 144 mhd2_dep = dependency('libmicrohttpd2', required: false) 145 if not mhd2_dep.found() 146 mhd2_dep = cc.find_library('microhttpd2', required: false) 147 endif 148 149 json_dep = dependency('jansson', required: false) 150 if not json_dep.found() 151 json_dep = cc.find_library('jansson', required: true) 152 endif 153 154 gcrypt_dep = dependency('libgcrypt', required: false) 155 if not gcrypt_dep.found() 156 gcrypt_dep = cc.find_library('gcrypt', required: true) 157 endif 158 159 private_config.set_quoted('NEED_LIBGCRYPT_VERSION', '1.6.1') 160 161 gnunetutil_dep = dependency('gnunetutil', required: false) 162 if not gnunetutil_dep.found() 163 gnunetutil_dep = cc.find_library('gnunetutil', required: true) 164 endif 165 166 cc.has_header_symbol( 167 'gnunet/gnunet_util_lib.h', 168 'GNUNET_TIME_round_up', 169 dependencies: [gnunetutil_dep], 170 required: true, 171 ) 172 173 gnunetjson_dep = dependency('gnunetjson', required: false) 174 if not gnunetjson_dep.found() 175 gnunetjson_dep = cc.find_library('gnunetjson', required: true) 176 endif 177 sodium_dep = dependency('libsodium', required: false, version: '>=1.0.18') 178 if not sodium_dep.found() 179 sodium_dep = cc.find_library('sodium', required: true) 180 sodium_version_check = '''#include <sodium.h> 181 int main(int argc, char **argv) { 182 #if !((SODIUM_LIBRARY_VERSION_MAJOR > 10) || \ 183 ((SODIUM_LIBRARY_VERSION_MAJOR == 10) && \ 184 (SODIUM_LIBRARY_VERSION_MINOR >= 3))) 185 #error "libsodium version >= 1.0.18 required" 186 #endif 187 return 0 188 } 189 ''' 190 if not cc.compiles( 191 sodium_version_check, 192 name: 'sodium version check', 193 dependencies: sodium_dep, 194 ) 195 error('libsodium version >=1.0.18 required') 196 endif 197 endif 198 199 curl_dep = dependency('libcurl', version: '>=7.34.0', required: false) 200 if not curl_dep.found() 201 curl_dep = cc.find_library('curl', required: true) 202 curl_version_check = '''#include <curl/curl.h> 203 int main(int argc, char **argv) { 204 #if LIBCURL_VERSION_NUM < 0x073400 205 #error "cURL version >= 7.34.0 required" 206 #endif 207 return 0; 208 } 209 ''' 210 if not cc.compiles( 211 curl_version_check, 212 name: 'cURL version check', 213 dependencies: curl_dep, 214 ) 215 error('cURL version >=7.34.0 required') 216 endif 217 endif 218 219 gnunetcurl_dep = dependency('gnunetcurl', required: false) 220 if not gnunetcurl_dep.found() 221 gnunetcurl_dep = cc.find_library('gnunetcurl', required: true) 222 endif 223 cc.has_header_symbol( 224 'gnunet/gnunet_curl_lib.h', 225 'GNUNET_CURL_get_select_info', 226 dependencies: [gnunetcurl_dep], 227 required: true, 228 ) 229 pq_dep = dependency('libpq', required: false) 230 if not pq_dep.found() 231 pq_dep = cc.find_library('pq', required: true) 232 endif 233 234 gnunetpq_dep = dependency('gnunetpq', required: false) 235 if not gnunetpq_dep.found() 236 gnunetpq_dep = cc.find_library('gnunetpq', required: true) 237 endif 238 cc.has_header_symbol( 239 'gnunet/gnunet_pq_lib.h', 240 'GNUNET_PQ_query_param_blind_sign_priv', 241 required: true, 242 dependencies: [pq_dep, gnunetpq_dep], 243 ) 244 private_config.set10('HAVE_GNUNETPQ', gnunetpq_dep.found()) 245 246 247 talerutil_dep = dependency('talerutil', required: false) 248 if not talerutil_dep.found() 249 talerutil_dep = cc.find_library('talerutil', required: true) 250 endif 251 cc.has_header_symbol( 252 'taler/taler_util.h', 253 'TALER_merchant_instance_auth_hash_with_salt', 254 required: true, 255 dependencies: [talerutil_dep], 256 ) 257 private_config.set10('HAVE_TALERUTIL', talerutil_dep.found()) 258 259 talerexchange_dep = dependency('talerexchange', required: false) 260 if not talerexchange_dep.found() 261 talerexchange_dep = cc.find_library('talerexchange', required: true) 262 endif 263 private_config.set10('HAVE_TALEREXCHANGE', talerexchange_dep.found()) 264 265 talercurl_dep = dependency('talercurl', required: false) 266 if not talercurl_dep.found() 267 talercurl_dep = cc.find_library('talercurl', required: true) 268 endif 269 talertesting_dep = dependency('talertesting', required: false) 270 if not talertesting_dep.found() 271 talertesting_dep = cc.find_library('talertesting', required: true) 272 endif 273 274 talermhd_dep = dependency('talermhd', required: false) 275 if not talermhd_dep.found() 276 talermhd_dep = cc.find_library('talermhd', required: true) 277 endif 278 cc.has_header_symbol( 279 'taler/taler_mhd_lib.h', 280 'TALER_MHD_parse_request_arg_rel_time', 281 required: true, 282 dependencies: [talermhd_dep], 283 ) 284 private_config.set10('HAVE_TALERMHD', talermhd_dep.found()) 285 286 287 talermerchant_dep = dependency('talermerchant', required: false) 288 if not talermerchant_dep.found() 289 talermerchant_dep = cc.find_library('talermerchant', required: true) 290 endif 291 cc.has_header_symbol( 292 'taler/taler_merchant_service.h', 293 'TALER_MERCHANT_parse_pay_uri', 294 required: true, 295 dependencies: [talermerchant_dep], 296 ) 297 private_config.set10('HAVE_TALERMERCHANT', talermerchant_dep.found()) 298 talermerchanttesting_dep = dependency( 299 'talermerchanttesting', 300 required: false, 301 ) 302 if not talermerchanttesting_dep.found() 303 talermerchanttesting_dep = cc.find_library( 304 'talermerchanttesting', 305 required: true, 306 ) 307 endif 308 309 talerjson_dep = dependency('talerjson', required: false) 310 if not talerjson_dep.found() 311 talerjson_dep = cc.find_library('talerjson', required: true) 312 endif 313 cc.has_header_symbol( 314 'taler/taler_json_lib.h', 315 'TALER_JSON_currency_specs_to_json', 316 required: true, 317 dependencies: [talerjson_dep], 318 ) 319 private_config.set10('HAVE_TALERJSON', talerjson_dep.found()) 320 321 322 talerpq_dep = dependency('talerpq', required: false) 323 if not talerpq_dep.found() 324 talerpq_dep = cc.find_library('talerpq', required: true) 325 endif 326 cc.has_header_symbol( 327 'taler/taler_pq_lib.h', 328 'TALER_PQ_query_param_array_blinded_denom_sig', 329 required: true, 330 dependencies: [talerpq_dep, pq_dep], 331 ) 332 private_config.set10('HAVE_TALERPQ', talerpq_dep.found()) 333 334 logging_opt = get_option('logging') 335 logging_verbosity = 0 336 337 if logging_opt == 'yes' 338 logging_verbosity = 1 339 endif 340 if logging_opt == 'no' 341 add_project_arguments('-DGNUNET_CULL_LOGGING=1', language: 'c') 342 endif 343 if logging_opt == 'verbose' 344 logging_verbosity = 2 345 endif 346 if logging_opt == 'veryverbose' 347 logging_verbosity = 3 348 endif 349 350 #add_project_arguments('-DGNUNET_EXTRA_LOGGING=@0@'.format(logging_verbosity), language: 'c') 351 352 353 # todo gcov has meson builtin 354 355 # Used to populate configuration file and script templates 356 357 358 libltversions = [ 359 ['libanastasis', '0:0:0'], 360 ['libanastasisutil', '1:0:0'], 361 ['libanastasisauthorization', '0:0:0'], 362 ['libanastasiseufin', '0:0:0'], 363 ['libanastasisdb', '4:0:0'], 364 ['libanastasisrest', '0:0:0'], 365 ['libanastasistesting', '0:0:0'], 366 ['libanastasisredux', '0:0:0'], 367 ] 368 369 solibversions = {} 370 371 foreach libversion : libltversions 372 ltversion = libversion[1].split(':') 373 current = ltversion[0].to_int() 374 revision = ltversion[1].to_int() 375 age = ltversion[2].to_int() 376 soversion_str = '@0@'.format(current - age) 377 ltversion_str = '@0@.@1@.@2@'.format(current - age, age, revision) 378 solibversions = solibversions + { 379 libversion[0]: { 380 'soversion': soversion_str, 381 'version': ltversion_str, 382 }, 383 } 384 endforeach 385 386 private_config.set_quoted('PACKAGE', meson.project_name()) 387 private_config.set_quoted('PACKAGE_VERSION', meson.project_version()) 388 # Compatibility. Used in source. 389 private_config.set_quoted('VERSION', meson.project_version()) 390 private_config.set_quoted('PACKAGE_BUGREPORT', 'taler@gnu.org') 391 configure_file(output: 'anastasis_config.h', configuration: private_config) 392 configuration_inc = include_directories('.') 393 394 cdata.merge_from(private_config) 395 add_project_arguments('-DHAVE_CONFIG_H', language: 'c') 396 397 pkg = import('pkgconfig') 398 subdir('contrib') 399 subdir('src') 400 if not get_option('disable-doc') 401 subdir('doc') 402 endif 403 404 taler_prefix = get_option('prefix') / get_option('libdir') 405 406 add_test_setup( 407 'default', 408 env: ['ANASTASIS_PREFIX=' + taler_prefix], 409 exclude_suites: ['perf', 'installcheck', 'integrationtests'], 410 is_default: true, 411 ) 412 else 413 subdir('contrib') 414 if not get_option('disable-doc') 415 subdir('doc') 416 endif 417 endif 418 419 meson.add_dist_script('meson-dist-script') 420