anastasis

Credential backup and recovery protocol and service
Log | Files | Refs | Submodules | README | LICENSE

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