summaryrefslogtreecommitdiff
path: root/cli/cli/buildfile
blob: 92c3e6ebcbfd5a097b381824b70e2fefec20555e (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# file      : cli/buildfile
# license   : MIT; see accompanying LICENSE file

import libs = libcutl%lib{cutl}

./: exe{cli}: cxx{cli} libue{cli}

# Target metadata, see also --build2-metadata in cli.cxx.
#
exe{cli}:
{
  export.metadata = 1 cli
  cli.name = [string] cli
  cli.version  = $version
  cli.checksum = $version
}

hdr = {hxx ixx txx}{* -cli -version -options -*.test...}
src =           cxx{* -cli -version -options -*.test...}

all_s = semantics/{hxx ixx txx cxx}{*}
all_t = traversal/{hxx ixx txx cxx}{*}

libue{cli}: $hdr $src $all_s $all_t {hxx}{version} $libs

hxx{version}: in{version} $src_root/manifest

# Build options (apply to both bootstrap and final version).
#
cxx.poptions =+ "-I$out_root" "-I$src_root"

# CLI uses its own generated code to handle the command line. To solve the
# chicken and egg problem that this poses we keep pregenerated source code in
# pregenerated/.
#
# In the consumption build ($config.cli.develop == false), we just use this
# pregenerated source code to build the final version of the compiler. In the
# development build ($config.cli.develop == true) we use this pregenerated
# source code to build a bootstrap version of the compiler which we then use
# to regenerate the source code and build that final version from that.

## Consumption build ($develop == false).
#

# Use pregenerated versions to build the final version of cli.
#
libue{cli}: pregenerated/{hxx ixx cxx}{**}: include = (!$develop)

if! $develop
  cxx.poptions =+ "-I($src_base/pregenerated)" # Note: must come first.

# Distribute pregenerated versions only in the consumption build.
#
pregenerated/{hxx ixx cxx}{*}: dist = (!$develop)

#
##

## Development build ($develop == true).
#
libue{cli}: {hxx ixx cxx}{options}: include = $develop

# Bootstrap.
#
# The plan is as follows:
#
# 1. Build the bootstrap version of cli using a copy of options.?xx saved in
#    pregenerated/cli/.
#
# 2. Use that to regenerate options.?xx. If the result differs from the saved
#    version, copy it over and fail the build, asking for a restart.
#
# 3. Otherwise, proceed to build the final version of cli using regenerated
#    options.?xx.
#
pregenerated/
{
  # This should only apply to the bootstrap build.
  #
  cxx.poptions =+ "-I$src_base" # Note: must come first.

  cli/
  {
    # Note: semantics/ and traversal/ do not include options.hxx so we can
    #       share their object files.
    #
    exe{cli}: obj{cli $name($src) options} ../../{$all_s $all_t} $libs

    for s: cli $name($src)
      obj{$s}: ../../cxx{$s} $libs

    obj{options}: {hxx ixx cxx}{options}

    obj{cli}: cxx.poptions += -DCLI_BOOTSTRAP
  }
}

# In the development build distribute regenerated {hxx ixx cxx}{options},
# remapping their locations to the paths of the pregenerated versions (which
# are only distributed in the consumption build; see above). This way we make
# sure that the distributed files are always up-to-date.
#
<{hxx ixx cxx}{options}>: cli{options} pregenerated/cli/exe{cli}
{
  dist = ($develop ? pregenerated/cli/ : false)

  # Symlink the generated code in src for convenience of development.
  #
  backlink = true
}
%
if $develop
{{
  options = --include-with-brackets --include-prefix cli   \
            --guard-prefix CLI --generate-file-scanner     \
            --generate-specifier --generate-modifier       \
            --suppress-undocumented --reserved-name stdout

  diag cli ($<[0]) -> $>
  ($<[1]) $options -o $out_base $path($<[0])

  # If the result differs from the bootstrap version, copy it over and
  # request the build restart.
  #
  if diff $src_base/pregenerated/cli/options.hxx $path($>[0]) >- && \
     diff $src_base/pregenerated/cli/options.ixx $path($>[1]) >- && \
     diff $src_base/pregenerated/cli/options.cxx $path($>[2]) >-
    exit
  end

  cp $path($>[0]) $src_base/pregenerated/cli/options.hxx
  cp $path($>[1]) $src_base/pregenerated/cli/options.ixx
  cp $path($>[2]) $src_base/pregenerated/cli/options.cxx

  exit "bootstrap options.?xx have changed, restart the build"
}}

#
##

# Pass the copyright notice extracted from the LICENSE file.
#
obj{cli}: cxx.poptions += -DCLI_COPYRIGHT=\"$copyright\"

# Unit tests.
#
exe{*.test}:
{
  test = true
  install = false
}

for t: cxx{**.test...}
{
  d = $directory($t)
  n = $name($t)...

  ./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n}
  $d/exe{$n}: libue{cli}: bin.whole = false
}