anastasis

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

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