]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | # |
2 | # Copyright (c) 2016 Stefan Seefeld | |
3 | # All rights reserved. | |
4 | # | |
5 | # Distributed under the Boost Software License, Version 1.0. | |
6 | # (See accompanying file LICENSE_1_0.txt or copy at | |
7 | # http://www.boost.org/LICENSE_1_0.txt) | |
8 | ||
9 | from SCons.Variables import * | |
10 | from SCons.Script import AddOption | |
11 | from collections import OrderedDict | |
12 | import platform | |
13 | from . import ui | |
14 | from . import cxx | |
15 | from . import python | |
16 | from . import numpy | |
17 | from . import boost | |
18 | ||
19 | def add_options(vars): | |
20 | ui.add_option('-V', '--verbose', dest='verbose', action='store_true', help='verbose mode: print full commands.') | |
21 | ui.add_option('--no-numpy', dest='numpy', action='store_false', help='do not attempt to build NumPy bindings.') | |
22 | python.add_options(vars) | |
23 | numpy.add_options(vars) | |
24 | boost.add_options(vars) | |
25 | ||
26 | vars.Add('CXX') | |
27 | vars.Add('CPPPATH', converter=lambda v:v.split()) | |
28 | vars.Add('CCFLAGS', converter=lambda v:v.split()) | |
29 | vars.Add('CXXFLAGS', converter=lambda v:v.split()) | |
30 | vars.Add('LIBPATH', converter=lambda v:v.split()) | |
31 | vars.Add('LIBS', converter=lambda v:v.split()) | |
32 | vars.Add('PYTHON') | |
33 | vars.Add('PYTHONLIBS') | |
34 | vars.Add('prefix') | |
35 | vars.Add('boostbook_prefix') | |
36 | vars.Add('CXX11') | |
37 | vars.Add('NUMPY') | |
38 | vars.Add('NUMPY_CPPPATH', converter=lambda v:v.split()) | |
39 | ||
40 | ui.add_variable(vars, ("arch", "target architeture", platform.machine())) | |
41 | ui.add_variable(vars, ("toolchain", "toolchain to use", 'gcc')) | |
42 | ui.add_variable(vars, ListVariable("variant", "Build configuration", "release", ["release", "debug", "profile"])) | |
43 | ui.add_variable(vars, ListVariable("link", "Library linking", "dynamic", ["static", "dynamic"])) | |
44 | ui.add_variable(vars, ListVariable("threading", "Multi-threading support", "multi", ["single", "multi"])) | |
45 | ui.add_variable(vars, EnumVariable("layout", "Layout of library names and header locations", "versioned", ["versioned", "system"])) | |
46 | ui.add_variable(vars, PathVariable("stagedir", "If --stage is passed install only compiled library files in this location", "stage", PathVariable.PathAccept)) | |
47 | ui.add_variable(vars, PathVariable("prefix", "Install prefix", "/usr/local", PathVariable.PathAccept)) | |
48 | ||
49 | ||
50 | def get_checks(env): | |
51 | checks = OrderedDict() | |
52 | checks['cxx'] = cxx.check | |
53 | checks['python'] = python.check | |
54 | if env.GetOption('numpy') is not False: | |
55 | checks['numpy'] = numpy.check | |
56 | else: | |
57 | env['NUMPY'] = False | |
58 | checks['boost'] = boost.check | |
59 | return checks | |
60 | ||
61 | ||
62 | def set_property(env, **kw): | |
63 | ||
64 | from toolchains.gcc import features as gcc_features | |
65 | from toolchains.msvc import features as msvc_features | |
66 | ||
67 | if 'gcc' in env['TOOLS']: features = gcc_features | |
68 | elif 'msvc' in env['TOOLS']: features = msvc_features | |
69 | else: raise Error('unknown toolchain') | |
70 | features.init_once(env) | |
71 | for (prop,value) in kw.items(): | |
72 | getattr(features, prop, lambda x, y : None)(env, value) | |
73 | env[prop.upper()] = value | |
74 | ||
75 | ||
76 | def boost_suffix(env): | |
77 | suffix = str() | |
78 | ||
79 | if env["layout"] == "versioned": | |
80 | if "gcc" in env["TOOLS"]: | |
81 | if env['CXX'] in ('clang', 'clang++'): | |
82 | suffix += "-clang" + "".join(env["CXXVERSION"].split(".")[0:2]) | |
83 | else: # assume g++ | |
84 | suffix += "-gcc" + "".join(env["CXXVERSION"].split(".")[0:2]) | |
85 | if env["THREADING"] == "multi": | |
86 | suffix += "-mt" | |
87 | if env["DEBUG"]: | |
88 | suffix += "-d" | |
89 | if env["layout"] == "versioned": | |
90 | suffix += "-" + "_".join(env["BPL_VERSION"].split(".")) | |
91 | ||
92 | return suffix | |
93 | ||
94 | ||
95 | def prepare_build_dir(env): | |
96 | ||
97 | vars = {} | |
98 | env["boost_suffix"] = boost_suffix | |
99 | build_dir="bin.SCons" | |
100 | # FIXME: Support 'toolchain' variable properly. | |
101 | # For now, we simply check whether $CXX refers to clang or gcc. | |
102 | if "gcc" in env["TOOLS"]: | |
103 | if env['CXX'] in ('clang', 'clang++'): | |
104 | build_dir+="/clang-%s"%env["CXXVERSION"] | |
105 | else: # assume g++ | |
106 | build_dir+="/gcc-%s"%env["CXXVERSION"] | |
107 | default_cxxflags = ['-ftemplate-depth-128', '-Wall', '-g', '-O2'] | |
108 | vars['CXXFLAGS'] = env.get('CXXFLAGS', default_cxxflags) | |
109 | elif "msvc" in env["TOOLS"]: | |
110 | build_dir+="/msvc-%s"%env["MSVS_VERSION"] | |
111 | vars['BOOST_BUILD_DIR'] = build_dir | |
112 | vars['BOOST_SUFFIX'] = "${boost_suffix(__env__)}" | |
113 | env.Replace(**vars) | |
114 | return build_dir | |
115 | ||
116 | ||
117 | def variants(env): | |
118 | ||
119 | env.Prepend(CPPPATH = "#/include", CPPDEFINES = ["BOOST_ALL_NO_LIB=1"]) | |
120 | set_property(env, architecture = env['TARGET_ARCH']) | |
121 | for variant in env["variant"]: | |
122 | e = env.Clone() | |
123 | e["current_variant"] = variant | |
124 | set_property(env, profile = False) | |
125 | if variant == "release": | |
126 | set_property(e, optimize = "speed", debug = False) | |
127 | elif variant == "debug": | |
128 | set_property(e, optimize = "no", debug = True) | |
129 | elif variant == "profile": | |
130 | set_property(e, optimize = "speed", profile = True, debug = True) | |
131 | for linking in env["link"]: | |
132 | e["linking"] = linking | |
133 | if linking == "dynamic": | |
134 | e["LINK_DYNAMIC"] = True | |
135 | else: | |
136 | e["LINK_DYNAMIC"] = False | |
137 | for threading in e["threading"]: | |
138 | e["current_threading"] = threading | |
139 | set_property(e, threading = threading) | |
140 | yield e |