Welcome to mirror list, hosted at ThFree Co, Russian Federation.

sanity.jam « jam-files - github.com/moses-smt/mosesdecoder.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: b16343c7b794c13eb4537d4d493fad11155b7252 (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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
import modules ;
import option ;
import os ;
import path ;
import project ;
import build-system ;
import version ;

#Shell with trailing line removed http://lists.boost.org/boost-build/2007/08/17051.php
rule trim-nl ( str extras * ) {
return [ MATCH "([^
]*)" : $(str) ] $(extras) ;
}
rule _shell ( cmd : extras * ) {
  return [ trim-nl [ SHELL $(cmd) : $(extras) ] ] ;
}

rule shell_or_fail ( cmd ) {
  local ret = [ SHELL $(cmd) : exit-status ] ;
  if $(ret[2]) != 0 {
    exit $(cmd) failed : 1 ;
  }
}

rule shell_or_die ( cmd ) {
  local ret = [ SHELL $(cmd) : exit-status ] ;
  if $(ret[2]) != 0 {
    exit $(cmd) failed : 1 ;
  }
  return [ trim-nl $(ret[1]) ] ;
}

cxxflags = [ os.environ "CXXFLAGS" ] ;
cflags = [ os.environ "CFLAGS" ] ;
ldflags = [ os.environ "LDFLAGS" ] ;

#Run g++ with empty main and these arguments to see if it passes.  
rule test_flags ( flags * : main ? ) {
  flags = $(cxxflags) $(ldflags) $(flags) ;
  if ! $(main) {
    main = "int main() {}" ;
  }
  local cmd = "bash -c \"g++ "$(flags:J=" ")" -x c++ - <<<'$(main)' -o $(TOP)/dummy >/dev/null 2>/dev/null && rm $(TOP)/dummy 2>/dev/null\"" ;
  local ret = [ SHELL $(cmd) : exit-status ] ;
  if --debug-configuration in [ modules.peek : ARGV ] {
    echo $(cmd) ;
    echo $(ret) ;
  }
  if $(ret[2]) = 0 {
    return true ;
  } else {
    return ;
  }
}

rule test_header ( name ) {
  return [ test_flags "-include $(name)" ] ;
}

requirements = ;

FORCE-STATIC = [ option.get "static" : : "yes" ] ;
if $(FORCE-STATIC) {
  requirements += <link>static <runtime-link>static ;
}

rule test_library ( name ) {
  if $(FORCE-STATIC) {
    return [ test_flags "-Wl,-Bstatic -l$(name) -Wl,-Bdynamic" ] ;
  } else {
    return [ test_flags "-l$(name)" ] ;
  }
}

{
  local cleaning = [ option.get "clean" : : yes ] ;
  cleaning ?= [ option.get "clean-all" : no : yes ] ;
  if "clean" in [ modules.peek : ARGV ] {
    cleaning = yes ;
  }
  constant CLEANING : $(cleaning) ;
}

shared-command-line = ;
local argv = [ modules.peek : ARGV ] ;
while $(argv) {
  if $(argv[1]) = "link=shared" {
    shared-command-line = <link>shared ;
  }
  argv = $(argv[2-]) ;
}

#Determine if a library can be compiled statically.  
rule auto-shared ( name : additional * ) {

  additional ?= "" ;
  if $(shared-command-line) = "<link>shared" {
    return "<link>shared" ;
  } else {
    if [ test_flags $(additional)" -Wl,-Bstatic -l"$(name)" -Wl,-Bdynamic" ] {
      return ;
    } else {
      if $(FORCE-STATIC) {
        echo "Could not statically link against lib $(name).  Your build will probably fail." ;
        return ;
      } else {
        return "<link>shared" ;
      }
    }
  }
}

# MacPorts' default location is /opt/local -- use this if no path is given.
with-macports = [ option.get "with-macports" : : "/opt/local" ] ;
if $(with-macports) {
  using darwin ;
  ECHO "Using --with-macports=$(with-macports), implying use of darwin GCC" ;

  L-boost-search = -L$(with-macports)/lib ;
  boost-search = <search>$(with-macports)/lib ;
  I-boost-include = -I$(with-macports)/include ;
  boost-include = <include>$(with-macports)/include ;
  requirements += $(boost-include) ;
} else {
  with-boost = [ option.get "with-boost" ] ;
  with-boost ?= [ os.environ "BOOST_ROOT" ] ;
  if $(with-boost) {
    L-boost-search = -L$(with-boost)/lib" "-L$(with-boost)/lib64 ;
    boost-search = <search>$(with-boost)/lib <search>$(with-boost)/lib64 ;
    I-boost-include = -I$(with-boost)/include ;
    boost-include = <include>$(with-boost)/include ;
    requirements += $(boost-include) ;
  } else {
    L-boost-search = "" ;
    boost-search = ;
    I-boost-include = "" ;
    boost-include = ;
  }
}
 
