|
1 | 1 | import os.path
|
2 | 2 | from buildbot.process import factory
|
3 |
| -from buildbot.steps.shell import Configure, Compile, ShellCommand |
| 3 | +from buildbot.steps.shell import ( |
| 4 | + Configure, |
| 5 | + Compile, |
| 6 | + ShellCommand, |
| 7 | + SetPropertyFromCommand, |
| 8 | +) |
| 9 | + |
| 10 | +from buildbot.plugins import util |
4 | 11 |
|
5 | 12 | from .steps import (
|
6 | 13 | Test,
|
@@ -577,3 +584,253 @@ class WindowsARM64ReleaseBuild(WindowsARM64Build):
|
577 | 584 | testFlags = WindowsARM64Build.testFlags + ["+d"]
|
578 | 585 | # keep default cleanFlags, both configurations get cleaned
|
579 | 586 | factory_tags = ["win-arm64", "nondebug"]
|
| 587 | + |
| 588 | +############################################################################## |
| 589 | +############################## WASM BUILDS ################################# |
| 590 | +############################################################################## |
| 591 | + |
| 592 | + |
| 593 | +class UnixCrossBuild(UnixBuild): |
| 594 | + configureFlags = [ |
| 595 | + "--with-pydebug", |
| 596 | + "--with-build-python=../build/python" |
| 597 | + ] |
| 598 | + extra_configure_flags = [] |
| 599 | + host_configure_cmd = ["../../configure"] |
| 600 | + host = None |
| 601 | + host_make_cmd = ["make"] |
| 602 | + can_execute_python = True |
| 603 | + |
| 604 | + def setup(self, parallel, branch, test_with_PTY=False, **kwargs): |
| 605 | + assert self.host is not None, "Must set self.host on cross builds" |
| 606 | + |
| 607 | + out_of_tree_dir = "build_oot" |
| 608 | + oot_dir_path = os.path.join("build", out_of_tree_dir) |
| 609 | + oot_build_path = os.path.join(oot_dir_path, "build") |
| 610 | + oot_host_path = os.path.join(oot_dir_path, "host") |
| 611 | + |
| 612 | + self.addStep( |
| 613 | + SetPropertyFromCommand( |
| 614 | + name="Gather build triple from worker", |
| 615 | + description="Get the build triple config.guess", |
| 616 | + command="./config.guess", |
| 617 | + property="build_triple", |
| 618 | + warnOnFailure=True, |
| 619 | + ) |
| 620 | + ) |
| 621 | + |
| 622 | + # Create out of tree directory for "build", the platform we are |
| 623 | + # currently running on |
| 624 | + self.addStep( |
| 625 | + ShellCommand( |
| 626 | + name="mkdir build out-of-tree directory", |
| 627 | + description="Create build out-of-tree directory", |
| 628 | + command=["mkdir", "-p", oot_build_path], |
| 629 | + warnOnFailure=True, |
| 630 | + ) |
| 631 | + ) |
| 632 | + # Create directory for "host", the platform we want to compile *for* |
| 633 | + self.addStep( |
| 634 | + ShellCommand( |
| 635 | + name="mkdir host out-of-tree directory", |
| 636 | + description="Create host out-of-tree directory", |
| 637 | + command=["mkdir", "-p", oot_host_path], |
| 638 | + warnOnFailure=True, |
| 639 | + ) |
| 640 | + ) |
| 641 | + |
| 642 | + # First, we build the "build" Python, which we need to cross compile |
| 643 | + # the "host" Python |
| 644 | + self.addStep( |
| 645 | + Configure( |
| 646 | + name="Configure build Python", |
| 647 | + command=["../../configure"], |
| 648 | + workdir=oot_build_path |
| 649 | + ) |
| 650 | + ) |
| 651 | + if parallel: |
| 652 | + compile = ["make", parallel] |
| 653 | + else: |
| 654 | + compile = ["make"] |
| 655 | + |
| 656 | + self.addStep( |
| 657 | + Compile( |
| 658 | + name="Compile build Python", |
| 659 | + command=compile, |
| 660 | + workdir=oot_build_path |
| 661 | + ) |
| 662 | + ) |
| 663 | + |
| 664 | + # Now that we have a "build" architecture Python, we can use that |
| 665 | + # to build a "host" (also known as the target we are cross compiling) |
| 666 | + # to |
| 667 | + configure_cmd = self.host_configure_cmd + ["--prefix", "$(PWD)/target/host"] |
| 668 | + configure_cmd += self.configureFlags + self.extra_configure_flags |
| 669 | + configure_cmd += [util.Interpolate("--build=%(prop:build_triple)s")] |
| 670 | + configure_cmd += [f"--host={self.host}"] |
| 671 | + self.addStep( |
| 672 | + Configure( |
| 673 | + name="Configure host Python", |
| 674 | + command=configure_cmd, |
| 675 | + env=self.compile_environ, |
| 676 | + workdir=oot_host_path |
| 677 | + ) |
| 678 | + ) |
| 679 | + |
| 680 | + testopts = self.testFlags |
| 681 | + if "-R" not in self.testFlags: |
| 682 | + testopts += " --junit-xml test-results.xml" |
| 683 | + if parallel: |
| 684 | + testopts = testopts + " " + parallel |
| 685 | + if "-j" not in testopts: |
| 686 | + testopts = "-j2 " + testopts |
| 687 | + |
| 688 | + # Timeout for the buildworker process |
| 689 | + self.test_timeout = self.test_timeout or TEST_TIMEOUT |
| 690 | + # Timeout for faulthandler |
| 691 | + faulthandler_timeout = self.test_timeout - 5 * 60 |
| 692 | + |
| 693 | + test = [ |
| 694 | + "make", |
| 695 | + "buildbottest", |
| 696 | + "TESTOPTS=" + testopts + " ${BUILDBOT_TESTOPTS}", |
| 697 | + "TESTPYTHONOPTS=" + self.interpreterFlags, |
| 698 | + "TESTTIMEOUT=" + str(faulthandler_timeout), |
| 699 | + ] |
| 700 | + |
| 701 | + if parallel: |
| 702 | + compile = self.host_make_cmd + [parallel, self.makeTarget] |
| 703 | + else: |
| 704 | + compile = self.host_make_cmd + [self.makeTarget] |
| 705 | + self.addStep( |
| 706 | + Compile( |
| 707 | + name="Compile host Python", |
| 708 | + command=compile, |
| 709 | + env=self.compile_environ, |
| 710 | + workdir=oot_host_path, |
| 711 | + ) |
| 712 | + ) |
| 713 | + if self.can_execute_python: |
| 714 | + self.addStep( |
| 715 | + ShellCommand( |
| 716 | + name="pythoninfo", |
| 717 | + description="pythoninfo", |
| 718 | + command=["make", "pythoninfo"], |
| 719 | + warnOnFailure=True, |
| 720 | + env=self.test_environ, |
| 721 | + workdir=oot_host_path, |
| 722 | + ) |
| 723 | + ) |
| 724 | + self.addStep( |
| 725 | + Test( |
| 726 | + command=test, |
| 727 | + timeout=self.test_timeout, |
| 728 | + usePTY=test_with_PTY, |
| 729 | + env=self.test_environ, |
| 730 | + workdir=oot_host_path, |
| 731 | + ) |
| 732 | + ) |
| 733 | + if branch not in ("3",) and "-R" not in self.testFlags: |
| 734 | + filename = os.path.join(oot_host_path, "test-results.xml") |
| 735 | + self.addStep(UploadTestResults(branch, filename=filename)) |
| 736 | + self.addStep( |
| 737 | + Clean( |
| 738 | + name="Clean build Python", |
| 739 | + workdir=oot_build_path, |
| 740 | + ) |
| 741 | + ) |
| 742 | + self.addStep( |
| 743 | + Clean( |
| 744 | + name="Clean host Python", |
| 745 | + workdir=oot_host_path, |
| 746 | + ) |
| 747 | + ) |
| 748 | + |
| 749 | + |
| 750 | +class Wasm32EmscriptenBuild(UnixCrossBuild): |
| 751 | + """wasm32-emscripten builder |
| 752 | +
|
| 753 | + * Emscripten SDK >= 3.1.12 must be installed |
| 754 | + * ccache must be installed |
| 755 | + * Emscripten PATHs must be pre-pended to PATH |
| 756 | + * ``which node`` must be equal $EMSDK_NODE |
| 757 | + """ |
| 758 | + factory_tags = ["wasm", "emscripten"] |
| 759 | + compile_environ = { |
| 760 | + "CONFIG_SITE": "../../Tools/wasm/config.site-wasm32-emscripten", |
| 761 | + "EM_COMPILER_WRAPPER": "ccache", |
| 762 | + } |
| 763 | + |
| 764 | + host = "wasm32-unknown-emscripten" |
| 765 | + host_configure_cmd = ["emconfigure", "../../configure"] |
| 766 | + host_make_cmd = ["emmake", "make"] |
| 767 | + |
| 768 | + |
| 769 | +class Wasm32EmscriptenNodeBuild(Wasm32EmscriptenBuild): |
| 770 | + buildersuffix = ".emscripten-node" |
| 771 | + extra_configure_flags = [ |
| 772 | + "--with-emscripten-target=node", |
| 773 | + "--disable-wasm-dynamic-linking", |
| 774 | + "--enable-wasm-pthreads", |
| 775 | + ] |
| 776 | + |
| 777 | + |
| 778 | +class Wasm32EmscriptenBrowserBuild(Wasm32EmscriptenBuild): |
| 779 | + buildersuffix = ".emscripten-browser" |
| 780 | + extra_configure_flags = [ |
| 781 | + "--with-emscripten-target=browser", |
| 782 | + "--enable-wasm-dynamic-linking", |
| 783 | + "--disable-wasm-pthreads", |
| 784 | + ] |
| 785 | + # browser builds do not accept argv from CLI |
| 786 | + can_execute_python = False |
| 787 | + |
| 788 | + |
| 789 | +class Wasm32WASIBuild(UnixCrossBuild): |
| 790 | + """wasm32-wasi builder |
| 791 | +
|
| 792 | + * WASI SDK >= 16 must be installed to default path /opt/wasi-sdk |
| 793 | + * WASIX must be installed to /opt/wasix |
| 794 | + * ccache must be installed |
| 795 | + * wasmtime must be installed and on PATH |
| 796 | + """ |
| 797 | + buildersuffix = ".wasi" |
| 798 | + factory_tags = ["wasm", "wasi"] |
| 799 | + extra_configure_flags = [ |
| 800 | + # debug builds exhaust the limited call stack on WASI |
| 801 | + "--without-pydebug", |
| 802 | + # ipv6 is not supported on WASI |
| 803 | + "--disable-ipv6", |
| 804 | + ] |
| 805 | + wasi_sdk = "/opt/wasi-sdk" |
| 806 | + wasi_sysroot = f"{wasi_sdk}/share/wasi-sysroot" |
| 807 | + wasix = "/opt/wasix" |
| 808 | + compile_environ = { |
| 809 | + "CONFIG_SITE": "../../Tools/wasm/config.site-wasm32-wasi", |
| 810 | + # use Clang from WASI-SDK |
| 811 | + "CC": f"ccache {wasi_sdk}/bin/clang", |
| 812 | + "LDSHARED": f"{wasi_sdk}/bin/wasm-ld", |
| 813 | + "AR": f"{wasi_sdk}/bin/llvm-ar", |
| 814 | + # use WASIX library with POSIX stubs |
| 815 | + "CFLAGS": f"-isystem {wasix}/include", |
| 816 | + "LDFLAGS": f"-L{wasix}/lib -lwasix", |
| 817 | + # WASI-SDK does not have a 'wasm32-unknown-wasi-pkg-config' script |
| 818 | + # force pkg-config into cross-compiling mode |
| 819 | + "PKG_CONFIG_PATH": "", |
| 820 | + "PKG_CONFIG_SYSROOT_DIR": wasi_sysroot, |
| 821 | + "PKG_CONFIG_LIBDIR": f"{wasi_sysroot}/lib/pkgconfig:{wasi_sysroot}/share/pkgconfig", |
| 822 | + } |
| 823 | + host = "wasm32-unknown-wasi" |
| 824 | + |
| 825 | + def setup(self, parallel, branch, test_with_PTY=False, **kwargs): |
| 826 | + self.addStep( |
| 827 | + ShellCommand( |
| 828 | + name="Touch srcdir Modules/Setup.local", |
| 829 | + description="Hack to work around wasmtime mapdir issue", |
| 830 | + command=["touch", "Modules/Setup.local"], |
| 831 | + haltOnFailure=True, |
| 832 | + ) |
| 833 | + ) |
| 834 | + super().setup( |
| 835 | + parallel, branch, test_with_PTY=test_with_PTY, **kwargs |
| 836 | + ) |
0 commit comments