1project(
2    'phosphor-fan-presence',
3    'cpp',
4    default_options: [
5        'warning_level=3',
6        'werror=true',
7        'cpp_std=c++23',
8        'buildtype=debugoptimized',
9        'prefix=/usr'
10    ],
11    license: 'Apache-2.0',
12    version: '1.0',
13    meson_version: '>=1.1.1',
14)
15
16python_prog = find_program('python3', native: true)
17
18cpp = meson.get_compiler('cpp')
19
20cli11_dep = dependency('cli11', required: false)
21
22if not cpp.has_header_symbol(
23    'CLI/CLI.hpp',
24    'CLI::App',
25    dependencies: cli11_dep,
26    required: false)
27    cli11_proj = subproject('cli11', required:false)
28    assert(cli11_proj.found(), 'CLI11 is required')
29    cli11_dep = cli11_proj.get_variable('CLI11_dep')
30endif
31
32cereal_dep = dependency('cereal', required: false)
33has_cereal = cpp.has_header_symbol(
34    'cereal/cereal.hpp',
35    'cereal::specialize',
36    dependencies: cereal_dep,
37    required: false)
38if not has_cereal
39    cereal_opts = import('cmake').subproject_options()
40    cereal_opts.add_cmake_defines({'BUILD_TESTS': 'OFF'})
41    cereal_proj = import('cmake').subproject(
42        'cereal',
43        options: cereal_opts,
44        required: false)
45    assert(cereal_proj.found(), 'cereal is required')
46    cereal_dep = cereal_proj.dependency('cereal')
47endif
48
49if cpp.has_header('nlohmann/json.hpp')
50    json_dep = declare_dependency()
51else
52    json_dep = dependency('nlohmann_json')
53endif
54
55fmt_dep = dependency('fmt')
56
57phosphor_dbus_interfaces_dep = dependency('phosphor-dbus-interfaces')
58phosphor_logging_dep = dependency('phosphor-logging')
59sdbusplus_dep = dependency('sdbusplus')
60sdeventplus_dep = dependency('sdeventplus')
61stdplus_dep = dependency('stdplus')
62systemd_dep = dependency('systemd')
63
64if(get_option('tests').enabled())
65    gmock_dep = dependency('gmock', disabler: true)
66    gtest_dep = dependency('gtest', main: true, disabler: true, required: false)
67
68    if not gtest_dep.found() or not gmock_dep.found()
69        gtest_proj = import('cmake').subproject('googletest', required: false)
70        if gtest_proj.found()
71            gtest_dep = declare_dependency(
72                dependencies: [
73                    dependency('threads'),
74                    gtest_proj.dependency('gtest'),
75                    gtest_proj.dependency('gtest_main'),
76                ]
77            )
78            gmock_dep = gtest_proj.dependency('gmock')
79        else
80            assert(
81                not get_option('tests').enabled(),
82                'Googletest is required if tests are enabled'
83            )
84        endif
85    endif
86    subdir('test')
87endif
88
89
90servicedir = systemd_dep.get_variable('systemdsystemunitdir')
91usr_share_dir = '/usr/share/phosphor-fan-presence'
92
93conf = configuration_data()
94
95# Control
96conf.set_quoted(
97    'CONTROL_PERSIST_ROOT_PATH', get_option('control-persist-root-path'))
98conf.set_quoted(
99    'CONTROL_PERSIST_ROOT_PATH', get_option('control-persist-root-path'))
100conf.set_quoted(
101    'FAN_DEF_YAML_FILE', get_option('fan-def-yaml-file'))
102conf.set_quoted(
103    'FAN_ZONE_YAML_FILE', get_option('fan-zone-yaml-file'))
104conf.set_quoted(
105    'ZONE_EVENTS_YAML_FILE', get_option('zone-events-yaml-file'))
106conf.set_quoted(
107    'ZONE_CONDITIONS_YAML_FILE', get_option('zone-conditions-yaml-file'))
108
109# Fan control can be in YAML mode when everything else is in JSON mode
110control_conf_type = 'yaml'
111if get_option('json-config').enabled() and get_option('json-control').enabled()
112    control_conf_type = 'json'
113endif
114
115# Monitor
116conf.set(
117    'NUM_MONITOR_LOG_ENTRIES', get_option('num-monitor-log-entries'))
118conf.set_quoted(
119    'FAN_MONITOR_YAML_FILE', get_option('fan-monitor-yaml-file'))
120conf.set('DELAY_HOST_CONTROL', get_option('delay-host-control'))
121if get_option('monitor-use-host-state').enabled()
122    conf.set('MONITOR_USE_HOST_STATE', '')
123endif
124
125# JSON-or-YAML (all programs)
126if get_option('json-config').enabled()
127    conf.set('PRESENCE_USE_JSON', '')
128    if control_conf_type == 'json'
129        conf.set('CONTROL_USE_JSON', '')
130    endif
131    conf.set('MONITOR_USE_JSON', '')
132
133    conf_type = 'json'
134else
135    conf_type = 'yaml'
136endif
137
138# Sensor Monitor
139conf.set_quoted('SENSOR_MONITOR_PERSIST_ROOT_PATH',
140                get_option('sensor-monitor-persist-root-path'))
141
142if get_option('use-host-power-state').enabled()
143    conf.set('ENABLE_HOST_STATE', '')
144endif
145
146conf.set(
147    'SHUTDOWN_ALARM_HARD_SHUTDOWN_DELAY_MS', get_option('sensor-monitor-hard-shutdown-delay'))
148conf.set(
149    'SHUTDOWN_ALARM_SOFT_SHUTDOWN_DELAY_MS', get_option('sensor-monitor-soft-shutdown-delay'))
150
151# Presence
152conf.set(
153    'NUM_PRESENCE_LOG_ENTRIES', get_option('num-presence-log-entries'))
154conf.set_quoted(
155    'PRESENCE_YAML_FILE', get_option('presence-config'))
156
157configure_file(output: 'config.h', configuration: conf)
158
159# Service: [name,[svcfiles]]
160services = []
161
162if get_option('control-service').enabled()
163    subdir('control')
164    service_files = ['phosphor-fan-control@.service']
165    if control_conf_type == 'yaml'
166        service_files += 'phosphor-fan-control-init@.service'
167    endif
168    services += [['control', service_files]]
169endif
170
171if get_option('monitor-service').enabled()
172    subdir('monitor')
173    service_files = ['phosphor-fan-monitor@.service']
174    if not get_option('json-config').enabled()
175        service_files += 'phosphor-fan-monitor-init@.service'
176    endif
177    services += [['monitor', service_files]]
178endif
179
180if get_option('cooling-type-service').enabled()
181    libevdev_dep = dependency('libevdev')
182    subdir('cooling-type')
183endif
184
185if get_option('presence-service').enabled()
186    libevdev_dep = dependency('libevdev')
187    subdir('presence')
188    services += [['presence', ['phosphor-fan-presence-tach@.service']]]
189endif
190
191if get_option('sensor-monitor-service').enabled()
192    subdir('sensor-monitor')
193    install_data('sensor-monitor/service_files/sensor-monitor.service',
194        install_dir: servicedir)
195endif
196
197foreach service : services
198    this_conf_type = conf_type
199
200    if service[0] == 'control'
201        this_conf_type = control_conf_type
202    endif
203
204    foreach service_file : service[1]
205        install_data(service[0] / 'service_files' / this_conf_type / service_file,
206                     install_dir: servicedir)
207    endforeach
208
209    if this_conf_type == 'json'
210        fs = import('fs')
211        dir = meson.current_source_dir() / service[0] / 'config_files' / get_option('machine-name')
212        if fs.is_dir(dir)
213            install_subdir(service[0] / 'config_files' / get_option('machine-name'),
214                          install_dir: usr_share_dir / service[0],
215                          strip_directory: true)
216        endif
217    endif
218endforeach
219
220