#Convenience rule for boost libraries.  Defines library boost_$(name).  
rule boost-lib ( name macro : deps * ) {
  lib boost_$(name)_static : $(deps) : $(boost-search) <name>boost_$(name)$(boost-lib-version) <link>static ;
  lib boost_$(name)_shared : $(deps) : $(boost-search) <name>boost_$(name)$(boost-lib-version) <link>shared : : <define>BOOST_$(macro) ;

  alias boost_$(name)_default : $(deps) : <link>static:<source>boost_$(name)_static <link>shared:<source>boost_$(name)_shared ;

  alias boost_$(name)_static_works : $(deps) : [ check-target-builds empty_test_shared "Shared Boost" : <source>boost_$(name)_default : <source>boost_$(name)_static ] ;
  alias boost_$(name) : $(deps) : [ check-target-builds empty_test_static "Static Boost" : <source>boost_$(name)_static_works : <source>boost_$(name)_shared ] ;
}

#Argument is e.g. 103600
rule boost ( min-version ) {
  local cmd = "bash -c \"g++ "$(I-boost-include)" -dM -x c++ -E /dev/null -include boost/version.hpp 2>/dev/null |grep '#define BOOST_'\"" ;
  local boost-shell = [ SHELL "$(cmd)" : exit-status ] ;
  if $(boost-shell[2]) != 0 && $(CLEANING) = no {
    echo Failed to run "$(cmd)" ;
    exit Boost does not seem to be installed or g++ is confused. : 1 ;
  }
  constant BOOST-VERSION : [ MATCH "#define BOOST_VERSION ([0-9]*)" : $(boost-shell[1]) ] ;
  if $(BOOST-VERSION) < $(min-version) && $(CLEANING) = no {
    exit You have Boost $(BOOST-VERSION).  This package requires Boost at least $(min-version) (and preferably newer). : 1 ;
  }
  # If matching version tags exist, use them.  
  boost-lib-version = [ MATCH "#define BOOST_LIB_VERSION \"([^\"]*)\"" : $(boost-shell[1]) ] ;
  if [ test_flags $(L-boost-search)" -lboost_program_options-"$(boost-lib-version) ] {
    boost-lib-version = "-"$(boost-lib-version) ;
  } else {
    boost-lib-version = "" ;
  }

  #Crazy amount of testing to make sure that BOOST_TEST_DYN_LINK is defined properly.
  lib boost_unit_test_framework_static_test : : $(boost-search) <name>boost_unit_test_framework$(boost-lib-version) <link>static ;
  obj empty_test_static.o : jam-files/empty_test_main.cc boost_unit_test_framework_static_test : $(boost-include) ;
  exe empty_test_static : empty_test_static.o boost_unit_test_framework_static_test ;

  lib boost_unit_test_framework_shared_test : : $(boost-search) <name>boost_unit_test_framework$(boost-lib-version) <link>shared : : <define>BOOST_TEST_DYN_LINK ;
  obj empty_test_shared.o : jam-files/empty_test_main.cc boost_unit_test_framework_shared_test : $(boost-include) ;
  exe empty_test_shared : empty_test_shared.o boost_unit_test_framework_shared_test ;

  explicit empty_test_static.o empty_test_static empty_test_shared.o empty_test_shared ;


  #See tools/build/v2/contrib/boost.jam in a boost distribution for a table of macros to define.   
  boost-lib system SYSTEM_DYN_LINK ;
  boost-lib thread THREAD_DYN_DLL : boost_system ;
  boost-lib program_options PROGRAM_OPTIONS_DYN_LINK ;
  boost-lib iostreams IOSTREAMS_DYN_LINK ;
  boost-lib filesystem FILE_SYSTEM_DYN_LINK ;
  boost-lib unit_test_framework TEST_DYN_LINK ;
#  if $(BOOST-VERSION) >= 104800 {
#    boost-lib chrono CHRONO_DYN_LINK ;
#    boost-lib timer TIMER_DYN_LINK : boost_chrono ;
#  }
}
 
#Link normally to a library, but sometimes static isn't installed so fall back to dynamic.
rule external-lib ( name : search-path * : deps * ) {
  lib $(name) : : [ auto-shared $(name) : "-L"$(search-path) ] <search>$(search-path) <use>$(deps) ;
}

#Write the current command line to previous.sh.  This does not do shell escaping.  
{
  local build-log = $(TOP)/previous.sh ;
  if ! [ path.exists $(build-log) ] {
    SHELL "touch \"$(build-log)\" && chmod +x \"$(build-log)\"" ;
  }
  local script = [ modules.peek : ARGV ] ;
  if $(script[1]) = "./jam-files/bjam" {
    #The ./bjam shell script calls ./jam-files/bjam so that appears in argv but
    #we want ./bjam to appear so the environment variables are set correctly.  
    script = "./bjam "$(script[2-]:J=" ") ;
  } else {
    script = $(script:J=" ") ;
  }
  script = "#!/bin/sh\n$(script)\n" ;
  local ignored = @($(build-log):E=$(script)) ;
}

#Boost jam's static clang for Linux is buggy.
requirements += <cxxflags>$(cxxflags) <cflags>$(cflags) <linkflags>$(ldflags) <os>LINUX,<toolset>clang:<link>shared ;

