Add ability to specify substitutions as key-value pairs
This commit is contained in:
parent
48fb7e2cc9
commit
ed653f0cc2
34
README.md
34
README.md
@ -55,8 +55,8 @@ h{config}: in{config}
|
||||
```
|
||||
|
||||
Besides the built-in configuration options, custom substitutions can be
|
||||
specified as `buildfile` variables in the same way as with the
|
||||
[`in`][module-in] module. For example:
|
||||
specified as `buildfile` variables or key-value pairs in the same way as with
|
||||
the [`in`][module-in] module. For example, as `buildfile` variables:
|
||||
|
||||
```
|
||||
/* config.h.in */
|
||||
@ -76,7 +76,35 @@ h{config}: in{config}
|
||||
}
|
||||
```
|
||||
|
||||
This mechanism can also be used to override the built-in checks, for example:
|
||||
As key-value pairs in the `autoconf.substitutions` map (which is an alias for
|
||||
the `in.substitutions` variable; see the [`in`][module-in] module for
|
||||
details):
|
||||
|
||||
```
|
||||
/* config.h.in */
|
||||
|
||||
#undef _GNU_SOURCE
|
||||
#undef _POSIX_SOURCE
|
||||
```
|
||||
|
||||
```
|
||||
gnu_source = ($c.stdlib == 'glibc')
|
||||
posix_source = ($c.target.class != 'windows' && !$gnu_source)
|
||||
|
||||
h{config}: in{config}
|
||||
{
|
||||
autoconf.substitutions = _GNU_SOURCE@$gnu_source
|
||||
autoconf.substitutions += _POSIX_SOURCE@$posix_source
|
||||
}
|
||||
```
|
||||
|
||||
In particular, the `autoconf.substitutions` mechanism is the only way to have
|
||||
substitutions that cannot be specified as `buildfile` variables because they
|
||||
start with an underscore (and thus are reserved, as in the above example) or
|
||||
refer to one of the predefined variables.
|
||||
|
||||
The custom substitutions can also be used to override the built-in checks, for
|
||||
example:
|
||||
|
||||
```
|
||||
h{config}: in{config}
|
||||
|
@ -7,5 +7,5 @@ license: MIT ; MIT License.
|
||||
description-file: README.md
|
||||
url: https://github.com/build2/libbuild2-autoconf
|
||||
email: users@build2.org
|
||||
depends: * build2 >= 0.15.0-
|
||||
depends: * bpkg >= 0.15.0-
|
||||
depends: * build2 >= 0.16.0-
|
||||
depends: * bpkg >= 0.16.0-
|
||||
|
@ -401,3 +401,26 @@ cat config.h >>EOO
|
||||
# define PREFIX_zzz_TEST_DUMMY5_H PREFIX_zzz_TEST_DUMMY4_H
|
||||
#endif /*zzz_TEST_DUMMY3_H*/
|
||||
EOO
|
||||
|
||||
: substitution-map
|
||||
:
|
||||
mkdir build;
|
||||
ln -s ../../bootstrap.build ../../root.build build/;
|
||||
cat <<EOI >=config.h.in;
|
||||
#undef _GNU_SOURCE
|
||||
#undef _POSIX_SOURCE
|
||||
#undef FOO
|
||||
EOI
|
||||
$* <<EOI &config.h &config.h.d;
|
||||
gnu = false
|
||||
./: h{config}: in{config}
|
||||
{
|
||||
autoconf.substitutions = _GNU_SOURCE@$gnu _POSIX_SOURCE@true
|
||||
FOO = true
|
||||
}
|
||||
EOI
|
||||
cat config.h >>EOO
|
||||
#undef _GNU_SOURCE
|
||||
#define _POSIX_SOURCE 1
|
||||
#define FOO 1
|
||||
EOO
|
||||
|
@ -43,6 +43,11 @@ namespace build2
|
||||
// Built-in checks prefix.
|
||||
//
|
||||
vp.insert<string> ("autoconf.prefix");
|
||||
|
||||
// Substitution map (an alias for in.substitutions).
|
||||
//
|
||||
vp.insert_alias (*vp.find ("in.substitutions"),
|
||||
"autoconf.substitutions");
|
||||
}
|
||||
|
||||
// Register the rule.
|
||||
|
@ -144,6 +144,7 @@ namespace build2
|
||||
const char* nl,
|
||||
char sym,
|
||||
bool strict,
|
||||
const substitution_map* smap,
|
||||
const optional<string>& null) const
|
||||
{
|
||||
auto ws = [] (char c)
|
||||
@ -182,7 +183,7 @@ namespace build2
|
||||
&l,
|
||||
a, &t,
|
||||
&dd, &dd_skip,
|
||||
nl, strict, &null,
|
||||
nl, strict, smap, &null,
|
||||
&s] (const string& name,
|
||||
bool value = true) -> optional<bool>
|
||||
{
|
||||
@ -195,7 +196,7 @@ namespace build2
|
||||
a, t,
|
||||
dd, dd_skip,
|
||||
name, 1 /* flags */,
|
||||
strict, null));
|
||||
strict, smap, null));
|
||||
|
||||
assert (ov); // C identifier is a valid variable name.
|
||||
string& v (*ov);
|
||||
@ -470,7 +471,8 @@ namespace build2
|
||||
}
|
||||
}
|
||||
|
||||
in::rule::process (l, a, t, dd, dd_skip, s, b, nl, sym, strict, null);
|
||||
in::rule::process (
|
||||
l, a, t, dd, dd_skip, s, b, nl, sym, strict, smap, null);
|
||||
}
|
||||
|
||||
string rule::
|
||||
@ -478,6 +480,7 @@ namespace build2
|
||||
action a, const target& t,
|
||||
const string& n,
|
||||
optional<uint64_t> flags,
|
||||
const substitution_map* smap,
|
||||
const optional<string>& null) const
|
||||
{
|
||||
if (flags)
|
||||
@ -508,7 +511,7 @@ namespace build2
|
||||
// variable is unlikely, something like const or volatile is
|
||||
// possible. Since there is no way to undefine a buildfile variable
|
||||
// (becasue we could always see a value from the outer scope), we
|
||||
// will treat null as an indication to use the built-in check.
|
||||
// will treat null as an instruction to use the built-in check.
|
||||
// While this clashes with the in.null semantics, it's just as
|
||||
// easy to set the variable to the real default value as to null.
|
||||
//
|
||||
@ -554,11 +557,31 @@ namespace build2
|
||||
(!up || strchr (i->modifier, '!') != nullptr)) ? i : nullptr;
|
||||
};
|
||||
|
||||
// Note: original name in variable lookup.
|
||||
// Return true if there is a custom substitution for the name.
|
||||
//
|
||||
// Note: see above on the special NULL semantics.
|
||||
//
|
||||
auto custom = [&t, smap] (const string& n) -> bool
|
||||
{
|
||||
if (smap != nullptr)
|
||||
{
|
||||
auto i (smap->find (n));
|
||||
|
||||
// Note that we treat NULL as the "use built-in check" instruction
|
||||
// (see above). So it's a return, not fall through.
|
||||
//
|
||||
if (i != smap->end ())
|
||||
return i->second.has_value ();
|
||||
}
|
||||
|
||||
return static_cast<bool> (t[n]);
|
||||
};
|
||||
|
||||
// Note: original name in the custom substitution lookup.
|
||||
//
|
||||
const check* c (find (en, pn == nullptr));
|
||||
|
||||
if (c != nullptr && !t[n])
|
||||
if (c != nullptr && !custom (n))
|
||||
{
|
||||
// The plan is as follows: keep adding base checks (suppressing
|
||||
// duplicates) followed by the main check while prefixing all the
|
||||
@ -616,9 +639,10 @@ namespace build2
|
||||
// Buildscript).
|
||||
//
|
||||
auto base = [this,
|
||||
&l, &t, a, &null,
|
||||
&l, &t, a, smap, &null,
|
||||
&md, &p, &ns,
|
||||
&find, &append, &prefix] (const string& n,
|
||||
&find, &custom,
|
||||
&append, &prefix] (const string& n,
|
||||
const char* bs,
|
||||
const auto& base) -> void
|
||||
{
|
||||
@ -666,9 +690,9 @@ namespace build2
|
||||
|
||||
md.checks.emplace (pn, n);
|
||||
|
||||
if (t[n])
|
||||
append (
|
||||
this->in::rule::lookup (l, a, t, n, nullopt, null).c_str ());
|
||||
if (custom (n))
|
||||
append (this->in::rule::lookup (
|
||||
l, a, t, n, nullopt, smap, null).c_str ());
|
||||
else
|
||||
{
|
||||
if (*c->base != '\0')
|
||||
@ -706,7 +730,7 @@ namespace build2
|
||||
}
|
||||
}
|
||||
|
||||
return in::rule::lookup (l, a, t, n, nullopt, null);
|
||||
return in::rule::lookup (l, a, t, n, nullopt, smap, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ namespace build2
|
||||
const char*,
|
||||
char,
|
||||
bool,
|
||||
const substitution_map*,
|
||||
const optional<string>&) const override;
|
||||
|
||||
virtual string
|
||||
@ -46,6 +47,7 @@ namespace build2
|
||||
action, const target&,
|
||||
const string&,
|
||||
optional<uint64_t>,
|
||||
const substitution_map*,
|
||||
const optional<string>&) const override;
|
||||
};
|
||||
}
|
||||
|
@ -9,6 +9,6 @@ url: https://github.com/build2/libbuild2-autoconf
|
||||
email: users@build2.org
|
||||
build-warning-email: builds@build2.org
|
||||
builds: all
|
||||
depends: * build2 >= 0.15.0-
|
||||
depends: * bpkg >= 0.15.0-
|
||||
depends: * build2 >= 0.16.0-
|
||||
depends: * bpkg >= 0.16.0-
|
||||
tests: * libbuild2-autoconf-tests == $
|
||||
|
Loading…
Reference in New Issue
Block a user