1# This file is part of libsigc++. 2 3project('libsigc++', 'cpp', 4 version: '3.0.7', 5 license: 'LGPLv2.1+', 6 default_options: [ 7 'cpp_std=c++17', 8 'warning_level=0', 9 ], 10 meson_version: '>= 0.51.0', # required for dep.get_variable() 11) 12#TODO: Require meson_version: '>= 0.54.0' when it's available 13# in GitHub's CI (continuous integration). 14# meson_version() >= 0.54.0 is necessary if sigc++ is a subproject, 15# or if mm-common is a subproject of sigc++. 16 17sigcxx_api_version = '3.0' 18sigcxx_pcname = 'sigc++-' + sigcxx_api_version 19 20sigcxx_version_array = meson.project_version().split('.') 21sigcxx_major_version = sigcxx_version_array[0].to_int() 22sigcxx_minor_version = sigcxx_version_array[1].to_int() 23sigcxx_micro_version = sigcxx_version_array[2].to_int() 24 25# http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html 26# The relation between libtool's current:revison:age interface versioning 27# and the .so filename, .so.x.y.z, is 28# x = current - age 29# y = age 30# z = revision 31# If libtool_soversion is updated as described in libtool's documentation, 32# x.y.z will usually *not* be equal to meson.project_version(). 33libtool_soversion = [0, 0, 0] 34sigcxx_libversion = '@0@.@1@.@2@'.format( 35 libtool_soversion[0] - libtool_soversion[2], 36 libtool_soversion[2], 37 libtool_soversion[1]) 38darwin_versions = [libtool_soversion[0] + 1, '@0@.@1@'.format(libtool_soversion[0] + 1, libtool_soversion[1])] 39 40# Use these instead of meson.source_root() and meson.build_root() in subdirectories. 41# source_root() and build_root() are not useful, if this is a subproject. 42project_source_root = meson.current_source_dir() 43project_build_root = meson.current_build_dir() 44 45cpp_compiler = meson.get_compiler('cpp') 46is_msvc = cpp_compiler.get_id() == 'msvc' 47python3 = import('python').find_installation() 48 49python_version = python3.language_version() 50python_version_req = '>= 3.5' 51if not python_version.version_compare(python_version_req) 52 error('Requires Python @0@, found @1@.'.format(python_version_req, python_version)) 53endif 54 55# Do we build from a git repository? 56# Suppose we do if and only if a '.git' directory or file exists. 57cmd_py = ''' 58import os 59import sys 60sys.exit(os.path.isdir("@0@") or os.path.isfile("@0@")) 61'''.format(project_source_root / '.git') 62is_git_build = run_command(python3, '-c', cmd_py).returncode() != 0 63 64# Are we testing a dist tarball while it's being built? 65# There ought to be a better way. https://github.com/mesonbuild/meson/issues/6866 66is_dist_check = project_source_root.contains('dist-unpack') and \ 67 project_build_root.contains('dist-build') 68 69# Options. 70maintainer_mode_opt = get_option('maintainer-mode') 71maintainer_mode = maintainer_mode_opt == 'true' or \ 72 (maintainer_mode_opt == 'if-git-build' and is_git_build) 73if is_dist_check 74 message('Looks like a tarball is being tested. ' + \ 75 'Option "dist-warnings" is used instead of "warnings".') 76 warning_level = get_option('dist-warnings') 77else 78 warning_level = get_option('warnings') 79endif 80build_deprecated_api = get_option('build-deprecated-api') 81build_documentation_opt = get_option('build-documentation') 82build_documentation = build_documentation_opt == 'true' or \ 83 (build_documentation_opt == 'if-maintainer-mode' and maintainer_mode) 84build_examples = get_option('build-examples') 85do_benchmark = get_option('benchmark') 86 87# Installation directories are relative to {prefix}. 88install_prefix = get_option('prefix') 89install_includedir = get_option('includedir') 90install_libdir = get_option('libdir') 91install_datadir = get_option('datadir') 92install_pkgconfigdir = install_libdir / 'pkgconfig' 93 94# Dependencies. 95# sigcxx_build_dep: Dependencies when building the libsigc++ library. 96# sigcxx_dep (created in sigc++/meson.build): 97# Dependencies when using the libsigc++ library. 98sigcxx_build_dep = [] # No dependencies 99 100benchmark_dep = dependency('boost', modules: ['system', 'timer'], 101 version: '>=1.20.0', required: do_benchmark) 102can_benchmark = benchmark_dep.found() 103 104if is_msvc 105 # We must have Visual Studio 2017 15.7 or later... 106 assert(cpp_compiler.version().split('.')[0].to_int() >= 19 and \ 107 cpp_compiler.version().split('.')[1].to_int() >= 15, 108 'Visual Studio 2017 15.7 or later is required') 109endif 110 111# Some dependencies are required only in maintainer mode and/or 112# if documentation shall be built. 113mm_common_get = find_program('mm-common-get', required: false) 114 115if maintainer_mode and not mm_common_get.found() 116 message('Maintainer mode requires the \'mm-common-get\' command. If it is not found,\n' + 117 'use \'-Dmaintainer-mode=false\' or install the \'mm-common\' package, version 1.0.0 or higher.') 118 # If meson --wrap-mode != forcefallback, Meson falls back to the mm-common 119 # subproject only if mm-common-get is required. 120 mm_common_get = find_program('mm-common-get', required: true) 121endif 122 123perl = find_program('perl', required: build_documentation) 124doxygen = find_program('doxygen', required: build_documentation) 125dot = find_program('dot', required: build_documentation) # Used by Doxygen 126xsltproc = find_program('xsltproc', required: build_documentation) 127 128script_dir = project_source_root / 'untracked' / 'build_scripts' 129doc_reference = script_dir / 'doc-reference.py' 130dist_changelog = script_dir / 'dist-changelog.py' 131dist_build_scripts = script_dir / 'dist-build-scripts.py' 132tutorial_custom_cmd = project_source_root / 'tools' / 'tutorial-custom-cmd.py' 133 134if maintainer_mode 135 # Copy files to untracked/build_scripts and untracked/docs/docs. 136 run_command(mm_common_get, '--force', script_dir, 137 project_source_root / 'untracked' / 'docs' / 'docs') 138else 139 cmd_py = ''' 140import os 141import sys 142sys.exit(os.path.isfile("@0@")) 143'''.format(doc_reference) 144 file_exists = run_command(python3, '-c', cmd_py).returncode() != 0 145 if not file_exists 146 warning('Missing files in untracked/. ' + \ 147 'Enable maintainer-mode if you want to build documentation or create a dist tarball.') 148 endif 149endif 150 151# Set compiler warnings. 152warning_flags = [] 153if warning_level == 'min' 154 if is_msvc 155 warning_flags = ['/W3'] 156 else 157 warning_flags = ['-Wall'] 158 endif 159elif warning_level == 'max' or warning_level == 'fatal' 160 if is_msvc 161 warning_flags = ['/W4'] 162 else 163 warning_flags = '-pedantic -Wall -Wextra -Wsuggest-override -Wshadow -Wzero-as-null-pointer-constant -Wformat-security'.split() 164 endif 165 if warning_level == 'fatal' 166 if is_msvc 167 warning_flags += ['/WX'] 168 else 169 warning_flags += ['-Werror'] 170 endif 171 endif 172endif 173 174warning_flags = cpp_compiler.get_supported_arguments(warning_flags) 175add_project_arguments(warning_flags, language: 'cpp') 176 177# MSVC: Ignore warnings that aren't really harmful, but make those 178# that should not be overlooked stand out. 179if is_msvc 180 foreach wd : ['/FImsvc_recommended_pragmas.h', '/EHsc', '/wd4267', '/utf-8'] 181 disabled_warning = cpp_compiler.get_supported_arguments(wd) 182 add_project_arguments(disabled_warning, language: 'cpp') 183 endforeach 184endif 185 186# Configure files 187pkg_conf_data = configuration_data() 188pkg_conf_data.set('prefix', install_prefix) 189pkg_conf_data.set('exec_prefix', '${prefix}') 190pkg_conf_data.set('libdir', '${exec_prefix}' / install_libdir) 191pkg_conf_data.set('datarootdir', '${prefix}' / install_datadir) 192pkg_conf_data.set('datadir', '${datarootdir}') 193pkg_conf_data.set('includedir', '${prefix}' / install_includedir) 194pkg_conf_data.set('top_srcdir', project_source_root) 195pkg_conf_data.set('PACKAGE_VERSION', meson.project_version()) 196pkg_conf_data.set('SIGCXX_API_VERSION', sigcxx_api_version) 197 198if not build_deprecated_api 199 pkg_conf_data.set('SIGCXX_DISABLE_DEPRECATED', true) 200endif 201pkg_conf_data.set('SIGCXX_MAJOR_VERSION', sigcxx_major_version) 202pkg_conf_data.set('SIGCXX_MINOR_VERSION', sigcxx_minor_version) 203pkg_conf_data.set('SIGCXX_MICRO_VERSION', sigcxx_micro_version) 204 205configure_file( 206 input: 'sigc++.pc.in', 207 output: sigcxx_pcname + '.pc', 208 configuration: pkg_conf_data, 209 install_dir: install_pkgconfigdir, 210) 211 212configure_file( 213 input: 'sigc++-uninstalled.pc.in', 214 output: sigcxx_pcname + '-uninstalled.pc', 215 configuration: pkg_conf_data, 216) 217 218install_includeconfigdir = install_libdir / sigcxx_pcname / 'include' 219sigcxxconfig_h = configure_file( 220 input: 'sigc++config.h.meson', 221 output: 'sigc++config.h', 222 configuration: pkg_conf_data, 223 install_dir: install_includeconfigdir, 224) 225 226# add_dist_script() is not allowed in a subproject if meson.version() < 0.58.0. 227can_add_dist_script = not meson.is_subproject() or meson.version().version_compare('>= 0.58.0') 228 229#subdir('cmake') 230subdir('MSVC_NMake') 231subdir('sigc++') 232subdir('examples') 233subdir('tests') 234subdir('docs/docs/reference') 235subdir('docs/docs/manual') 236 237if can_add_dist_script 238 # Add a ChangeLog file to the distribution directory. 239 meson.add_dist_script( 240 python3.path(), dist_changelog, 241 project_source_root, 242 ) 243 # Add build scripts to the distribution directory, and delete .gitignore 244 # files and an empty $MESON_PROJECT_DIST_ROOT/build/ directory. 245 meson.add_dist_script( 246 python3.path(), dist_build_scripts, 247 project_source_root, 248 'untracked' / 'build_scripts', 249 ) 250endif 251 252if meson.is_subproject() 253 pkgconfig_vars = { 254 'htmlrefdir': install_prefix / install_docdir / 'reference' / 'html', 255 'htmlrefpub': 'http://library.gnome.org/devel/libsigc++/unstable/' 256 } 257 if build_documentation 258 pkgconfig_vars += {'doxytagfile': tag_file.full_path()} 259 # May be used in a main project. 260 global_tag_file_target = tag_file 261 endif 262 sigcxx_dep = declare_dependency( 263 dependencies: sigcxx_own_dep, 264 variables: pkgconfig_vars, 265 ) 266 267 # A main project that looks for sigcxx_pcname.pc shall find sigcxx_dep. 268 meson.override_dependency(sigcxx_pcname, sigcxx_dep) 269endif 270 271# Print a summary. 272real_maintainer_mode = '' 273if maintainer_mode_opt == 'if-git-build' 274 real_maintainer_mode = ' (@0@)'.format(maintainer_mode) 275endif 276 277real_build_documentation = '' 278if build_documentation_opt == 'if-maintainer-mode' 279 real_build_documentation = ' (@0@)'.format(build_documentation) 280endif 281 282validate = get_option('validation') and can_parse_and_validate 283explain_val = '' 284if get_option('validation') and not validate 285 explain_val = ' (requires xmllint)' 286endif 287 288build_pdf = build_pdf_by_default and can_build_pdf 289explain_pdf = '' 290if build_pdf_by_default and not build_pdf 291 explain_pdf = ' (requires dblatex or (xmllint and docbook2pdf))' 292endif 293 294 295 296summary = [ 297 '', 298 '------', 299 meson.project_name() + ' ' + meson.project_version(), 300 '', 301 ' Maintainer mode: @0@@1@'.format(maintainer_mode_opt, real_maintainer_mode), 302 ' Compiler warnings: @0@'.format(warning_level), 303 ' Build deprecated API: @0@'.format(build_deprecated_api), 304 'Build HTML documentation: @0@@1@'.format(build_documentation_opt, real_build_documentation), 305 ' XML validation: @0@@1@'.format(validate, explain_val), 306 ' Build PDF: @0@@1@'.format(build_pdf, explain_pdf), 307 ' Build example programs: @0@'.format(build_examples), 308 ' Benchmark: @0@'.format(do_benchmark), 309 'Directories:', 310 ' prefix: @0@'.format(install_prefix), 311 ' includedir: @0@'.format(install_prefix / install_includedir), 312 ' includesigcxxdir: @0@'.format(install_prefix / install_includedir / sigcxx_pcname), 313 ' libdir: @0@'.format(install_prefix / install_libdir), 314 ' includeconfigdir: @0@'.format(install_prefix / install_includeconfigdir), 315 ' pkgconfigdir: @0@'.format(install_prefix / install_pkgconfigdir), 316 ' datadir: @0@'.format(install_prefix / install_datadir), 317 ' docdir: @0@'.format(install_prefix / install_docdir), 318 ' devhelpdir: @0@'.format(install_prefix / install_devhelpdir), 319 ' tutorialdir: @0@'.format(install_prefix / install_tutorialdir), 320 '------' 321] 322 323message('\n'.join(summary)) 324