[ci skip] Add note that this change may break SetOption() + ninja usage with fix
[scons.git] / SConstruct
blob04bde628501b8ef78367fdd55905eccfc62d1e8e
1 # MIT License
3 # Copyright The SCons Foundation
5 # Permission is hereby granted, free of charge, to any person obtaining
6 # a copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish,
9 # distribute, sublicense, and/or sell copies of the Software, and to
10 # permit persons to whom the Software is furnished to do so, subject to
11 # the following conditions:
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
17 # KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
18 # WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 """SConstruct file to build scons packages during development/release."""
27 # See the README.rst file for an overview of how SCons is built and tested.
29 import os.path
30 import sys
31 import textwrap
32 from time import strftime
34 copyright_years = strftime('2001 - %Y')
36 # This gets inserted into the man pages to reflect the month of release.
37 month_year = strftime('%B %Y')
38 project = 'scons'
39 default_version = '4.7.1'
40 copyright = f"Copyright (c) {copyright_years} The SCons Foundation"
42 # We let the presence or absence of various utilities determine whether
43 # or not we bother to build certain pieces of things. This should allow
44 # people to still do SCons packaging work even if they don't have all
45 # of the utilities installed
46 print(f"git :{git}")
47 print(f"gzip :{gzip}")
48 print(f"unzip :{unzip}")
49 print(f"zip :{zip_path}")
52 # Adding some paths to sys.path, this is mainly needed
53 # for the doc toolchain.
55 addpaths = [
56 os.path.abspath(os.path.join(os.getcwd(), 'bin')),
57 os.path.abspath(os.path.join(os.getcwd(), 'testing/framework')),
59 for a in addpaths:
60 if a not in sys.path:
61 sys.path.append(a)
63 # Use site_scons logic to process command line arguments
64 command_line = BuildCommandLine(default_version)
65 command_line.process_command_line_vars()
67 Default('.', command_line.build_dir)
68 # Just make copies, don't symlink them.
69 SetOption('duplicate', 'copy')
71 packaging_flavors = [
73 'wheel',
74 "The Python wheel file for pip installations."
77 'tar-gz',
78 "The normal .tar.gz file for end-user installation."
81 'local-tar-gz',
82 "A .tar.gz file for dropping into other software for local use.",
85 'zip',
86 "The normal .zip file for end-user installation."),
88 'local-zip',
89 "A .zip file for dropping into other software for local use."
92 'src-tar-gz',
93 "A .tar.gz file containing all the source (including tests and documentation).",
96 'src-zip',
97 "A .zip file containing all the source (including tests and documentation).",
100 'local-zipapp',
101 "A .pyz local zipapp. Like local-zip without need to unpack.",
105 test_tar_gz_dir = os.path.join(command_line.build_dir, "test-tar-gz")
106 test_src_tar_gz_dir = os.path.join(command_line.build_dir, "test-src-tar-gz")
107 test_local_tar_gz_dir = os.path.join(command_line.build_dir, "test-local-tar-gz")
108 test_zip_dir = os.path.join(command_line.build_dir, "test-zip")
109 test_src_zip_dir = os.path.join(command_line.build_dir, "test-src-zip")
110 test_local_zip_dir = os.path.join(command_line.build_dir, "test-local-zip")
112 unpack_tar_gz_dir = os.path.join(command_line.build_dir, "unpack-tar-gz")
113 unpack_zip_dir = os.path.join(command_line.build_dir, "unpack-zip")
115 if is_windows():
116 tar_hflag = ''
117 # python_project_subinst_dir = os.path.join("Lib", "site-packages", project)
118 # project_script_subinst_dir = 'Scripts'
119 else:
120 tar_hflag = 'h'
121 # python_project_subinst_dir = os.path.join("lib", project)
122 # project_script_subinst_dir = 'bin'
124 indent_fmt = ' %-14s '
126 Help("""\
127 The following aliases build packages of various types, and unpack the
128 contents into build/test-$PACKAGE subdirectories, which can be used by the
129 runtest.py -p option to run tests against what's been actually packaged:
131 """)
133 aliases = sorted(packaging_flavors + [('doc', 'The SCons documentation.')])
135 for alias, help_text in aliases:
136 tw = textwrap.TextWrapper(
137 width=78,
138 initial_indent=indent_fmt % alias,
139 subsequent_indent=indent_fmt % '' + ' ',
141 Help(tw.fill(help_text) + '\n')
143 Help("""
144 The following command-line variables can be set:
146 """)
148 for variable, help_text in command_line.command_line_variables:
149 tw = textwrap.TextWrapper(
150 width=78,
151 initial_indent=indent_fmt % variable,
152 subsequent_indent=indent_fmt % '' + ' ',
154 Help(tw.fill(help_text) + '\n')
156 revaction = SCons_revision
157 revbuilder = Builder(action=Action(SCons_revision, varlist=['COPYRIGHT', 'VERSION']))
159 env = Environment(
160 ENV=command_line.ENV,
161 BUILD=command_line.build_id,
162 BUILDDIR=command_line.build_dir,
163 BUILDSYS=command_line.build_system,
164 COPYRIGHT_YEARS=copyright_years,
165 COPYRIGHT=copyright,
166 DATE=command_line.date,
167 DEB_DATE=deb_date,
168 DEVELOPER=command_line.developer,
169 DISTDIR=os.path.join(command_line.build_dir, 'dist'),
170 MONTH_YEAR=month_year,
171 REVISION=command_line.revision,
172 VERSION=command_line.version,
173 TAR_HFLAG=tar_hflag,
174 ZIP=zip_path,
175 ZIPFLAGS='-r',
176 UNZIP=unzip,
177 UNZIPFLAGS='-o -d $UNPACK_ZIP_DIR',
178 # ZCAT=zcat,
179 # ZIPID=zipit,
180 TEST_SRC_TAR_GZ_DIR=test_src_tar_gz_dir,
181 TEST_SRC_ZIP_DIR=test_src_zip_dir,
182 TEST_TAR_GZ_DIR=test_tar_gz_dir,
183 TEST_ZIP_DIR=test_zip_dir,
184 UNPACK_TAR_GZ_DIR=unpack_tar_gz_dir,
185 UNPACK_ZIP_DIR=unpack_zip_dir,
186 BUILDERS={'SCons_revision': revbuilder, 'SOElim': soelimbuilder},
187 PYTHON=f'"{sys.executable}"',
188 PYTHONFLAGS='-tt',
191 Version_values = [Value(command_line.version), Value(command_line.build_id)]
192 installed_local_files = create_local_packages(env)
193 update_init_file(env)
195 # Documentation
196 Export('command_line', 'env', 'whereis', 'revaction')
197 SConscript('doc/SConscript')
199 # Copy manpages into base dir for inclusion in pypi packages
200 man_pages = env.Install("#/", Glob("#/build/doc/man/*.1"))
202 # Build packages for pypi. 'build' makes sdist (tgz) + whl
203 wheel = env.Command(
204 target=[
205 '$DISTDIR/SCons-${VERSION}-py3-none-any.whl',
206 '$DISTDIR/SCons-${VERSION}.tar.gz',
208 source=['pyproject.toml', 'setup.py', 'SCons/__init__.py'] + man_pages,
209 action='$PYTHON -m build --outdir $DISTDIR',
211 env.Alias("wheel", wheel[0])
212 env.Alias("tar-gz", wheel[1])
214 # TODO: this is built the old way, because "build" doesn't make zipfiles,
215 # and it deletes its isolated env so we can't just zip that one up.
216 zip_file = env.Command(
217 target='$DISTDIR/SCons-${VERSION}.zip',
218 source=['pyproject.toml', 'setup.py', 'SCons/__init__.py'] + man_pages,
219 action='$PYTHON setup.py sdist --format=zip',
221 env.Alias("zip", zip_file)
223 # Now set depends so the above run in a particular order
224 # NOTE: 'build' with default options builds sdist, then whl from sdist,
225 # so it's already ordered.
226 # env.Depends(tgz_file, [zip_file, wheel])
228 # NOTE: Commenting this out as the manpages are expected to be in the base directory when manually
229 # running setup.py from the base of the repo.
230 # NOTE: This used by distro package maintainers.
231 # env.AddPostAction(tgz_file, Delete(man_pages))
233 # TODO add auto copyright date to README.rst, LICENSE
234 # TODO build API DOCS