summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Linden <karl.j.linden@gmail.com>2018-10-06 12:57:58 +0200
committerKarl Linden <karl.j.linden@gmail.com>2018-10-06 14:57:45 +0200
commitb45b6b69a35de77c1640b9a2285adf8c51553d4a (patch)
treec9f48dc20369770bb696bf414b321993c5e2980d
parentafcc0afbd52af40fb0951fa3f560fc77dd3366a1 (diff)
downloadjack2-b45b6b69a35de77c1640b9a2285adf8c51553d4a.tar.gz
Update autooptions and move to an own directory
-rw-r--r--autooptions/README6
-rw-r--r--autooptions/__init__.py395
-rw-r--r--wscript445
3 files changed, 481 insertions, 365 deletions
diff --git a/autooptions/README b/autooptions/README
new file mode 100644
index 00000000..5787838d
--- /dev/null
+++ b/autooptions/README
@@ -0,0 +1,6 @@
+Do not modify the code in this directory. It has been copied from its upstream
+git repo [1]. When submodules are introduced this directory can be made a
+submodule, but until then a verbatim copy is better than inlining the code in
+the toplevel wscript.
+
+[1] https://gitlab.com/karllinden/waf-autooptions
diff --git a/autooptions/__init__.py b/autooptions/__init__.py
new file mode 100644
index 00000000..f0b22887
--- /dev/null
+++ b/autooptions/__init__.py
@@ -0,0 +1,395 @@
+#
+# Copyright (C) 2017 Karl Linden
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+import optparse
+import sys
+from waflib import Configure, Logs, Options, Utils
+
+# A list of AutoOptions. It is local to each module, so all modules that
+# use AutoOptions need to run both opt.load and conf.load. In contrast
+# to the define and style options this does not need to and cannot be
+# declared in the OptionsContext, because it is needed both for the
+# options and the configure phase.
+auto_options = []
+
+class AutoOption:
+ """
+ This class represents an auto option that can be used in conjunction
+ with the waf build system. By default it adds options --foo and
+ --no-foo respectively to turn on or off foo respectively.
+ Furthermore it incorporats logic and checks that are required for
+ these features.
+
+ An option can have an arbitrary number of dependencies that must be
+ present for the option to be enabled. An option can be enabled or
+ disabled by default. Here is how the logic works:
+ 1. If the option is explicitly disabled, through --no-foo, then no
+ checks are made and the option is disabled.
+ 2. If the option is explicitly enabled, through --foo, then check
+ for all required dependencies, and if some of them are not
+ found, then print a fatal error telling the user there were
+ dependencies missing.
+ 3. Otherwise, if the option is enabled by default, then check for
+ all dependencies. If all dependencies are found the option is
+ enabled. Otherwise it is disabled.
+ 4. Lastly, if no option was given and the option is disabled by
+ default, then no checks are performed and the option is
+ disabled.
+
+ To add a dependency to an option use the check, check_cfg and
+ find_program methods of this class. The methods are merely small
+ wrappers around their configuration context counterparts and behave
+ identically. Note that adding dependencies is done in the options
+ phase and not in the configure phase, although the checks are
+ acutally executed during the configure phase.
+
+ Custom check functions can be added using the add_function method.
+ As with the other checks the check function will be invoked during
+ the configuration. Refer to the documentation of the add_function
+ method for details.
+
+ When all checks have been made and the class has made a decision the
+ result is saved in conf.env['NAME'] where 'NAME' by default is the
+ uppercase of the name argument to __init__, with hyphens replaced by
+ underscores. This default can be changed with the conf_dest argument
+ to __init__.
+
+ The class will define a preprocessor symbol with the result. The
+ default name is WITH_NAME, to not collide with the standard define
+ of check_cfg, but it can be changed using the define argument to
+ __init__. It can also be changed globally using
+ set_auto_options_define.
+ """
+
+ def __init__(self, opt, name, help=None, default=True,
+ conf_dest=None, define=None, style=None):
+ """
+ Class initializing method.
+
+ Arguments:
+ opt OptionsContext
+ name name of the option, e.g. alsa
+ help help text that will be displayed in --help output
+ conf_dest conf.env variable to define to the result
+ define the preprocessor symbol to define with the result
+ style the option style to use; see below for options
+ """
+
+ # The dependencies to check for. The elements are on the form
+ # (func, k, kw) where func is the function or function name that
+ # is used for the check and k and kw are the arguments and
+ # options to give the function.
+ self.deps = []
+
+ # Whether or not the option should be enabled. None indicates
+ # that the checks have not been performed yet.
+ self.enable = None
+
+ self.help = help
+ if help:
+ if default:
+ help_comment = ' (enabled by default if possible)'
+ else:
+ help_comment = ' (disabled by default)'
+ option_help = help + help_comment
+ no_option_help = None
+ else:
+ option_help = no_option_help = optparse.SUPPRESS_HELP
+
+ self.dest = 'auto_option_' + name
+
+ self.default = default
+
+ safe_name = Utils.quote_define_name(name)
+ self.conf_dest = conf_dest or safe_name
+
+ default_define = opt.get_auto_options_define()
+ self.define = define or default_define % safe_name
+
+ if not style:
+ style = opt.get_auto_options_style()
+ self.style = style
+
+ # plain (default):
+ # --foo | --no-foo
+ # yesno:
+ # --foo=yes | --foo=no
+ # yesno_and_hack:
+ # --foo[=yes] | --foo=no or --no-foo
+ # enable:
+ # --enable-foo | --disble-foo
+ # with:
+ # --with-foo | --without-foo
+ if style in ['plain', 'yesno', 'yesno_and_hack']:
+ self.no_option = '--no-' + name
+ self.yes_option = '--' + name
+ elif style == 'enable':
+ self.no_option = '--disable-' + name
+ self.yes_option = '--enable-' + name
+ elif style == 'with':
+ self.no_option = '--without-' + name
+ self.yes_option = '--with-' + name
+ else:
+ opt.fatal('invalid style')
+
+ if style in ['yesno', 'yesno_and_hack']:
+ opt.add_option(
+ self.yes_option,
+ dest=self.dest,
+ action='store',
+ choices=['auto', 'no', 'yes'],
+ default='auto',
+ help=option_help,
+ metavar='no|yes')
+ else:
+ opt.add_option(
+ self.yes_option,
+ dest=self.dest,
+ action='store_const',
+ const='yes',
+ default='auto',
+ help=option_help)
+ opt.add_option(
+ self.no_option,
+ dest=self.dest,
+ action='store_const',
+ const='no',
+ default='auto',
+ help=no_option_help)
+
+ def check(self, *k, **kw):
+ self.deps.append(('check', k, kw))
+ def check_cfg(self, *k, **kw):
+ self.deps.append(('check_cfg', k, kw))
+ def find_program(self, *k, **kw):
+ self.deps.append(('find_program', k, kw))
+
+ def add_function(self, func, *k, **kw):
+ """
+ Add a custom function to be invoked as part of the
+ configuration. During the configuration the function will be
+ invoked with the configuration context as first argument
+ followed by the arugments to this method, except for the func
+ argument. The function must print a 'Checking for...' message,
+ because it is referred to if the check fails and this option is
+ requested.
+
+ On configuration error the function shall raise
+ conf.errors.ConfigurationError.
+ """
+ self.deps.append((func, k, kw))
+
+ def _check(self, conf, required):
+ """
+ This private method checks all dependencies. It checks all
+ dependencies (even if some dependency was not found) so that the
+ user can install all missing dependencies in one go, instead of
+ playing the infamous hit-configure-hit-configure game.
+
+ This function returns True if all dependencies were found and
+ False otherwise.
+ """
+ all_found = True
+
+ for (f,k,kw) in self.deps:
+ if hasattr(f, '__call__'):
+ # This is a function supplied by add_function.
+ func = f
+ k = list(k)
+ k.insert(0, conf)
+ k = tuple(k)
+ else:
+ func = getattr(conf, f)
+
+ try:
+ func(*k, **kw)
+ except conf.errors.ConfigurationError:
+ all_found = False
+ if required:
+ Logs.error('The above check failed, but the '
+ 'checkee is required for %s.' %
+ self.yes_option)
+
+ return all_found
+
+ def configure(self, conf):
+ """
+ This function configures the option examining the command line
+ option. It sets self.enable to whether this options should be
+ enabled or not, that is True or False respectively. If not all
+ dependencies were found self.enable will be False.
+ conf.env['NAME'] and a preprocessor symbol will be defined with
+ the result.
+
+ If the option was desired but one or more dependencies were not
+ found the an error message will be printed for each missing
+ dependency.
+
+ This function returns True on success and False on if the option
+ was requested but cannot be enabled.
+ """
+ # If the option has already been configured once, do not
+ # configure it again.
+ if self.enable != None:
+ return True
+
+ argument = getattr(Options.options, self.dest)
+ if argument == 'no':
+ self.enable = False
+ retvalue = True
+ elif argument == 'yes':
+ retvalue = self.enable = self._check(conf, True)
+ else:
+ self.enable = self.default and self._check(conf, False)
+ retvalue = True
+
+ conf.env[self.conf_dest] = self.enable
+ conf.define(self.define, int(self.enable))
+ return retvalue
+
+ def summarize(self, conf):
+ """
+ This function displays a result summary with the help text and
+ the result of the configuration.
+ """
+ if self.help:
+ if self.enable:
+ conf.msg(self.help, 'yes', color='GREEN')
+ else:
+ conf.msg(self.help, 'no', color='YELLOW')
+
+def options(opt):
+ """
+ This function declares necessary variables in the option context.
+ The reason for saving variables in the option context is to allow
+ autooptions to be loaded from modules (which will receive a new
+ instance of this module, clearing any global variables) with a
+ uniform style and default in the entire project.
+
+ Call this function through opt.load('autooptions').
+ """
+ if not hasattr(opt, 'auto_options_style'):
+ opt.auto_options_style = 'plain'
+ if not hasattr(opt, 'auto_options_define'):
+ opt.auto_options_define = 'WITH_%s'
+
+def opt(f):
+ """
+ Decorator: attach a new option function to Options.OptionsContext.
+
+ :param f: method to bind
+ :type f: function
+ """
+ setattr(Options.OptionsContext, f.__name__, f)
+
+@opt
+def add_auto_option(self, *k, **kw):
+ """
+ This function adds an AutoOption to the options context. It takes
+ the same arguments as the initializer funtion of the AutoOptions
+ class.
+ """
+ option = AutoOption(self, *k, **kw)
+ auto_options.append(option)
+ return option
+
+@opt
+def get_auto_options_define(self):
+ """
+ This function gets the default define name. This default can be
+ changed through set_auto_optoins_define.
+ """
+ return self.auto_options_define
+
+@opt
+def set_auto_options_define(self, define):
+ """
+ This function sets the default define name. The default is
+ 'WITH_%s', where %s will be replaced with the name of the option in
+ uppercase.
+ """
+ self.auto_options_define = define
+
+@opt
+def get_auto_options_style(self):
+ """
+ This function gets the default option style, which will be used for
+ the subsequent options.
+ """
+ return self.auto_options_style
+
+@opt
+def set_auto_options_style(self, style):
+ """
+ This function sets the default option style, which will be used for
+ the subsequent options.
+ """
+ self.auto_options_style = style
+
+@opt
+def apply_auto_options_hack(self):
+ """
+ This function applies the hack necessary for the yesno_and_hack
+ option style. The hack turns --foo into --foo=yes and --no-foo into
+ --foo=no.
+
+ It must be called before options are parsed, that is before the
+ configure phase.
+ """
+ for option in auto_options:
+ # With the hack the yesno options simply extend plain options.
+ if option.style == 'yesno_and_hack':
+ for i in range(1, len(sys.argv)):
+ if sys.argv[i] == option.yes_option:
+ sys.argv[i] = option.yes_option + '=yes'
+ elif sys.argv[i] == option.no_option:
+ sys.argv[i] = option.yes_option + '=no'
+
+@Configure.conf
+def summarize_auto_options(self):
+ """
+ This function prints a summary of the configuration of the auto
+ options. Obviously, it must be called after
+ conf.load('autooptions').
+ """
+ for option in auto_options:
+ option.summarize(self)
+
+def configure(conf):
+ """
+ This configures all auto options. Call it through
+ conf.load('autooptions').
+ """
+ ok = True
+ for option in auto_options:
+ if not option.configure(conf):
+ ok = False
+ if not ok:
+ conf.fatal('Some requested options had unsatisfied ' +
+ 'dependencies.\n' +
+ 'See the above configuration for details.')
diff --git a/wscript b/wscript
index e9c30c35..dc9b7f6b 100644
--- a/wscript
+++ b/wscript
@@ -22,310 +22,12 @@ out = 'build'
# lib32 variant name used when building in mixed mode
lib32 = 'lib32'
-auto_options = []
-
def display_feature(conf, msg, build):
if build:
conf.msg(msg, 'yes', color='GREEN')
else:
conf.msg(msg, 'no', color='YELLOW')
-# This function prints an error without stopping waf. The reason waf should not
-# be stopped is to be able to list all missing dependencies in one chunk.
-def print_error(msg):
- print(Logs.colors.RED + msg + Logs.colors.NORMAL)
-
-class AutoOption:
- """
- This class is the foundation for the auto options. It adds an option
- --foo=no|yes to the list of options and deals with all logic and checks for
- these options.
-
- Each option can have different dependencies that will be checked. If all
- dependencies are available and the user has not done any request the option
- will be enabled. If the user has requested to enable the option the class
- ensures that all dependencies are available and prints an error message
- otherwise. If the user disables the option, i.e. --foo=no, no checks are
- made.
-
- For each option it is possible to add packages that are required for the
- option using the add_package function. For dependency programs add_program
- should be used. For libraries (without pkg-config support) the add_library
- function should be used. For headers the add_header function exists. If
- there is another type of requirement or dependency the check hook (an
- external function called when configuring) can be used.
-
- When all checks have been made and the class has made a decision the result
- is saved in conf.env['NAME'] where 'NAME' by default is the uppercase of the
- name argument to __init__, but it can be changed with the conf_dest argument
- to __init__.
-
- The class will define a preprocessor symbol with the result. The default
- name is HAVE_NAME, but it can be changed using the define argument to
- __init__.
- """
-
- def __init__(self, opt, name, help, conf_dest=None, define=None):
- # check hook to call upon configuration
- self.check_hook = None
- self.check_hook_error = None
- self.check_hook_found = True
-
- # required libraries
- self.libs = [] # elements on the form [lib,uselib_store]
- self.libs_not_found = [] # elements on the form lib
-
- # required headers
- self.headers = []
- self.headers_not_found = []
-
- # required packages (checked with pkg-config)
- self.packages = [] # elements on the form [package,uselib_store,atleast_version]
- self.packages_not_found = [] # elements on the form [package,atleast_version]
-
- # required programs
- self.programs = [] # elements on the form [program,var]
- self.programs_not_found = [] # elements on the form program
-
- # the result of the configuration (should the option be enabled or not?)
- self.result = False
-
- self.help = help
- self.option = '--' + name
- self.dest = 'auto_option_' + name
- if conf_dest:
- self.conf_dest = conf_dest
- else:
- self.conf_dest = name.upper()
- if not define:
- self.define = 'HAVE_' + name.upper()
- else:
- self.define = define
- opt.add_option(self.option, type='string', default='auto', dest=self.dest, help=self.help+' (enabled by default if possible)', metavar='no|yes')
-
- def add_library(self, library, uselib_store=None):
- """
- Add a required library that should be checked during configuration. The
- library will be checked using the conf.check function. If the
- uselib_store arugment is not given it defaults to LIBRARY (the uppercase
- of the library argument). The uselib_store argument will be passed to
- check which means LIB_LIBRARY, CFLAGS_LIBRARY and DEFINES_LIBRARY, etc.
- will be defined if the option is enabled.
- """
- if not uselib_store:
- uselib_store = library.upper().replace('-', '_')
- self.libs.append([library, uselib_store])
-
- def add_header(self, header):
- """
- Add a required header that should be checked during configuration. The
- header will be checked using the conf.check function which means
- HAVE_HEADER_H will be defined if found.
- """
- self.headers.append(header)
-
- def add_package(self, package, uselib_store=None, atleast_version=None):
- """
- Add a required package that should be checked using pkg-config during
- configuration. The package will be checked using the conf.check_cfg
- function and the uselib_store and atleast_version will be passed to
- check_cfg. If uselib_store is None it defaults to PACKAGE (uppercase of
- the package argument) with hyphens and dots replaced with underscores.
- If atleast_version is None it defaults to '0'.
- """
- if not uselib_store:
- uselib_store = package.upper().replace('-', '_').replace('.', '_')
- if not atleast_version:
- atleast_version = '0'
- self.packages.append([package, uselib_store, atleast_version])
-
- def add_program(self, program, var=None):
- """
- Add a required program that should be checked during configuration. If
- var is not given it defaults to PROGRAM (the uppercase of the program
- argument). If the option is enabled the program is saved as a list (?!)
- in conf.env['PROGRAM'].
- """
- if not var:
- var = program.upper().replace('-', '_')
- self.programs.append([program, var])
-
- def set_check_hook(self, check_hook, check_hook_error):
- """
- Set the check hook and the corresponding error printing function to the
- configure step. The check_hook argument is a function that should return
- True if the extra prerequisites were found and False if not. The
- check_hook_error argument is an error printing function that should
- print an error message telling the user that --foo was explicitly
- requested but cannot be built since the extra prerequisites were not
- found. Both function should take a single argument that is the waf
- configuration context.
- """
- self.check_hook = check_hook
- self.check_hook_error = check_hook_error
-
- def _check(self, conf):
- """
- This is an internal function that runs all necessary configure checks.
- It checks all dependencies (even if some dependency was not found) so
- that the user can install all missing dependencies in one go, instead
- of playing the infamous hit-configure-hit-configure game.
-
- This function returns True if all dependencies were found and False if
- not.
- """
- all_found = True
-
- # Use-variables that should be used when checking libraries, headers and
- # programs. The list will be populated when looking for packages.
- use = []
-
- # check for packages
- for package,uselib_store,atleast_version in self.packages:
- try:
- conf.check_cfg(package=package, uselib_store=uselib_store, atleast_version=atleast_version, args='--cflags --libs')
- use.append(uselib_store)
- except conf.errors.ConfigurationError:
- all_found = False
- self.packages_not_found.append([package,atleast_version])
-
- # check for libraries
- for lib,uselib_store in self.libs:
- try:
- conf.check(lib=lib, uselib_store=uselib_store, use=use)
- except conf.errors.ConfigurationError:
- all_found = False
- self.libs_not_found.append(lib)
-
- # check for headers
- for header in self.headers:
- try:
- conf.check(header_name=header, use=use)
- except conf.errors.ConfigurationError:
- all_found = False
- self.headers_not_found.append(header)
-
- # check for programs
- for program,var in self.programs:
- try:
- conf.find_program(program, var=var, use=use)
- except conf.errors.ConfigurationError:
- all_found = False
- self.programs_not_found.append(program)
-
- # call hook (if specified)
- if self.check_hook:
- self.check_hook_found = self.check_hook(conf)
- if not self.check_hook_found:
- all_found = False
-
- return all_found
-
- def _configure_error(self, conf):
- """
- This is an internal function that prints errors for each missing
- dependency. The error messages tell the user that this option required
- some dependency, but it cannot be found.
- """
-
- for lib in self.libs_not_found:
- print_error('%s requires the %s library, but it cannot be found.' % (self.option, lib))
-
- for header in self.headers_not_found:
- print_error('%s requires the %s header, but it cannot be found.' % (self.option, header))
-
- for package,atleast_version in self.packages_not_found:
- string = package
- if atleast_version:
- string += ' >= ' + atleast_version
- print_error('%s requires the package %s, but it cannot be found.' % (self.option, string))
-
- for program in self.programs_not_found:
- print_error('%s requires the %s program, but it cannot be found.' % (self.option, program))
-
- if not self.check_hook_found:
- self.check_hook_error(conf)
-
- def configure(self, conf):
- """
- This function configures the option examining the argument given too
- --foo (where foo is this option). This function sets self.result to the
- result of the configuration; True if the option should be enabled or
- False if not. If not all dependencies were found self.result will shall
- be False. conf.env['NAME'] will be set to the same value aswell as a
- preprocessor symbol will be defined according to the result.
-
- If --foo[=yes] was given, but some dependency was not found an error
- message is printed (foreach missing dependency).
-
- This function returns True on success and False on error.
- """
- argument = getattr(Options.options, self.dest)
- if argument == 'no':
- self.result = False
- retvalue = True
- elif argument == 'yes':
- if self._check(conf):
- self.result = True
- retvalue = True
- else:
- self.result = False
- retvalue = False
- self._configure_error(conf)
- elif argument == 'auto':
- self.result = self._check(conf)
- retvalue = True
- else:
- print_error('Invalid argument "' + argument + '" to ' + self.option)
- self.result = False
- retvalue = False
-
- conf.env[self.conf_dest] = self.result
- if self.result:
- conf.define(self.define, 1)
- else:
- conf.define(self.define, 0)
- return retvalue
-
- def display_message(self, conf):
- """
- This function displays a result message with the help text and the
- result of the configuration.
- """
- display_feature(conf, self.help, self.result)
-
-# This function adds an option to the list of auto options and returns the newly
-# created option.
-def add_auto_option(opt, name, help, conf_dest=None, define=None):
- option = AutoOption(opt, name, help, conf_dest=conf_dest, define=define)
- auto_options.append(option)
- return option
-
-# This function applies a hack that for each auto option --foo=no|yes replaces
-# any occurence --foo in argv with --foo=yes, in effect interpreting --foo as
-# --foo=yes. The function has to be called before waf issues the option parser,
-# i.e. before the configure phase.
-def auto_options_argv_hack():
- for option in auto_options:
- for x in range(1, len(sys.argv)):
- if sys.argv[x] == option.option:
- sys.argv[x] += '=yes'
-
-# This function configures all auto options. It stops waf and prints an error
-# message if there were unsatisfied requirements.
-def configure_auto_options(conf):
- ok = True
- for option in auto_options:
- if not option.configure(conf):
- ok = False
- if not ok:
- conf.fatal('There were unsatisfied requirements.')
-
-# This function displays all options and the configuration results.
-def display_auto_options_messages(conf):
- for option in auto_options:
- option.display_message(conf)
-
def check_for_celt(conf):
found = False
for version in ['11', '8', '7', '5']:
@@ -339,10 +41,9 @@ def check_for_celt(conf):
except conf.errors.ConfigurationError:
pass
conf.define(define, 0)
- return found
-def check_for_celt_error(conf):
- print_error('--celt requires the package celt, but it could not be found.')
+ if not found:
+ raise conf.errors.ConfigurationError
# The readline/readline.h header does not work if stdio.h is not included
# before. Thus a fragment with both stdio.h and readline/readline.h need to be
@@ -350,42 +51,29 @@ def check_for_celt_error(conf):
def check_for_readline(conf):
# FIXME: This check can be incorporated into the AutoOptions class by
# passing header_name=['stdio.h', 'readline/readline.h'] to check.
- try:
- conf.check(fragment='''
- #include <stdio.h>
- #include <readline/readline.h>
- int main(void) { return 0; }''',
- execute=False,
- msg='Checking for header readline/readline.h',
- errmsg='not found')
- return True
- except conf.errors.ConfigurationError:
- return False
-
-def check_for_readline_error(conf):
- print_error('--readline requires the readline/readline.h header, but it cannot be found.')
+ conf.check(fragment='''
+ #include <stdio.h>
+ #include <readline/readline.h>
+ int main(void) { return 0; }''',
+ execute=False,
+ msg='Checking for header readline/readline.h',
+ errmsg='not found')
def check_for_mmsystem(conf):
# FIXME: See comment in check_for_readline.
- try:
- conf.check(fragment='''
- #include <windows.h>
- #include <mmsystem.h>
- int main(void) { return 0; }''',
- execute=False,
- msg='Checking for header mmsystem.h',
- errmsg='not found')
- return True
- except conf.errors.ConfigurationError:
- return False
-
-def check_for_mmsystem_error(conf):
- print_error('--winmme requires the mmsystem.h header, but it cannot be found.')
+ conf.check(fragment='''
+ #include <windows.h>
+ #include <mmsystem.h>
+ int main(void) { return 0; }''',
+ execute=False,
+ msg='Checking for header mmsystem.h',
+ errmsg='not found')
def options(opt):
# options provided by the modules
opt.load('compiler_cxx')
opt.load('compiler_c')
+ opt.load('autooptions');
opt.load('xcode')
opt.load('xcode6')
@@ -409,77 +97,106 @@ def options(opt):
opt.add_option('--clients', default=64, type='int', dest='clients', help='Maximum number of JACK clients')
opt.add_option('--ports-per-application', default=768, type='int', dest='application_ports', help='Maximum number of ports per application')
+ opt.set_auto_options_define('HAVE_%s')
+ opt.set_auto_options_style('yesno_and_hack')
+
# options with third party dependencies
- doxygen = add_auto_option(opt,
+ doxygen = opt.add_auto_option(
'doxygen',
help='Build doxygen documentation',
conf_dest='BUILD_DOXYGEN_DOCS')
- doxygen.add_program('doxygen')
- alsa = add_auto_option(opt,
+ doxygen.find_program('doxygen')
+ alsa = opt.add_auto_option(
'alsa',
help='Enable ALSA driver',
conf_dest='BUILD_DRIVER_ALSA')
- alsa.add_package('alsa', atleast_version='1.0.18')
- firewire = add_auto_option(opt,
+ alsa.check_cfg(
+ package='alsa',
+ atleast_version='1.0.18',
+ args='--cflags --libs')
+ firewire = opt.add_auto_option(
'firewire',
help='Enable FireWire driver (FFADO)',
conf_dest='BUILD_DRIVER_FFADO')
- firewire.add_package('libffado', atleast_version='1.999.17')
- freebob = add_auto_option(opt,
+ firewire.check_cfg(
+ package='libffado',
+ atleast_version='1.999.17',
+ args='--cflags --libs')
+ freebob = opt.add_auto_option(
'freebob',
help='Enable FreeBob driver')
- freebob.add_package('libfreebob', atleast_version='1.0.0')
- iio = add_auto_option(opt,
+ freebob.check_cfg(
+ package='libfreebob',
+ atleast_version='1.0.0',
+ args='--cflags --libs')
+ iio = opt.add_auto_option(
'iio',
help='Enable IIO driver',
conf_dest='BUILD_DRIVER_IIO')
- iio.add_package('gtkIOStream', atleast_version='1.4.0')
- iio.add_package('eigen3', atleast_version='3.1.2')
- portaudio = add_auto_option(opt,
+ iio.check_cfg(
+ package='gtkIOStream',
+ atleast_version='1.4.0',
+ args='--cflags --libs')
+ iio.check_cfg(
+ package='eigen3',
+ atleast_version='3.1.2',
+ args='--cflags --libs')
+ portaudio = opt.add_auto_option(
'portaudio',
help='Enable Portaudio driver',
conf_dest='BUILD_DRIVER_PORTAUDIO')
- portaudio.add_header('windows.h') # only build portaudio on windows
- portaudio.add_package('portaudio-2.0', uselib_store='PORTAUDIO', atleast_version='19')
- winmme = add_auto_option(opt,
+ portaudio.check(header_name='windows.h') # only build portaudio on windows
+ portaudio.check_cfg(
+ package='portaudio-2.0',
+ uselib_store='PORTAUDIO',
+ atleast_version='19',
+ args='--cflags --libs')
+ winmme = opt.add_auto_option(
'winmme',
help='Enable WinMME driver',
conf_dest='BUILD_DRIVER_WINMME')
- winmme.set_check_hook(check_for_mmsystem, check_for_mmsystem_error)
+ winmme.add_function(check_for_mmsystem)
- celt = add_auto_option(opt,
+ celt = opt.add_auto_option(
'celt',
help='Build with CELT')
- celt.set_check_hook(check_for_celt, check_for_celt_error)
- opus = add_auto_option(opt,
+ celt.add_function(check_for_celt)
+ opus = opt.add_auto_option(
'opus',
help='Build Opus netjack2')
- opus.add_header('opus/opus_custom.h')
- opus.add_package('opus', atleast_version='0.9.0')
- samplerate = add_auto_option(opt,
+ opus.check(header_name='opus/opus_custom.h')
+ opus.check_cfg(
+ package='opus',
+ atleast_version='0.9.0',
+ args='--cflags --libs')
+ samplerate = opt.add_auto_option(
'samplerate',
help='Build with libsamplerate')
- samplerate.add_package('samplerate')
- sndfile = add_auto_option(opt,
+ samplerate.check_cfg(
+ package='samplerate',
+ args='--cflags --libs')
+ sndfile = opt.add_auto_option(
'sndfile',
help='Build with libsndfile')
- sndfile.add_package('sndfile')
- readline = add_auto_option(opt,
+ sndfile.check_cfg(
+ package='sndfile',
+ args='--cflags --libs')
+ readline = opt.add_auto_option(
'readline',
help='Build with readline')
- readline.add_library('readline')
- readline.set_check_hook(check_for_readline, check_for_readline_error)
- sd = add_auto_option(opt,
+ readline.check(lib='readline')
+ readline.add_function(check_for_readline)
+ sd = opt.add_auto_option(
'systemd',
help='Use systemd notify')
- sd.add_header('systemd/sd-daemon.h')
- sd.add_library('systemd')
+ sd.check(header_name='systemd/sd-daemon.h')
+ sd.check(lib='systemd')
# dbus options
opt.recurse('dbus')
# this must be called before the configure phase
- auto_options_argv_hack()
+ opt.apply_auto_options_hack()
def detect_platform(conf):
# GNU/kFreeBSD and GNU/Hurd are treated as Linux
@@ -519,8 +236,7 @@ def configure(conf):
if conf.env['IS_MACOSX']:
conf.check(lib='aften', uselib='AFTEN', define_name='AFTEN')
- # configure all auto options
- configure_auto_options(conf)
+ conf.load('autooptions')
# Check for functions.
conf.check(
@@ -712,8 +428,7 @@ def configure(conf):
print(Logs.colors.RED + 'WARNING !! mixing both jackd and jackdbus may cause issues:' + Logs.colors.NORMAL)
print(Logs.colors.RED + 'WARNING !! jackdbus does not use .jackdrc nor qjackctl settings' + Logs.colors.NORMAL)
- # display configuration result messages for auto options
- display_auto_options_messages(conf)
+ conf.summarize_auto_options()
if conf.env['BUILD_JACKDBUS']:
conf.msg('D-Bus service install directory', conf.env['DBUS_SERVICES_DIR'], color='CYAN')