aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/buildfile
blob: 578a4c84f43057b21aab716092c8c00294c1f569 (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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# file      : libbuild2/buildfile
# license   : MIT; see accompanying LICENSE file

# NOTE: remember to update bundled_modules in libbuild2/module.cxx if adding a
#       new module.
#
bundled_modules = bash/ bin/ c/ cc/ cxx/ in/ version/

./: lib{build2} $bundled_modules

# Note that we have to load these buildfiles explicitly in order to have their
# imports processed before the $config.save() call below. Failed that, we will
# get a warning about saving unused config.import.* values.
#
include $bundled_modules

# A module should treat lib{build2} as an "implied interface dependency"
# meaning that it can link it as an implementation dependency and assume that
# whomever imports and links this module will also import and link lib{build2}
# explicitly. A module should also assume that lib{butl} will always be an
# interface dependency of lib{build2} and therefore need not be explicitly
# imported or linked.
#
import int_libs = libbutl%lib{butl}

lib{build2}: libul{build2}:                                            \
  {hxx ixx txx cxx}{* -utility-*installed -config -version -*.test...} \
  {hxx}{config version}

# Note that this won't work in libul{} since it's not installed.
#
lib{build2}: cxx{utility-installed}:   for_install = true
lib{build2}: cxx{utility-uninstalled}: for_install = false

# These are "core modules" that come bundled with libbuild2 (see also unit
# tests loop below). Note that the build system core can still function
# without them or with their alternative implementations. Also note that
# config/utility.?xx are part of the build system core (see comments in the
# header for details).
#
# NOTE: remember to update import_modules() in libbuild2/modules.cxx if adding
#       a new such module.
#
libul{build2}: config/{hxx ixx txx cxx}{** -host-config -**.test...} \
               config/cxx{host-config}

# This will of course blow up spectacularly if we are cross-compiling. But
# let's wait and enjoy the fireworks (and get a sense of why someone would
# want to cross-compile a build system).
#
config/cxx{host-config}: config/in{host-config}
{
  # For the ~host configuration we only want c/cxx/cc and bin that they load.
  # For ~build2 we want to keep everything except dist.
  #
  # We also remove comment lines which could be confused with preprocessor
  # directives by some lesser compilers.
  #
  # For ~build2 also filter out config.install.chroot -- we definitely don't
  # want it carried through.
  #
  build2_config = $regex.replace_lines(                 \
    $config.save(),                                     \
    '^ *(#|config\.dist\.|config\.install\.chroot).*$', \
    [null],                                             \
    return_lines)

  host_config = $regex.replace_lines(             \
    $build2_config,                               \
    '^ *config\.(c[. ]|cxx[. ]|cc[.]|bin[.]).*$', \
    '$&',                                         \
    format_no_copy return_lines)
}

libul{build2}: dist/{hxx ixx txx cxx}{** -**.test...}

libul{build2}: install/{hxx ixx txx cxx}{** -**.test...}

libul{build2}: test/{hxx ixx txx cxx}{** -**-options -**.test...} \
               test/script/{hxx ixx cxx}{builtin-options}

libul{build2}: $int_libs

# Include the generated config and version headers into the distribution (so
# that we don't pick up installed ones) and don't remove them when cleaning in
# src (so that clean results in a state identical to distributed).
#
hxx{config}: in{config}
hxx{version}: in{version} $src_root/manifest

hxx{config version}:
{
  dist  = true
  clean = ($src_root != $out_root)
}

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

for t:         cxx{ *.test...} \
        config/cxx{**.test...} \
          dist/cxx{**.test...} \
       install/cxx{**.test...} \
          test/cxx{**.test...}
{
  d = $directory($t)
  n = $name($t)...
  b = $path.base($name($t))

  ./: $d/exe{$n}: $t $d/{hxx ixx txx}{+$n} $d/testscript{+$n +$b+*.test...}
  $d/exe{$n}: libul{build2}: bin.whole = false
  $d/exe{$n}: cxx{utility-uninstalled}
}

# Build options.
#
# NOTE: this scope happens to be outer to the bundled modules which means they
#       will inherit any scope-wide options. So we should normally only set
#       them on targets.
#
obja{*}: cxx.poptions += -DLIBBUILD2_STATIC_BUILD
objs{*}: cxx.poptions += -DLIBBUILD2_SHARED_BUILD

# Pass our compiler target to be used as build2 host and our out_root to be
# used as the build system import path (unless cross-compiling and not
# forgetting to escape backslashes on Windows).
#
{obja objs}{context}: cxx.poptions += "-DBUILD2_HOST_TRIPLET=\"$cxx.target\""

# Note that we used to compare complete target triplets but that proved too
# strict. For example, we may be running on x86_64-apple-darwin17.7.0 while
# the compiler is targeting x86_64-apple-darwin17.3.0.
#
cross = ($cxx.target.cpu != $build.host.cpu || \
         $cxx.target.system != $build.host.system)

if! $cross
{
  {obja objs}{context}: cxx.poptions += \
    -DBUILD2_IMPORT_PATH=\"$regex.replace($out_root, '\\', '\\\\')\"

  # While this object file should only be linked when we are installing, it
  # will be compiled even in the uninstalled case.
  #
  if ($install.root != [null])
    {obja objs}{utility-installed}: cxx.poptions += \
      -DBUILD2_INSTALL_LIB=\"$regex.replace(\
        $install.resolve($install.lib), '\\', '\\\\')\"
}

if ($cxx.target.class != 'windows')
{
  libul{build2}: cxx.libs += -lpthread

  if ($cxx.target.class != "bsd")
    libul{build2}: cxx.libs += -ldl
}

# Export options.
#
lib{build2}:
{
  cxx.export.poptions = "-I$out_root" "-I$src_root"
  cxx.export.libs = $int_libs
}

# While we don't call any pthread_*() functions in our API, this appears to be
# needed for some std::thread implementations (like libstdc++).
#
if ($cxx.target.class != 'windows')
  lib{build2}: cxx.export.libs += -lpthread

liba{build2}: cxx.export.poptions += -DLIBBUILD2_STATIC
libs{build2}: cxx.export.poptions += -DLIBBUILD2_SHARED

# For pre-releases use the complete version to make sure they cannot be used
# in place of another pre-release or the final version. See the version module
# for details on the version.* variable values.
#
if $version.pre_release
  lib{build2}: bin.lib.version = @"-$version.project_id"
else
  lib{build2}: bin.lib.version = @"-$version.major.$version.minor"

# Generated options parser.
#
test/script/
{
  if $cli.configured
  {
    cli.cxx{builtin-options}: cli{builtin}

    cli.options += --std c++11 -I $src_root --include-with-brackets \
--include-prefix libbuild2/test/script --guard-prefix LIBBUILD2_TEST_SCRIPT \
--cli-namespace build2::test::script::cli --generate-vector-scanner \
--generate-specifier --suppress-usage

    cli.cxx{*}:
    {
      # Include the generated cli files into the distribution and don't remove
      # them when cleaning in src (so that clean results in a state identical
      # to distributed). But don't install their headers since they are only
      # used internally in the testscript implementation.
      #
      dist  = true
      clean = ($src_root != $out_root)
      install = false

      # We keep the generated code in the repository so copy it back to src in
      # case of a forwarded configuration.
      #
      backlink = overwrite
    }
  }
  else
    # No install for the pre-generated case.
    #
    hxx{builtin-options}@./ ixx{builtin-options}@./: install = false
}

# Install into the libbuild2/ subdirectory of, say, /usr/include/
# recreating subdirectories.
#
{hxx ixx txx}{*}:
{
  install         = include/libbuild2/
  install.subdirs = true
}