if ! [ option.get "without-libsegfault" : : "yes" ] && ! $(FORCE-STATIC) {
  #libSegFault prints a stack trace on segfault.  Link against it if available.  
  if [ test_flags "-lSegFault" ] {
    external-lib SegFault ;
    requirements += <library>SegFault ;
  }
}

if [ option.get "git" : : "yes" ] {
  local revision = [ _shell "git rev-parse --verify HEAD |head -c 7" ] ;
  constant GITTAG : "/"$(revision) ;
} else {
  constant GITTAG : "" ;
}

local prefix = [ option.get "prefix" ] ;
if $(prefix) {
  prefix = [ path.root $(prefix) [ path.pwd ] ] ;
  prefix = $(prefix)$(GITTAG) ;
} else {
  prefix = $(TOP)$(GITTAG) ;
}

path-constant PREFIX : $(prefix) ;

path-constant BINDIR : [ option.get "bindir" : $(PREFIX)/bin ] ;
path-constant LIBDIR : [ option.get "libdir" : $(PREFIX)/lib ] ;
rule install-bin-libs ( deps * ) {
  install prefix-bin : $(deps) : <location>$(BINDIR) <install-dependencies>on <install-type>EXE <link>shared:<dll-path>$(LIBDIR) ;
  install prefix-lib : $(deps) : <location>$(LIBDIR) <install-dependencies>on <install-type>LIB <link>shared:<dll-path>$(LIBDIR) ;
}
rule install-headers ( name : list * : source-root ? ) {
  local includedir = [ option.get "includedir" : $(prefix)/include ] ;
  source-root ?= "." ;
  install $(name) : $(list) : <location>$(includedir) <install-source-root>$(source-root) ;
}

rule build-projects ( projects * ) {
  for local p in $(projects) {
    build-project $(p) ;
  }
}

#Only one post build hook is allowed.  Allow multiple.  
post-hooks = ;
rule post-build ( ok ? ) {
  for local r in $(post-hooks) {
    $(r) $(ok) ;
  }
}
IMPORT $(__name__) : post-build : : $(__name__).post-build ;
build-system.set-post-build-hook $(__name__).post-build ;
rule add-post-hook ( names * ) {
  post-hooks += $(names) ;
}

rule failure-message ( ok ? ) {
  if $(ok) != "ok" {
    local args = [ modules.peek : ARGV ] ;
    local args = $(args:J=" ") ;
    if --debug-configuration in [ modules.peek : ARGV ] {
      echo "The build failed with command line: " ;
      echo "  $(args)" ;
      echo "If you need support, attach the full output to your e-mail." ;
    } else {
      echo "The build failed.  If you need support, run:" ;
      echo "  $(args) --debug-configuration -d2 |gzip >build.log.gz" ;
      echo "then attach build.log.gz to your e-mail." ;
      echo "You MUST do 3 things before sending to the mailing list:" ;
      echo "   1. Subscribe to the mailing list at http://mailman.mit.edu/mailman/listinfo/moses-support" ;
      echo "   2. Attach build.log.gz to your e-mail" ;
      echo "   3. Say what is the EXACT command you executed when you got the error" ;
    }
    echo "ERROR" ;
  } else {
    echo "SUCCESS" ;
  }
}
add-post-hook failure-message ;

import feature : feature ;
feature options-to-write : : free ;
import toolset : flags ;
flags write-options OPTIONS-TO-WRITE <options-to-write> ;
actions write-options {
  echo "$(OPTIONS-TO-WRITE)" > $(<) ;
}

#Compare contents of file with current.  If they're different, write to the 
#file.  This file can then be used with <dependency>$(file) to force
#recompilation.
rule update-if-changed ( file current ) {
  if ( ! [ path.exists $(file) ] ) || ( [ _shell "cat $(file)" ] != $(current) ) {
    make $(file) : : $(__name__).write-options : <options-to-write>$(current) ;
    always $(file) ;
  }
}

if [ option.get "sanity-test" : : "yes" ] {
  local current_version = [ modules.peek : JAM_VERSION ] ;
  if ( $(current_version[0]) < 2000 && [ version.check-jam-version 3 1 16 ] ) || [ version.check-jam-version 2011 0 0 ] {
    EXIT "Sane" : 0 ;
  } else {
    EXIT "Bad" : 1 ;
  }
}

#Hack to act like alias in the sense that no lib is built, but only build cpp files once.  
import type ;
rule fakelib ( name : deps * : requirements * : default-build * : usage-requirements * ) {
  local c-files = ;
  local real-deps = ;
  for local c in $(deps) {
    if [ type.type $(c) ] = CPP {
      c-files += $(c) ;
    } else {
      real-deps += $(c) ;
    }
  }
  for local c in $(c-files) {
    obj $(c:B).o : $(c) $(real-deps) : $(requirements) : $(default-build) : $(usage_requirements) ;
  }
  alias $(name) : $(c-files:B).o $(real-deps) : $(requirements) : $(default-build) : $(usage-requirements) ;
}

use-project /top : . ;