Merge pull request #4674 from bdbaddog/fix_2281_Aliases_ignore_pre_post_add_actions
[scons.git] / test / sconsign / script / Signatures.py
bloba355068de345188913e76998df3db1941926e5f8
1 #!/usr/bin/env python
3 # MIT License
5 # Copyright The SCons Foundation
7 # Permission is hereby granted, free of charge, to any person obtaining
8 # a copy of this software and associated documentation files (the
9 # "Software"), to deal in the Software without restriction, including
10 # without limitation the rights to use, copy, modify, merge, publish,
11 # distribute, sublicense, and/or sell copies of the Software, and to
12 # permit persons to whom the Software is furnished to do so, subject to
13 # the following conditions:
15 # The above copyright notice and this permission notice shall be included
16 # in all copies or substantial portions of the Software.
18 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
19 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
20 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 """
27 Verify that the sconsign script works when using a .sconsign file in
28 each subdirectory (SConsignFile(None)) written with the non-default
29 value of Decider('timestamp-newer').
30 """
32 import TestSCons
33 import TestSConsign
35 from TestSCons import _python_
36 from TestCmd import NEED_HELPER
38 test = TestSConsign.TestSConsign(match = TestSConsign.match_re)
40 if NEED_HELPER:
41 test.skip_test("Test host cannot directly execute scripts, skipping test\n")
43 # Note: We don't use os.path.join() representations of the file names
44 # in the expected output because paths in the .sconsign files are
45 # canonicalized to use / as the separator.
47 sub1_hello_c = 'sub1/hello.c'
48 sub1_hello_obj = 'sub1/hello.obj'
50 test.subdir('sub1', 'sub2')
52 # Because this test sets SConsignFile(None), we execute our fake
53 # scripts directly, not by feeding them to the Python executable.
54 # That is, we chmod 0o755 and use a "#!/usr/bin/env python" first
55 # line for POSIX systems, and add .PY to the %PATHEXT% variable on
56 # Windows. If we didn't do this, then running this script with
57 # suitable prileveges would create a .sconsign file in the directory
58 # where the Python executable lives. This can happen out of the
59 # box on Mac OS X, with the result that the .sconsign statefulness
60 # can mess up other tests.
62 fake_cc_py = test.workpath('fake_cc.py')
63 fake_link_py = test.workpath('fake_link.py')
65 test.write(
66 fake_cc_py,
67 fr"""#!{_python_}
68 import os
69 import re
70 import sys
72 path = sys.argv[1].split()
74 def find_file(f):
75 for dir in path:
76 p = dir + os.sep + f
77 if os.path.exists(p):
78 return open(p, 'r')
79 return None
81 def process(infp, outfp):
82 for line in infp.readlines():
83 m = re.match('#include <(.*)>', line)
84 if m:
85 file = m.group(1)
86 found = find_file(file)
87 process(found, outfp)
88 if found:
89 found.close()
90 else:
91 outfp.write(line)
93 with open(sys.argv[2], 'w') as outf, open(sys.argv[3], 'r') as ifp:
94 outf.write('fake_cc.py: %s\n' % sys.argv)
95 process(ifp, outf)
97 sys.exit(0)
98 """,
101 test.write(
102 fake_link_py,
103 fr"""#!{_python_}
104 import sys
106 with open(sys.argv[1], 'w') as outf, open(sys.argv[2], 'r') as ifp:
107 outf.write('fake_link.py: %s\n' % sys.argv)
108 outf.write(ifp.read())
110 sys.exit(0)
111 """,
114 test.chmod(fake_cc_py, 0o755)
115 test.chmod(fake_link_py, 0o755)
117 test.write(
118 'SConstruct',
119 f"""
120 SConsignFile(None)
121 Decider('timestamp-newer')
122 env1 = Environment(
123 PROGSUFFIX='.exe',
124 OBJSUFFIX='.obj',
125 # Specify the command lines with lists-of-lists so
126 # finding the implicit dependencies works even with
127 # spaces in the fake_*_py path names.
128 CCCOM=[[r'{fake_cc_py}', 'sub2', '$TARGET', '$SOURCE']],
129 LINKCOM=[[r'{fake_link_py}', '$TARGET', '$SOURCE']],
131 env1.PrependENVPath('PATHEXT', '.PY')
132 env1.Program('sub1/hello.c')
133 env2 = env1.Clone(CPPPATH=['sub2'])
134 env2.Program('sub2/hello.c')
135 """,
137 # TODO in the above, we would normally want to run a python program
138 # using "our Python" like this:
139 # CCCOM=[[r'{_python_}', r'{fake_cc_py}', 'sub2', '$TARGET', '$SOURCE']],
140 # LINKCOM=[[r'{_python_}', r'{fake_link_py}', '$TARGET', '$SOURCE']],
141 # however we're looking at dependencies with sconsign, so that breaks things.
142 # It still breaks things on Windows if something else is registered as the
143 # handler for .py files, as Visual Studio Code installs itself.
145 test.write(['sub1', 'hello.c'], r"""\
146 sub1/hello.c
147 """)
149 test.write(['sub2', 'hello.c'], r"""\
150 #include <inc1.h>
151 #include <inc2.h>
152 sub2/hello.c
153 """)
155 test.write(['sub2', 'inc1.h'], r"""\
156 #define STRING1 "inc1.h"
157 """)
159 test.write(['sub2', 'inc2.h'], r"""\
160 #define STRING2 "inc2.h"
161 """)
163 test.sleep() # delay for timestamps
164 test.run(arguments = '. --max-drift=1')
166 sig_re = r'[0-9a-fA-F]{32,64}'
167 date_re = r'\S+ \S+ [ \d]\d \d\d:\d\d:\d\d \d\d\d\d'
168 database_name = test.get_sconsignname()
170 test.run_sconsign(
171 arguments=f"-e hello.exe -e hello.obj sub1/{database_name}",
172 stdout=r"""hello.exe: %(sig_re)s \d+(\.\d*)? \d+
173 %(sub1_hello_obj)s: %(sig_re)s \d+(\.\d*)? \d+
174 fake_link\.py: None \d+(\.\d*)? \d+
175 %(sig_re)s \[.*\]
176 hello.obj: %(sig_re)s \d+(\.\d*)? \d+
177 %(sub1_hello_c)s: None \d+(\.\d*)? \d+
178 fake_cc\.py: None \d+(\.\d*)? \d+
179 %(sig_re)s \[.*\]
180 """ % locals(),
183 test.run_sconsign(
184 arguments=f"-e hello.exe -e hello.obj -r sub1/{database_name}",
185 stdout=r"""hello.exe: %(sig_re)s '%(date_re)s' \d+(\.\d*)?
186 %(sub1_hello_obj)s: %(sig_re)s '%(date_re)s' \d+(\.\d*)?
187 fake_link\.py: None '%(date_re)s' \d+(\.\d*)?
188 %(sig_re)s \[.*\]
189 hello.obj: %(sig_re)s '%(date_re)s' \d+(\.\d*)?
190 %(sub1_hello_c)s: None '%(date_re)s' \d+(\.\d*)?
191 fake_cc\.py: None '%(date_re)s' \d+(\.\d*)?
192 %(sig_re)s \[.*\]
193 """ % locals(),
196 test.pass_test()
198 # Local Variables:
199 # tab-width:4
200 # indent-tabs-mode:nil
201 # End:
202 # vim: set expandtab tabstop=4 shiftwidth=4: