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