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
|
Besides the built-in configuration options, custom substitutions can be
|
||||||
specified as `buildfile` variables in the same way as with the
|
specified as `buildfile` variables or key-value pairs in the same way as with
|
||||||
[`in`][module-in] module. For example:
|
the [`in`][module-in] module. For example, as `buildfile` variables:
|
||||||
|
|
||||||
```
|
```
|
||||||
/* config.h.in */
|
/* 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}
|
h{config}: in{config}
|
||||||
|
@ -7,5 +7,5 @@ license: MIT ; MIT License.
|
|||||||
description-file: README.md
|
description-file: README.md
|
||||||
url: https://github.com/build2/libbuild2-autoconf
|
url: https://github.com/build2/libbuild2-autoconf
|
||||||
email: users@build2.org
|
email: users@build2.org
|
||||||
depends: * build2 >= 0.15.0-
|
depends: * build2 >= 0.16.0-
|
||||||
depends: * bpkg >= 0.15.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
|
# define PREFIX_zzz_TEST_DUMMY5_H PREFIX_zzz_TEST_DUMMY4_H
|
||||||
#endif /*zzz_TEST_DUMMY3_H*/
|
#endif /*zzz_TEST_DUMMY3_H*/
|
||||||
EOO
|
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.
|
// Built-in checks prefix.
|
||||||
//
|
//
|
||||||
vp.insert<string> ("autoconf.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.
|
// Register the rule.
|
||||||
|
@ -144,6 +144,7 @@ namespace build2
|
|||||||
const char* nl,
|
const char* nl,
|
||||||
char sym,
|
char sym,
|
||||||
bool strict,
|
bool strict,
|
||||||
|
const substitution_map* smap,
|
||||||
const optional<string>& null) const
|
const optional<string>& null) const
|
||||||
{
|
{
|
||||||
auto ws = [] (char c)
|
auto ws = [] (char c)
|
||||||
@ -182,7 +183,7 @@ namespace build2
|
|||||||
&l,
|
&l,
|
||||||
a, &t,
|
a, &t,
|
||||||
&dd, &dd_skip,
|
&dd, &dd_skip,
|
||||||
nl, strict, &null,
|
nl, strict, smap, &null,
|
||||||
&s] (const string& name,
|
&s] (const string& name,
|
||||||
bool value = true) -> optional<bool>
|
bool value = true) -> optional<bool>
|
||||||
{
|
{
|
||||||
@ -195,7 +196,7 @@ namespace build2
|
|||||||
a, t,
|
a, t,
|
||||||
dd, dd_skip,
|
dd, dd_skip,
|
||||||
name, 1 /* flags */,
|
name, 1 /* flags */,
|
||||||
strict, null));
|
strict, smap, null));
|
||||||
|
|
||||||
assert (ov); // C identifier is a valid variable name.
|
assert (ov); // C identifier is a valid variable name.
|
||||||
string& v (*ov);
|
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::
|
string rule::
|
||||||
@ -478,6 +480,7 @@ namespace build2
|
|||||||
action a, const target& t,
|
action a, const target& t,
|
||||||
const string& n,
|
const string& n,
|
||||||
optional<uint64_t> flags,
|
optional<uint64_t> flags,
|
||||||
|
const substitution_map* smap,
|
||||||
const optional<string>& null) const
|
const optional<string>& null) const
|
||||||
{
|
{
|
||||||
if (flags)
|
if (flags)
|
||||||
@ -508,7 +511,7 @@ namespace build2
|
|||||||
// variable is unlikely, something like const or volatile is
|
// variable is unlikely, something like const or volatile is
|
||||||
// possible. Since there is no way to undefine a buildfile variable
|
// possible. Since there is no way to undefine a buildfile variable
|
||||||
// (becasue we could always see a value from the outer scope), we
|
// (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
|
// 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.
|
// 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;
|
(!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));
|
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
|
// The plan is as follows: keep adding base checks (suppressing
|
||||||
// duplicates) followed by the main check while prefixing all the
|
// duplicates) followed by the main check while prefixing all the
|
||||||
@ -616,11 +639,12 @@ namespace build2
|
|||||||
// Buildscript).
|
// Buildscript).
|
||||||
//
|
//
|
||||||
auto base = [this,
|
auto base = [this,
|
||||||
&l, &t, a, &null,
|
&l, &t, a, smap, &null,
|
||||||
&md, &p, &ns,
|
&md, &p, &ns,
|
||||||
&find, &append, &prefix] (const string& n,
|
&find, &custom,
|
||||||
const char* bs,
|
&append, &prefix] (const string& n,
|
||||||
const auto& base) -> void
|
const char* bs,
|
||||||
|
const auto& base) -> void
|
||||||
{
|
{
|
||||||
auto df = make_diag_frame (
|
auto df = make_diag_frame (
|
||||||
[&n] (const diag_record& dr)
|
[&n] (const diag_record& dr)
|
||||||
@ -666,9 +690,9 @@ namespace build2
|
|||||||
|
|
||||||
md.checks.emplace (pn, n);
|
md.checks.emplace (pn, n);
|
||||||
|
|
||||||
if (t[n])
|
if (custom (n))
|
||||||
append (
|
append (this->in::rule::lookup (
|
||||||
this->in::rule::lookup (l, a, t, n, nullopt, null).c_str ());
|
l, a, t, n, nullopt, smap, null).c_str ());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (*c->base != '\0')
|
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*,
|
const char*,
|
||||||
char,
|
char,
|
||||||
bool,
|
bool,
|
||||||
|
const substitution_map*,
|
||||||
const optional<string>&) const override;
|
const optional<string>&) const override;
|
||||||
|
|
||||||
virtual string
|
virtual string
|
||||||
@ -46,6 +47,7 @@ namespace build2
|
|||||||
action, const target&,
|
action, const target&,
|
||||||
const string&,
|
const string&,
|
||||||
optional<uint64_t>,
|
optional<uint64_t>,
|
||||||
|
const substitution_map*,
|
||||||
const optional<string>&) const override;
|
const optional<string>&) const override;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,6 @@ url: https://github.com/build2/libbuild2-autoconf
|
|||||||
email: users@build2.org
|
email: users@build2.org
|
||||||
build-warning-email: builds@build2.org
|
build-warning-email: builds@build2.org
|
||||||
builds: all
|
builds: all
|
||||||
depends: * build2 >= 0.15.0-
|
depends: * build2 >= 0.16.0-
|
||||||
depends: * bpkg >= 0.15.0-
|
depends: * bpkg >= 0.16.0-
|
||||||
tests: * libbuild2-autoconf-tests == $
|
tests: * libbuild2-autoconf-tests == $
|
||||||
|
Loading…
Reference in New Issue
Block a user