xref: /aosp_15_r20/external/flashrom/meson.build (revision 0d6140be3aa665ecc836e8907834fcd3e3b018fc)
1project('flashrom', 'c',
2  version : run_command('cat', 'VERSION', check: true).stdout().strip(),
3  license : 'GPL-2.0',
4  meson_version : '>=0.56.0',
5  default_options : [
6    'warning_level=2',
7    'c_std=c99',
8    'werror=true',
9    'optimization=s',
10    'debug=false',
11    'default_library=both'
12  ],
13)
14
15fs = import('fs')
16
17if get_option('classic_cli').enabled() and get_option('default_library') == 'shared'
18  error('''
19    Cannot build cli_classic with shared libflashrom. Use \'-Dclassic_cli=disabled\' to disable the cli,
20    or use \'--default-library=both\' to also build the classic_cli
21  ''')
22endif
23
24# libtool versioning
25lt_current = '1'
26lt_revision = '0'
27lt_age = '0'
28lt_version = '@0@.@1@.@2@'.format(lt_current, lt_age, lt_revision)
29
30flashrom_version = meson.project_version()
31git = find_program('git', native : true, required : false)
32if git.found()
33  version_git = run_command('git', 'describe', check : false)
34  if version_git.returncode() == 0
35    flashrom_version += ' (git:@0@)'.format(version_git.stdout().strip())
36  endif
37endif
38
39subdir('doc')
40
41# hide/enable some warnings
42warning_flags = [
43  '-Wshadow',
44  '-Wmissing-prototypes',
45  '-Wwrite-strings',
46  '-Wno-unused-parameter',
47  '-Wno-address-of-packed-member',
48  '-Wno-enum-conversion',
49  '-Wno-missing-braces',
50]
51
52cc = meson.get_compiler('c')
53add_project_arguments(cc.get_supported_arguments(warning_flags), language : 'c')
54add_project_arguments('-D_DEFAULT_SOURCE', language : 'c')
55add_project_arguments('-D_POSIX_C_SOURCE=200809L', language : 'c') # required for fileno, nanosleep, and strndup
56add_project_arguments('-D_BSD_SOURCE', language : 'c') # required for glibc < v2.19
57add_project_arguments('-D__BSD_VISIBLE', language : 'c') # required for u_char, u_int, u_long on FreeBSD
58add_project_arguments('-D__XSI_VISIBLE', language : 'c') # required for gettimeofday() on FreeBSD
59add_project_arguments('-D_NETBSD_SOURCE', language : 'c') # required for indirect include of strings.h on NetBSD
60add_project_arguments('-D_DARWIN_C_SOURCE', language : 'c') # required for indirect include of strings.h on MacOS
61add_project_arguments('-DFLASHROM_VERSION="' + flashrom_version + '"', language : 'c')
62
63# get defaults from configure
64config_print_wiki= get_option('classic_cli_print_wiki')
65config_default_programmer_name = get_option('default_programmer_name')
66config_default_programmer_args = get_option('default_programmer_args')
67
68cargs = []
69link_args = []
70deps = []
71srcs = files(
72  '82802ab.c',
73  'at45db.c',
74  'bitbang_spi.c',
75  'edi.c',
76  'en29lv640b.c',
77  'erasure_layout.c',
78  'flashchips.c',
79  'flashrom.c',
80  'fmap.c',
81  'helpers.c',
82  'helpers_fileio.c',
83  'ich_descriptors.c',
84  'jedec.c',
85  'printlock.c',
86  'layout.c',
87  'libflashrom.c',
88  'opaque.c',
89  'parallel.c',
90  'print.c',
91  'programmer.c',
92  'programmer_table.c',
93  's25f.c',
94  'sfdp.c',
95  'spi25.c',
96  'spi25_statusreg.c',
97  'spi95.c',
98  'spi.c',
99  'sst28sf040.c',
100  'sst49lfxxxc.c',
101  'sst_fwhub.c',
102  'stm50.c',
103  'w29ee011.c',
104  'w39.c',
105  'writeprotect.c',
106  'writeprotect_ranges.c',
107)
108
109# Select an appropriate delay implementation for the target OS
110delay_src = files('udelay.c')
111if target_machine.system() == 'dos'
112  delay_src = files('udelay_dos.c')
113endif
114srcs += delay_src
115cargs += ['-DCONFIG_DELAY_MINIMUM_SLEEP_US=@0@'.format(
116  get_option('delay_minimum_sleep_us')
117)]
118
119### CrOS Tree
120srcs += files(
121  'power.c',
122  'action_descriptor.c',
123  'flashchips_crosbl.c',
124  'cros_ec.c',
125  'big_lock.c',
126  'file_lock.c',
127)
128cargs += '-DCONFIG_CROS_EC=1'
129cargs += '-DUSE_BIG_LOCK=1'
130###
131
132# check for required symbols
133if cc.has_function('clock_gettime')
134  add_project_arguments('-DHAVE_CLOCK_GETTIME=1', language : 'c')
135endif
136if cc.has_function('strnlen')
137  add_project_arguments('-DHAVE_STRNLEN=1', language : 'c')
138endif
139if cc.check_header('getopt.h')
140  add_project_arguments('-DHAVE_GETOPT_H=1', language : 'c')
141endif
142if cc.check_header('pciutils/pci.h')
143  add_project_arguments('-DHAVE_PCIUTILS_PCI_H=1', language : 'c')
144endif
145if cc.check_header('sys/utsname.h')
146  add_project_arguments('-DHAVE_UTSNAME=1', language : 'c')
147endif
148if host_machine.system() in ['cygwin', 'windows']
149  add_project_arguments('-DIS_WINDOWS=1', language : 'c')
150else
151  add_project_arguments('-DIS_WINDOWS=0', language : 'c')
152endif
153
154if host_machine.system() == 'linux'
155  custom_baud_c = 'custom_baud_linux.c'
156elif host_machine.system() == 'darwin'
157  custom_baud_c = 'custom_baud_darwin.c'
158else
159  custom_baud_c = 'custom_baud.c'
160endif
161
162systems_hwaccess   = [ 'linux', 'openbsd', 'freebsd', 'dragonfly', 'netbsd', 'dos' ]
163systems_serial     = [ 'linux', 'openbsd', 'freebsd', 'dragonfly', 'netbsd', 'darwin', 'windows' ]
164
165cpus_port_io = [ 'x86', 'x86_64' ]
166
167group_ftdi   = get_option('programmer').contains('group_ftdi')
168group_pci    = get_option('programmer').contains('group_pci')
169group_usb    = get_option('programmer').contains('group_usb')
170group_i2c    = get_option('programmer').contains('group_i2c')
171group_serial = get_option('programmer').contains('group_serial')
172group_jlink  = get_option('programmer').contains('group_jlink')
173group_internal = get_option('programmer').contains('group_internal')
174group_external = get_option('programmer').contains('group_external')
175
176libpci     = dependency('libpci', required : group_pci, version : '>=2.2.0',
177  static : (host_machine.system() == 'openbsd' ? true : false)) # On openbsd a static version of libpci is needed to get also -libz
178libusb1    = dependency('libusb-1.0', required : group_usb)
179libftdi1   = dependency('libftdi1', required : group_ftdi)
180libjaylink = dependency('libjaylink', required : group_jlink, version : '>=0.3.0')
181
182# ECAM is supported in libpci after 3.13.0
183if libpci.version().version_compare('>=3.13.0')
184    add_project_arguments('-DCONFIG_USE_LIBPCI_ECAM=1', language: 'c')
185else
186    add_project_arguments('-DCONFIG_USE_LIBPCI_ECAM=0', language: 'c')
187endif
188
189if host_machine.system() == 'windows'
190  # Specifying an include_path that doesn't exist is an error,
191  # but we only use this if the library is found in the same directory.
192  ni845x_search_path = get_option('ni845x_search_path')
193  if fs.is_dir(ni845x_search_path)
194    ni845x_include_path = [ni845x_search_path]
195  else
196    ni845x_include_path = []
197  endif
198
199  libni845x = declare_dependency(
200    dependencies : [
201      cc.find_library(
202        'ni845x',
203        dirs : get_option('ni845x_search_path'),
204        required : get_option('programmer').contains('ni845x_spi')
205      ),
206    ],
207    include_directories : ni845x_include_path,
208  )
209else
210  libni845x = dependency('', required : false)
211endif
212
213subdir('platform')
214
215if systems_hwaccess.contains(host_machine.system())
216  srcs += files('hwaccess_physmap.c')
217  if ['x86', 'x86_64'].contains(host_machine.cpu_family())
218    srcs += files('hwaccess_x86_msr.c', 'hwaccess_x86_io.c')
219  endif
220endif
221
222# Pseudo dependencies
223linux_headers = \
224  cc.has_header('linux/i2c.h')     and \
225  cc.has_header('linux/i2c-dev.h') and \
226  cc.has_header('mtd/mtd-user.h')  and \
227  cc.has_header('linux/spi/spidev.h') ? declare_dependency() : dependency('', required : false)
228
229# '<programmer_name>' : {
230#   'system'      : list[string],  # default: ['all']
231#   'cpu_families : list[string],  # default: ['all']
232#   'deps'        : list[dep],     # default: []
233#   'groups       : list[boolean], # default: []
234#   'srcs'        : list[file],    # default: []
235#   'flags'       : list[string],  # default: []
236#   'default'     : boolean,       # default: true
237#   'active'      : boolean,       # added on runtime
238# }
239programmer = {
240  'asm106x' : {
241    'systems' : systems_hwaccess,
242    'deps'    : [ libpci ],
243    'groups'  : [ group_pci, group_internal ],
244    'srcs'    : files('asm106x.c', 'pcidev.c'),
245    'flags'   : [ '-DCONFIG_ASM106X=1' ],
246  },
247  'atahpt' : {
248    'systems' : systems_hwaccess,
249    'cpu_families' : cpus_port_io,
250    'deps'    : [ libpci ],
251    'groups'  : [ group_pci, group_internal ],
252    'srcs'    : files('atahpt.c', 'pcidev.c'),
253    'flags'   : [ '-DCONFIG_ATAHPT=1' ],
254    'default' : false, # not yet working
255  },
256  'atapromise' : {
257    'systems' : systems_hwaccess,
258    'cpu_families' : cpus_port_io,
259    'deps'    : [ libpci ],
260    'groups'  : [ group_pci, group_internal ],
261    'srcs'    : files('atapromise.c', 'pcidev.c'),
262    'flags'   : [ '-DCONFIG_ATAPROMISE=1' ],
263    'default' : false,
264  },
265  'atavia' : {
266    'systems' : systems_hwaccess,
267    'deps'    : [ libpci ],
268    'groups'  : [ group_pci, group_internal ],
269    'srcs'    : files('atavia.c', 'pcidev.c'),
270    'flags'   : [ '-DCONFIG_ATAVIA=1' ],
271  },
272  'buspirate_spi' : {
273    'systems' : systems_serial,
274    'groups'  : [ group_serial, group_external ],
275    'srcs'    : files('buspirate_spi.c', 'serial.c', custom_baud_c),
276    'flags'   : [ '-DCONFIG_BUSPIRATE_SPI=1' ],
277  },
278  'ch341a_spi' : {
279    'deps'    : [ libusb1 ],
280    'groups'  : [ group_usb, group_external ],
281    'srcs'    : files('ch341a_spi.c'),
282    'test_srcs' : files('tests/ch341a_spi.c'),
283    'flags'   : [ '-DCONFIG_CH341A_SPI=1' ],
284  },
285  'ch347_spi' : {
286    'deps'    : [ libusb1 ],
287    'groups'  : [ group_usb, group_external ],
288    'srcs'    : files('ch347_spi.c'),
289    'flags'   : [ '-DCONFIG_CH347_SPI=1' ],
290  },
291  'dediprog' : {
292    'deps'    : [ libusb1 ],
293    'groups'  : [ group_usb, group_external ],
294    'srcs'    : files('dediprog.c', 'usbdev.c'),
295    'test_srcs' : files('tests/dediprog.c'),
296    'flags'   : [ '-DCONFIG_DEDIPROG=1' ],
297  },
298  'developerbox_spi' : {
299    'deps'    : [ libusb1 ],
300    'groups'  : [ group_usb, group_external ],
301    'srcs'    : files('developerbox_spi.c', 'usbdev.c'),
302    'flags'   : [ '-DCONFIG_DEVELOPERBOX_SPI=1' ],
303  },
304  'digilent_spi' : {
305    'deps'    : [ libusb1 ],
306    'groups'  : [ group_usb, group_external ],
307    'srcs'    : files('digilent_spi.c'),
308    'flags'   : [ '-DCONFIG_DIGILENT_SPI=1' ],
309  },
310  'dirtyjtag_spi' : {
311    'deps'    : [ libusb1 ],
312    'groups'  : [ group_usb, group_external ],
313    'srcs'    : files('dirtyjtag_spi.c'),
314    'flags'   : [ '-DCONFIG_DIRTYJTAG_SPI=1' ],
315  },
316  'drkaiser' : {
317    'systems' : systems_hwaccess,
318    'deps'    : [ libpci ],
319    'groups'  : [ group_pci, group_internal ],
320    'srcs'    : files('drkaiser.c', 'pcidev.c'),
321    'flags'   : [ '-DCONFIG_DRKAISER=1' ],
322  },
323  'dummy'     : {
324    'srcs'    : files('dummyflasher.c'),
325    'test_srcs' : files('tests/dummyflasher.c'),
326    'flags'   : [ '-DCONFIG_DUMMY=1' ],
327  },
328  'ft2232_spi' : {
329    'deps'    : [ libftdi1 ],
330    'groups'  : [ group_ftdi, group_external ],
331    'srcs'    : files('ft2232_spi.c' ),
332    'flags'   : [ '-DCONFIG_FT2232_SPI=1' ],
333  },
334  'gfxnvidia' : {
335    'systems' : systems_hwaccess,
336    'deps'    : [ libpci ],
337    'groups'  : [ group_pci, group_internal ],
338    'srcs'    : files('gfxnvidia.c', 'pcidev.c'),
339    'flags'   : [ '-DCONFIG_GFXNVIDIA=1' ],
340  },
341  'internal' : {
342    'systems' : systems_hwaccess + ['linux'],
343    'cpu_families' : (host_machine.system() == 'linux' ? [host_machine.cpu_family()] : ['x86', 'x86_64']),
344    'deps'    : [ libpci ],
345    'groups'  : [ group_internal ],
346    'srcs'    : (host_machine.cpu_family() in ['x86', 'x86_64'] ? files(
347      'processor_enable.c',
348      'chipset_enable.c',
349      'board_enable.c',
350      'cbtable.c',
351      'internal.c',
352      'internal_par.c',
353      'it87spi.c',
354      'sb600spi.c',
355      'superio.c',
356      'amd_imc.c',
357      'wbsio_spi.c',
358      'mcp6x_spi.c',
359      'ichspi.c',
360      'dmi.c',
361      'pcidev.c',
362      'known_boards.c',
363    ) : files(
364      'board_enable.c',
365      'cbtable.c',
366      'chipset_enable.c',
367      'internal.c',
368      'internal_par.c',
369      'processor_enable.c',
370      'pcidev.c',
371      'known_boards.c',
372    )),
373    'flags' : [
374      '-DCONFIG_INTERNAL=1',
375      '-DCONFIG_INTERNAL_DMI=' + (get_option('use_internal_dmi') ? '1' : '0'),
376    ]
377  },
378  'it8212' : {
379    'systems' : systems_hwaccess,
380    'deps'    : [ libpci ],
381    'groups'  : [ group_pci, group_internal ],
382    'srcs'    : files('it8212.c', 'pcidev.c'),
383    'flags'   : [ '-DCONFIG_IT8212=1' ],
384  },
385  'jlink_spi' : {
386    'deps'    : [ libjaylink ],
387    'groups'  : [ group_jlink, group_external ],
388    'srcs'    : files('jlink_spi.c'),
389    'flags'   : [ '-DCONFIG_JLINK_SPI=1' ],
390  },
391  'linux_mtd' : {
392    'systems' : [ 'linux' ],
393    'deps'    : [ linux_headers ],
394    'groups'  : [ group_internal ],
395    'srcs'    : files('linux_mtd.c'),
396    'test_srcs' : files('tests/linux_mtd.c'),
397    'flags'   : [ '-DCONFIG_LINUX_MTD=1' ],
398  },
399  'linux_spi' : {
400    'systems' : [ 'linux' ],
401    'deps'    : [ linux_headers ],
402              # internal / external?
403    'srcs'    : files('linux_spi.c'),
404    'test_srcs' : files('tests/linux_spi.c'),
405    'flags'   : [ '-DCONFIG_LINUX_SPI=1' ],
406  },
407  'parade_lspcon' : {
408    'systems' : [ 'linux' ],
409    'deps'    : [ linux_headers ],
410    'groups'  : [ group_i2c ],
411    'srcs'    : files('parade_lspcon.c', 'i2c_helper_linux.c'),
412    'test_srcs' : files('tests/parade_lspcon.c'),
413    'flags'   : [ '-DCONFIG_PARADE_LSPCON=1' ],
414    'default' : false
415  },
416  'mediatek_i2c_spi' : {
417    'systems' : [ 'linux' ],
418    'deps'    : [ linux_headers ],
419    'groups'  : [ group_i2c ],
420    'srcs'    : files('mediatek_i2c_spi.c', 'i2c_helper_linux.c'),
421    'test_srcs' : files('tests/mediatek_i2c_spi.c'),
422    'flags'   : [ '-DCONFIG_MEDIATEK_I2C_SPI=1' ],
423    'default' : false,
424  },
425  'mstarddc_spi' : {
426    'systems' : [ 'linux' ],
427    'deps'    : [ linux_headers ],
428    'groups'  : [ group_i2c ],
429    'srcs'    : files('mstarddc_spi.c', 'i2c_helper_linux.c'),
430    'flags'   : [ '-DCONFIG_MSTARDDC_SPI=1' ],
431    'default' : false
432  },
433  'ni845x_spi' : {
434    'systems' : [ 'windows' ],
435    'cpu_families' : [ 'x86' ], # The required ni845x library is 32-bit only
436    'deps'    : [ libni845x ],
437    'srcs'    : files('ni845x_spi.c'),
438    'flags'   : [ '-DCONFIG_NI845X_SPI=1' ],
439    'default' : false,
440  },
441  'nic3com' : {
442    'systems' : systems_hwaccess,
443    'cpu_families' : cpus_port_io,
444    'deps'    : [ libpci ],
445    'groups'  : [ group_pci, group_internal ],
446    'srcs'    : files('nic3com.c', 'pcidev.c'),
447    'flags'   : [ '-DCONFIG_NIC3COM=1' ],
448  },
449  'nicintel' : {
450    'systems' : systems_hwaccess,
451    'deps'    : [ libpci ],
452    'groups'  : [ group_pci, group_internal ],
453    'srcs'    : files('nicintel.c', 'pcidev.c'),
454    'flags'   : [ '-DCONFIG_NICINTEL=1' ],
455  },
456  'nicintel_eeprom' : {
457    'systems' : systems_hwaccess,
458    'deps'    : [ libpci ],
459    'groups'  : [ group_pci, group_internal ],
460    'srcs'    : files('nicintel_eeprom.c', 'pcidev.c'),
461    'flags'   : [ '-DCONFIG_NICINTEL_EEPROM=1' ],
462  },
463  'nicintel_spi' : {
464    'systems' : systems_hwaccess,
465    'deps'    : [ libpci ],
466    'groups'  : [ group_pci, group_internal ],
467    'srcs'    : files('nicintel_spi.c', 'pcidev.c'),
468    'flags'   : [ '-DCONFIG_NICINTEL_SPI=1' ],
469  },
470  'nicnatsemi' : {
471    'systems' : systems_hwaccess,
472    'cpu_families' : cpus_port_io,
473    'deps'    : [ libpci ],
474    'groups'  : [ group_pci, group_internal ],
475    'srcs'    : files('nicnatsemi.c', 'pcidev.c'),
476    'flags'   : [ '-DCONFIG_NICNATSEMI=1' ],
477    'default' : false, # not complete nor tested
478  },
479  'nicrealtek' : {
480    'systems' : systems_hwaccess,
481    'cpu_families' : cpus_port_io,
482    'deps'    : [ libpci ],
483    'groups'  : [ group_pci, group_internal ],
484    'srcs'    : files('nicrealtek.c', 'pcidev.c'),
485    'test_srcs' : files('tests/nicrealtek.c'),
486    'flags'   : [ '-DCONFIG_NICREALTEK=1' ],
487  },
488  'ogp_spi' : {
489    'systems' : systems_hwaccess,
490    'deps'    : [ libpci ],
491    'groups'  : [ group_pci, group_internal ],
492    'srcs'    : files('ogp_spi.c', 'pcidev.c'),
493    'flags'   : [ '-DCONFIG_OGP_SPI=1' ],
494  },
495  'pickit2_spi' : {
496    'deps'    : [ libusb1 ],
497    'groups'  : [ group_usb, group_external ],
498    'srcs'    : files('pickit2_spi.c'),
499    'flags'   : [ '-DCONFIG_PICKIT2_SPI=1' ],
500  },
501  'pony_spi' : {
502    'systems' : systems_serial,
503    'groups'  : [ group_serial, group_external ],
504    'srcs'    : files('pony_spi.c', 'serial.c', custom_baud_c),
505    'flags'   : [ '-DCONFIG_PONY_SPI=1' ],
506  },
507  'raiden_debug_spi' : {
508    'deps'    : [ libusb1 ],
509    'groups'  : [ group_usb, group_external ],
510    'srcs'    : files('raiden_debug_spi.c', 'usb_device.c'),
511    'test_srcs' : files('tests/raiden_debug_spi.c'),
512    'flags'   : [ '-DCONFIG_RAIDEN_DEBUG_SPI=1' ],
513  },
514  'rayer_spi' : {
515    'systems' : systems_hwaccess,
516    'cpu_families' : cpus_port_io,
517    'groups'  : [ group_internal ],
518    'srcs'    : files('rayer_spi.c'),
519    'flags'   : [ '-DCONFIG_RAYER_SPI=1' ],
520  },
521  'realtek_mst_i2c_spi' : {
522    'systems' : [ 'linux' ],
523    'deps'    : [ linux_headers ],
524    'groups'  : [ group_i2c ],
525    'srcs'    : files('realtek_mst_i2c_spi.c', 'i2c_helper_linux.c'),
526    'test_srcs' : files('tests/realtek_mst_i2c_spi.c'),
527    'flags'   : [ '-DCONFIG_REALTEK_MST_I2C_SPI=1' ],
528    'default' : false,
529  },
530  'satamv' : {
531    'systems' : systems_hwaccess,
532    'cpu_families' : cpus_port_io,
533    'deps'    : [ libpci ],
534    'groups'  : [ group_pci, group_internal ],
535    'srcs'    : files('satamv.c', 'pcidev.c'),
536    'flags'   : ['-DCONFIG_SATAMV=1'],
537  },
538  'satasii' : {
539    'systems' : systems_hwaccess,
540    'deps'    : [ libpci ],
541    'groups'  : [ group_pci, group_internal ],
542    'srcs'    : files('satasii.c', 'pcidev.c'),
543    'flags'   : [ '-DCONFIG_SATASII=1' ],
544  },
545  'serprog' : {
546    'systems' : systems_serial,
547    'groups'  : [ group_serial, group_external ],
548    'srcs'    : files('serprog.c', 'serial.c', custom_baud_c),
549    'flags'   : [ '-DCONFIG_SERPROG=1' ],
550  },
551  'stlinkv3_spi' : {
552    'deps'    : [ libusb1 ],
553    'groups'  : [ group_usb, group_external ],
554    'srcs'    : files('stlinkv3_spi.c', 'usbdev.c'),
555    'flags'   : [ '-DCONFIG_STLINKV3_SPI=1' ],
556  },
557  'usbblaster_spi' : {
558    'deps'    : [ libftdi1 ],
559    'groups'  : [ group_ftdi, group_external ],
560    'srcs'    : files('usbblaster_spi.c'),
561    'flags'   : [ '-DCONFIG_USBBLASTER_SPI=1' ],
562  },
563}
564
565active_programmer_count = 0
566foreach p_name, p_data : programmer
567  p_data += {
568    'systems' : p_data.get('systems', ['all']),
569    'cpu_families' : p_data.get('cpu_families', ['all']),
570    'deps' : p_data.get('deps', []),
571    'groups' : p_data.get('groups', []),
572    'srcs' : p_data.get('srcs', []),
573    'test_srcs': p_data.get('test_srcs', []),
574    'flags' : p_data.get('flags', []),
575    'default' : p_data.get('default', true),
576  }
577
578  active        = false
579  deps_found    = true
580  not_found_dep = ''
581  not_active_message = ''
582  selected_hard = p_name in get_option('programmer')
583  selected_soft = p_data.get('groups').contains(true) or \
584                  'all' in get_option('programmer') or \
585                  'auto' in get_option('programmer') and p_data.get('default')
586  available     = (p_data.get('systems').contains('all') or p_data.get('systems').contains(host_machine.system())) \
587                  and (p_data.get('cpu_families').contains('all') or p_data.get('cpu_families').contains(host_machine.cpu_family()))
588
589  foreach dep : p_data.get('deps')
590    if not dep.found()
591      deps_found = false
592      not_found_dep = dep.name()
593      break
594    endif
595  endforeach
596
597  if selected_hard
598    if not available
599      error('programmer @0@ was selected but is not supported on this platform (needs @1@/@2@, but system is @3@/@4@)'.format(
600        p_name,
601        p_data.get('systems'),
602        p_data.get('cpu_families'),
603        host_machine.system(),
604        host_machine.cpu_family()
605      ))
606    elif not deps_found
607      error(p_name + ' selected but dependency ' + not_found_dep +'not found')
608    else
609      active = true
610    endif
611  elif selected_soft
612    if not available
613      not_active_message = 'Not available on platform'
614    elif not deps_found
615      not_active_message = 'dependency ' + not_found_dep + ' not found'
616    else
617      active = true
618    endif
619  else
620    not_active_message = 'not selected'
621  endif
622
623  p_data += {
624    'active' : active,
625    'summary' : not_active_message,
626  }
627  programmer += {p_name : p_data}
628  if active
629    active_programmer_count += 1
630  endif
631endforeach
632
633if active_programmer_count == 0
634  error('At least one programmer must be selected')
635endif
636
637# add srcs, cargs & deps from active programmer to global srcs, cargs & deps
638foreach p_name, p_data : programmer
639  if p_data.get('active')
640    srcs += p_data.get('srcs')
641    cargs += p_data.get('flags')
642    deps += p_data.get('deps')
643  endif
644endforeach
645
646if config_print_wiki.enabled()
647  if get_option('classic_cli').disabled()
648    error('`classic_cli_print_wiki` can not be enabled without `classic_cli`')
649  else
650    srcs += files('print_wiki.c')
651    cargs += '-DCONFIG_PRINT_WIKI=1'
652  endif
653endif
654
655if config_default_programmer_name != ''
656  cargs += '-DCONFIG_DEFAULT_PROGRAMMER_NAME=&programmer_' + config_default_programmer_name
657else
658  cargs += '-DCONFIG_DEFAULT_PROGRAMMER_NAME=NULL'
659endif
660
661cargs += '-DCONFIG_DEFAULT_PROGRAMMER_ARGS="' + config_default_programmer_args + '"'
662
663if get_option('llvm_cov').enabled()
664  cargs += ['-fprofile-instr-generate', '-fcoverage-mapping']
665  link_args += ['-fprofile-instr-generate', '-fcoverage-mapping']
666endif
667
668install_headers([
669    'include/libflashrom.h',
670  ],
671)
672
673include_dir = include_directories('include')
674
675mapfile = 'libflashrom.map'
676if host_machine.system() == 'darwin'
677  vflag = ''
678else
679  vflag = '-Wl,--version-script,@0@/@1@'.format(meson.current_source_dir(), mapfile)
680endif
681libflashrom = library(
682  'flashrom',
683  sources : [
684    srcs,
685  ],
686  include_directories : include_dir,
687  soversion : lt_current,
688  version : lt_version,
689  dependencies : [
690    deps,
691  ],
692  c_args : [
693    cargs,
694  ],
695  install : true,
696  link_args : link_args + [vflag],
697  link_depends : mapfile,
698)
699
700pkgg = import('pkgconfig')
701pkgg.generate(
702  libraries : libflashrom,
703  version : flashrom_version.split()[0], # cut off the git version
704  name : 'flashrom',
705  filebase : 'flashrom',
706  description : 'library to interact with flashrom',
707)
708
709if get_option('classic_cli').enabled() or get_option('classic_cli').auto() and not get_option('default_library') == 'shared'
710
711  cli_srcs = files(
712    'cli_classic.c',
713    'cli_common.c',
714    'cli_output.c'
715  )
716
717  if not cc.has_function('getopt_long')
718    cli_srcs += files('cli_getopt.c')
719  endif
720
721  classic_cli = executable(
722    'flashrom',
723    cli_srcs,
724    c_args : cargs,
725    include_directories : include_dir,
726    install : true,
727    install_dir : get_option('sbindir'),
728    link_args : link_args,
729    # flashrom needs internal symbols of libflashrom
730    link_with : get_option('default_library') == 'static' ? libflashrom : libflashrom.get_static_lib(),
731  )
732  if get_option('llvm_cov').enabled()
733    run_target('llvm-cov-cli', command : ['scripts/llvm-cov', classic_cli])
734  endif
735endif
736
737if get_option('ich_descriptors_tool').auto() or get_option('ich_descriptors_tool').enabled()
738  subdir('util/ich_descriptors_tool')
739endif
740
741if get_option('bash_completion').auto() or get_option('bash_completion').enabled()
742  if get_option('classic_cli').disabled()
743    if get_option('bash_completion').enabled()
744      error('`bash_completion` can not be enabled without `classic_cli`')
745    endif
746  else
747    bash_comp = dependency('bash-completion', required : false)
748    if bash_comp.found()
749      bash_comp_install_dir = bash_comp.get_variable(
750        pkgconfig : 'completionsdir',
751        pkgconfig_define : ['datadir', get_option('datadir')]
752      )
753    else
754      bash_comp_install_dir = join_paths(get_option('datadir'), 'bash-completion', 'completions')
755    endif
756
757    programmer_names_active_str = ''
758    foreach p_name, p_data : programmer
759      if p_data.get('active')
760        programmer_names_active_str += p_name + ' '
761      endif
762    endforeach
763
764    configure_file(
765      input : 'util/flashrom.bash-completion.tmpl',
766      output : 'flashrom.bash',
767      configuration : {
768        'PROGRAMMERS' : programmer_names_active_str,
769      },
770      install: true,
771      install_dir: bash_comp_install_dir,
772    )
773  endif
774endif
775
776# Use `.auto() or .enabled()` instead of `.allowed()` to keep the minimum meson version as low as possible.
777# `.allowed()` gets introduced in 0.59.0
778if get_option('tests').auto() or get_option('tests').enabled()
779  # unit-test framework
780  cmocka_dep = dependency(
781    'cmocka',
782    fallback: ['cmocka', 'cmocka_dep'],
783    required : get_option('tests')
784  )
785
786  flashrom_test_dep = declare_dependency(
787    include_directories : include_dir,
788    sources : [
789      srcs,
790      'cli_common.c',
791      'cli_output.c',
792      'flashrom.c',
793    ],
794    compile_args : [
795      '-includestdlib.h',
796      '-includeunittest_env.h',
797    ],
798    dependencies : [
799      deps,
800    ],
801  )
802
803  if cmocka_dep.found()
804    subdir('tests')
805  endif
806endif
807
808programmer_names_active     = []
809programmer_names_not_active = []
810foreach p_name, p_data : programmer
811  if p_data.get('active')
812    programmer_names_active += p_name
813  else
814    programmer_names_not_active += p_name + ' (' + p_data.get('summary', '') + ')'
815  endif
816endforeach
817
818summary({
819  'active' : [programmer_names_active],
820  'non active' : [programmer_names_not_active],
821}, section : 'Programmer')
822