]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | # Copyright 2018 Steven Watanabe |
2 | # Distributed under the Boost Software License, Version 1.0. | |
1e59de90 TL |
3 | # (See accompanying file LICENSE.txt or copy at |
4 | # https://www.bfgroup.xyz/b2/LICENSE.txt) | |
11fdf7f2 TL |
5 | |
6 | # defines the check-has-flag rule. | |
7 | ||
8 | import "class" ; | |
9 | import common ; | |
10 | import feature : feature ; | |
11 | import generators ; | |
12 | import make ; | |
13 | import print ; | |
14 | import project ; | |
15 | import toolset : flags ; | |
16 | ||
17 | rule init ( ) | |
18 | { | |
19 | if ! $(.initialized) | |
20 | { | |
21 | .initialized = true ; | |
22 | project.push-current ; | |
23 | project.initialize $(__name__) ; | |
24 | project /check/flags ; | |
25 | .project = [ project.current ] ; | |
26 | make empty.c : : @write-main ; | |
27 | make empty.cpp : : @write-main ; | |
28 | obj empty.obj : empty.cpp ; | |
29 | project : requirements <flags.check>on ; | |
30 | project.pop-current ; | |
31 | } | |
32 | } | |
33 | ||
34 | rule write-main ( target : : properties * ) | |
35 | { | |
36 | print.output $(target) ; | |
37 | print.text "int main() { return 0; }\n" : yes ; | |
38 | } | |
39 | ||
40 | # Applies true-properties if the toolset recognizes a specific flag. | |
41 | # Otherwise applies false-properties. | |
42 | # | |
43 | # Option must be one of <cflags>, <cxxflags>, or <linkflags>. | |
44 | # | |
45 | # Example:: | |
46 | # | |
47 | # exe foo : foo.cpp : | |
48 | # [ check-has-flag <cxxflags>-std=c++11 : <cxxflags>-std=c++11 ] ; | |
49 | # | |
50 | rule check-has-flag ( option message ? : true-properties * : false-properties * ) | |
51 | { | |
52 | init ; | |
53 | local id = [ MD5 $(option) ] ; | |
54 | ||
55 | if ! $(.targets.$(id)) | |
56 | { | |
57 | project.push-current $(.project) ; | |
58 | switch $(option:G) | |
59 | { | |
60 | case <cflags> : obj flags_$(id) : empty.c : $(option) ; | |
61 | case <cxxflags> : obj flags_$(id) : empty.cpp : $(option) ; | |
62 | case <linkflags> : exe flags_$(id) : empty.obj : $(option) ; | |
63 | case * : | |
64 | import errors ; | |
65 | errors.user-error "Don't know how to check $(option:G)" ; | |
66 | } | |
67 | project.pop-current ; | |
68 | .targets.$(id) = true ; | |
69 | } | |
70 | message ?= "has $(option:G=)" ; | |
71 | return [ check-target-builds /check/flags//flags_$(id) $(message) | |
72 | : $(true-properties) : $(false-properties) ] ; | |
73 | } | |
74 | ||
75 | IMPORT $(__name__) : check-has-flag : : check-has-flag ; | |
76 | ||
77 | feature flags.check : on : optional composite ; | |
78 | feature.compose <flags.check>on : <warnings-as-errors>on ; | |
79 | ||
80 | # Some compilers don't have an easy way to cause an error | |
81 | # for unknown options. In this case, we need to check | |
82 | # their stdout/stderr. This generator will copy it's | |
83 | # source, but will cause an error if the given pattern | |
84 | # matches the output from the source. | |
85 | # | |
86 | ||
87 | feature flags.pattern : : free ; | |
88 | ||
89 | class flag-check-generator : generator | |
90 | { | |
91 | rule __init__ ( type : requirements * : pattern ) | |
92 | { | |
93 | generator.__init__ flags.check-output : $(type) : $(type)(%_valid) : | |
94 | $(requirements) <flags.check>on ; | |
95 | self.pattern = $(pattern) ; | |
96 | } | |
97 | rule run ( project name ? : property-set : sources * ) | |
98 | { | |
99 | property-set = [ property-set.create | |
100 | [ property.change [ $(property-set).raw ] : <flags.check> ] | |
101 | <flags.pattern>$(self.pattern) ] ; | |
102 | return [ generator.run $(project) $(name) | |
103 | : $(property-set) : $(sources) ] ; | |
104 | } | |
105 | rule action-class ( ) | |
106 | { | |
107 | return non-scanning-action ; | |
108 | } | |
109 | } | |
110 | ||
111 | # These generator definitions should probably be moved to the individual toolsets. | |
112 | ||
113 | # msvc-7.1 uses 4002. Later versions use 9002. | |
114 | generators.register | |
115 | [ class.new flag-check-generator OBJ : <toolset>msvc : "(D[94]002)" ] ; | |
116 | generators.register | |
117 | [ class.new flag-check-generator EXE : <toolset>msvc : "(LNK4044)" ] ; | |
118 | generators.register | |
119 | [ class.new flag-check-generator OBJ : <toolset>intel : "(#10006)" ] ; | |
120 | generators.register | |
121 | [ class.new flag-check-generator EXE : <toolset>intel : "(#10006)" ] ; | |
122 | generators.override flags.check-output : all ; | |
123 | ||
124 | rule check-output-callback ( targets * : source-targets * : ignored * : output ? ) | |
125 | { | |
126 | if [ MATCH [ on $(targets) return $(PATTERN) ] : $(output) ] | |
127 | { | |
128 | FLAG_CHECK_COMMAND on $(targets) = illegal-ad22d215a8bbd73 ; | |
129 | } | |
130 | } | |
131 | ||
132 | IMPORT $(__name__) : check-output-callback : : flags.check-output-callback ; | |
133 | ||
134 | flags flags.check-output PATTERN : <flags.pattern> ; | |
135 | ||
136 | rule check-output ( targets * : sources * : properties * ) | |
137 | { | |
138 | local action = [ on $(sources) return $(.action) ] ; | |
139 | local all-sources ; | |
140 | for local t in [ $(action).targets ] | |
141 | { | |
142 | all-sources += [ $(t).actualize ] ; | |
143 | } | |
144 | REBUILDS $(targets) : $(sources) ; | |
145 | __ACTION_RULE__ on $(all-sources) = flags.check-output-callback $(targets) ; | |
146 | common.copy $(targets[1]) : $(sources[1]) ; | |
147 | } | |
148 | ||
149 | actions check-output | |
150 | { | |
151 | $(FLAG_CHECK_COMMAND) | |
152 | } |