forked from Brewtarget/brewtarget
-
Notifications
You must be signed in to change notification settings - Fork 0
/
meson.build
1726 lines (1640 loc) · 84.4 KB
/
meson.build
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#
# meson.build is part of Brewtarget, and is copyright the following authors 2022-2024:
# • Matt Young <[email protected]>
#
# Brewtarget is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# Brewtarget is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with this program. If not, see
# <http://www.gnu.org/licenses/>.
#
#-----------------------------------------------------------------------------------------------------------------------
#
# NB: This is now the primary way of building and packaging the software. You can also still CMake to compile the
# product and install it locally, but we no longer support using CMake to do packaging.
#
# STEP 1: Ensure Python is installed:
# -----------------------------------
# On Ubuntu and other Debian-based versions of Linux:
# sudo apt install python3
#
# On Windows, in the 32-bit MSYS2 (https://www.msys2.org/) environment:
# pacman -S --needed mingw-w64-i686-python
# pacman -S --needed mingw-w64-i686-python-pip
# On Windows, in the 64-bit MSYS2 environment you would do the following HOWEVER NB WE HAVE NOT GOT PACKAGING WORKING
# FOR 64-BIT BUILDS YET SO THIS IS NOT SUPPORTED AND MAY REQUIRE CHANGES TO THE bt SCRIPT:
# pacman -S --needed mingw-w64-x86_64-python
# pacman -S --needed mingw-w64-x86_64-python-pip
#
# On a Mac with homebrew (https://brew.sh/) installed
# brew install [email protected]
#
#
# STEP 2 (WINDOWS ONLY): Extra set-up
# -----------------------------------
# On Windows, there are a couple of extra things we need to do before running the bt script:
#
# - For historical reasons, Linux and other platforms need to run both Python v2 (still used by some bits of
# system) and Python v3 (eg that you installed yourself) so there are usually two corresponding Python
# executables, python2 and python3. On Windows there is only whatever Python you installed and it's called
# python.exe. To keep the shebang in the bt script working, we just make a softlink to python called python3.
#
# - Getting Unicode input/output to work is fun. We should already have a Unicode locale, but it seems we also
# need to set PYTHONIOENCODING (see https://docs.python.org/3/using/cmdline.html#envvar-PYTHONIOENCODING, even
# though it seems to imply you don't need to set it on recent versions of Python).
#
# - The version of Pip we install above does not put it in the "right" place. Specifically it will not be in the
# PATH when we run bt. The following seems to be the least hacky way around this:
# curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
# python get-pip.py
# python -m pip install -U --force-reinstall pip
# See https://stackoverflow.com/questions/48087004/installing-pip-on-msys for more discussion on this.
#
# TLDR: Here's what you need to run in the MSYS2 Mintty terminal:
# if [[ ! -f $(dirname $(which python))/python3 ]]; then ln -s $(which python) $(dirname $(which python))/python3; fi
# export PYTHONIOENCODING=utf8
# curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
# python get-pip.py
# python -m pip install -U --force-reinstall pip
#
#
# STEP 3: Automatically install other dependencies and set up the Meson build:
# ----------------------------------------------------------------------------
# Then everything else can be installed by running:
# ./bt setup all
#
# This will also set up the Meson build. Amongst other things, this creates the 'mbuild' directory tree for the Meson
# build (so no clashes with a CMake build in the 'build' directory tree).
#
# Alternatively, if you decided to install all the dependencies manually, or if you need to reset the build directory
# after it got in a bad state, you can run:
# ./bt setup
#
#
# STEP 4: Compile, test, install:
# -------------------------------
# Everything else is done from the 'mbuild' directory, so start with:
# cd mbuild
#
# To compile:
# meson compile
# Alternatively, to get more detailed output:
# meson compile --verbose
#
# To run unit tests:
# meson test
#
# Then to install:
# meson install
# Or, on Linux, you can do:
# sudo meson install
# which avoids the pop-up window
#
# Note that, on Linux, using `sudo meson install` sometimes creates problems with file permissions - eg
# mbuild/meson-logs/install-log.txt ends up being writable only by root and that results in an error when you run
# `bt package`, but this should be fixed in Meson 1.1.0.
#
# To build source packages (in the meson-dist subdirectory of the build directory):
# meson dist
# This will build a .tar.xz file and create a corresponding .tar.xz.sha256sum file for it.
#
# STEP 5 (OPTIONAL): Build code documentation
# -------------------------------------------
# To build Doxygen-generated HTML code documentation (from the comments in the source files) to the mbuild/doc
# directory, use:
# meson compile doc
# Then open the file mbuild/doc/html/index.html in a web browser.
#
# NOTE that as, at 2023-08-05, there are quite a lot of things that Doxygen is unable to parse in the code, which means
# the generated documentation, whilst extensive, is missing quite a few classes (even though they have Doxygen
# comments). It would be good to fix this, but I fear it is not trivial... :-/
#
# STEP 6 (OPTIONAL): Build distributable packages
# -----------------------------------------------
# To build binary packages:
# ../bt package ⭐⭐⭐ This is the bit that is not yet working on all platforms ⭐⭐⭐
#
#
# Finally, note that if you want to add new build targets or change the names of existing targets, you have to run the
# following command from the same directory as this file:
# meson --reconfigure mbuild
# See https://stackoverflow.com/questions/63329923/how-to-make-meson-scan-for-new-target for more on this.
# Alternatively, you can run 'bt setup' again.
#
#-----------------------------------------------------------------------------------------------------------------------
#=======================================================================================================================
#================================================== Project Settings ===================================================
#=======================================================================================================================
#
# We'll get an error if 'project' isn't the first call in this file
#
# Note that we need:
# - Meson 0.56.0 or newer to use Meson's 'substring' call.
# - Meson 0.59.0 or newer to use qt.compile_resources, qt.compile_ui and qt.compile_moc
# - Meson 0.60.0 or newer to use + to append items to lists (aka 'list.<plus>' feature -- at least that's what the
# warning message says if you've specified a lower minimum version of Meson)
# - Meson 0.62.0 or newer for dep 'dl' custom lookup, but current version of Meson on Ubuntu 22.04 LTS is only 0.61.2
# - Meson 0.63.0 or newer to correctly locate versions of Qt >= 6.1 -- see https://mesonbuild.com/Qt6-module.html
#
# NB: Per https://mesonbuild.com/Reference-manual_functions.html#project the default_options settings "are only used
# when running Meson for the first time"! So if you change any of the default_options settings you *MUST* delete
# the entire build directory and run
# meson setup <build dir name>
# again to recreate the build directory and all its contained config. Eg, if you are in the mbuild directory, you
# need to run:
# cd ..
# rm -r mbuild
# meson setup mbuild
# cd mbuild
# meson compile
# Otherwise, as explained at
# https://mesonbuild.com/FAQ.html#why-are-changes-to-default-project-options-ignored, your changes WILL HAVE NO
# EFFECT. TLDR this is because you can change all the settings via the command line and it would be hard to keep
# track of where a setting had last been modified, so the default_options are only ever read once.
# See also https://github.com/mesonbuild/meson/issues/2193 for further discussion about this.
#
# Default options (mostly ultimately controlling compiler settings):
#
# - cpp_std We need C++23 for std::ranges::zip_view, C++20 for std::map::contains(), C++17 or later for nested
# namespaces and structured bindings, and C++11 or later for lambdas.
#
# - warning_level 3 is the highest level ie warns about the most things. For gcc it translates to
# -Wall -Winvalid-pch -Wextra -Wpedantic
# (Prior to Meson 1.0.0, it also included -Wnon-virtual-dtor, but this was removed because "GCC devs
# think it's a bad idea to force projects to use it [and] it belongs in -Weffc++ rather than being
# lumped in with -Wall.)
#
# - prefer_static We want to try static linking before shared linking because it makes packaging a lot easier on
# Windows and Mac. NB: This requires meson 0.63.0 or newer. Current version of meson in Ubuntu
# 22.04 repositories is 0.61.2. For the moment, we do static setting on a library-by-library basis
# (by setting 'static : true' on all the dependency() calls.
#
# - buildtype For the moment at least, I'm not making a distinction between debug and release builds. Unless we
# find some compelling performance etc reason to do otherwise, my instinct is to have as much diagnostic
# information in the build in "release" as we would in "development/debug", on the grounds that it can
# only help if an end user hits a core-dumping bug.
# Meson encourages you to use either the buildtype option or the debug and optimization options
# rather than setting compiler options directly. However, this does not give us as much control as we
# would like over compiler flags. Eg switching 'debug' to 'true' turns on the '-g' flag (equivalent to
# '-g2') on GCC, but there isn't a way via the meson options to set '-g3' for GCC. So, we set
# 'buildtype=plain' and manage compiler flags directly.
#
#
project('brewtarget', 'cpp',
version: '4.0.10',
license: 'GPL-3.0-or-later',
meson_version: '>=0.63.0',
default_options : ['cpp_std=c++23',
'warning_level=3',
# 'prefer_static=true', See comment above for why this is commented-out for now
'buildtype=plain'])
#
# Although Meson itself is written in Python, Meson build files uses a slightly different syntax and have less
# functionality than Python. See
# https://mesonbuild.com/FAQ.html#why-is-meson-not-just-a-python-module-so-i-could-code-my-build-setup-in-python and
# links therefrom for the rationale for avoiding being a full programming language.
#
# Besides some (sometimes annoying) variations in syntax, this also means that you sometimes have to do things in a
# slightly more cumbersome way than you would in a Python script. Eg here, in regular Python, we would write:
# capitalisedProjectName = projectName.capitalize()
# But meson.project_name() returns a Meson String, not a Python String, so there's a bit more work to do to get the same
# result.
#
projectName = meson.project_name().to_lower()
capitalisedProjectName = projectName.substring(0, 1).to_upper() + projectName.substring(1)
#
# Meson writes out a lot of useful info straight away, eg:
#
# The Meson build system
# Version: 1.0.1
# Source dir: /home/runner/work/brewtarget/brewtarget
# Build dir: /home/runner/work/brewtarget/brewtarget/mbuild
# Build type: native build
# Project name: brewtarget
# Project version: 3.0.7
# C++ compiler for the host machine: c++ (gcc 9.4.0 "c++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0")
# C++ linker for the host machine: c++ ld.bfd 2.34
# Host machine cpu family: x86_64
# Host machine cpu: x86_64
#
# You can get this info inside the script too:
#
# Version: = meson.version()
# Source dir: = meson.project_source_root()
# Build dir: = meson.project_build_root()
# Build type: ≈ meson.can_run_host_binaries()
# Project name: = meson.project_name()
# Project version: = meson.project_version()
# C++ compiler for the host machine: = compiler.get_id() and related commands
# C++ linker for the host machine: = compiler.get_linker_id() and related commands
# Host machine cpu family: = build_machine.cpu_family()
# Host machine cpu: = build_machine.cpu()
#
message('⭐ Building', projectName, 'version', meson.project_version(), 'for', host_machine.system(),
'on', build_machine.system(), '⭐')
compiler = meson.get_compiler('cpp')
#
# We need two versions of the main executable name because they are different on Windows:
#
# mainExecutableTargetName = "target" name _without_ the '.exe' suffix, which we pass to the executable() command.
# On Windows, Meson will always add its own '.exe' suffix and we don't want to end up
# with '.exe.exe' as the suffix!
#
# mainExecutableTargetName = The actual name of the file, including the '.exe' suffix. We export this as
# CONFIG_EXECUTABLE_NAME for anywhere else that needs it (currently only the NSIS
# packaging scripts on Windows)
#
# (We could also obtain mainExecutableTargetName via the full_path() method on the return object from the executable()
# command, but we'd have to strip off the path.)
#
# The default (on Windows and Linux) is to use Unix-style executable names, ie all lower case
#
mainExecutableTargetName = projectName
if host_machine.system() == 'darwin'
# On Mac we don't need a suffix but have always capitalised the executable name because "Don't question the APPLE".
mainExecutableTargetName = capitalisedProjectName
endif
if host_machine.system() == 'windows'
mainExecutableFileName = mainExecutableTargetName + '.exe'
else
mainExecutableFileName = mainExecutableTargetName
endif
testRunnerTargetName = mainExecutableTargetName + '_tests'
#=======================================================================================================================
#==================================================== Meson modules ====================================================
#=======================================================================================================================
# Import the Qt tools. See https://mesonbuild.com/Qt6-module.html
qt = import('qt6')
# File System module - see https://mesonbuild.com/Fs-module.html
fs = import('fs')
#=======================================================================================================================
#==================================================== Build options ====================================================
#=======================================================================================================================
prefix = get_option('prefix')
#=======================================================================================================================
#============================================== Frameworks and Libraries ===============================================
#=======================================================================================================================
#
# It would be neat within the build system to automate the _installation_ and upgrade of libraries and frameworks on
# which we depend. However, I have yet to find a universal pain-free solution.
#
# Meson has its own dependency management system, Wrap, but the list of pre-provided projects at
# https://mesonbuild.com/Wrapdb-projects.html does not include Qt, Boost, Xerces, Xalan or Valijson.
#
# You can bridge out to other systems such as Conan or vcpkg, but it's a bit clunky.
#
# So, for now at least, we manage dependency installation in the `bt` Python script.
#
# Although we request static libraries in a lot of places, we don't always get them, so we assume we need to deal with
# shared libraries (aka DLLs on Windows).
#
# Aside from ensuring all dependencies are present on the build machine, we also have to worry about run-time
# dependencies for packaging. In particular, on Windows and Mac, because there is not built-in default package manager,
# we typically need to include in our package all the non-system shared libraries on which it depends. For the Qt
# libraries, there are handy tools `windeployqt` and `macdeployqt` that do most of the necessary work. However, these
# tools do not (reliably) detect other shared libraries on which we depend. The paths of these shared libraries should
# be knowable during compilation (or more specifically linking). We want to get the paths during the build so that we
# can export them for use in the packaging step (which is done outside of Meson by the "build tool" bt Python script.
#
# Finding out how to get shared library paths information was, err, fun because it's not very well documented.
# Eventually, I realised that you can look in meson-private/cmake_XercesC/cmake_trace.txt,
# meson-private/cmake_XalanC/cmake_trace.txt and so on to see what information Meson got back from CMake and thus know
# which CMake variables are exposed via the get_variable() call.
#
sharedLibraryPaths = []
#========================================================= Qt ==========================================================
# We need not just the "core" bit of Qt but various "optional" elements.
#
# We try to keep the minimum Qt version we need as low as we can.
#
# Note that if you change the minimum Qt version, you need to make corresponding changes to the .github/workflows/*.yml
# files so that GitHub uses the appropriate version of Qt for the automated builds.
#
# As of 2024-09-30:
# - Qt 6.2.4 is the maximum available in Ubuntu 22.04 (Jammy).
# - Qt 6.4.2 is the maximum available in Ubuntu 24.04 (Noble).
#
minVersionOfQt = '>=6.2.4'
# Tell meson which Qt modules we need
qtCommonDependencies = dependency('qt6',
version : minVersionOfQt,
modules : ['Core',
'Gui', # Needed for QColor on Mac?
'Multimedia',
'Network',
'PrintSupport',
'Sql',
'Svg', # Needed to make the deploy scripts pick up the svg plugins
'Widgets',
'Xml'], # TBD: Not sure we need this any more
include_type : 'system',
static : true)
# The Qt Gui module is only needed for the main program. (We don't want the tests to try to load it or it could barf
# in a GitHub action that does not have a display running.)
qtMainExeDependencies = dependency('qt6', version : minVersionOfQt, modules: ['Gui'])
# The Qt Test module is only needed for the unit tests
qtTestRunnerDependencies = dependency('qt6', version : minVersionOfQt, modules: ['Test'])
#===================================================== Find Boost ======================================================
# Boost is a collection of separate libraries, some, but not all, of which are header-only. We only specify the Boost
# libraries that we actually use.
#
# On Linux, there are cases where we need a more recent version of a Boost library than is readily-available in system-
# supplied packages. I haven't found a slick way to solve this in CMake, though https://github.com/Orphis/boost-cmake
# looks promising. (For header-only Boost libraries, you might think it would be relatively painless to pull them in
# from where they are hosted on GitHub (see https://github.com/boostorg), but this is not the case. AFAICT you can't
# easily pull a specific release, and just pulling master doesn't guarantee that everything compiles.) So, anyway, on
# Debian-based distros of Linux, such as Ubuntu, you need to do the following to install Boost 1.79 in place of whatever
# (if anything) is already installed:
#
# $ sudo apt remove boost-all-dev
# $ cd ~
# $ mkdir boost-tmp
# $ cd boost-tmp
# $ wget https://boostorg.jfrog.io/artifactory/main/release/1.79.0/source/boost_1_79_0.tar.bz2
# $ tar --bzip2 -xf boost_1_79_0.tar.bz2
# $ cd boost_1_79_0
# $ ./bootstrap.sh --prefix=/usr
# $ sudo ./b2 install
# $ cd ../..
# $ sudo rm -rf boost-tmp
#
# (Obviously if you want to make the necessary change to install an even more recent version than Boost 1.79 then that
# should be fine.)
#
# We do the same in .github/workflows/linux-ubuntu.yml to make GitHub automated builds work.
#
# Note that this means we want to _statically_ link Boost rather than force end users to have to do all the palava above
#
# ************************
# *** Boost Stacktrace ***
# ************************
#
# We use this for diagnostics. In certain error cases it's very helpful to be able to log the call stack.
#
# On Windows, using MSYS2, the mingw-w64-boost packages do not include libboost_stacktrace_backtrace, but
# https://www.boost.org/doc/libs/1_76_0/doc/html/stacktrace/configuration_and_build.html suggests it is not required
# (because on Windows, if you have libbacktrace installed, you can set BOOST_STACKTRACE_USE_BACKTRACE in header-only
# mode).
#
# .:TODO:. Not sure how to get libboost_stacktrace_backtrace installed on Mac. It doesn't seem to be findable by
# CMake after installing Boost via Homebrew (https://brew.sh/). For the moment, skip trying to use
# libboost_stacktrace_backtrace on Mac
#
# .:TODO:. So far don't have stacktraces working properly on Windows (everything shows as register_frame_ctor), so
# that needs some more investigation. (It could be that it's a bug in Boost, at least according to
# https://stackoverflow.com/questions/54333608/boost-stacktrace-not-demangling-names-when-cross-compiled)
#
# ******************
# *** Boost JSON ***
# ******************
#
# Boost JSON is an (optionally) header-only library that was introduced in Boost 1.75 in December 2020. One of the
# features we use, JSON pointers (the equivalent of XML's XPaths) was only introduced in Boost 1.79. As of March
# 2022, Ubunutu 20.04 LTS only has packages for Boost 1.71 from August 2019, hence the need to manually install a
# newer Boost.
#
# ******************
# *** Boost.Core ***
# ******************
#
# Boost.Core, part of collection of the Boost C++ Libraries, is a collection of core utilities used by other Boost
# libraries. Boost JSON needs a more recent version than 1.71.
#
# For Boost, per https://mesonbuild.com/Dependencies.html#boost, we only need to supply module names for libraries we
# need to link against. For the header-only Boost libraries, the 'boost' dependency suffices.
boostModules = []
if host_machine.system() == 'linux'
boostModules += 'stacktrace_backtrace'
add_global_arguments('-DBOOST_STACKTRACE_LINK', language : 'cpp')
add_global_arguments('-DBOOST_STACKTRACE_USE_BACKTRACE', language : 'cpp')
endif
boostDependency = dependency('boost',
version : '>=1.79.0',
modules : boostModules,
static : true)
message('Boost:', boostDependency.name(), 'found =', boostDependency.found(), 'version =', boostDependency.version())
#
# Extra requirements for Boost Stacktrace
#
# Per https://www.boost.org/doc/libs/1_76_0/doc/html/stacktrace/configuration_and_build.html, by default
# Boost.Stacktrace is a header-only library. However, you get better results by linking (either statically or
# dynamically) with a helper library. Of the various options, it seems like boost_stacktrace_backtrace gives the most
# functionality over the most platforms. This has dependencies on:
# - libdl on POSIX platforms -- but see note below
# - libbacktrace
# The latter is a widely-used cross-platform open source library available at
# https://github.com/ianlancetaylor/libbacktrace. On some POSIX plaforms it's already either installed on the system
# (eg see https://man7.org/linux/man-pages/man3/backtrace.3.html) or available as an optional component of the GCC
# compiler. However, it seems this is something that can change over time. It's a small and stable library, so we
# just build it from sources -- which is done in the `bt` script when you run `bt setup all`.
#
# Just to make things extra fun, in 2021, the GNU compilers did away with libdl and incorporated its functionality into
# libc, per section 2.3 of release info at https://sourceware.org/glibc/wiki/Release/2.34. This means, if we're using
# the GNU tool chain and libc is v2.34 or newer, then we should NOT look for libdl, as we won't find it! To find the
# version of libc, you execute 'ldd --version', which gives multi-line output, of which the first line will be something
# such as:
# ldd (Ubuntu GLIBC 2.35-0ubuntu3.1) 2.35
# In this case, that means libc is version 2.35
#
# If we _don't_ need libdl, we just create an "unrequired" dependency. This saves having to repeat a bunch of logic
# later on when we get to the main build.
#
# On newer versions of Meson (>= 0.62.0), the dependency() command has special-case code for dealing with libdl being
# built into the compiler. This means if we write:
#
# dlDependency = dependency('dl', required : needLibdl, static : true)
#
# then, on Mac for instance, dlDependency.found() can be true without there being any cmake variable such as
# PACKAGE_LIBRARIES (because the library was found by Meson special case code, not by cmake).
#
# The good news is that, on Mac and Linux, there's a more elegant way of handling the dl dependency, which relies on the
# fact that opening a shared library is a POSIX operation with calls declared in a POSIX-defined header (see eg
# https://man7.org/linux/man-pages/man0/dlfcn.h.0p.html). We just ask the compiler whether it has dlopen() built-in,
# and, if not, please can it tell us where to find it!
#
# (On Windows, we don't need the dl dependency because Windows doesn't have the POSIX interface for shared library
# opening, and Boost Stacktrace doesn't seem to need anything in its place.)
#
dlDependency = declare_dependency()
if host_machine.system() != 'windows'
if not compiler.has_function('dlopen', prefix: '#include <dlfcn.h>')
dlDependency = compiler.find_library('dl', has_headers: 'dlfcn.h')
endif
endif
# Note that, unlike, say, the parameters to include_directories(), the dirs argument to find_library() must be absolute
# paths
libbacktraceDir = join_paths(meson.project_source_root(), 'third-party/libbacktrace/.libs')
backtraceDependency = compiler.find_library('backtrace',
required : true,
static : true,
dirs : [libbacktraceDir])
#======================================== Find the other libraries we depend on ========================================
#
# See https://mesonbuild.com/Reference-manual_returned_dep.html for what info we can pull from a dependency object
#
# For BeerXML processing we need Xerces-C++ and Xalan-C++. Meson can find both of these automatically in a couple of
# different ways. The official way is to use `dependency('xerces-c')` and `dependency('xalan-c')`. However, I don't
# think this gives us access to the paths of the libraries (which we want to export for the packaging scripts -- see
# various comments about shared libraries in the `bt` build tool script). Instead, we can have Meson use CMake's
# find_package(), as long as (a) CMake is installed(!) and (b) we provide the right library names ('XercesC' per
# https://cmake.org/cmake/help/latest/module/FindXercesC.html and 'XalanC' per
# https://cmake.org/cmake/help/latest/module/FindXalanC.html)
#
xercesDependency = dependency('XercesC',
version : '>=3.2.2',
required : true,
static : true)
xercesLibPaths = xercesDependency.get_variable(cmake : 'PACKAGE_LIBRARIES')
message('Xerces Library:', xercesDependency.name(), 'found =', xercesDependency.found(),
'version =', xercesDependency.version(), 'path(s)=', xercesLibPaths)
sharedLibraryPaths += xercesLibPaths
xalanDependency = dependency('XalanC',
version : '>=1.11.0',
required : true,
static : true)
xalanLibPaths = xalanDependency.get_variable(cmake : 'PACKAGE_LIBRARIES')
message('Xalan Library:', xalanDependency.name(), 'found =', xalanDependency.found(),
'version =', xalanDependency.version(), 'path(s)=', xalanLibPaths)
sharedLibraryPaths += xalanLibPaths
#======================================================= OpenSSL =======================================================
# This is needed for us to use https with Boost.Asio
#
# As of 2024-10-29, 3.0.2 is the most recent version of OpenSSL available on Ubuntu 22.04, so that's the minimum we
# specify here.
#
openSslDependency = dependency('OpenSSL',
version : '>=3.0.2',
required : true,
static : true)
#openSslLibPaths = openSslDependency.get_variable(cmake : 'PACKAGE_LIBRARIES')
message('OpenSSL Library:', openSslDependency.name(), 'found =', openSslDependency.found(),
'version =', openSslDependency.version())
#sharedLibraryPaths += openSslLibPaths
#====================================================== Valijson =======================================================
# Don't need to do anything special, other than set include directories below, as it's header-only and we pull it in as
# a Git submodule.
#==================================================== Other headers ====================================================
# Other directories to search in for headers. Meson will barf an error if any of these directories does not exist.
includeDirs = include_directories('src', 'third-party/valijson/include', 'third-party/libbacktrace')
#=======================================================================================================================
#============================================= Extra Windows dependencies ==============================================
#=======================================================================================================================
# .:TBD:. Don't think we need this bit any more
if host_machine.system() == 'windows'
#
# We can't assume that the person running the code will have MSYS2/MinGW installed, so we need to include the DLLs
# that ship with them and get pulled in by the packaging process. There is a bit of trial-and-error in compiling
# this list, but, mostly, if you miss a needed DLL from the package, Windows will give you an error message at
# start-up telling you which DLL(s) it needed but could not find.
#
foreach extraLib : ['gcc',
'winpthread',
'stdc++',
'xalanMsg']
extraLibDependency = compiler.find_library(extraLib, required : true)
if extraLibDependency.found()
# extraLibPath = extraLibDependency.get_variable(cmake : 'LIB_ARCH_LIST')
# message(extraLib, ' found at', extraLibPath)
# sharedLibraryPaths += extraLibPath
else
# message(extraLib, ' not found')
endif
endforeach
endif
#=======================================================================================================================
#============================================== Extra Apple dependencies ===============================================
#=======================================================================================================================
if host_machine.system() == 'darwin'
# Statically linking Xalan, Xerces etc requires CFStringLowercase, CFStringUppercase, etc on Mac
corefoundationDependency = dependency(
'appleframeworks',
modules: ['CoreFoundation'],
required: false,
)
endif
#=======================================================================================================================
#===================================================== Input Files =====================================================
#=======================================================================================================================
# Sub-directories of the one containing this (meson.build) file are
# src = C++ source code
# ui = QML UI layout files
# data = Binary files, including sounds and default database
# translations = Translated texts
# mac = Mac-specific files (desktop icon)
# win = Windows-specific files (desktop icon)
# packaging = Packaging-related config
#=======================================================================================================================
#
# List of the C++ source files that are common to the app and the unit tests - ie all .cpp files _except_ main.cpp and
# test.cpp
#
# See https://mesonbuild.com/FAQ.html#why-cant-i-specify-target-files-with-a-wildcard for why it is strongly recommended
# not to use wildcard specification. (This is common to many build systems.)
#
# You can recreate the body of this list by running the following from the bash prompt in the mbuild directory:
# find ../src -name '*.cpp' | grep -v 'src/unitTests/' | grep -v '/main.cpp$' | sed "s+^../+ \'+; s+$+\',+" | LC_ALL=C sort
#
# (See https://stackoverflow.com/questions/68319427/bash-sort-command-do-not-treat-dots for why LC_ALL=C is needed!)
#
# The files() wrapper around the array ensures that all the files exist and means you don't have to worry as much about
# subdirectories as you might otherwise -- see https://mesonbuild.com/Reference-manual_functions.html#files
#
commonSourceFiles = files([
'src/AboutDialog.cpp',
'src/AlcoholTool.cpp',
'src/Algorithms.cpp',
'src/AncestorDialog.cpp',
'src/Application.cpp',
'src/BeerColorWidget.cpp',
'src/BrewDayFormatter.cpp',
'src/BrewDayScrollWidget.cpp',
'src/BrewNoteWidget.cpp',
'src/BtColor.cpp',
'src/BtDatePopup.cpp',
'src/BtFieldType.cpp',
'src/BtHorizontalTabs.cpp',
'src/BtSplashScreen.cpp',
'src/BtTabWidget.cpp',
'src/BtTextEdit.cpp',
'src/ConverterTool.cpp',
'src/HeatCalculations.cpp',
'src/HelpDialog.cpp',
'src/Html.cpp',
'src/HydrometerTool.cpp',
'src/IbuGuSlider.cpp',
'src/InventoryFormatter.cpp',
'src/LatestReleaseFinder.cpp',
'src/Localization.cpp',
'src/Logging.cpp',
'src/MainWindow.cpp',
'src/MashDesigner.cpp',
'src/MashWizard.cpp',
'src/NamedEntitySortProxyModel.cpp',
'src/OgAdjuster.cpp',
'src/OptionDialog.cpp',
'src/PersistentSettings.cpp',
'src/PitchDialog.cpp',
'src/PrimingDialog.cpp',
'src/PrintAndPreviewDialog.cpp',
'src/RadarChart.cpp',
'src/RangedSlider.cpp',
'src/RecipeExtrasWidget.cpp',
'src/RecipeFormatter.cpp',
'src/RefractoDialog.cpp',
'src/ScaleRecipeTool.cpp',
'src/StrikeWaterDialog.cpp',
'src/StyleRangeWidget.cpp',
'src/TimerListDialog.cpp',
'src/TimerMainDialog.cpp',
'src/TimerWidget.cpp',
'src/WaterDialog.cpp',
'src/boiltime.cpp',
'src/buttons/BoilButton.cpp',
'src/buttons/EquipmentButton.cpp',
'src/buttons/FermentationButton.cpp',
'src/buttons/MashButton.cpp',
'src/buttons/RecipeAttributeButton.cpp',
'src/buttons/StyleButton.cpp',
'src/buttons/WaterButton.cpp',
'src/catalogs/EquipmentCatalog.cpp',
'src/catalogs/FermentableCatalog.cpp',
'src/catalogs/HopCatalog.cpp',
'src/catalogs/MiscCatalog.cpp',
'src/catalogs/StyleCatalog.cpp',
'src/catalogs/YeastCatalog.cpp',
'src/database/BtSqlQuery.cpp',
'src/database/Database.cpp',
'src/database/DatabaseSchemaHelper.cpp',
'src/database/DbTransaction.cpp',
'src/database/DefaultContentLoader.cpp',
'src/database/ObjectStore.cpp',
'src/database/ObjectStoreTyped.cpp',
'src/editors/BoilEditor.cpp',
'src/editors/BoilStepEditor.cpp',
'src/editors/EquipmentEditor.cpp',
'src/editors/FermentableEditor.cpp',
'src/editors/FermentationEditor.cpp',
'src/editors/FermentationStepEditor.cpp',
'src/editors/HopEditor.cpp',
'src/editors/MashEditor.cpp',
'src/editors/MashStepEditor.cpp',
'src/editors/MiscEditor.cpp',
'src/editors/NamedMashEditor.cpp',
'src/editors/StyleEditor.cpp',
'src/editors/WaterEditor.cpp',
'src/editors/YeastEditor.cpp',
'src/listModels/EquipmentListModel.cpp',
'src/listModels/FermentableListModel.cpp',
'src/listModels/HopListModel.cpp',
'src/listModels/MashListModel.cpp',
'src/listModels/MashStepListModel.cpp',
'src/listModels/MiscListModel.cpp',
'src/listModels/RecipeAdditionFermentableListModel.cpp',
'src/listModels/RecipeAdditionHopListModel.cpp',
'src/listModels/RecipeAdditionMiscListModel.cpp',
'src/listModels/RecipeAdditionYeastListModel.cpp',
'src/listModels/RecipeAdjustmentSaltListModel.cpp',
'src/listModels/SaltListModel.cpp',
'src/listModels/StyleListModel.cpp',
'src/listModels/WaterListModel.cpp',
'src/listModels/YeastListModel.cpp',
'src/measurement/Amount.cpp',
'src/measurement/ColorMethods.cpp',
'src/measurement/IbuMethods.cpp',
'src/measurement/Measurement.cpp',
'src/measurement/PhysicalQuantity.cpp',
'src/measurement/SucroseConversion.cpp',
'src/measurement/SystemOfMeasurement.cpp',
'src/measurement/Unit.cpp',
'src/measurement/UnitSystem.cpp',
'src/model/Boil.cpp',
'src/model/BoilStep.cpp',
'src/model/BrewNote.cpp',
'src/model/Equipment.cpp',
'src/model/Fermentable.cpp',
'src/model/Fermentation.cpp',
'src/model/FermentationStep.cpp',
'src/model/Folder.cpp',
'src/model/Hop.cpp',
'src/model/Ingredient.cpp',
'src/model/IngredientInRecipe.cpp',
'src/model/Instruction.cpp',
'src/model/Inventory.cpp', # NB: No model/InventoryFermentable.cpp, model/InventoryHop.cpp
'src/model/Mash.cpp',
'src/model/MashStep.cpp',
'src/model/Misc.cpp',
'src/model/NamedEntity.cpp',
'src/model/NamedParameterBundle.cpp',
'src/model/OutlineableNamedEntity.cpp',
'src/model/OwnedByRecipe.cpp',
'src/model/Recipe.cpp',
'src/model/RecipeAddition.cpp',
'src/model/RecipeAdditionFermentable.cpp',
'src/model/RecipeAdditionHop.cpp',
'src/model/RecipeAdditionMisc.cpp',
'src/model/RecipeAdditionYeast.cpp',
'src/model/RecipeAdjustmentSalt.cpp',
'src/model/RecipeUseOfWater.cpp',
'src/model/Salt.cpp',
'src/model/Step.cpp',
'src/model/StepExtended.cpp',
'src/model/Style.cpp',
'src/model/Water.cpp',
'src/model/Yeast.cpp',
'src/serialization/ImportExport.cpp',
'src/serialization/SerializationRecord.cpp',
'src/serialization/json/BeerJson.cpp',
'src/serialization/json/JsonCoding.cpp',
'src/serialization/json/JsonMeasureableUnitsMapping.cpp',
'src/serialization/json/JsonRecord.cpp',
'src/serialization/json/JsonRecordDefinition.cpp',
'src/serialization/json/JsonSchema.cpp',
'src/serialization/json/JsonUtils.cpp',
'src/serialization/json/JsonXPath.cpp',
'src/serialization/xml/BeerXml.cpp',
'src/serialization/xml/BtDomErrorHandler.cpp',
'src/serialization/xml/XercesHelpers.cpp',
'src/serialization/xml/XmlCoding.cpp',
'src/serialization/xml/XmlMashRecord.cpp',
'src/serialization/xml/XmlMashStepRecord.cpp',
'src/serialization/xml/XmlRecipeRecord.cpp',
'src/serialization/xml/XmlRecord.cpp',
'src/serialization/xml/XmlRecordDefinition.cpp',
'src/sortFilterProxyModels/EquipmentSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/FermentableSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/HopSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/MiscSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/RecipeAdditionFermentableSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/RecipeAdditionHopSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/RecipeAdditionMiscSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/RecipeAdditionYeastSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/StyleSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/WaterSortFilterProxyModel.cpp',
'src/sortFilterProxyModels/YeastSortFilterProxyModel.cpp',
'src/tableModels/BoilStepTableModel.cpp',
'src/tableModels/BtTableModel.cpp',
'src/tableModels/EquipmentTableModel.cpp',
'src/tableModels/FermentableTableModel.cpp',
'src/tableModels/FermentationStepTableModel.cpp',
'src/tableModels/HopTableModel.cpp',
'src/tableModels/MashStepTableModel.cpp',
'src/tableModels/MiscTableModel.cpp',
'src/tableModels/RecipeAdditionFermentableTableModel.cpp',
'src/tableModels/RecipeAdditionHopTableModel.cpp',
'src/tableModels/RecipeAdditionMiscTableModel.cpp',
'src/tableModels/RecipeAdditionYeastTableModel.cpp',
'src/tableModels/RecipeAdjustmentSaltTableModel.cpp',
'src/tableModels/SaltTableModel.cpp',
'src/tableModels/StyleTableModel.cpp',
'src/tableModels/WaterTableModel.cpp',
'src/tableModels/YeastTableModel.cpp',
'src/trees/TreeFilterProxyModel.cpp',
'src/trees/TreeModel.cpp',
'src/trees/TreeNode.cpp',
'src/trees/TreeView.cpp',
'src/undoRedo/SimpleUndoableUpdate.cpp',
'src/utils/BtException.cpp',
'src/utils/BtStringConst.cpp',
'src/utils/BtStringStream.cpp',
'src/utils/EnumStringMapping.cpp',
'src/utils/FileSystemHelpers.cpp',
'src/utils/Fonts.cpp',
'src/utils/FuzzyCompare.cpp',
'src/utils/ImportRecordCount.cpp',
'src/utils/MetaTypes.cpp',
'src/utils/OStreamWriterForQFile.cpp',
'src/utils/OptionalHelpers.cpp',
'src/utils/PropertyPath.cpp',
'src/utils/TimerUtils.cpp',
'src/utils/TypeLookup.cpp',
'src/widgets/Animator.cpp',
'src/widgets/BtBoolComboBox.cpp',
'src/widgets/BtComboBox.cpp',
'src/widgets/BtOptionalDateEdit.cpp',
'src/widgets/CustomComboBox.cpp',
'src/widgets/InfoButton.cpp',
'src/widgets/InfoText.cpp',
'src/widgets/MashComboBox.cpp',
'src/widgets/SelectionControl.cpp',
'src/widgets/SmartAmountSettings.cpp',
'src/widgets/SmartAmounts.cpp',
'src/widgets/SmartDigitWidget.cpp',
'src/widgets/SmartField.cpp',
'src/widgets/SmartLabel.cpp',
'src/widgets/SmartLineEdit.cpp',
'src/widgets/ToggleSwitch.cpp',
'src/widgets/UnitAndScalePopUpMenu.cpp',
])
applicationMainSourceFile = files([
'src/main.cpp'
])
unitTestMainSourceFile = files([
'src/unitTests/Testing.cpp'
])
#
# These are the headers that need to be processed by the Qt Meta Object Compiler (MOC). Note that this is _not_ all the
# headers in the project. Also, note that there is a separate (trivial) list of MOC headers for the unit test runner.
#
# You can recreate the body of this list by running the following from the bash prompt in the mbuild directory:
# grep -rl '^ *Q_OBJECT' ../src | grep -v Testing.h | LC_ALL=C sort | sed "s+^../src/+ \'src/+; s/$/\',/"
#
# (See https://stackoverflow.com/questions/68319427/bash-sort-command-do-not-treat-dots for why LC_ALL=C is needed!)
#
mocHeaders = files([
'src/AboutDialog.h',
'src/AlcoholTool.h',
'src/AncestorDialog.h',
'src/BeerColorWidget.h',
'src/BrewDayFormatter.h',
'src/BrewDayScrollWidget.h',
'src/BrewNoteWidget.h',
'src/BtDatePopup.h',
'src/BtSplashScreen.h',
'src/BtTabWidget.h',
'src/BtTextEdit.h',
'src/ConverterTool.h',
'src/HelpDialog.h',
'src/HydrometerTool.h',
'src/IbuGuSlider.h',
'src/LatestReleaseFinder.h',
'src/MainWindow.h',
'src/MashDesigner.h',
'src/MashWizard.h',
'src/NamedEntitySortProxyModel.h',
'src/OgAdjuster.h',
'src/OptionDialog.h',
'src/PitchDialog.h',
'src/PrimingDialog.h',
'src/PrintAndPreviewDialog.h',
'src/RangedSlider.h',
'src/RecipeExtrasWidget.h',
'src/RecipeFormatter.h',
'src/RefractoDialog.h',
'src/ScaleRecipeTool.h',
'src/StrikeWaterDialog.h',
'src/StyleRangeWidget.h',
'src/TimerListDialog.h',
'src/TimerMainDialog.h',
'src/TimerWidget.h',
'src/WaterDialog.h',
'src/boiltime.h',
'src/buttons/BoilButton.h',
'src/buttons/EquipmentButton.h',
'src/buttons/FermentationButton.h',
'src/buttons/MashButton.h',
'src/buttons/RecipeAttributeButton.h',
'src/buttons/StyleButton.h',
'src/buttons/WaterButton.h',
'src/catalogs/EquipmentCatalog.h',
'src/catalogs/FermentableCatalog.h',
'src/catalogs/HopCatalog.h',
'src/catalogs/MiscCatalog.h',
'src/catalogs/StyleCatalog.h',
'src/catalogs/YeastCatalog.h',
'src/database/ObjectStore.h',
'src/editors/BoilEditor.h',
'src/editors/BoilStepEditor.h',
'src/editors/EquipmentEditor.h',
'src/editors/FermentableEditor.h',
'src/editors/FermentationEditor.h',
'src/editors/FermentationStepEditor.h',
'src/editors/HopEditor.h',
'src/editors/MashEditor.h',
'src/editors/MashStepEditor.h',
'src/editors/MiscEditor.h',
'src/editors/NamedMashEditor.h',
'src/editors/StyleEditor.h',
'src/editors/WaterEditor.h',
'src/editors/YeastEditor.h',
'src/listModels/EquipmentListModel.h',
'src/listModels/FermentableListModel.h',
'src/listModels/HopListModel.h',
'src/listModels/MashListModel.h',
'src/listModels/MashStepListModel.h',
'src/listModels/MiscListModel.h',
'src/listModels/RecipeAdditionFermentableListModel.h',
'src/listModels/RecipeAdditionHopListModel.h',
'src/listModels/RecipeAdditionMiscListModel.h',
'src/listModels/RecipeAdditionYeastListModel.h',
'src/listModels/RecipeAdjustmentSaltListModel.h',
'src/listModels/SaltListModel.h',
'src/listModels/StyleListModel.h',
'src/listModels/WaterListModel.h',
'src/listModels/YeastListModel.h',
'src/model/Boil.h',
'src/model/BoilStep.h',
'src/model/BrewNote.h',
'src/model/Equipment.h',
'src/model/Fermentable.h',
'src/model/Fermentation.h',
'src/model/FermentationStep.h',
'src/model/Folder.h',
'src/model/Hop.h',
'src/model/Ingredient.h',
'src/model/IngredientInRecipe.h',
'src/model/Instruction.h',
'src/model/Inventory.h',
'src/model/InventoryFermentable.h', # NB: Function definitions in model/Inventory.cpp
'src/model/InventoryHop.h', # NB: Function definitions in model/Inventory.cpp
'src/model/InventoryMisc.h', # NB: Function definitions in model/Inventory.cpp
'src/model/InventorySalt.h', # NB: Function definitions in model/Inventory.cpp
'src/model/InventoryYeast.h', # NB: Function definitions in model/Inventory.cpp
'src/model/Mash.h',
'src/model/MashStep.h',
'src/model/Misc.h',
'src/model/NamedEntity.h',
'src/model/OutlineableNamedEntity.h',
'src/model/OwnedByRecipe.h',
'src/model/Recipe.h',
'src/model/RecipeAddition.h',
'src/model/RecipeAdditionFermentable.h',
'src/model/RecipeAdditionHop.h',
'src/model/RecipeAdditionMisc.h',
'src/model/RecipeAdditionYeast.h',
'src/model/RecipeAdjustmentSalt.h',
'src/model/RecipeUseOfWater.h',
'src/model/Salt.h',
'src/model/Step.h',
'src/model/StepExtended.h',
'src/model/Style.h',
'src/model/Water.h',
'src/model/Yeast.h',
'src/sortFilterProxyModels/EquipmentSortFilterProxyModel.h',
'src/sortFilterProxyModels/FermentableSortFilterProxyModel.h',
'src/sortFilterProxyModels/HopSortFilterProxyModel.h',
'src/sortFilterProxyModels/MiscSortFilterProxyModel.h',
'src/sortFilterProxyModels/RecipeAdditionFermentableSortFilterProxyModel.h',
'src/sortFilterProxyModels/RecipeAdditionHopSortFilterProxyModel.h',
'src/sortFilterProxyModels/RecipeAdditionMiscSortFilterProxyModel.h',
'src/sortFilterProxyModels/RecipeAdditionYeastSortFilterProxyModel.h',
'src/sortFilterProxyModels/StyleSortFilterProxyModel.h',
'src/sortFilterProxyModels/WaterSortFilterProxyModel.h',
'src/sortFilterProxyModels/YeastSortFilterProxyModel.h',
'src/tableModels/BoilStepTableModel.h',
'src/tableModels/BtTableModel.h',
'src/tableModels/EquipmentTableModel.h',
'src/tableModels/FermentableTableModel.h',
'src/tableModels/FermentationStepTableModel.h',
'src/tableModels/HopTableModel.h',
'src/tableModels/MashStepTableModel.h',
'src/tableModels/MiscTableModel.h',
'src/tableModels/RecipeAdditionFermentableTableModel.h',
'src/tableModels/RecipeAdditionHopTableModel.h',
'src/tableModels/RecipeAdditionMiscTableModel.h',
'src/tableModels/RecipeAdditionYeastTableModel.h',
'src/tableModels/RecipeAdjustmentSaltTableModel.h',
'src/tableModels/SaltTableModel.h',
'src/tableModels/StyleTableModel.h',
'src/tableModels/WaterTableModel.h',
'src/tableModels/YeastTableModel.h',
'src/trees/TreeFilterProxyModel.h',