]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | #!/usr/bin/python |
2 | # | |
3 | # Copyright 2017 Steven Watanabe | |
4 | # | |
5 | # Distributed under the Boost Software License, Version 1.0. | |
1e59de90 TL |
6 | # (See accompanying file LICENSE.txt or copy at |
7 | # https://www.bfgroup.xyz/b2/LICENSE.txt) | |
11fdf7f2 TL |
8 | |
9 | # validates a toolset using a mock of the compiler | |
10 | ||
11 | import BoostBuild | |
12 | import os | |
13 | import re | |
14 | import sys | |
15 | ||
16 | renames = {"debug": "variant=debug", "release": "variant=release"} | |
17 | ||
18 | def set_default_target_os(os): | |
19 | global removed | |
20 | global default_target_os | |
21 | default_target_os = os | |
22 | removed = set() | |
23 | removed.add("target-os=" + default_target_os) | |
24 | ||
25 | def adjust_property(property): | |
26 | global renames | |
27 | if property in renames: | |
28 | return renames[property] | |
29 | else: | |
30 | return property | |
31 | ||
32 | def adjust_properties(properties): | |
33 | global removed | |
34 | return [adjust_property(p) for p in properties if p not in removed] | |
35 | ||
36 | def has_property(name, properties): | |
37 | return name in [re.sub("=.*", "", p) for p in properties] | |
38 | ||
39 | def get_property(name, properties): | |
40 | for m in [re.match("(.*)=(.*)", p) for p in properties]: | |
41 | if m and m.group(1) == name: | |
42 | return m.group(2) | |
43 | ||
44 | def get_target_os(properties): | |
45 | return get_property("target-os", properties) or default_target_os | |
46 | ||
1e59de90 | 47 | def expand_properties(properties, toolset): |
11fdf7f2 TL |
48 | result = properties[:] |
49 | if not has_property("variant", properties): | |
50 | result += ["variant=debug"] | |
51 | if not has_property("threading", properties): | |
52 | result += ["threading=single"] | |
53 | if not has_property("exception-handling", properties): | |
54 | result += ["exception-handling=on"] | |
55 | if not has_property("link", properties): | |
56 | result += ["link=shared"] | |
57 | if not has_property("rtti", properties): | |
58 | result += ["rtti=on"] | |
59 | if not has_property("runtime-link", properties): | |
60 | result += ["runtime-link=shared"] | |
1e59de90 TL |
61 | if toolset == "msvc" and "runtime-link=shared" in result: |
62 | result.remove("threading=" + get_property("threading", result)) | |
63 | result += ["threading=multi"] | |
11fdf7f2 TL |
64 | if not has_property("strip", properties): |
65 | result += ["strip=off"] | |
66 | if not has_property("target-os", properties): | |
67 | result += ["target-os=" + default_target_os] | |
1e59de90 TL |
68 | if not has_property("windows-api", properties): |
69 | result += ["windows-api=desktop"] | |
11fdf7f2 TL |
70 | return result |
71 | ||
72 | def compute_path(properties, target_type): | |
73 | path = "" | |
74 | if "variant=release" in properties: | |
75 | path += "/release" | |
76 | else: | |
77 | path += "/debug" | |
78 | if has_property("address-model", properties): | |
79 | path += "/address-model-" + get_property("address-model", properties) | |
80 | if has_property("architecture", properties): | |
81 | path += "/architecture-" + get_property("architecture", properties) | |
82 | if "cxxstd=latest" in properties: | |
83 | path += "/cxxstd-latest-iso" | |
84 | if "exception-handling=off" in properties: | |
85 | path += "/exception-handling-off" | |
86 | if "link=static" in properties: | |
87 | path += "/link-static" | |
88 | if "rtti=off" in properties: | |
89 | path += "/rtti-off" | |
1e59de90 | 90 | if "runtime-link=static" in properties: # and target_type in ["exe"]: |
11fdf7f2 TL |
91 | path += "/runtime-link-static" |
92 | if "strip=on" in properties and target_type in ["dll", "exe", "obj2"]: | |
93 | path += "/strip-on" | |
94 | if get_target_os(properties) != default_target_os: | |
95 | path += "/target-os-" + get_target_os(properties) | |
96 | if "threading=multi" in properties: | |
1e59de90 | 97 | if "runtime-link=static" not in properties: # TODO: I don't think this it's intended to work this way though |
11fdf7f2 | 98 | path += "/threading-multi" |
1e59de90 TL |
99 | if not "windows-api=desktop" in properties: |
100 | path += "/windows-api-" + get_property("windows-api", properties) | |
11fdf7f2 TL |
101 | return path |
102 | ||
103 | def test_toolset(toolset, version, property_sets): | |
104 | t = BoostBuild.Tester() | |
105 | ||
106 | t.set_tree("toolset-mock") | |
107 | ||
108 | # Build necessary tools | |
109 | t.run_build_system(["-sPYTHON_CMD=%s" % sys.executable], subdir="src") | |
110 | set_default_target_os(t.read("src/bin/target-os.txt").strip()) | |
111 | ||
112 | for properties in property_sets: | |
113 | t.set_toolset(toolset + "-" + version, get_target_os(properties)) | |
114 | properties = adjust_properties(properties) | |
1e59de90 | 115 | expanded_properties = expand_properties(properties, toolset) |
11fdf7f2 | 116 | def path(t): |
1e59de90 TL |
117 | return toolset.split("-")[0] + "-*" + version + compute_path(expanded_properties, t) |
118 | os.environ["B2_PROPERTIES"] = " ".join(expanded_properties) | |
92f5a8d4 | 119 | t.run_build_system(["--user-config=", "-sPYTHON_CMD=%s" % sys.executable] + properties) |
11fdf7f2 TL |
120 | t.expect_addition("bin/%s/lib.obj" % (path("obj"))) |
121 | if "link=static" not in properties: | |
1e59de90 TL |
122 | if get_target_os(properties) in ["cygwin", "windows"] and toolset != "clang-linux": |
123 | t.expect_addition("bin/%s/l1.implib" % (path("dll"))) | |
11fdf7f2 | 124 | t.expect_addition("bin/%s/l1.dll" % (path("dll"))) |
20effc67 | 125 | t.ignore_addition("bin/%s/*l1.*.rsp" % (path("dll"))) |
11fdf7f2 TL |
126 | else: |
127 | t.expect_addition("bin/%s/l1.lib" % (path("lib"))) | |
128 | t.expect_addition("bin/%s/main.obj" % (path("obj2"))) | |
129 | t.expect_addition("bin/%s/test.exe" % (path("exe"))) | |
20effc67 | 130 | t.ignore_addition("bin/%s/test.rsp" % (path("exe"))) |
11fdf7f2 TL |
131 | t.expect_nothing_more() |
132 | t.rm("bin") | |
133 | ||
134 | t.cleanup() |