Qt Extended Home · Build System Home · Reference · User Guide · Internals codeless banner

Opt System

This document describes the opt system, used to decide which options are available in configure.

Defining a new opt variable

It's a little non-intuitive but easy enough to fill out.

    set_optvar("name", +{
        "attribute" => "value",
        "attribute" => "value",
    });

There are a number of attributes with specific meanings:

The order that options are presented to the user is based on the order that they appear in configure.

type

The type is mandatory.

Note that only the list type has a default value. The other types have a default value of undef.

Setters

There are 4 setters.

There are 2 ways to define these depending on if you want help for each switch or one set of help for all switches. Using help for each switch is typically done for bool types.

    "set" => [ "%", "Enable foo." ],
    "unset" => [ "no-%", "Disable foo." ],

Using help for all switches is typically done for list types.

    "add" => "add-%=s",
    "remove" => "remove-%=s",
    "set" => [ "%s=s", "Select the things to build." ],

Complex list types may wish to avoid set as it requires items to be split on comma or space.

The % in the above is expanded to the opt name. Any _ in the opt name are converted to - for the switch.

Note that value and list types must have =s (which tells Getopt to accept an argument) and bool types cannot have this.

List types should set arg to multiple values with a comma.

    set_optvar("myopts", +{
        "type" => "list",
        "add" => [ "%=s", "Add opt." ],
        "remove" => [ "no-%=s", "Remove opt." ],
        "set" => [ "set-%=s", "Set all opts." ],
        "arg" => "opt,opt",
    });

The opt system will only list up to the comma for the add and remove help.

Note, an option that has "hidden" as its help will not be displayed in configure -help but will still be accepted.

Aliases exist for compatibility. Every setter can have aliases. They are set as a list.

    set_optvar("myopt", +{
        "type" => "bool",
        "set" => [ "%", "Enable foo." ],
        "setaliases" => [ "foo", "bar" ],
    });

If the user enters one of these switches they will be given the following message.

    WARNING: -foo is deprecated. Please use -myopt instead.

Every setter can also have a function that is called after applying the value. This can be handy when turning on one option implies another option.

    set_optvar("myopt", +{
        "type" => "bool",
        "set" => [ "%", "Enable foo." ],
        "setfunc" => sub { opt("otheropt") = 1; },
    });

Accessing variables

The simple case is easy.

    opt("variable") = "foo";
    print "I got ".opt("variable")."\n";

Lists are a bit harder.

    # Store the ref and access via stored copy
    my $ref = opt("variable");
    push(@$ref, "foo");
    print "I got ".join(" ", @$ref)."\n";

    # Access directly
    for ( @{opt("variable")} ) {
        print "I got $_\n";
    }

You can access indivitual attributes too. This could come in handy if you need to calculate a default (before opt_get_options() is called).

    opt("variable", "default") = 2;

Extra attributes

You can create your own attributes. It is recommended to declare your attributes up front, even if you give them an empty value. This is required for lists. Here's some extra attributes being initialised.

    "color" => "",
    "frobnitz" => [],

Default values

Part of the reason for implementing the new opt system was for default value detection and notification. However, there are some caveats here.

If you need to generate a default after the defaults have been assigned, you must do some extra work. I will include an example for the qvfb option since it relies on other options so it can't be figured out until after the defaults have been applied.

If the value is changed from undef then the user needs to know it was an automatic default. Setting the auto attribute to a non-zero value will make this happen.

    opt("qvfb") = 1;
    opt("qvfb", "auto") = 1;

A caveat here is that list variables will not have a value of undef. Instead they will have a value equal to the reference to an empty list. In other words, don't set auto for a null list!

Conditional defaults

Variables that are specific to Qt Extended or Qt Extended Sync Agent should use the visible and autodep attributes.

    set_optvar( "quicklaunch", +{
        "set" => [ "%",
            "Use the quicklaunch method of speeding up application loading. ".
            "Applications that allow it are built as plugins." ],
        "unset" => [ "no-quicklaunch",
            "Don't use the quicklaunch method of application loading." ],
        "default" => 1,
        "visible" => sub { $build_core || $build_pda || $build_phone },
        "autodep" => sub { opt("edition") },
    });

This means that the switches aren't available if you can't build Qt Extended and the default value stuff isn't displayed if opt("edition") isn't set (only Qt Extended Sync Agent is being built). These functions can also be used for platform-specific settings.

Undefined values

If an opt variable have no default and the value is not set, it will have an undefined value. This can cause problems if you try to use the variable later. Here's some examples of how this can affect you. Specifically, you should ensure that warnings are not going to be produced.

    if ( opt("variable") ) {
        # variable has a non-zero, defined value
    }
    if ( opt("variable") == 1 ) {
        # variable has a value of 1 (will warn if the value is undefined)
    }
    if ( !opt("variable") ) {
        # variable has a zero or undefined value
    }
    if ( !defined(opt("variable")) ) {
        # variable has an undefined value
    }
    if ( defined(opt("variable")) && opt("variable") == 0 ) {
        # variable is defined and has a value of 0
    }

Computed defaults

If your generated default is merely dependant on another option, you can express that in this way.

    my %options = ( "foo" => "1", "bar" => "2", "baz" => "3" );
    ...
        "default" => sub { $options{opt_resolve("othervar")} },
        "visref" => sub { opt("othervar") },
        "autodep" => sub { opt("othervar") },

opt_resolve causes the variable's real or default value to be returned. This is required when othervar might be null while the help is showing (eg. The edition value has a default but it's not yet applied during the help display).

Attributes that take multiple types

There are some attributes that can take multiple types. All of these can accept a scalar, array or code block.

config_pri

This attribute is handled by write_config_pri.

If the option has the config_pri attribute and is visible, it is evaluated as a series of commands.

If the command contains %, it is printed with % replaced by opt("option", "value") and %{foo} replaced by opt("option", "foo").

If the command doesn't contain % it is printed if the value is not null or empty.

You can add flags by prefixing a command with (). The following flags are available:

opt_call

Some options have side effects. Things like adding/removing modules, and anything with a setter func may have problems if you enable them in code with just:

    opt("option") = 1;

The opt_call function allows you to invoke the function that is invoked when the users sets configure switches. This ensures that any side effects will also take place.

    opt_call("option", "set", 1);


Copyright © 2009 Trolltech
Qt Extended - Build System Documentation