|
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