|
41 | 41 | log = logging.getLogger("multissl")
|
42 | 42 |
|
43 | 43 | OPENSSL_OLD_VERSIONS = [
|
44 |
| - "0.9.8zh", |
45 |
| - "1.0.1u", |
| 44 | + "0.9.8zh", |
| 45 | + "1.0.1u", |
| 46 | + "1.0.2", |
46 | 47 | ]
|
47 | 48 |
|
48 | 49 | OPENSSL_RECENT_VERSIONS = [
|
49 |
| - "1.0.2", |
50 |
| - "1.0.2m", |
51 |
| - "1.1.0g", |
| 50 | + "1.0.2o", |
| 51 | + "1.1.0h", |
| 52 | + # "1.1.1-pre7", |
52 | 53 | ]
|
53 | 54 |
|
54 | 55 | LIBRESSL_OLD_VERSIONS = [
|
55 |
| - "2.3.10", |
56 |
| - "2.4.5", |
| 56 | + "2.5.5", |
| 57 | + "2.6.4", |
57 | 58 | ]
|
58 | 59 |
|
59 | 60 | LIBRESSL_RECENT_VERSIONS = [
|
60 |
| - "2.5.5", |
61 |
| - "2.6.4", |
62 |
| - "2.7.1", |
| 61 | + "2.7.3", |
63 | 62 | ]
|
64 | 63 |
|
65 | 64 | # store files in ../multissl
|
66 |
| -HERE = os.path.abspath(os.getcwd()) |
67 |
| -MULTISSL_DIR = os.path.abspath(os.path.join(HERE, '..', 'multissl')) |
| 65 | +HERE = os.path.dirname(os.path.abspath(__file__)) |
| 66 | +PYTHONROOT = os.path.abspath(os.path.join(HERE, '..', '..')) |
| 67 | +MULTISSL_DIR = os.path.abspath(os.path.join(PYTHONROOT, '..', 'multissl')) |
| 68 | + |
68 | 69 |
|
69 | 70 | parser = argparse.ArgumentParser(
|
70 | 71 | prog='multissl',
|
|
76 | 77 | parser.add_argument(
|
77 | 78 | '--debug',
|
78 | 79 | action='store_true',
|
79 |
| - help="Enable debug mode", |
| 80 | + help="Enable debug logging", |
80 | 81 | )
|
81 | 82 | parser.add_argument(
|
82 | 83 | '--disable-ancient',
|
|
119 | 120 | help="Disable network tests."
|
120 | 121 | )
|
121 | 122 | parser.add_argument(
|
122 |
| - '--compile-only', |
123 |
| - action='store_true', |
124 |
| - help="Don't run tests, only compile _ssl.c and _hashopenssl.c." |
| 123 | + '--steps', |
| 124 | + choices=['library', 'modules', 'tests'], |
| 125 | + default='tests', |
| 126 | + help=( |
| 127 | + "Which steps to perform. 'library' downloads and compiles OpenSSL " |
| 128 | + "or LibreSSL. 'module' also compiles Python modules. 'tests' builds " |
| 129 | + "all and runs the test suite." |
| 130 | + ) |
125 | 131 | )
|
126 | 132 | parser.add_argument(
|
127 | 133 | '--system',
|
128 | 134 | default='',
|
129 | 135 | help="Override the automatic system type detection."
|
130 | 136 | )
|
| 137 | +parser.add_argument( |
| 138 | + '--force', |
| 139 | + action='store_true', |
| 140 | + dest='force', |
| 141 | + help="Force build and installation." |
| 142 | +) |
| 143 | +parser.add_argument( |
| 144 | + '--keep-sources', |
| 145 | + action='store_true', |
| 146 | + dest='keep_sources', |
| 147 | + help="Keep original sources for debugging." |
| 148 | +) |
131 | 149 |
|
132 | 150 |
|
133 | 151 | class AbstractBuilder(object):
|
134 | 152 | library = None
|
135 | 153 | url_template = None
|
136 | 154 | src_template = None
|
137 | 155 | build_template = None
|
| 156 | + install_target = 'install' |
138 | 157 |
|
139 | 158 | module_files = ("Modules/_ssl.c",
|
140 | 159 | "Modules/_hashopenssl.c")
|
141 | 160 | module_libs = ("_ssl", "_hashlib")
|
142 | 161 |
|
143 |
| - def __init__(self, version, compile_args=(), |
144 |
| - basedir=MULTISSL_DIR): |
| 162 | + def __init__(self, version, args): |
145 | 163 | self.version = version
|
146 |
| - self.compile_args = compile_args |
| 164 | + self.args = args |
147 | 165 | # installation directory
|
148 | 166 | self.install_dir = os.path.join(
|
149 |
| - os.path.join(basedir, self.library.lower()), version |
| 167 | + os.path.join(args.base_directory, self.library.lower()), version |
150 | 168 | )
|
151 | 169 | # source file
|
152 |
| - self.src_dir = os.path.join(basedir, 'src') |
| 170 | + self.src_dir = os.path.join(args.base_directory, 'src') |
153 | 171 | self.src_file = os.path.join(
|
154 | 172 | self.src_dir, self.src_template.format(version))
|
155 | 173 | # build directory (removed after install)
|
@@ -258,24 +276,31 @@ def _build_src(self):
|
258 | 276 | """Now build openssl"""
|
259 | 277 | log.info("Running build in {}".format(self.build_dir))
|
260 | 278 | cwd = self.build_dir
|
261 |
| - cmd = ["./config", "shared", "--prefix={}".format(self.install_dir)] |
262 |
| - cmd.extend(self.compile_args) |
263 |
| - env = None |
| 279 | + cmd = [ |
| 280 | + "./config", |
| 281 | + "shared", "--debug", |
| 282 | + "--prefix={}".format(self.install_dir) |
| 283 | + ] |
| 284 | + env = os.environ.copy() |
| 285 | + # set rpath |
| 286 | + env["LD_RUN_PATH"] = self.lib_dir |
264 | 287 | if self.system:
|
265 |
| - env = os.environ.copy() |
266 | 288 | env['SYSTEM'] = self.system
|
267 | 289 | self._subprocess_call(cmd, cwd=cwd, env=env)
|
268 | 290 | # Old OpenSSL versions do not support parallel builds.
|
269 | 291 | self._subprocess_call(["make", "-j1"], cwd=cwd, env=env)
|
270 | 292 |
|
271 |
| - def _make_install(self, remove=True): |
272 |
| - self._subprocess_call(["make", "-j1", "install"], cwd=self.build_dir) |
273 |
| - if remove: |
| 293 | + def _make_install(self): |
| 294 | + self._subprocess_call( |
| 295 | + ["make", "-j1", self.install_target], |
| 296 | + cwd=self.build_dir |
| 297 | + ) |
| 298 | + if not self.args.keep_sources: |
274 | 299 | shutil.rmtree(self.build_dir)
|
275 | 300 |
|
276 | 301 | def install(self):
|
277 | 302 | log.info(self.openssl_cli)
|
278 |
| - if not self.has_openssl: |
| 303 | + if not self.has_openssl or self.args.force: |
279 | 304 | if not self.has_src:
|
280 | 305 | self._download_src()
|
281 | 306 | else:
|
@@ -341,6 +366,8 @@ class BuildOpenSSL(AbstractBuilder):
|
341 | 366 | url_template = "https://www.openssl.org/source/openssl-{}.tar.gz"
|
342 | 367 | src_template = "openssl-{}.tar.gz"
|
343 | 368 | build_template = "openssl-{}"
|
| 369 | + # only install software, skip docs |
| 370 | + install_target = 'install_sw' |
344 | 371 |
|
345 | 372 |
|
346 | 373 | class BuildLibreSSL(AbstractBuilder):
|
@@ -379,57 +406,63 @@ def main():
|
379 | 406 |
|
380 | 407 | start = datetime.now()
|
381 | 408 |
|
382 |
| - for name in ['python', 'setup.py', 'Modules/_ssl.c']: |
383 |
| - if not os.path.isfile(name): |
| 409 | + if args.steps in {'modules', 'tests'}: |
| 410 | + for name in ['setup.py', 'Modules/_ssl.c']: |
| 411 | + if not os.path.isfile(os.path.join(PYTHONROOT, name)): |
| 412 | + parser.error( |
| 413 | + "Must be executed from CPython build dir" |
| 414 | + ) |
| 415 | + if not os.path.samefile('python', sys.executable): |
384 | 416 | parser.error(
|
385 |
| - "Must be executed from CPython build dir" |
| 417 | + "Must be executed with ./python from CPython build dir" |
386 | 418 | )
|
387 |
| - if not os.path.samefile('python', sys.executable): |
388 |
| - parser.error( |
389 |
| - "Must be executed with ./python from CPython build dir" |
390 |
| - ) |
391 |
| - |
392 |
| - # check for configure and run make |
393 |
| - configure_make() |
| 419 | + # check for configure and run make |
| 420 | + configure_make() |
394 | 421 |
|
395 | 422 | # download and register builder
|
396 | 423 | builds = []
|
397 | 424 |
|
398 | 425 | for version in args.openssl:
|
399 |
| - build = BuildOpenSSL(version) |
| 426 | + build = BuildOpenSSL( |
| 427 | + version, |
| 428 | + args |
| 429 | + ) |
400 | 430 | build.install()
|
401 | 431 | builds.append(build)
|
402 | 432 |
|
403 | 433 | for version in args.libressl:
|
404 |
| - build = BuildLibreSSL(version) |
| 434 | + build = BuildLibreSSL( |
| 435 | + version, |
| 436 | + args |
| 437 | + ) |
405 | 438 | build.install()
|
406 | 439 | builds.append(build)
|
407 | 440 |
|
408 |
| - for build in builds: |
409 |
| - try: |
410 |
| - build.recompile_pymods() |
411 |
| - build.check_pyssl() |
412 |
| - if not args.compile_only: |
413 |
| - build.run_python_tests( |
414 |
| - tests=args.tests, |
415 |
| - network=args.network, |
416 |
| - ) |
417 |
| - except Exception as e: |
418 |
| - log.exception("%s failed", build) |
419 |
| - print("{} failed: {}".format(build, e), file=sys.stderr) |
420 |
| - sys.exit(2) |
421 |
| - |
422 |
| - print("\n{} finished in {}".format( |
423 |
| - "Tests" if not args.compile_only else "Builds", |
424 |
| - datetime.now() - start |
425 |
| - )) |
| 441 | + if args.steps in {'modules', 'tests'}: |
| 442 | + for build in builds: |
| 443 | + try: |
| 444 | + build.recompile_pymods() |
| 445 | + build.check_pyssl() |
| 446 | + if args.steps == 'tests': |
| 447 | + build.run_python_tests( |
| 448 | + tests=args.tests, |
| 449 | + network=args.network, |
| 450 | + ) |
| 451 | + except Exception as e: |
| 452 | + log.exception("%s failed", build) |
| 453 | + print("{} failed: {}".format(build, e), file=sys.stderr) |
| 454 | + sys.exit(2) |
| 455 | + |
| 456 | + log.info("\n{} finished in {}".format( |
| 457 | + args.steps.capitalize(), |
| 458 | + datetime.now() - start |
| 459 | + )) |
426 | 460 | print('Python: ', sys.version)
|
427 |
| - if args.compile_only: |
428 |
| - print('Build only') |
429 |
| - elif args.tests: |
430 |
| - print('Executed Tests:', ' '.join(args.tests)) |
431 |
| - else: |
432 |
| - print('Executed all SSL tests.') |
| 461 | + if args.steps == 'tests': |
| 462 | + if args.tests: |
| 463 | + print('Executed Tests:', ' '.join(args.tests)) |
| 464 | + else: |
| 465 | + print('Executed all SSL tests.') |
433 | 466 |
|
434 | 467 | print('OpenSSL / LibreSSL versions:')
|
435 | 468 | for build in builds:
|
|
0 commit comments