aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/bin/functions.cxx
blob: 1c6c0f4abb54426793cba5bb5dd8228b12092bf6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
// file      : libbuild2/bin/functions.cxx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

#include <libbuild2/function.hxx>
#include <libbuild2/variable.hxx>

#include <libbuild2/bin/utility.hxx>

namespace build2
{
  namespace bin
  {
    void
    functions (function_map& m)
    {
      function_family f (m, "bin");

      // Given a linker output target type ("exe", "lib[as]", or "libu[eas]")
      // and a lib{} target group, return the type of library member ("liba"
      // or "libs") that will be picked when linking this library group to
      // this target type.
      //
      // The lib{} target is only used to resolve the scope to lookup the
      // bin.lib value on. As a result, it can be omitted in which case the
      // function call scope is used (covers project-local lib{} targets).
      //
      // Note that this function is not pure.
      //
      // @@ TODO: support for target (note that if it's out of project, then
      //          it's imported, which means it might still be qualified.)
      //
      // @@ TODO: support utility libraries (see link_member()).
      //
      f.insert (".link_member", false) += [] (const scope* bs, names ns)
      {
        string t (convert<string> (move (ns)));

        if (bs == nullptr)
          fail << "bin.link_member() called out of scope";

        const scope* rs (bs->root_scope ());

        if (rs == nullptr)
          fail << "bin.link_member() called out of root scope";

        const target_type* tt (bs->find_target_type (t));

        if (tt == nullptr)
          fail << "unknown target type '" << t << "'";

        otype ot (link_type (*tt).type);

        switch (ot)
        {
        case otype::e:
        case otype::a:
        case otype::s:
          break;
        default:
          fail << "target type " << t << " is not linker output";
        }

        lorder lo (link_order (*bs, ot));
        lmembers lm (link_members (*rs));

        return link_member (lm, lo).first == otype::s ? "libs" : "liba";
      };
    }
  }
}