├── .bazelignore ├── .bcr ├── metadata.template.json ├── presubmit.yml └── source.template.json ├── .buildifier.json ├── .github ├── CODEOWNERS └── workflows │ ├── release.yml │ ├── release_notes_template.txt │ ├── release_prep.sh │ └── tests.yml ├── .gitignore ├── .trunk ├── .gitignore ├── configs │ ├── .editorconfig │ ├── .markdownlint.yaml │ ├── .shellcheckrc │ └── .yamllint.yaml └── trunk.yaml ├── LICENSE ├── MODULE.bazel ├── README.md ├── REPO_RENAME.md ├── WORKSPACE ├── platforms └── BUILD.bazel ├── renovate.json ├── tests ├── .bazelrc ├── .buildifier.json ├── BUILD.bazel ├── MODULE.bazel ├── WORKSPACE ├── WORKSPACE.bzlmod ├── file_dependency_test.sh ├── foreign │ └── BUILD.bazel ├── omp_test.c ├── omp_test.cc ├── openssl │ ├── BUILD.bazel │ ├── crypto │ │ └── include │ │ │ └── internal │ │ │ ├── bn_conf.h │ │ │ └── dso_conf.h │ ├── include │ │ └── openssl │ │ │ └── opensslconf.h │ └── openssl.bazel ├── scripts │ ├── archlinux_test.sh │ ├── bazel.sh │ ├── centos_test.sh │ ├── debian_test.sh │ ├── fedora_test.sh │ ├── linux_sysroot_test.sh │ ├── run_docker_exec_test.sh │ ├── run_external_tests.sh │ ├── run_tests.sh │ ├── run_toolchain_tests.sh │ ├── run_xcompile_tests.sh │ ├── suse_leap_test.sh │ ├── suse_tumbleweed_test.sh │ ├── ubuntu_20_04_test.sh │ ├── ubuntu_22_04_test.sh │ └── ubuntu_install_libtinfo.sh ├── stdlib.cc ├── stdlib.h ├── stdlib_test.cc ├── test_cxx_standard.cc ├── test_cxx_standard_main.cc ├── transitions.bzl └── wasm │ ├── BUILD.bazel │ ├── wasi_sdk.bzl │ ├── wasm_strlen.c │ ├── wasm_strlen_nolibc.c │ └── wasm_strlen_wasi.c ├── toolchain ├── BUILD.bazel ├── BUILD.llvm_repo ├── BUILD.toolchain.tpl ├── aliases.bzl ├── cc_toolchain_config.bzl ├── cc_wrapper.sh.tpl ├── config │ └── BUILD.bazel ├── deps.bzl ├── extensions │ ├── BUILD.bazel │ └── llvm.bzl ├── internal │ ├── BUILD.bazel │ ├── common.bzl │ ├── configure.bzl │ ├── llvm_distributions.bzl │ ├── llvm_distributions.golden.out.txt │ ├── llvm_distributions.golden.sel.txt │ ├── llvm_distributions_select_no_error_test.sh │ ├── repo.bzl │ ├── sysroot.bzl │ ├── system_module_map.bzl │ └── template.modulemap ├── osx_cc_wrapper.sh.tpl ├── rules.bzl └── toolchains.bzl.tpl └── utils └── llvm_checksums.sh /.bazelignore: -------------------------------------------------------------------------------- 1 | tests 2 | -------------------------------------------------------------------------------- /.bcr/metadata.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "homepage": "https://github.com/bazel-contrib/toolchains_llvm", 3 | "maintainers": [ 4 | { 5 | "email": "fabian@meumertzhe.im", 6 | "github": "fmeum", 7 | "name": "Fabian Meumertzheim" 8 | }, 9 | { 10 | "email": "james.sharpe@zenotech.com", 11 | "github": "jsharpe", 12 | "name": "James Sharpe" 13 | }, 14 | { 15 | "email": "rrbutani@users.noreply.github.com", 16 | "github": "rrbutani", 17 | "name": "Rahul Butani" 18 | } 19 | ], 20 | "repository": ["github:bazel-contrib/toolchains_llvm"], 21 | "versions": [], 22 | "yanked_versions": {} 23 | } 24 | -------------------------------------------------------------------------------- /.bcr/presubmit.yml: -------------------------------------------------------------------------------- 1 | matrix: 2 | bazel: [7.x] 3 | platform: [ubuntu2004, macos, macos_arm64] 4 | tasks: 5 | verify_targets: 6 | name: Verify build targets 7 | bazel: ${{ bazel }} 8 | platform: ${{ platform }} 9 | build_targets: 10 | - "@toolchains_llvm//toolchain:all" 11 | - "@toolchains_llvm//platforms:all" 12 | bcr_test_module: 13 | module_path: tests 14 | matrix: 15 | bazel: [7.x] 16 | platform: [ubuntu2004, macos, macos_arm64] 17 | tasks: 18 | run_test_module: 19 | name: Run test module 20 | bazel: ${{ bazel }} 21 | platform: ${{ platform }} 22 | build_targets: 23 | - //:all 24 | test_targets: 25 | - //:all 26 | -------------------------------------------------------------------------------- /.bcr/source.template.json: -------------------------------------------------------------------------------- 1 | { 2 | "integrity": "**leave this alone**", 3 | "strip_prefix": "{REPO}-{TAG}", 4 | "url": "https://github.com/{OWNER}/{REPO}/releases/download/{TAG}/toolchains_llvm-{TAG}.tar.gz" 5 | } 6 | -------------------------------------------------------------------------------- /.buildifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "auto", 3 | "mode": "fix", 4 | "lint": "fix", 5 | "warningsList": [ 6 | "attr-applicable_licenses", 7 | "attr-cfg", 8 | "attr-license", 9 | "attr-licenses", 10 | "attr-non-empty", 11 | "attr-output-default", 12 | "attr-single-file", 13 | "build-args-kwargs", 14 | "bzl-visibility", 15 | "confusing-name", 16 | "constant-glob", 17 | "ctx-actions", 18 | "ctx-args", 19 | "deprecated-function", 20 | "depset-items", 21 | "depset-iteration", 22 | "depset-union", 23 | "dict-concatenation", 24 | "dict-method-named-arg", 25 | "duplicated-name", 26 | "filetype", 27 | "git-repository", 28 | "http-archive", 29 | "integer-division", 30 | "keyword-positional-params", 31 | "list-append", 32 | "load", 33 | "name-conventions", 34 | "native-android", 35 | "native-build", 36 | "native-cc", 37 | "native-package", 38 | "native-proto", 39 | "native-py", 40 | "no-effect", 41 | "output-group", 42 | "overly-nested-depset", 43 | "package-name", 44 | "package-on-top", 45 | "positional-args", 46 | "print", 47 | "provider-params", 48 | "redefined-variable", 49 | "repository-name", 50 | "return-value", 51 | "rule-impl-return", 52 | "skylark-comment", 53 | "skylark-docstring", 54 | "string-iteration", 55 | "uninitialized", 56 | "unnamed-macro", 57 | "unreachable", 58 | "unused-variable" 59 | ] 60 | } 61 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @siddharthab @rrbutani @jsharpe @fmeum 2 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # Cut a release whenever a new tag is pushed to the repo. 2 | # You should use an annotated tag, like `git tag -a v1.2.3` 3 | # and put the release notes into the commit message for the tag. 4 | name: Release 5 | 6 | on: 7 | push: 8 | tags: 9 | - "*.*.*" 10 | 11 | permissions: read-all 12 | 13 | jobs: 14 | release: 15 | permissions: 16 | contents: write 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v4 21 | - name: Prepare release 22 | run: .github/workflows/release_prep.sh > release_notes.txt 23 | - name: Release 24 | uses: softprops/action-gh-release@v2 25 | with: 26 | prerelease: false 27 | generate_release_notes: true 28 | body_path: release_notes.txt 29 | files: toolchains_llvm-*.tar.gz 30 | fail_on_unmatched_files: true 31 | -------------------------------------------------------------------------------- /.github/workflows/release_notes_template.txt: -------------------------------------------------------------------------------- 1 | Minimum bazel version: **7.0.0** 2 | 3 | If you're using `bzlmod`, add the following to `MODULE.bazel`: 4 | 5 | ```starlark 6 | bazel_dep(name = "toolchains_llvm", version = "{version}") 7 | 8 | # Configure and register the toolchain. 9 | llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") 10 | llvm.toolchain( 11 | llvm_version = "16.0.0", 12 | ) 13 | 14 | use_repo(llvm, "llvm_toolchain") 15 | # use_repo(llvm, "llvm_toolchain_llvm") # if you depend on specific tools in scripts 16 | 17 | register_toolchains("@llvm_toolchain//:all") 18 | ``` 19 | 20 | To directly use a commit from GitHub, add this block and replace commit with the commit you want. 21 | ```starlark 22 | git_override( 23 | module_name = "toolchains_llvm", 24 | commit = "{commit}", 25 | remote = "https://github.com/bazel-contrib/toolchains_llvm", 26 | ) 27 | ``` 28 | 29 | If not using `bzlmod`, include this section in your `WORKSPACE`: 30 | 31 | ```starlark 32 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 33 | 34 | http_archive( 35 | name = "toolchains_llvm", 36 | sha256 = "{sha}", 37 | strip_prefix = "{prefix}", 38 | canonical_id = "{tag}", 39 | url = "https://github.com/bazel-contrib/toolchains_llvm/releases/download/{tag}/{archive}", 40 | ) 41 | 42 | load("@toolchains_llvm//toolchain:deps.bzl", "bazel_toolchain_dependencies") 43 | 44 | bazel_toolchain_dependencies() 45 | 46 | load("@toolchains_llvm//toolchain:rules.bzl", "llvm_toolchain") 47 | 48 | llvm_toolchain( 49 | name = "llvm_toolchain", 50 | llvm_version = "16.0.0", 51 | ) 52 | 53 | load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains") 54 | 55 | llvm_register_toolchains() 56 | ``` 57 | -------------------------------------------------------------------------------- /.github/workflows/release_prep.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -o errexit -o nounset -o pipefail 4 | 5 | git config user.email "you@example.com" 6 | git config user.name "Your Name" 7 | 8 | # Set by GH actions, see 9 | # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables 10 | tag="${GITHUB_REF_NAME}" 11 | commit="${GITHUB_SHA}" 12 | # The prefix is chosen to match what GitHub generates for source archives 13 | prefix="toolchains_llvm-${tag}" 14 | archive="toolchains_llvm-${tag}.tar.gz" 15 | sed -i.bak "s/0.0.0/${tag}/" MODULE.bazel && git add MODULE.bazel && git commit -m "Update version" >/dev/null 16 | git archive --format=tar --prefix="${prefix}/" HEAD | gzip >"${archive}" 17 | sha=$(shasum -a 256 "${archive}" | cut -f1 -d' ') 18 | 19 | # Strip leading "v" from the tag if present to create the semver version. 20 | sed \ 21 | -e "s/{version}/${tag#v}/g" \ 22 | -e "s/{tag}/${tag}/g" \ 23 | -e "s/{commit}/${commit}/g" \ 24 | -e "s/{prefix}/${prefix}/g" \ 25 | -e "s/{archive}/${archive}/g" \ 26 | -e "s/{sha}/${sha}/g" \ 27 | .github/workflows/release_notes_template.txt 28 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: Tests 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | concurrency: 10 | group: ${{ github.head_ref || github.run_id }} 11 | cancel-in-progress: true 12 | 13 | permissions: read-all 14 | 15 | jobs: 16 | lint: 17 | runs-on: ubuntu-latest 18 | permissions: 19 | checks: write # For trunk to post annotations 20 | contents: read # For repo checkout 21 | steps: 22 | - name: Checkout 23 | uses: actions/checkout@v4 24 | - name: Trunk Check 25 | uses: trunk-io/trunk-action@v1 26 | test: 27 | strategy: 28 | fail-fast: false 29 | matrix: 30 | os: [macos-latest, ubuntu-latest] 31 | # TODO: Test with Bazel 8 after https://github.com/bazelbuild/bazel/pull/24154 has been released. 32 | bazel_version: [7.x, latest] # Minimum supported Bazel version is 7.x 33 | bzlmod: [true, false] 34 | runs-on: ${{ matrix.os }} 35 | steps: 36 | - uses: actions/checkout@v4 37 | - if: startsWith(matrix.os, 'ubuntu') 38 | run: tests/scripts/ubuntu_install_libtinfo.sh 39 | - name: Test 40 | env: 41 | USE_BAZEL_VERSION: ${{ matrix.bazel_version }} 42 | USE_BZLMOD: ${{ matrix.bzlmod }} 43 | run: tests/scripts/run_tests.sh 44 | toolchain_test: 45 | runs-on: ubuntu-latest 46 | steps: 47 | - uses: actions/checkout@v4 48 | - name: Test 49 | env: 50 | USE_BAZEL_VERSION: latest 51 | USE_BZLMOD: true 52 | run: tests/scripts/run_toolchain_tests.sh 53 | external_test: 54 | strategy: 55 | fail-fast: false 56 | matrix: 57 | # TODO: This doesn't work with arm64 Macs yet, hence pinning to macos-13. 58 | os: [macos-13, ubuntu-latest] 59 | bazel_version: [latest] # rules_rust bzlmod support is experimental and needs latest version as of now (20230912). 60 | bzlmod: [true, false] 61 | runs-on: ${{ matrix.os }} 62 | steps: 63 | - uses: actions/checkout@v4 64 | - if: startsWith(matrix.os, 'ubuntu') 65 | run: tests/scripts/ubuntu_install_libtinfo.sh 66 | - name: Test 67 | env: 68 | USE_BAZEL_VERSION: ${{ matrix.bazel_version }} 69 | USE_BZLMOD: ${{ matrix.bzlmod }} 70 | run: tests/scripts/run_external_tests.sh 71 | container_test: 72 | strategy: 73 | fail-fast: false 74 | matrix: 75 | script: 76 | [ 77 | archlinux, 78 | debian, 79 | fedora, 80 | suse_leap, 81 | suse_tumbleweed, 82 | ubuntu_20_04, 83 | ubuntu_22_04, 84 | linux_sysroot, 85 | ] 86 | bzlmod: [true, false] 87 | runs-on: ubuntu-latest 88 | steps: 89 | - uses: actions/checkout@v4 90 | - name: Test 91 | env: 92 | USE_BZLMOD: ${{ matrix.bzlmod }} 93 | run: tests/scripts/${{ matrix.script }}_test.sh 94 | xcompile_test: 95 | strategy: 96 | fail-fast: false 97 | matrix: 98 | bzlmod: [true, false] 99 | runs-on: macos-latest 100 | steps: 101 | - uses: actions/checkout@v4 102 | - name: Test 103 | env: 104 | USE_BZLMOD: ${{ matrix.bzlmod }} 105 | run: tests/scripts/run_xcompile_tests.sh 106 | abs_paths_test: 107 | strategy: 108 | fail-fast: false 109 | matrix: 110 | bzlmod: [true, false] 111 | runs-on: ubuntu-latest 112 | steps: 113 | - uses: actions/checkout@v4 114 | - run: tests/scripts/ubuntu_install_libtinfo.sh 115 | - name: Test 116 | env: 117 | USE_BZLMOD: ${{ matrix.bzlmod }} 118 | run: tests/scripts/run_tests.sh -t @llvm_toolchain_with_absolute_paths//:cc-toolchain-x86_64-linux 119 | sys_paths_test: 120 | strategy: 121 | fail-fast: false 122 | matrix: 123 | bzlmod: [true, false] 124 | runs-on: ubuntu-latest 125 | steps: 126 | - uses: actions/checkout@v4 127 | - run: tests/scripts/ubuntu_install_libtinfo.sh 128 | - name: Download and Extract LLVM distribution 129 | env: 130 | release: llvmorg-16.0.0 131 | archive: clang+llvm-16.0.0-x86_64-linux-gnu-ubuntu-18.04 132 | ext: .tar.xz 133 | local_path: /opt/llvm-16 134 | run: wget --no-verbose "https://github.com/llvm/llvm-project/releases/download/${release}/${archive}${ext}" && tar -xf "${archive}${ext}" && mv "${archive}" "${local_path}" 135 | - name: Test 136 | env: 137 | USE_BZLMOD: ${{ matrix.bzlmod }} 138 | run: tests/scripts/run_tests.sh -t @llvm_toolchain_with_system_llvm//:cc-toolchain-x86_64-linux 139 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /bazel-* 2 | /tests/bazel-* 3 | /toolchain/tools/__pycache__ 4 | /toolchain/tools/host_os_key.pyc 5 | MODULE.bazel.lock 6 | -------------------------------------------------------------------------------- /.trunk/.gitignore: -------------------------------------------------------------------------------- 1 | *out 2 | *logs 3 | *actions 4 | *notifications 5 | *tools 6 | plugins 7 | user_trunk.yaml 8 | user.yaml 9 | -------------------------------------------------------------------------------- /.trunk/configs/.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 2 6 | -------------------------------------------------------------------------------- /.trunk/configs/.markdownlint.yaml: -------------------------------------------------------------------------------- 1 | # Autoformatter friendly markdownlint config (all formatting rules disabled) 2 | default: true 3 | blank_lines: false 4 | bullet: false 5 | html: false 6 | indentation: false 7 | line_length: false 8 | spaces: false 9 | url: false 10 | whitespace: false 11 | -------------------------------------------------------------------------------- /.trunk/configs/.shellcheckrc: -------------------------------------------------------------------------------- 1 | enable=all 2 | source-path=SCRIPTDIR 3 | disable=SC2154 4 | 5 | # If you're having issues with shellcheck following source, disable the errors via: 6 | # disable=SC1090 7 | # disable=SC1091 8 | -------------------------------------------------------------------------------- /.trunk/configs/.yamllint.yaml: -------------------------------------------------------------------------------- 1 | rules: 2 | quoted-strings: 3 | required: only-when-needed 4 | extra-allowed: ["{|}"] 5 | empty-values: 6 | forbid-in-block-mappings: true 7 | forbid-in-flow-mappings: true 8 | key-duplicates: {} 9 | octal-values: 10 | forbid-implicit-octal: true 11 | -------------------------------------------------------------------------------- /.trunk/trunk.yaml: -------------------------------------------------------------------------------- 1 | version: 0.1 2 | cli: 3 | version: 1.15.0 4 | plugins: 5 | sources: 6 | - id: trunk 7 | ref: v1.2.3 8 | uri: https://github.com/trunk-io/plugins 9 | runtimes: 10 | enabled: 11 | - go@1.21.0 12 | - node@18.12.1 13 | - python@3.10.8 14 | lint: 15 | definitions: 16 | - name: buildifier 17 | files: [starlark, bazel-build, bazel-workspace] 18 | tools: [buildifier] 19 | commands: 20 | - name: fix 21 | run: buildifier --lint=fix "${target}" 22 | output: rewrite 23 | cache_results: true 24 | formatter: true 25 | in_place: true 26 | batch: true 27 | success_codes: [0] 28 | - name: warn 29 | run: buildifier --lint=warn --format=json --mode=check "${target}" 30 | # Custom parser type defined in the trunk cli to handle buildifier's JSON output. 31 | output: buildifier 32 | cache_results: true 33 | batch: true 34 | success_codes: [0] 35 | suggest_if: files_present 36 | direct_configs: 37 | - .buildifier.json 38 | # Not a native buildifier construct, but useful for 'addTables', see test file 39 | - .buildifier-tables.json 40 | environment: 41 | - name: PATH 42 | list: ["${linter}"] 43 | known_good_version: 7.1.0 44 | version_command: 45 | parse_regex: ${semver} 46 | run: buildifier --version 47 | # Default shfmt config uses -s flag to simplify code but this can cause 48 | # unwanted semantic changes 49 | - name: shfmt 50 | commands: 51 | - name: format 52 | output: shfmt 53 | run: shfmt -w ${target} 54 | success_codes: [0, 1] 55 | cache_results: true 56 | formatter: true 57 | batch: true 58 | in_place: true 59 | enabled: 60 | - actionlint@1.6.25 61 | - buildifier@7.1.0 62 | - checkov@2.4.9 63 | - git-diff-check 64 | - markdownlint@0.36.0 65 | - prettier@3.0.3 66 | - shellcheck@0.9.0 67 | - shfmt@3.6.0 68 | - trivy@0.45.0 69 | - trufflehog@3.55.1 70 | - yamllint@1.32.0 71 | actions: 72 | enabled: 73 | - trunk-announce 74 | - trunk-check-pre-push 75 | - trunk-fmt-pre-commit 76 | - trunk-upgrade-available 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /MODULE.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | module( 16 | name = "toolchains_llvm", 17 | version = "0.0.0", 18 | bazel_compatibility = [">=7.0.0"], 19 | compatibility_level = 0, 20 | ) 21 | 22 | bazel_dep(name = "bazel_skylib", version = "1.5.0") 23 | bazel_dep(name = "rules_cc", version = "0.0.17") 24 | bazel_dep(name = "platforms", version = "0.0.8") 25 | 26 | # TODO: Remove when protobuf is released with a version of rules_python that supports 8.x 27 | bazel_dep(name = "rules_python", version = "1.0.0", dev_dependency = True) 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LLVM toolchain for Bazel [![Tests](https://github.com/bazel-contrib/toolchains_llvm/actions/workflows/tests.yml/badge.svg)](https://github.com/bazel-contrib/toolchains_llvm/actions/workflows/tests.yml) 2 | 3 | ## Quickstart 4 | 5 | See notes on the [release](https://github.com/bazel-contrib/toolchains_llvm/releases) 6 | for how to get started. 7 | 8 | NOTE: For releases prior to 0.10.1, please also see [these notes](REPO_RENAME.md). 9 | 10 | 11 | 12 | ## Basic Usage 13 | 14 | The toolchain can automatically detect your OS and arch type, and use the right 15 | pre-built binary LLVM distribution. See the section on "Bring Your Own LLVM" 16 | below for more options. 17 | 18 | See in-code documentation in [rules.bzl](toolchain/rules.bzl) for available 19 | attributes to `llvm_toolchain`. 20 | 21 | ## Advanced Usage 22 | 23 | ### Per host architecture LLVM version 24 | 25 | LLVM does not come with distributions for all host architectures in each 26 | version. In particular patch versions often come with few prebuilt packages. 27 | This means that a single version probably is not enough to address all hosts 28 | one wants to support. 29 | 30 | This can be solved by providing a target/version map with a default version. 31 | The example below selects `15.0.6` as the default version for all targets not 32 | specified explicitly. This is like providing `llvm_version = "15.0.6"`, just 33 | like in the example on the top. However, here we provide two more entries that 34 | map their respective target to a distinct version: 35 | 36 | ```starlark 37 | llvm_toolchain( 38 | name = "llvm_toolchain", 39 | llvm_versions = { 40 | "": "15.0.6", 41 | "darwin-aarch64": "15.0.7", 42 | "darwin-x86_64": "15.0.7", 43 | }, 44 | ) 45 | ``` 46 | 47 | ### Customizations 48 | 49 | We currently offer limited customizability through attributes of the 50 | [llvm_toolchain\_\* rules](toolchain/rules.bzl). You can send us a PR to add 51 | more configuration attributes. 52 | 53 | The `MODULE.bazel` example below demonstrates how to add new LLVM distributions before the toolchain has 54 | been updated. They can easily be computed using the provided checksum tool (see `llvm_checksums.sh -h`). 55 | 56 | ```starlark 57 | llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm", dev_dependency = True) 58 | llvm.toolchain( 59 | name = "llvm_toolchain", 60 | llvm_version = "20.1.4", 61 | extra_llvm_distributions = { 62 | "LLVM-20.1.4-Linux-ARM64.tar.xz": "4de80a332eecb06bf55097fd3280e1c69ed80f222e5bdd556221a6ceee02721a", 63 | "LLVM-20.1.4-Linux-X64.tar.xz": "113b54c397adb2039fa45e38dc8107b9ec5a0baead3a3bac8ccfbb65b2340caa", 64 | "LLVM-20.1.4-macOS-ARM64.tar.xz": "debb43b7b364c5cf864260d84ba1b201d49b6460fe84b76eaa65688dfadf19d2", 65 | "clang+llvm-20.1.4-x86_64-pc-windows-msvc.tar.xz": "2b12ac1a0689e29a38a7c98c409cbfa83f390aea30c60b7a06e4ed73f82d2457", 66 | }, 67 | ) 68 | ``` 69 | 70 | The following `WORKSPACE` snippet shows how to add a specific version for a specific target before 71 | the version was added to [llvm_distributions.bzl](toolchain/internal/llvm_distributions.bzl). 72 | 73 | ```starlark 74 | llvm_toolchain( 75 | name = "llvm_toolchain", 76 | llvm_version = "19.1.6", 77 | sha256 = {"linux-x86_64": "d55dcbb309de7ade4e3073ec3ac3fac4d3ff236d54df3c4de04464fe68bec531"}, 78 | strip_prefix = { 79 | "linux-x86_64": "LLVM-19.1.6-Linux-X64", 80 | }, 81 | urls = { 82 | "linux-x86_64": [ 83 | "https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.6/LLVM-19.1.6-Linux-X64.tar.xz", 84 | ], 85 | }, 86 | ) 87 | ``` 88 | 89 | A majority of the complexity of this project is to make it generic for multiple 90 | use cases. For one-off experiments with new architectures, cross-compilations, 91 | new compiler features, etc., my advice would be to look at the toolchain 92 | configurations generated by this repo, and copy-paste/edit to make your own in 93 | any package in your own workspace. 94 | 95 | ```sh 96 | bazel query --output=build @llvm_toolchain//:all | grep -v -e '^#' -e '^ generator' 97 | ``` 98 | 99 | Besides defining your toolchain in your package BUILD file, and until this 100 | [issue](https://github.com/bazelbuild/bazel/issues/7746) is resolved, you would 101 | also need a way for bazel to access the tools in LLVM distribution as relative 102 | paths from your package without using `..` up-references. For this, you can 103 | create a symlink that uses up-references to point to the LLVM distribution 104 | directory, and also create a wrapper script for clang such that the actual 105 | clang invocation is not through the symlinked path. See the files in the 106 | `@llvm_toolchain//:` package as a reference. 107 | 108 | ```sh 109 | # See generated files for reference. 110 | ls -lR "$(bazel info output_base)/external/llvm_toolchain" 111 | 112 | # Create symlink to LLVM distribution. 113 | cd _your_package_directory_ 114 | ln -s ../....../external/llvm_toolchain_llvm llvm 115 | 116 | # Create CC wrapper script. 117 | mkdir bin 118 | cp "$(bazel info output_base)/external/llvm_toolchain/bin/cc_wrapper.sh" bin/cc_wrapper.sh 119 | vim bin/cc_wrapper.sh # Review to ensure relative paths, etc. are good. 120 | ``` 121 | 122 | See [bazel 123 | tutorial](https://docs.bazel.build/versions/main/tutorial/cc-toolchain-config.html) 124 | for how CC toolchains work in general. 125 | 126 | ### Selecting Toolchains 127 | 128 | If toolchains are registered (see Quickstart section above), you do not need to 129 | do anything special for bazel to find the toolchain. You may want to check once 130 | with the `--toolchain_resolution_debug` flag to see which toolchains were 131 | selected by bazel for your target platform. 132 | 133 | For specifying unregistered toolchains on the command line, please use the 134 | `--extra_toolchains` flag. For example, 135 | `--extra_toolchains=@llvm_toolchain//:cc-toolchain-x86_64-linux`. 136 | 137 | ### Bring Your Own LLVM 138 | 139 | The following mechanisms are available for using an LLVM toolchain: 140 | 141 | 1. Host OS information is used to find the right pre-built binary distribution 142 | from llvm.org, given the `llvm_version` or `llvm_versions` attribute. The 143 | LLVM toolchain archive is downloaded and extracted as a separate repository 144 | with the suffix `_llvm`. The detection logic for `llvm_version` is not 145 | perfect, so you may have to use `llvm_versions` for some host OS type and 146 | versions. We expect the detection logic to grow through community 147 | contributions. We welcome PRs. 148 | 2. You can use the `urls` attribute to specify your own URLs for each OS type, 149 | version and architecture. For example, you can specify a different URL for 150 | Arch Linux and a different one for Ubuntu. Just as with the option above, 151 | the archive is downloaded and extracted as a separate repository with the 152 | suffix `_llvm`. 153 | 3. You can also specify your own bazel package paths or local absolute paths 154 | for each host os-arch pair through the `toolchain_roots` attribute (without 155 | bzlmod) or the `toolchain_root` module extension tags (with bzlmod). Note 156 | that the keys here are different and less granular than the keys in the `urls` 157 | attribute. When using a bazel package path, each of the values is typically 158 | a package in the user's workspace or configured through `local_repository` or 159 | `http_archive`; the BUILD file of the package should be similar to 160 | `@toolchains_llvm//toolchain:BUILD.llvm_repo`. If using only 161 | `http_archive`, maybe consider using the `urls` attribute instead to get more 162 | flexibility if you need. 163 | 4. All the above options rely on host OS information, and are not suited for 164 | docker based sandboxed builds or remote execution builds. Such builds will 165 | need a single distribution version specified through the `distribution` 166 | attribute, or URLs specified through the `urls` attribute with an empty key, or 167 | a toolchain root specified through the `toolchain_roots` attribute with an 168 | empty key. 169 | 170 | ### Sysroots 171 | 172 | A sysroot can be specified through the `sysroot` attribute (without bzlmod) or 173 | the `sysroot` module extension tag (with bzlmod). This can be either a path on 174 | the user's system, or a bazel `filegroup` like label. One way to create a 175 | sysroot is to use `docker export` to get a single archive of the entire 176 | filesystem for the image you want. Another way is to use the build scripts 177 | provided by the [Chromium 178 | project](https://chromium.googlesource.com/chromium/src/+/HEAD/docs/linux/sysroot.md). 179 | 180 | ### Cross-compilation 181 | 182 | The toolchain supports cross-compilation if you bring your own sysroot. When 183 | cross-compiling, we link against the libstdc++ from the sysroot 184 | (single-platform build behavior is to link against libc++ bundled with LLVM). 185 | The following pairs have been tested to work for some hello-world binaries: 186 | 187 | - {linux, x86_64} -> {linux, aarch64} 188 | - {linux, aarch64} -> {linux, x86_64} 189 | - {darwin, x86_64} -> {linux, x86_64} 190 | - {darwin, x86_64} -> {linux, aarch64} 191 | 192 | A recommended approach would be to define two toolchains, one without sysroot 193 | for single-platform builds, and one with sysroot for cross-compilation builds. 194 | Then, when cross-compiling, explicitly specify the toolchain with the sysroot 195 | and the target platform. For example, see the [MODULE.bazel](tests/MODULE.bazel) 196 | file for `llvm_toolchain_with_sysroot` and the [test 197 | script](tests/scripts/run_xcompile_tests.sh) for cross-compilation. 198 | 199 | ```sh 200 | bazel build \ 201 | --platforms=@toolchains_llvm//platforms:linux-x86_64 \ 202 | --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux \ 203 | //... 204 | ``` 205 | 206 | ### Multi-platform builds 207 | 208 | The toolchain supports multi-platform builds through the combination of the 209 | `exec_os`, `exec_arch` attribute pair, and either the `distribution` attribute, 210 | or the `urls` attribute. This allows one to run their builds on one platform 211 | (e.g. macOS) and their build actions to run on another (e.g. Linux), enabling 212 | remote build execution (RBE). For example, see the [MODULE.bazel](tests/MODULE.bazel) 213 | file for `llvm_toolchain_linux_exec` and the [test 214 | script](tests/scripts/run_docker_exec_test.sh) for running the build actions on 215 | Linux even if the build is being run from macOS. 216 | 217 | ```sh 218 | bazel build \ 219 | --platforms=@toolchains_llvm//platforms:linux-x86_64 \ 220 | --extra_execution_platforms=@toolchains_llvm//platforms:linux-x86_64 \ 221 | --extra_toolchains=@llvm_toolchain_linux_exec//:cc-toolchain-x86_64-linux \ 222 | //... 223 | ``` 224 | 225 | ### Supporting New Target Platforms 226 | 227 | The following is a rough (untested) list of steps: 228 | 229 | 1. To help us detect if you are cross-compiling or not, note the arch string as 230 | given by `python3 -c 'import platform; print(platform.machine())`. 231 | 2. Edit `SUPPORTED_TARGETS` in 232 | [toolchain/internal/common.bzl](toolchain/internal/common.bzl) with the os 233 | and the arch string from above. 234 | 3. Add `target_system_name`, etc. in 235 | [toolchain/cc_toolchain_config.bzl](toolchain/cc_toolchain_config.bzl). 236 | 4. For cross-compiling, add a `platform` bazel type for your target platform in 237 | [platforms/BUILD.bazel](platforms/BUILD.bazel), and add an appropriate 238 | sysroot entry to your `llvm_toolchain` repository definition. 239 | 5. If not cross-compiling, bring your own LLVM (see section above) through the 240 | `toolchain_roots` or `urls` attribute. 241 | 6. Test your build. 242 | 243 | ### Sandbox 244 | 245 | Sandboxing the toolchain introduces a significant overhead (100ms per action, 246 | as of mid 2018). To overcome this, one can use 247 | `--experimental_sandbox_base=/dev/shm`. However, not all environments might 248 | have enough shared memory available to load all the files in memory. If this is 249 | a concern, you may set the attribute for using absolute paths, which will 250 | substitute templated paths to the toolchain as absolute paths. When running 251 | bazel actions, these paths will be available from inside the sandbox as part of 252 | the / read-only mount. Note that this will make your builds non-hermetic. 253 | 254 | ### Compatibility 255 | 256 | The toolchain is tested to work with `rules_go`, `rules_rust`, and 257 | `rules_foreign_cc`. 258 | 259 | ### Accessing tools 260 | 261 | The LLVM distribution also provides several tools like `clang-format`. You can 262 | depend on these tools directly in the bin directory of the distribution. When 263 | not using the `toolchain_roots` attribute, the distribution is available in the 264 | repo with the suffix `_llvm` appended to the name you used for the 265 | `llvm_toolchain` rule. For example, `@llvm_toolchain_llvm//:bin/clang-format` 266 | is a valid and visible target in the quickstart example above. 267 | 268 | When using the `toolchain_roots` attribute, there is currently no single target 269 | that you can reference, and you may have to alias the tools you want with a 270 | `select` clause in your workspace. 271 | 272 | As a convenience, some targets are aliased appropriately in the configuration 273 | repo (as opposed to the LLVM distribution repo) for you to use and will work 274 | even when using `toolchain_roots`. The complete list is in the file 275 | [aliases.bzl](toolchain/aliases.bzl). If your repo is named `llvm_toolchain`, 276 | then they can be referenced as: 277 | 278 | - `@llvm_toolchain//:omp` 279 | - `@llvm_toolchain//:clang-format` 280 | - `@llvm_toolchain//:llvm-cov` 281 | 282 | ### Strict header deps (Linux only) 283 | 284 | The toolchain supports Bazel's `layering_check` feature, which relies on 285 | [Clang modules](https://clang.llvm.org/docs/Modules.html) to implement strict 286 | deps (also known as "depend on what you use") for `cc_*` rules. This feature 287 | can be enabled by enabling the `layering_check` feature on a per-target, 288 | per-package or global basis. 289 | 290 | ## Prior Art 291 | 292 | Other examples of toolchain configuration: 293 | 294 | https://bazel.build/tutorials/ccp-toolchain-config 295 | 296 | https://github.com/vsco/bazel-toolchains 297 | -------------------------------------------------------------------------------- /REPO_RENAME.md: -------------------------------------------------------------------------------- 1 | # Rename from bazel-toolchain to toolchains_llvm 2 | 3 | As part of the transfer to the bazel-contrib org, the repo has been renamed to 4 | `toolchains_llvm`. This has affected the dynamically generated source archives 5 | which now have a different tree prefix, and consequently, a different shasum. 6 | 7 | From release 0.10.1 onwards, the releases have all generated a release artifact 8 | which is guaranteed to be stable. But for prior releases, users need to change 9 | the `shasum` and `strip_prefix` attributes for referencing this repo. 10 | 11 | 0.10.0: 12 | 13 | ```bzl 14 | strip_prefix = "toolchains_llvm-0.10.0", 15 | shasum = "a2877b8bf596ee4c0310b50463796efd8f360dcb087675e9101e15c39e03d7ea", 16 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.10.0.tar.gz", 17 | ``` 18 | 19 | 0.9: 20 | 21 | ```bzl 22 | strip_prefix = "toolchains_llvm-0.9", 23 | shasum = "b2d168315dd0785f170b2b306b86e577c36e812b8f8b05568f9403141f2c24dd", 24 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.9.tar.gz", 25 | ``` 26 | 27 | 0.8.2: 28 | 29 | ```bzl 30 | strip_prefix = "toolchains_llvm-0.8.2", 31 | shasum = "3e251524b3e8f3b9ec93848e5267c168424f43b7b554efc983a5291c33d78cde", 32 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.8.2.tar.gz", 33 | ``` 34 | 35 | 0.8.1: 36 | 37 | ```bzl 38 | strip_prefix = "toolchains_llvm-0.8.1", 39 | shasum = "3bb45f480e3eb198f39fc97e91df2c2fc0beaabbea620ba3034ac505786a1813", 40 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.8.1.tar.gz", 41 | ``` 42 | 43 | 0.8: 44 | 45 | ```bzl 46 | strip_prefix = "toolchains_llvm-0.8", 47 | shasum = "f121449dd565d59274b7421a62f3ed1f16ad7ceab4575c5b34f882ba441093bd", 48 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.8.tar.gz", 49 | ``` 50 | 51 | 0.7.2: 52 | 53 | ```bzl 54 | strip_prefix = "toolchains_llvm-0.7.2", 55 | shasum = "ea7d247dd4a0058c008a6e8fa0855a69d57b0cb500271c7b48c1a28512608ecd", 56 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.7.2.tar.gz", 57 | ``` 58 | 59 | 0.7.1: 60 | 61 | ```bzl 62 | strip_prefix = "toolchains_llvm-0.7.1", 63 | shasum = "5613b430a6b7f6d0eb03011976df53abe7f4cc6c3ec43be066b679c4ad81e3bf", 64 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.7.1.tar.gz", 65 | ``` 66 | 67 | 0.7: 68 | 69 | ```bzl 70 | strip_prefix = "toolchains_llvm-0.7", 71 | shasum = "bb07651178c6fbdc0981799b96a09ea5b4f01d98a98ca64c679db1601a92a66f", 72 | url = "https://github.com/bazel-contrib/toolchains_llvm/archive/refs/tags/0.7.tar.gz", 73 | ``` 74 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | workspace( 16 | name = "toolchains_llvm", 17 | ) 18 | -------------------------------------------------------------------------------- /platforms/BUILD.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | package(default_visibility = ["//visibility:public"]) 16 | 17 | platform( 18 | name = "linux-x86_64", 19 | constraint_values = [ 20 | "@platforms//os:linux", 21 | "@platforms//cpu:x86_64", 22 | ], 23 | ) 24 | 25 | platform( 26 | name = "none-x86_64", 27 | constraint_values = [ 28 | "@platforms//os:none", 29 | "@platforms//cpu:x86_64", 30 | ], 31 | ) 32 | 33 | platform( 34 | name = "linux-aarch64", 35 | constraint_values = [ 36 | "@platforms//os:linux", 37 | "@platforms//cpu:aarch64", 38 | ], 39 | ) 40 | 41 | platform( 42 | name = "linux-armv7", 43 | constraint_values = [ 44 | "@platforms//os:linux", 45 | "@platforms//cpu:armv7", 46 | ], 47 | ) 48 | 49 | platform( 50 | name = "darwin-x86_64", 51 | constraint_values = [ 52 | "@platforms//os:osx", 53 | "@platforms//cpu:x86_64", 54 | ], 55 | ) 56 | 57 | platform( 58 | name = "darwin-aarch64", 59 | constraint_values = [ 60 | "@platforms//os:osx", 61 | "@platforms//cpu:aarch64", 62 | ], 63 | ) 64 | 65 | platform( 66 | name = "wasm32", 67 | constraint_values = [ 68 | "@platforms//os:none", 69 | "@platforms//cpu:wasm32", 70 | ], 71 | ) 72 | 73 | platform( 74 | name = "wasm64", 75 | constraint_values = [ 76 | "@platforms//os:none", 77 | "@platforms//cpu:wasm64", 78 | ], 79 | ) 80 | 81 | platform( 82 | name = "wasip1-wasm32", 83 | constraint_values = [ 84 | "@platforms//os:wasi", 85 | "@platforms//cpu:wasm32", 86 | ], 87 | ) 88 | 89 | platform( 90 | name = "wasip1-wasm64", 91 | constraint_values = [ 92 | "@platforms//os:wasi", 93 | "@platforms//cpu:wasm64", 94 | ], 95 | ) 96 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | ":dependencyDashboard", 5 | ":semanticPrefixFixDepsChoreOthers", 6 | "group:monorepos", 7 | "group:recommended", 8 | "replacements:all", 9 | "workarounds:all" 10 | ], 11 | "packageRules": [ 12 | { 13 | "matchFiles": ["MODULE.bazel"], 14 | "enabled": false 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /tests/.bazelrc: -------------------------------------------------------------------------------- 1 | common --incompatible_disallow_empty_glob 2 | common --nolegacy_external_runfiles 3 | build --features=layering_check 4 | -------------------------------------------------------------------------------- /tests/.buildifier.json: -------------------------------------------------------------------------------- 1 | ../.buildifier.json -------------------------------------------------------------------------------- /tests/BUILD.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load("@bazel_skylib//rules:build_test.bzl", "build_test") 16 | load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") 17 | load(":transitions.bzl", "dwp_file", "transition_library_to_platform") 18 | 19 | cc_library( 20 | name = "stdlib", 21 | srcs = ["stdlib.cc"], 22 | hdrs = ["stdlib.h"], 23 | ) 24 | 25 | # We want to emulate the behavior of cc_binary but be able to run the target as 26 | # a test, so we use a cc_test target with linkstatic. 27 | cc_test( 28 | name = "stdlib_test", 29 | srcs = ["stdlib_test.cc"], 30 | linkstatic = True, 31 | deps = [":stdlib"], 32 | ) 33 | 34 | # We want to test a `.stripped` target to make sure `llvm-strip` can be called. 35 | # 36 | # For this we need `cc_binary`; `cc_test` does not create `.stripped` targets. 37 | cc_binary( 38 | name = "stdlib_bin", 39 | srcs = ["stdlib_test.cc"], 40 | deps = [":stdlib"], 41 | ) 42 | 43 | build_test( 44 | name = "stripped_binary_test", 45 | targets = [ 46 | ":stdlib_bin.stripped", 47 | ], 48 | ) 49 | 50 | # We want to test that `llvm-dwp` (used when assembling a `.dwp` file from 51 | # `.dwo` files) can be called. 52 | # 53 | # `--fission=yes` enables this for all compilation modes but we also need to 54 | # enable the `per_object_debug_info` feature manually because 55 | # `unix_cc_toolchain_config.bzl`'s` `cc_toolchain_config` does not (see #109). 56 | # 57 | # Additionally, newer versions of clang (12+) require a non-zero `-g` setting to 58 | # actually produce the `.dwo` files in addition to the `-gsplit-dwarf` flag. The 59 | # feature in `unix_cc_toolchain_config.bzl` should be updated to reflect this 60 | # and pass in an appropriate `-g` flag. 61 | # 62 | # bazelbuild/rules_cc#115 is a patch that does this 63 | # (https://github.com/bazelbuild/rules_cc/pull/115). 64 | # 65 | # bazelbuild/bazel#14028 tracks this 66 | # (https://github.com/bazelbuild/bazel/issues/14038). 67 | # 68 | # #109 in this repo and this comment 69 | # (https://github.com/bazel-contrib/toolchains_llvm/pull/108#issuecomment-928839768) 70 | # have some additional details. 71 | # 72 | # For now, we'll specify `-c dbg` when building `.dwo` and `.dwp` files. 73 | # 74 | # This (setting the fission flag, enabling the `per_object_debug_info` feature, 75 | # and setting the compilation mode to `dbg`) is what `dwp_file` does using a 76 | # transition. 77 | # 78 | # Unfortunately `per_object_debug_info` breaks on macOS which is why this target 79 | # is marked as only being compatible with Linux (see #109). 80 | dwp_file( 81 | name = "stdlib.dwp", 82 | src = ":stdlib_bin", 83 | # NOTE: we should eventually we able to drop this; see #109. 84 | override_compilation_mode = "dbg", 85 | target_compatible_with = [ 86 | "@platforms//os:linux", 87 | ], 88 | ) 89 | 90 | build_test( 91 | name = "dwp_test", 92 | targets = [ 93 | ":stdlib.dwp", 94 | ], 95 | ) 96 | 97 | # Simple test in C that depends on libomp. 98 | cc_test( 99 | name = "omp_test", 100 | srcs = ["omp_test.c"], 101 | copts = ["-fopenmp"], 102 | linkopts = ["-fopenmp"], 103 | deps = ["@llvm_toolchain//:omp"], 104 | ) 105 | 106 | # C++ variant of omp_test; needed to check that including the llvm toolchain 107 | # lib directory in the library search path (for including libomp.dylib) does 108 | # not pick up unintentional static libraries in a way that breaks the binary. 109 | # See note in cc_toolchain_config.bzl where we include -lc++ and -lc++abi for 110 | # macOS. 111 | cc_test( 112 | name = "omp_test_cc", 113 | srcs = ["omp_test.cc"], 114 | copts = ["-fopenmp"], 115 | linkopts = ["-fopenmp"], 116 | deps = ["@llvm_toolchain//:omp"], 117 | ) 118 | 119 | sh_test( 120 | name = "file_dependency_test", 121 | srcs = ["file_dependency_test.sh"], 122 | args = [ 123 | "$(rootpath @llvm_toolchain_llvm//:bin/clang-format)", 124 | "$(rootpaths @llvm_toolchain_llvm//:lib)", 125 | ], 126 | data = [ 127 | "@llvm_toolchain_llvm//:bin/clang-format", 128 | "@llvm_toolchain_llvm//:lib", 129 | ], 130 | ) 131 | 132 | # As a workaround for https://github.com/bazelbuild/rules_foreign_cc/issues/1018. 133 | toolchain( 134 | name = "ninja_mac_arm64_toolchain", 135 | exec_compatible_with = [ 136 | "@platforms//cpu:arm64", 137 | "@platforms//os:macos", 138 | ], 139 | toolchain = "@ninja_mac//:ninja_tool", 140 | toolchain_type = "@rules_foreign_cc//toolchains:ninja_toolchain", 141 | ) 142 | 143 | # Testing extra_target_compatible_with 144 | constraint_setting( 145 | name = "cxx_standard", 146 | default_constraint_value = ":cxx17", 147 | visibility = ["//visibility:public"], 148 | ) 149 | 150 | constraint_value( 151 | name = "cxx20", 152 | constraint_setting = ":cxx_standard", 153 | visibility = ["//visibility:public"], 154 | ) 155 | 156 | constraint_value( 157 | name = "cxx17", 158 | constraint_setting = ":cxx_standard", 159 | visibility = ["//visibility:public"], 160 | ) 161 | 162 | platform( 163 | name = "cxx20_platform", 164 | constraint_values = [ 165 | ":cxx20", 166 | ], 167 | parents = ["@platforms//host"], 168 | visibility = ["//visibility:public"], 169 | ) 170 | 171 | cc_library( 172 | name = "test_cxx_standard_lib", 173 | srcs = ["test_cxx_standard.cc"], 174 | ) 175 | 176 | cc_test( 177 | name = "test_cxx_standard_is_17", 178 | size = "small", 179 | srcs = ["test_cxx_standard_main.cc"], 180 | args = ["201703"], 181 | deps = [":test_cxx_standard_lib"], 182 | ) 183 | 184 | transition_library_to_platform( 185 | name = "test_cxx_standard_lib_transitioned", 186 | lib = ":test_cxx_standard_lib", 187 | platform = ":cxx20_platform", 188 | ) 189 | 190 | cc_test( 191 | name = "test_cxx_standard_is_20", 192 | size = "small", 193 | srcs = ["test_cxx_standard_main.cc"], 194 | args = ["202002"], 195 | 196 | # Since some platforms require special toolchains (e.g. llvm 13.0.0) this 197 | # target won't build on those platforms unless we create a new toolchain per 198 | # platform with c++20. So instead just only run this test on platforms that 199 | # can use the default toolchain 200 | tags = ["manual"], 201 | deps = [":test_cxx_standard_lib_transitioned"], 202 | ) 203 | -------------------------------------------------------------------------------- /tests/MODULE.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2023 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | module(name = "toolchains_llvm_tests") 16 | 17 | bazel_dep(name = "toolchains_llvm", version = "0.0.0") 18 | local_path_override( 19 | module_name = "toolchains_llvm", 20 | path = "..", 21 | ) 22 | 23 | bazel_dep(name = "bazel_skylib", version = "1.7.1") 24 | bazel_dep(name = "platforms", version = "0.0.11") 25 | bazel_dep(name = "rules_cc", version = "0.0.9") 26 | bazel_dep(name = "rules_go", version = "0.50.1", repo_name = "io_bazel_rules_go") 27 | bazel_dep(name = "rules_rust", version = "0.54.1") 28 | bazel_dep(name = "rules_foreign_cc", version = "0.13.0") 29 | bazel_dep(name = "abseil-cpp", version = "20240722.0", repo_name = "com_google_absl") 30 | 31 | # TODO: Remove when protobuf is released with a version of rules_python that supports 8.x 32 | bazel_dep(name = "rules_python", version = "1.1.0") 33 | 34 | # As a workaround for https://github.com/bazelbuild/rules_foreign_cc/issues/1018. 35 | rules_foreign_cc_tools = use_extension("@rules_foreign_cc//foreign_cc:extensions.bzl", "tools") 36 | use_repo(rules_foreign_cc_tools, ninja_mac = "ninja_1.12.1_mac") 37 | 38 | register_toolchains( 39 | "//:ninja_mac_arm64_toolchain", 40 | ) 41 | 42 | go_sdk = use_extension("@io_bazel_rules_go//go:extensions.bzl", "go_sdk") 43 | go_sdk.download( 44 | name = "go_sdk", 45 | version = "1.21.0", 46 | ) 47 | use_repo(go_sdk, "go_toolchains") 48 | 49 | register_toolchains("@go_toolchains//:all") 50 | 51 | rust = use_extension("@rules_rust//rust:extensions.bzl", "rust") 52 | rust.toolchain(edition = "2023") 53 | use_repo( 54 | rust, 55 | "rust_toolchains", 56 | ) 57 | 58 | register_toolchains("@rust_toolchains//:all") 59 | 60 | llvm = use_extension("@toolchains_llvm//toolchain/extensions:llvm.bzl", "llvm") 61 | 62 | # When updating this version, also update the versions associated with 63 | # llvm_toolchain below, sys_paths_test in the workflows file, and xcompile_test 64 | # through the `llvm_toolchain_with_sysroot` toolchain. 65 | LLVM_VERSIONS = { 66 | "": "16.0.0", 67 | "darwin-aarch64": "16.0.5", 68 | "darwin-x86_64": "15.0.7", 69 | } 70 | 71 | llvm.toolchain( 72 | name = "llvm_toolchain", 73 | cxx_standard = {"": "c++17"}, 74 | llvm_versions = LLVM_VERSIONS, 75 | ) 76 | llvm.extra_target_compatible_with( 77 | name = "llvm_toolchain", 78 | constraints = ["@//:cxx17"], 79 | ) 80 | use_repo(llvm, "llvm_toolchain", "llvm_toolchain_llvm") 81 | 82 | register_toolchains("@llvm_toolchain//:all") 83 | 84 | llvm.toolchain( 85 | name = "llvm_toolchain_cxx20", 86 | cxx_standard = {"": "c++20"}, 87 | llvm_versions = LLVM_VERSIONS, 88 | ) 89 | llvm.extra_target_compatible_with( 90 | name = "llvm_toolchain_cxx20", 91 | constraints = ["//:cxx20"], 92 | ) 93 | use_repo(llvm, "llvm_toolchain_cxx20") 94 | 95 | register_toolchains("@llvm_toolchain_cxx20//:all") 96 | 97 | # Example toolchain with user provided URLs. 98 | # TODO(siddharthab): Add test. 99 | llvm.toolchain( 100 | name = "llvm_toolchain_with_urls", 101 | llvm_versions = { 102 | "": "15.0.6", 103 | "darwin-aarch64": "15.0.7", 104 | "darwin-x86_64": "15.0.7", 105 | }, 106 | sha256 = { 107 | "": "38bc7f5563642e73e69ac5626724e206d6d539fbef653541b34cae0ba9c3f036", 108 | "darwin-aarch64": "867c6afd41158c132ef05a8f1ddaecf476a26b91c85def8e124414f9a9ba188d", 109 | "darwin-x86_64": "d16b6d536364c5bec6583d12dd7e6cf841b9f508c4430d9ee886726bd9983f1c", 110 | }, 111 | strip_prefix = { 112 | "": "clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04", 113 | "darwin-aarch64": "clang+llvm-15.0.7-arm64-apple-darwin22.0", 114 | "darwin-x86_64": "clang+llvm-15.0.7-x86_64-apple-darwin21.0", 115 | }, 116 | urls = { 117 | "": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz"], 118 | "darwin-aarch64": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/clang+llvm-15.0.7-arm64-apple-darwin22.0.tar.xz"], 119 | "darwin-x86_64": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz"], 120 | }, 121 | ) 122 | use_repo(llvm, "llvm_toolchain_with_urls") 123 | 124 | # This is the last known LLVM version with zlib support in ld.lld. Without zlib 125 | # support, if the installed gcc toolchain has compressed sections in its object 126 | # files, then ld.lld won't be able to process them. Example is archlinux docker 127 | # image base-devel as of the time of this writing (23 May 2022). 128 | llvm.toolchain( 129 | name = "llvm_toolchain_13_0_0", 130 | llvm_version = "13.0.0", 131 | ) 132 | use_repo(llvm, "llvm_toolchain_13_0_0") 133 | 134 | # Toolchain example with absolute paths; tested in GitHub CI. 135 | llvm.toolchain( 136 | name = "llvm_toolchain_with_absolute_paths", 137 | absolute_paths = True, 138 | llvm_versions = LLVM_VERSIONS, 139 | ) 140 | 141 | # We can share the downloaded LLVM distribution with the first configuration. 142 | llvm.toolchain_root( 143 | name = "llvm_toolchain_with_absolute_paths", 144 | label = "@llvm_toolchain_llvm//:BUILD", 145 | ) 146 | use_repo(llvm, "llvm_toolchain_with_absolute_paths") 147 | 148 | # Toolchain example with system LLVM; tested in GitHub CI. 149 | llvm.toolchain( 150 | name = "llvm_toolchain_with_system_llvm", 151 | llvm_versions = LLVM_VERSIONS, 152 | ) 153 | 154 | # For this toolchain to work, the LLVM distribution archive would need to be unpacked here. 155 | llvm.toolchain_root( 156 | name = "llvm_toolchain_with_system_llvm", 157 | path = "/opt/llvm-16", 158 | ) 159 | use_repo(llvm, "llvm_toolchain_with_system_llvm") 160 | 161 | # Toolchain example with a sysroot. 162 | llvm.toolchain( 163 | name = "llvm_toolchain_with_sysroot", 164 | llvm_versions = LLVM_VERSIONS, 165 | ) 166 | 167 | # We can share the downloaded LLVM distribution with the first configuration. 168 | llvm.toolchain_root( 169 | name = "llvm_toolchain_with_sysroot", 170 | label = "@llvm_toolchain_llvm//:BUILD", 171 | ) 172 | llvm.sysroot( 173 | name = "llvm_toolchain_with_sysroot", 174 | label = "@org_chromium_sysroot_linux_x64//:sysroot", 175 | targets = ["linux-x86_64"], 176 | ) 177 | use_repo(llvm, "llvm_toolchain_with_sysroot") 178 | llvm.toolchain( 179 | name = "llvm_toolchain_linux_exec", 180 | exec_arch = "amd64", 181 | # Option 2: 182 | # distribution = "clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz", 183 | exec_os = "linux", 184 | llvm_version = "17.0.6", 185 | # Option 1: 186 | sha256 = {"": "884ee67d647d77e58740c1e645649e29ae9e8a6fe87c1376be0f3a30f3cc9ab3"}, 187 | strip_prefix = {"": "clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04"}, 188 | urls = {"": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz"]}, 189 | ) 190 | use_repo(llvm, "llvm_toolchain_linux_exec") 191 | 192 | # Toolchain example for WebAssembly wasm* targets. 193 | llvm.toolchain( 194 | name = "llvm_toolchain_wasm", 195 | libclang_rt = { 196 | "@libclang_rt_wasm32//:libclang_rt.builtins-wasm32.a": "wasm32-unknown-unknown/libclang_rt.builtins.a", 197 | }, 198 | # WebAssembly tests use a separate (newer) version of LLVM to exercise 199 | # support for experimental features such as wasm64. 200 | llvm_versions = { 201 | # The most recent LLVM as of 2024-10-17 202 | "": "19.1.0", 203 | }, 204 | stdlib = { 205 | "wasm32": "libc", 206 | "wasm64": "none", 207 | }, 208 | ) 209 | llvm.sysroot( 210 | name = "llvm_toolchain_wasm", 211 | label = "@wasi_sdk_sysroots//wasm32-wasip2", 212 | targets = ["wasm32"], 213 | ) 214 | llvm.sysroot( 215 | name = "llvm_toolchain_wasm", 216 | label = "@wasi_sdk_sysroots//empty", 217 | targets = ["wasm64"], 218 | ) 219 | use_repo(llvm, "llvm_toolchain_wasm") 220 | 221 | register_toolchains("@llvm_toolchain_wasm//:all") 222 | 223 | # Toolchain example for WebAssembly wasm*-wasi* targets. 224 | llvm.toolchain( 225 | name = "llvm_toolchain_wasm_wasi", 226 | libclang_rt = { 227 | "@libclang_rt_wasm32//:libclang_rt.builtins-wasm32.a": "wasm32-unknown-wasip1/libclang_rt.builtins.a", 228 | }, 229 | # WebAssembly tests use a separate (newer) version of LLVM to exercise 230 | # support for experimental features such as wasm64. 231 | llvm_versions = { 232 | # The most recent LLVM as of 2024-10-17 233 | "": "19.1.0", 234 | }, 235 | stdlib = { 236 | "wasip1-wasm32": "libc", 237 | }, 238 | ) 239 | llvm.sysroot( 240 | name = "llvm_toolchain_wasm_wasi", 241 | label = "@wasi_sdk_sysroots//wasm32-wasip1", 242 | targets = ["wasip1-wasm32"], 243 | ) 244 | use_repo(llvm, "llvm_toolchain_wasm_wasi") 245 | 246 | register_toolchains("@llvm_toolchain_wasm_wasi//:all") 247 | 248 | wasi_sdk_sysroots = use_repo_rule("//wasm:wasi_sdk.bzl", "wasi_sdk_sysroots") 249 | 250 | wasi_sdk_sysroots(name = "wasi_sdk_sysroots") 251 | 252 | libclang_rt_wasm32 = use_repo_rule("//wasm:wasi_sdk.bzl", "libclang_rt_wasm32") 253 | 254 | libclang_rt_wasm32(name = "libclang_rt_wasm32") 255 | 256 | http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 257 | 258 | # This sysroot is used by github.com/vsco/bazel-toolchains. 259 | http_archive( 260 | name = "org_chromium_sysroot_linux_x64", 261 | build_file_content = """ 262 | filegroup( 263 | name = "sysroot", 264 | srcs = glob(["*/**"]), 265 | visibility = ["//visibility:public"], 266 | ) 267 | """, 268 | sha256 = "84656a6df544ecef62169cfe3ab6e41bb4346a62d3ba2a045dc5a0a2ecea94a3", 269 | urls = ["https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/2202c161310ffde63729f29d27fe7bb24a0bc540/debian_stretch_amd64_sysroot.tar.xz"], 270 | ) 271 | -------------------------------------------------------------------------------- /tests/WORKSPACE: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | workspace(name = "toolchains_llvm_tests") 16 | 17 | local_repository( 18 | name = "toolchains_llvm", 19 | path = "..", 20 | ) 21 | 22 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 23 | load("@toolchains_llvm//toolchain:deps.bzl", "bazel_toolchain_dependencies") 24 | 25 | bazel_toolchain_dependencies() 26 | 27 | load("@toolchains_llvm//toolchain:rules.bzl", "llvm_toolchain") 28 | 29 | # When updating this version, also update the versions associated with 30 | # llvm_toolchain below, sys_paths_test in the workflows file, and xcompile_test 31 | # through the `llvm_toolchain_with_sysroot` toolchain. 32 | LLVM_VERSIONS = { 33 | "": "16.0.0", 34 | "darwin-aarch64": "16.0.5", 35 | "darwin-x86_64": "15.0.7", 36 | } 37 | 38 | llvm_toolchain( 39 | name = "llvm_toolchain", 40 | cxx_standard = {"": "c++17"}, 41 | extra_target_compatible_with = { 42 | "": ["@//:cxx17"], 43 | }, 44 | llvm_versions = LLVM_VERSIONS, 45 | ) 46 | 47 | llvm_toolchain( 48 | name = "llvm_toolchain_cxx20", 49 | cxx_standard = {"": "c++20"}, 50 | extra_target_compatible_with = { 51 | "": ["@//:cxx20"], 52 | }, 53 | llvm_versions = LLVM_VERSIONS, 54 | ) 55 | 56 | # Example toolchain with user provided URLs. 57 | # TODO(siddharthab): Add test. 58 | llvm_toolchain( 59 | name = "llvm_toolchain_with_urls", 60 | llvm_versions = LLVM_VERSIONS, 61 | sha256 = { 62 | "": "38bc7f5563642e73e69ac5626724e206d6d539fbef653541b34cae0ba9c3f036", 63 | "darwin-aarch64": "867c6afd41158c132ef05a8f1ddaecf476a26b91c85def8e124414f9a9ba188d", 64 | "darwin-x86_64": "d16b6d536364c5bec6583d12dd7e6cf841b9f508c4430d9ee886726bd9983f1c", 65 | }, 66 | strip_prefix = { 67 | "": "clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04", 68 | "darwin-aarch64": "clang+llvm-15.0.7-arm64-apple-darwin22.0", 69 | "darwin-x86_64": "clang+llvm-15.0.7-x86_64-apple-darwin21.0", 70 | }, 71 | urls = { 72 | "": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz"], 73 | "darwin-aarch64": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/clang+llvm-15.0.7-arm64-apple-darwin22.0.tar.xz"], 74 | "darwin-x86_64": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.7/clang+llvm-15.0.7-x86_64-apple-darwin21.0.tar.xz"], 75 | }, 76 | ) 77 | 78 | # This is the last known LLVM version with zlib support in ld.lld. Without zlib 79 | # support, if the installed gcc toolchain has compressed sections in its object 80 | # files, then ld.lld won't be able to process them. Example is archlinux docker 81 | # image base-devel as of the time of this writing (23 May 2022). 82 | llvm_toolchain( 83 | name = "llvm_toolchain_13_0_0", 84 | llvm_version = "13.0.0", 85 | ) 86 | 87 | load("@llvm_toolchain//:toolchains.bzl", "llvm_register_toolchains") 88 | 89 | llvm_register_toolchains() 90 | 91 | load("@llvm_toolchain_cxx20//:toolchains.bzl", llvm_register_toolchains_cxx20 = "llvm_register_toolchains") 92 | 93 | llvm_register_toolchains_cxx20() 94 | 95 | ## Toolchain example with absolute paths; tested in GitHub CI. 96 | llvm_toolchain( 97 | name = "llvm_toolchain_with_absolute_paths", 98 | absolute_paths = True, 99 | llvm_versions = LLVM_VERSIONS, 100 | # We can share the downloaded LLVM distribution with the first configuration. 101 | toolchain_roots = { 102 | "": "@llvm_toolchain_llvm//", 103 | }, 104 | ) 105 | 106 | ## Toolchain example with system LLVM; tested in GitHub CI. 107 | llvm_toolchain( 108 | name = "llvm_toolchain_with_system_llvm", 109 | llvm_versions = LLVM_VERSIONS, 110 | # For this toolchain to work, the LLVM distribution archive would need to be unpacked here. 111 | toolchain_roots = {"": "/opt/llvm-16"}, 112 | ) 113 | 114 | ## Toolchain example with a sysroot. 115 | 116 | # This sysroot is used by github.com/vsco/bazel-toolchains. 117 | http_archive( 118 | name = "org_chromium_sysroot_linux_x64", 119 | build_file_content = """ 120 | filegroup( 121 | name = "sysroot", 122 | srcs = glob(["*/**"]), 123 | visibility = ["//visibility:public"], 124 | ) 125 | """, 126 | sha256 = "84656a6df544ecef62169cfe3ab6e41bb4346a62d3ba2a045dc5a0a2ecea94a3", 127 | urls = ["https://commondatastorage.googleapis.com/chrome-linux-sysroot/toolchain/2202c161310ffde63729f29d27fe7bb24a0bc540/debian_stretch_amd64_sysroot.tar.xz"], 128 | ) 129 | 130 | llvm_toolchain( 131 | name = "llvm_toolchain_with_sysroot", 132 | llvm_versions = LLVM_VERSIONS, 133 | sysroot = { 134 | "linux-x86_64": "@org_chromium_sysroot_linux_x64//:sysroot", 135 | }, 136 | # We can share the downloaded LLVM distribution with the first configuration. 137 | toolchain_roots = { 138 | "": "@llvm_toolchain_llvm//", 139 | }, 140 | ) 141 | 142 | load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace") 143 | 144 | bazel_skylib_workspace() 145 | 146 | llvm_toolchain( 147 | name = "llvm_toolchain_linux_exec", 148 | exec_arch = "amd64", 149 | # Option 2: 150 | # distribution = "clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz", 151 | exec_os = "linux", 152 | llvm_version = "17.0.6", 153 | # Option 1: 154 | sha256 = {"": "884ee67d647d77e58740c1e645649e29ae9e8a6fe87c1376be0f3a30f3cc9ab3"}, 155 | strip_prefix = {"": "clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04"}, 156 | urls = {"": ["https://github.com/llvm/llvm-project/releases/download/llvmorg-17.0.6/clang+llvm-17.0.6-x86_64-linux-gnu-ubuntu-22.04.tar.xz"]}, 157 | ) 158 | 159 | # Toolchain example for WebAssembly wasm* targets. 160 | llvm_toolchain( 161 | name = "llvm_toolchain_wasm", 162 | libclang_rt = { 163 | "@libclang_rt_wasm32//:libclang_rt.builtins-wasm32.a": "wasm32-unknown-unknown/libclang_rt.builtins.a", 164 | }, 165 | # WebAssembly tests use a separate (newer) version of LLVM to exercise 166 | # support for experimental features such as wasm64. 167 | llvm_versions = { 168 | # The most recent LLVM as of 2024-10-17 169 | "": "19.1.0", 170 | }, 171 | stdlib = { 172 | "wasm32": "libc", 173 | "wasm64": "none", 174 | }, 175 | sysroot = { 176 | "wasm32": "@wasi_sdk_sysroots//wasm32-wasip2", 177 | "wasm64": "@wasi_sdk_sysroots//empty", 178 | }, 179 | ) 180 | 181 | load( 182 | "@llvm_toolchain_wasm//:toolchains.bzl", 183 | llvm_register_toolchains_wasm = "llvm_register_toolchains", 184 | ) 185 | 186 | llvm_register_toolchains_wasm() 187 | 188 | # Toolchain example for WebAssembly wasm*-wasi* targets. 189 | llvm_toolchain( 190 | name = "llvm_toolchain_wasm_wasi", 191 | libclang_rt = { 192 | "@libclang_rt_wasm32//:libclang_rt.builtins-wasm32.a": "wasm32-unknown-wasip1/libclang_rt.builtins.a", 193 | }, 194 | # WebAssembly tests use a separate (newer) version of LLVM to exercise 195 | # support for experimental features such as wasm64. 196 | llvm_versions = { 197 | # The most recent LLVM as of 2024-10-17 198 | "": "19.1.0", 199 | }, 200 | stdlib = { 201 | "wasip1-wasm32": "libc", 202 | }, 203 | sysroot = { 204 | "wasip1-wasm32": "@wasi_sdk_sysroots//wasm32-wasip1", 205 | }, 206 | ) 207 | 208 | load( 209 | "@llvm_toolchain_wasm_wasi//:toolchains.bzl", 210 | llvm_register_toolchains_wasm_wasi = "llvm_register_toolchains", 211 | ) 212 | 213 | llvm_register_toolchains_wasm_wasi() 214 | 215 | load("//wasm:wasi_sdk.bzl", "libclang_rt_wasm32", "wasi_sdk_sysroots") 216 | 217 | libclang_rt_wasm32(name = "libclang_rt_wasm32") 218 | 219 | wasi_sdk_sysroots(name = "wasi_sdk_sysroots") 220 | 221 | ## Test dependencies. 222 | 223 | # Well known repos; present here only for testing. 224 | 225 | http_archive( 226 | name = "com_google_absl", 227 | sha256 = "f50e5ac311a81382da7fa75b97310e4b9006474f9560ac46f54a9967f07d4ae3", 228 | strip_prefix = "abseil-cpp-20240722.0", 229 | urls = ["https://github.com/abseil/abseil-cpp/releases/download/20240722.0/abseil-cpp-20240722.0.tar.gz"], 230 | ) 231 | 232 | # As a test dep of com_google_absl. 233 | http_archive( 234 | name = "com_google_googletest", 235 | sha256 = "78c676fc63881529bf97bf9d45948d905a66833fbfa5318ea2cd7478cb98f399", 236 | strip_prefix = "googletest-1.16.0", 237 | urls = ["https://github.com/google/googletest/archive/v1.16.0.tar.gz"], 238 | ) 239 | 240 | http_archive( 241 | name = "openssl", 242 | build_file = "//openssl:openssl.bazel", 243 | sha256 = "f6fb3079ad15076154eda9413fed42877d668e7069d9b87396d0804fdb3f4c90", 244 | strip_prefix = "openssl-1.1.1c", 245 | urls = ["https://www.openssl.org/source/openssl-1.1.1c.tar.gz"], 246 | ) 247 | 248 | http_archive( 249 | name = "io_bazel_rules_go", 250 | sha256 = "f4a9314518ca6acfa16cc4ab43b0b8ce1e4ea64b81c38d8a3772883f153346b8", 251 | urls = [ 252 | "https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip", 253 | "https://github.com/bazelbuild/rules_go/releases/download/v0.50.1/rules_go-v0.50.1.zip", 254 | ], 255 | ) 256 | 257 | load("@io_bazel_rules_go//go:deps.bzl", "go_download_sdk", "go_rules_dependencies") 258 | 259 | go_rules_dependencies() 260 | 261 | go_download_sdk( 262 | name = "go_sdk", 263 | version = "1.21.0", 264 | ) 265 | 266 | # For testing rules_rust. 267 | 268 | http_archive( 269 | name = "rules_rust", 270 | sha256 = "af4f56caae50a99a68bfce39b141b509dd68548c8204b98ab7a1cafc94d5bb02", 271 | urls = ["https://github.com/bazelbuild/rules_rust/releases/download/0.54.1/rules_rust-v0.54.1.tar.gz"], 272 | ) 273 | 274 | load("@rules_rust//rust:repositories.bzl", "rules_rust_dependencies", "rust_register_toolchains") 275 | 276 | rules_rust_dependencies() 277 | 278 | rust_register_toolchains() 279 | 280 | http_archive( 281 | name = "rules_python", 282 | sha256 = "9c6e26911a79fbf510a8f06d8eedb40f412023cf7fa6d1461def27116bff022c", 283 | strip_prefix = "rules_python-1.1.0", 284 | url = "https://github.com/bazelbuild/rules_python/releases/download/1.1.0/rules_python-1.1.0.tar.gz", 285 | ) 286 | 287 | load("@rules_python//python:repositories.bzl", "py_repositories") 288 | 289 | py_repositories() 290 | 291 | # For testing rules_foreign_cc. 292 | # See https://bazelbuild.github.io/rules_foreign_cc/0.6.0/cmake.html 293 | 294 | http_archive( 295 | name = "rules_foreign_cc", 296 | sha256 = "8e5605dc2d16a4229cb8fbe398514b10528553ed4f5f7737b663fdd92f48e1c2", 297 | strip_prefix = "rules_foreign_cc-0.13.0", 298 | url = "https://github.com/bazelbuild/rules_foreign_cc/archive/0.13.0.tar.gz", 299 | ) 300 | 301 | http_archive( 302 | name = "com_google_protobuf", 303 | sha256 = "e9b9ac1910b1041065839850603caf36e29d3d3d230ddf52bd13778dd31b9046", 304 | strip_prefix = "protobuf-29.3", 305 | urls = ["https://github.com/protocolbuffers/protobuf/releases/download/v29.3/protobuf-29.3.zip"], 306 | ) 307 | 308 | load("@com_google_protobuf//:protobuf_deps.bzl", "protobuf_deps") 309 | 310 | protobuf_deps() 311 | 312 | http_archive( 313 | name = "rules_java", 314 | sha256 = "f79a6e10cdd213ceded45884914bb8c68f0c8d41144e74ec89ebb74984c409ac", 315 | urls = ["https://github.com/bazelbuild/rules_java/releases/download/8.8.0/rules_java-8.8.0.tar.gz"], 316 | ) 317 | 318 | load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies") 319 | 320 | rules_java_dependencies() 321 | 322 | load("@rules_foreign_cc//foreign_cc:repositories.bzl", "rules_foreign_cc_dependencies") 323 | 324 | rules_foreign_cc_dependencies() 325 | 326 | load("@bazel_features//:deps.bzl", "bazel_features_deps") 327 | 328 | # Dep of `rules_foreign_cc`. 329 | bazel_features_deps() 330 | 331 | _ALL_CONTENT = """\ 332 | filegroup( 333 | name = "all_srcs", 334 | srcs = glob(["**"]), 335 | visibility = ["//visibility:public"], 336 | ) 337 | """ 338 | 339 | http_archive( 340 | name = "pcre", 341 | build_file_content = _ALL_CONTENT, 342 | sha256 = "0b8e7465dc5e98c757cc3650a20a7843ee4c3edf50aaf60bb33fd879690d2c73", 343 | strip_prefix = "pcre-8.43", 344 | urls = [ 345 | "https://mirror.bazel.build/ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz", 346 | "https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz", 347 | ], 348 | ) 349 | 350 | http_archive( 351 | name = "platforms", 352 | sha256 = "29742e87275809b5e598dc2f04d86960cc7a55b3067d97221c9abbc9926bff0f", 353 | urls = [ 354 | "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz", 355 | "https://github.com/bazelbuild/platforms/releases/download/0.0.11/platforms-0.0.11.tar.gz", 356 | ], 357 | ) 358 | 359 | load("@platforms//host:extension.bzl", "host_platform_repo") 360 | 361 | host_platform_repo(name = "host_platform") 362 | -------------------------------------------------------------------------------- /tests/WORKSPACE.bzlmod: -------------------------------------------------------------------------------- 1 | workspace(name = "toolchains_llvm_tests") 2 | 3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 4 | 5 | # Well known repos; present here only for testing. 6 | 7 | http_archive( 8 | name = "openssl", 9 | build_file = "//openssl:openssl.bazel", 10 | sha256 = "f6fb3079ad15076154eda9413fed42877d668e7069d9b87396d0804fdb3f4c90", 11 | strip_prefix = "openssl-1.1.1c", 12 | urls = ["https://www.openssl.org/source/openssl-1.1.1c.tar.gz"], 13 | ) 14 | 15 | _ALL_CONTENT = """\ 16 | filegroup( 17 | name = "all_srcs", 18 | srcs = glob(["**"]), 19 | visibility = ["//visibility:public"], 20 | ) 21 | """ 22 | 23 | http_archive( 24 | name = "pcre", 25 | build_file_content = _ALL_CONTENT, 26 | sha256 = "0b8e7465dc5e98c757cc3650a20a7843ee4c3edf50aaf60bb33fd879690d2c73", 27 | strip_prefix = "pcre-8.43", 28 | urls = [ 29 | "https://mirror.bazel.build/ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz", 30 | "https://ftp.pcre.org/pub/pcre/pcre-8.43.tar.gz", 31 | ], 32 | ) 33 | -------------------------------------------------------------------------------- /tests/file_dependency_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2022 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | fail() { 17 | echo >&2 "$@" 18 | exit 1 19 | } 20 | 21 | clang_format_path=$1 22 | libcpp_path=$2 23 | 24 | [[ -e ${clang_format_path} ]] || fail "bin/clang-format not found at ${clang_format_path}" 25 | 26 | [[ -e ${libcpp_path} ]] || 27 | compgen -G "${libcpp_path}" >/dev/null || 28 | fail "libc++.a not found at ${libcpp_path}" 29 | 30 | echo "SUCCESS!" 31 | -------------------------------------------------------------------------------- /tests/foreign/BUILD.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load("@rules_foreign_cc//foreign_cc:defs.bzl", "cmake") 16 | 17 | # See https://bazelbuild.github.io/rules_foreign_cc/0.6.0/cmake.html 18 | cmake( 19 | name = "pcre", 20 | cache_entries = { 21 | "CMAKE_C_FLAGS": "-fPIC", 22 | }, 23 | lib_source = "@pcre//:all_srcs", 24 | out_static_libs = ["libpcre.a"], 25 | ) 26 | 27 | # A smaller test would be something like 28 | # https://github.com/bazelbuild/rules_foreign_cc/blob/0.6.0/examples/cmake_hello_world_lib/binary/BUILD.bazel 29 | -------------------------------------------------------------------------------- /tests/omp_test.c: -------------------------------------------------------------------------------- 1 | // Copyright 2023 The Bazel Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0(the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http: // www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | int main(int argc, char *argv[]) { 20 | // Start of parallel region 21 | #pragma omp parallel 22 | { printf("Hello World... from thread = %d\n", omp_get_thread_num()); } 23 | // End of parallel region 24 | } 25 | -------------------------------------------------------------------------------- /tests/omp_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2022 The Bazel Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0(the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http: // www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | int main() { 21 | std::cout << "Begin parallel section" << std::endl; 22 | #pragma omp parallel 23 | { std::printf("Hello World... from thread = %d\n", omp_get_thread_num()); } 24 | std::cout << "End parallel section" << std::endl; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /tests/openssl/BUILD.bazel: -------------------------------------------------------------------------------- 1 | exports_files( 2 | srcs = glob(["**/*.h"]), 3 | visibility = ["//visibility:public"], 4 | ) 5 | -------------------------------------------------------------------------------- /tests/openssl/crypto/include/internal/bn_conf.h: -------------------------------------------------------------------------------- 1 | /* WARNING: do not edit! */ 2 | /* Generated by Makefile from crypto/include/internal/bn_conf.h.in */ 3 | /* 4 | * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. 5 | * 6 | * Licensed under the OpenSSL license (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * https://www.openssl.org/source/license.html 10 | */ 11 | 12 | #ifndef HEADER_BN_CONF_H 13 | #define HEADER_BN_CONF_H 14 | 15 | /* 16 | * The contents of this file are not used in the UEFI build, as 17 | * both 32-bit and 64-bit builds are supported from a single run 18 | * of the Configure script. 19 | */ 20 | 21 | /* Should we define BN_DIV2W here? */ 22 | 23 | /* Only one for the following should be defined */ 24 | #define SIXTY_FOUR_BIT_LONG 25 | #undef SIXTY_FOUR_BIT 26 | #undef THIRTY_TWO_BIT 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /tests/openssl/crypto/include/internal/dso_conf.h: -------------------------------------------------------------------------------- 1 | /* WARNING: do not edit! */ 2 | /* Generated by Makefile from crypto/include/internal/dso_conf.h.in */ 3 | /* 4 | * Copyright 2016-2019 The OpenSSL Project Authors. All Rights Reserved. 5 | * 6 | * Licensed under the OpenSSL license (the "License"). You may not use 7 | * this file except in compliance with the License. You can obtain a copy 8 | * in the file LICENSE in the source distribution or at 9 | * https://www.openssl.org/source/license.html 10 | */ 11 | 12 | #ifndef HEADER_DSO_CONF_H 13 | #define HEADER_DSO_CONF_H 14 | #define DSO_DLFCN 15 | #define HAVE_DLFCN_H 16 | #define DSO_EXTENSION ".dylib" 17 | #endif 18 | -------------------------------------------------------------------------------- /tests/openssl/include/openssl/opensslconf.h: -------------------------------------------------------------------------------- 1 | /* 2 | * WARNING: do not edit! 3 | * Generated by Makefile from include/openssl/opensslconf.h.in 4 | * 5 | * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved. 6 | * 7 | * Licensed under the OpenSSL license (the "License"). You may not use 8 | * this file except in compliance with the License. You can obtain a copy 9 | * in the file LICENSE in the source distribution or at 10 | * https://www.openssl.org/source/license.html 11 | */ 12 | 13 | #include 14 | 15 | #ifdef __cplusplus 16 | extern "C" { 17 | #endif 18 | 19 | #ifdef OPENSSL_ALGORITHM_DEFINES 20 | #error OPENSSL_ALGORITHM_DEFINES no longer supported 21 | #endif 22 | 23 | /* 24 | * OpenSSL was configured with the following options: 25 | */ 26 | 27 | #ifndef OPENSSL_NO_MD2 28 | #define OPENSSL_NO_MD2 29 | #endif 30 | #ifndef OPENSSL_NO_RC5 31 | #define OPENSSL_NO_RC5 32 | #endif 33 | #ifndef OPENSSL_THREADS 34 | #define OPENSSL_THREADS 35 | #endif 36 | #ifndef OPENSSL_RAND_SEED_OS 37 | #define OPENSSL_RAND_SEED_OS 38 | #endif 39 | #ifndef OPENSSL_NO_ASAN 40 | #define OPENSSL_NO_ASAN 41 | #endif 42 | #ifndef OPENSSL_NO_CRYPTO_MDEBUG 43 | #define OPENSSL_NO_CRYPTO_MDEBUG 44 | #endif 45 | #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE 46 | #define OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE 47 | #endif 48 | #ifndef OPENSSL_NO_DEVCRYPTOENG 49 | #define OPENSSL_NO_DEVCRYPTOENG 50 | #endif 51 | #ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 52 | #define OPENSSL_NO_EC_NISTP_64_GCC_128 53 | #endif 54 | #ifndef OPENSSL_NO_EGD 55 | #define OPENSSL_NO_EGD 56 | #endif 57 | #ifndef OPENSSL_NO_EXTERNAL_TESTS 58 | #define OPENSSL_NO_EXTERNAL_TESTS 59 | #endif 60 | #ifndef OPENSSL_NO_FUZZ_AFL 61 | #define OPENSSL_NO_FUZZ_AFL 62 | #endif 63 | #ifndef OPENSSL_NO_FUZZ_LIBFUZZER 64 | #define OPENSSL_NO_FUZZ_LIBFUZZER 65 | #endif 66 | #ifndef OPENSSL_NO_HEARTBEATS 67 | #define OPENSSL_NO_HEARTBEATS 68 | #endif 69 | #ifndef OPENSSL_NO_MSAN 70 | #define OPENSSL_NO_MSAN 71 | #endif 72 | #ifndef OPENSSL_NO_SCTP 73 | #define OPENSSL_NO_SCTP 74 | #endif 75 | #ifndef OPENSSL_NO_SSL_TRACE 76 | #define OPENSSL_NO_SSL_TRACE 77 | #endif 78 | #ifndef OPENSSL_NO_SSL3 79 | #define OPENSSL_NO_SSL3 80 | #endif 81 | #ifndef OPENSSL_NO_SSL3_METHOD 82 | #define OPENSSL_NO_SSL3_METHOD 83 | #endif 84 | #ifndef OPENSSL_NO_UBSAN 85 | #define OPENSSL_NO_UBSAN 86 | #endif 87 | #ifndef OPENSSL_NO_UNIT_TEST 88 | #define OPENSSL_NO_UNIT_TEST 89 | #endif 90 | #ifndef OPENSSL_NO_WEAK_SSL_CIPHERS 91 | #define OPENSSL_NO_WEAK_SSL_CIPHERS 92 | #endif 93 | #ifndef OPENSSL_NO_STATIC_ENGINE 94 | #define OPENSSL_NO_STATIC_ENGINE 95 | #endif 96 | 97 | /* 98 | * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers 99 | * don't like that. This will hopefully silence them. 100 | */ 101 | #define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy; 102 | 103 | /* 104 | * Applications should use -DOPENSSL_API_COMPAT= to suppress the 105 | * declarations of functions deprecated in or before . Otherwise, they 106 | * still won't see them if the library has been built to disable deprecated 107 | * functions. 108 | */ 109 | #ifndef DECLARE_DEPRECATED 110 | #define DECLARE_DEPRECATED(f) f; 111 | #ifdef __GNUC__ 112 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0) 113 | #undef DECLARE_DEPRECATED 114 | #define DECLARE_DEPRECATED(f) f __attribute__((deprecated)); 115 | #endif 116 | #endif 117 | #endif 118 | 119 | #ifndef OPENSSL_FILE 120 | #ifdef OPENSSL_NO_FILENAMES 121 | #define OPENSSL_FILE "" 122 | #define OPENSSL_LINE 0 123 | #else 124 | #define OPENSSL_FILE __FILE__ 125 | #define OPENSSL_LINE __LINE__ 126 | #endif 127 | #endif 128 | 129 | #ifndef OPENSSL_MIN_API 130 | #define OPENSSL_MIN_API 0 131 | #endif 132 | 133 | #if !defined(OPENSSL_API_COMPAT) || OPENSSL_API_COMPAT < OPENSSL_MIN_API 134 | #undef OPENSSL_API_COMPAT 135 | #define OPENSSL_API_COMPAT OPENSSL_MIN_API 136 | #endif 137 | 138 | /* 139 | * Do not deprecate things to be deprecated in version 1.2.0 before the 140 | * OpenSSL version number matches. 141 | */ 142 | #if OPENSSL_VERSION_NUMBER < 0x10200000L 143 | #define DEPRECATEDIN_1_2_0(f) f; 144 | #elif OPENSSL_API_COMPAT < 0x10200000L 145 | #define DEPRECATEDIN_1_2_0(f) DECLARE_DEPRECATED(f) 146 | #else 147 | #define DEPRECATEDIN_1_2_0(f) 148 | #endif 149 | 150 | #if OPENSSL_API_COMPAT < 0x10100000L 151 | #define DEPRECATEDIN_1_1_0(f) DECLARE_DEPRECATED(f) 152 | #else 153 | #define DEPRECATEDIN_1_1_0(f) 154 | #endif 155 | 156 | #if OPENSSL_API_COMPAT < 0x10000000L 157 | #define DEPRECATEDIN_1_0_0(f) DECLARE_DEPRECATED(f) 158 | #else 159 | #define DEPRECATEDIN_1_0_0(f) 160 | #endif 161 | 162 | #if OPENSSL_API_COMPAT < 0x00908000L 163 | #define DEPRECATEDIN_0_9_8(f) DECLARE_DEPRECATED(f) 164 | #else 165 | #define DEPRECATEDIN_0_9_8(f) 166 | #endif 167 | 168 | /* Generate 80386 code? */ 169 | #undef I386_ONLY 170 | 171 | #undef OPENSSL_UNISTD 172 | #define OPENSSL_UNISTD 173 | 174 | #undef OPENSSL_EXPORT_VAR_AS_FUNCTION 175 | 176 | /* 177 | * The following are cipher-specific, but are part of the public API. 178 | */ 179 | #if !defined(OPENSSL_SYS_UEFI) 180 | #undef BN_LLONG 181 | /* Only one for the following should be defined */ 182 | #define SIXTY_FOUR_BIT_LONG 183 | #undef SIXTY_FOUR_BIT 184 | #undef THIRTY_TWO_BIT 185 | #endif 186 | 187 | #define RC4_INT unsigned int 188 | 189 | #ifdef __cplusplus 190 | } 191 | #endif 192 | -------------------------------------------------------------------------------- /tests/scripts/archlinux_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | images=( 19 | "archlinux:base-devel" 20 | ) 21 | 22 | # See note next to the definition of this toolchain in the WORKSPACE file. 23 | toolchain="@llvm_toolchain_13_0_0//:cc-toolchain-x86_64-linux" 24 | 25 | git_root=$(git rev-parse --show-toplevel) 26 | readonly git_root 27 | 28 | for image in "${images[@]}"; do 29 | docker pull "${image}" 30 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src:ro" "${image}" -c """ 31 | set -exuo pipefail 32 | 33 | # Run tests 34 | cd /src 35 | tests/scripts/run_tests.sh -t ${toolchain} 36 | """ 37 | done 38 | -------------------------------------------------------------------------------- /tests/scripts/bazel.sh: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # shellcheck shell=bash 16 | 17 | short_uname="$(uname -s)" 18 | readonly short_uname 19 | 20 | os="$(echo "${short_uname}" | tr "[:upper:]" "[:lower:]")" 21 | readonly os 22 | 23 | arch="$(uname -m)" 24 | if [[ ${arch} == "x86_64" ]]; then 25 | arch="amd64" 26 | elif [[ ${arch} == "aarch64" ]] || [[ ${arch} == "arm64" ]]; then 27 | arch="arm64" 28 | else 29 | echo >&2 "Unknown architecture: ${arch}" 30 | fi 31 | readonly arch 32 | 33 | # Use bazelisk to catch migration problems. 34 | readonly bazelisk_version="v1.18.0" 35 | readonly url="https://github.com/bazelbuild/bazelisk/releases/download/${bazelisk_version}/bazelisk-${os}-${arch}" 36 | bazel="${TMPDIR:-/tmp}/bazelisk" 37 | readonly bazel 38 | 39 | common_args=( 40 | "--enable_bzlmod=${USE_BZLMOD:-true}" 41 | "--enable_workspace" 42 | ) 43 | 44 | # shellcheck disable=SC2034 45 | common_test_args=( 46 | "${common_args[@]}" 47 | "--symlink_prefix=/" 48 | "--color=yes" 49 | "--show_progress_rate_limit=30" 50 | "--keep_going" 51 | "--test_output=errors" 52 | "--features=layering_check" 53 | ) 54 | 55 | # Do not run autoconf to configure local CC toolchains. 56 | export BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1 57 | 58 | curl -L -sSf -o "${bazel}" "${url}" 59 | chmod a+x "${bazel}" 60 | -------------------------------------------------------------------------------- /tests/scripts/centos_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # Disable the unreachable code warning because the test is disabled. 17 | # shellcheck disable=SC2317 18 | 19 | echo "This test is disabled because our supported versions of LLVM do not work with CentOS." 20 | exit 1 21 | 22 | set -euo pipefail 23 | 24 | images=( 25 | "centos:7" 26 | ) 27 | 28 | git_root=$(git rev-parse --show-toplevel) 29 | readonly git_root 30 | 31 | for image in "${images[@]}"; do 32 | docker pull "${image}" 33 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src:ro" "${image}" -c """ 34 | set -exuo pipefail 35 | 36 | # Need system glibc and headers. 37 | yum install -y -q glibc-headers 38 | 39 | # Run tests 40 | cd /src 41 | tests/scripts/run_tests.sh 42 | """ 43 | done 44 | -------------------------------------------------------------------------------- /tests/scripts/debian_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | images=( 19 | "debian:latest" 20 | ) 21 | 22 | git_root=$(git rev-parse --show-toplevel) 23 | readonly git_root 24 | 25 | for image in "${images[@]}"; do 26 | docker pull "${image}" 27 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src:ro" "${image}" -c """ 28 | set -exuo pipefail 29 | 30 | # Common setup 31 | export DEBIAN_FRONTEND=noninteractive 32 | apt-get -qq update 33 | apt-get -qq -y install curl libtinfo5 libxml2 zlib1g-dev >/dev/null 34 | # The above command gives some verbose output that can not be silenced easily. 35 | # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=288778 36 | 37 | # Run tests 38 | cd /src 39 | tests/scripts/run_tests.sh 40 | """ 41 | done 42 | -------------------------------------------------------------------------------- /tests/scripts/fedora_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | images=( 19 | "fedora:latest" 20 | ) 21 | 22 | git_root=$(git rev-parse --show-toplevel) 23 | readonly git_root 24 | 25 | for image in "${images[@]}"; do 26 | docker pull "${image}" 27 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src:ro" "${image}" -c """ 28 | set -exuo pipefail 29 | 30 | # Need system glibc headers (e.g. features.h). 31 | dnf install -qy glibc-headers ncurses-compat-libs 32 | 33 | # Run tests 34 | cd /src 35 | tests/scripts/run_tests.sh 36 | """ 37 | done 38 | -------------------------------------------------------------------------------- /tests/scripts/linux_sysroot_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | images=( 19 | "ubuntu:22.04" 20 | ) 21 | 22 | git_root=$(git rev-parse --show-toplevel) 23 | readonly git_root 24 | 25 | for image in "${images[@]}"; do 26 | docker pull "${image}" 27 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src:ro" "${image}" -c """ 28 | set -exuo pipefail 29 | 30 | # Common setup 31 | export DEBIAN_FRONTEND=noninteractive 32 | apt-get -qq update 33 | apt-get -qq -y install curl libtinfo5 libxml2 zlib1g-dev >/dev/null 34 | # The above command gives some verbose output that can not be silenced easily. 35 | # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=288778 36 | 37 | # Run tests 38 | cd /src 39 | tests/scripts/run_tests.sh -t '@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux' 40 | """ 41 | done 42 | -------------------------------------------------------------------------------- /tests/scripts/run_docker_exec_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2024 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | os="$(uname -s)" 19 | if [[ ${os} != "Darwin" ]]; then 20 | echo >&2 "Test, to be most effective, is meant to be run on Darwin." 21 | exit 1 22 | fi 23 | 24 | if "${CI:-false}"; then 25 | # macOS GitHub Action Runners do not have docker installed on them. 26 | echo >&2 "Test can not be run on GitHub Actions" 27 | exit 1 28 | fi 29 | 30 | scripts_dir="$(dirname "${BASH_SOURCE[0]}")" 31 | source "${scripts_dir}/bazel.sh" 32 | "${bazel}" version 33 | 34 | cd "${scripts_dir}" 35 | 36 | base_image="debian:stable-slim" 37 | binpath="$("${bazel}" info "${common_args[@]}" bazel-bin)/stdlib_test" 38 | 39 | docker build --platform=linux/amd64 --pull --tag=bazel-docker-sandbox - <<-EOF 40 | FROM ${base_image} 41 | ENV DEBIAN_FRONTEND=noninteractive 42 | RUN apt-get -qq update && \ 43 | apt-get -qq -y install libtinfo5 libxml2 zlib1g-dev libxml2 44 | EOF 45 | 46 | build_args=( 47 | "${common_args[@]}" 48 | # Platforms 49 | "--platforms=@toolchains_llvm//platforms:linux-x86_64" 50 | "--extra_execution_platforms=@toolchains_llvm//platforms:linux-x86_64" 51 | "--extra_toolchains=@llvm_toolchain_linux_exec//:cc-toolchain-x86_64-linux" 52 | # Docker sandbox 53 | "--experimental_enable_docker_sandbox" 54 | "--experimental_docker_verbose" 55 | "--experimental_docker_image=bazel-docker-sandbox" 56 | "--spawn_strategy=docker" 57 | # Verbosity of build actions 58 | "--copt=-v" 59 | "--linkopt=-v" 60 | "--linkopt=-Wl,-v" 61 | ) 62 | 63 | "${bazel}" --bazelrc=/dev/null build "${build_args[@]}" //:stdlib_test 64 | file "${binpath}" | tee /dev/stderr | grep -q ELF 65 | docker run --rm -it --platform=linux/amd64 \ 66 | --mount "type=bind,source=${binpath},target=/stdlib_test" "${base_image}" /stdlib_test 67 | -------------------------------------------------------------------------------- /tests/scripts/run_external_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | scripts_dir="$(dirname "${BASH_SOURCE[0]}")" 19 | source "${scripts_dir}/bazel.sh" 20 | "${bazel}" version 21 | 22 | cd "${scripts_dir}" 23 | 24 | # Generate some files needed for the tests. 25 | "${bazel}" query "${common_args[@]}" @io_bazel_rules_go//tests/core/cgo:dylib_test >/dev/null 26 | if [[ ${USE_BZLMOD} == "true" ]]; then 27 | script="$("${bazel}" info output_base)/external/rules_go~/tests/core/cgo/generate_imported_dylib.sh" 28 | if [[ -f "${script}" ]]; then 29 | "${script}" 30 | else 31 | "$("${bazel}" info output_base)/external/rules_go+/tests/core/cgo/generate_imported_dylib.sh" 32 | fi 33 | else 34 | "$("${bazel}" info output_base)/external/io_bazel_rules_go/tests/core/cgo/generate_imported_dylib.sh" 35 | fi 36 | 37 | test_args=( 38 | "${common_test_args[@]}" 39 | "--copt=-Wno-deprecated-builtins" # https://github.com/abseil/abseil-cpp/issues/1201 40 | # Disable the "hermetic sandbox /tmp" behavior of Bazel 7 as it results in broken symlinks when 41 | # rules_foreign_cc builds pcre. 42 | # TODO: Remove this once rules_foreign_cc is fully compatible with Bazel 7. 43 | "--sandbox_add_mount_pair=/tmp" 44 | ) 45 | 46 | # We exclude the following targets: 47 | # - cc_libs_test from rules_go because it assumes that stdlibc++ has been dynamically linked, but we 48 | # link it statically on linux. 49 | # - external_includes_test from rules_go because it is a nested bazel test and so takes a long time 50 | # to run, and it is not particularly useful to us. 51 | # - time_zone_format_test from abseil-cpp because it assumes TZ is set to America/Los_Angeles, but 52 | # we run the tests in UTC. 53 | # - {cdylib,bin}_has_native_dep_and_alwayslink_test from rules_rust because they assume the test is 54 | # being run in the root module (use 'rules_rust' in the bazel-bin path instead of 'rules_rust~'). 55 | # shellcheck disable=SC2207 56 | absl_targets=($("${bazel}" query "${common_args[@]}" 'attr(timeout, short, tests(@com_google_absl//absl/...) except attr(tags, benchmark, tests(@com_google_absl//absl/...)))')) 57 | "${bazel}" --bazelrc=/dev/null test "${test_args[@]}" -- \ 58 | //foreign:pcre \ 59 | @openssl//:libssl \ 60 | @rules_rust//test/unit/{interleaved_cc_info,native_deps}:all \ 61 | @io_bazel_rules_go//tests/core/cgo:all \ 62 | -@io_bazel_rules_go//tests/core/cgo:cc_libs_test \ 63 | -@io_bazel_rules_go//tests/core/cgo:external_includes_test \ 64 | -@rules_rust//test/unit/native_deps:{cdylib,bin}_has_native_dep_and_alwayslink_test \ 65 | "${absl_targets[@]}" \ 66 | -@com_google_absl//absl/time/internal/cctz:time_zone_format_test 67 | -------------------------------------------------------------------------------- /tests/scripts/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | toolchain_name="" 19 | disable_wasm_tests="" 20 | 21 | while getopts "t:hW" opt; do 22 | case "${opt}" in 23 | "t") toolchain_name="${OPTARG}" ;; 24 | "h") 25 | echo "Usage:" 26 | echo "-t - Toolchain name to use for testing; default is llvm_toolchain" 27 | exit 2 28 | ;; 29 | "W") 30 | disable_wasm_tests="yes" 31 | ;; 32 | *) 33 | echo "invalid option: -${OPTARG}" 34 | exit 1 35 | ;; 36 | esac 37 | done 38 | 39 | scripts_dir="$(dirname "${BASH_SOURCE[0]}")" 40 | source "${scripts_dir}/bazel.sh" 41 | "${bazel}" version 42 | 43 | cd "${scripts_dir}" 44 | 45 | set -x 46 | test_args=( 47 | "--extra_toolchains=${toolchain_name}" 48 | "--copt=-v" 49 | "--linkopt=-Wl,-v" 50 | "--linkopt=-Wl,-t" 51 | ) 52 | 53 | targets=( 54 | "//:all" 55 | ) 56 | # :test_cxx_standard_is_20 builds with a version of the default toolchain, if 57 | # we're trying to build with a different toolchain then it's likely the default 58 | # toolchain won't work so :test_cxx_standard_is_20 won't build. 59 | if [[ -z ${toolchain_name} ]]; then 60 | targets+=("//:test_cxx_standard_is_20") 61 | fi 62 | 63 | "${bazel}" ${TEST_MIGRATION:+"--strict"} --bazelrc=/dev/null test \ 64 | "${common_test_args[@]}" "${test_args[@]}" "${targets[@]}" 65 | 66 | # Note that the following flags are currently known to cause issues in migration tests: 67 | # --incompatible_disallow_struct_provider_syntax # https://github.com/bazelbuild/bazel/issues/7347 68 | # --incompatible_no_rule_outputs_param # from rules_rust 69 | 70 | # WebAssembly tests use a separate (newer) version of LLVM to exercise support 71 | # for experimental features such as wasm64, which can cause the CI environment 72 | # to run out of disk space. 73 | # 74 | # Mitigate this by expunging the workspace before trying to build Wasm targets. 75 | if [[ -z ${toolchain_name} && -z ${disable_wasm_tests} ]]; then 76 | # Redefine `test_args` without `--linkopt=-Wl,-v`, which breaks `wasm-ld`. 77 | # 78 | # https://github.com/llvm/llvm-project/issues/112836 79 | test_args=( 80 | "--copt=-v" 81 | "--linkopt=-Wl,-t" 82 | ) 83 | wasm_targets=( 84 | "//wasm:all" 85 | ) 86 | "${bazel}" clean --expunge 87 | "${bazel}" ${TEST_MIGRATION:+"--strict"} --bazelrc=/dev/null test \ 88 | "${common_test_args[@]}" "${test_args[@]}" "${wasm_targets[@]}" 89 | fi 90 | -------------------------------------------------------------------------------- /tests/scripts/run_toolchain_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2018 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | while getopts "h" opt; do 19 | case "${opt}" in 20 | "h") 21 | echo "Usage: No options" 22 | exit 2 23 | ;; 24 | *) 25 | echo "invalid option: -${OPTARG}" 26 | exit 1 27 | ;; 28 | esac 29 | done 30 | 31 | scripts_dir="$(dirname "${BASH_SOURCE[0]}")" 32 | source "${scripts_dir}/bazel.sh" 33 | "${bazel}" version 34 | 35 | set -x 36 | test_args=( 37 | "--check_direct_dependencies=off" 38 | ) 39 | 40 | targets=( 41 | "//toolchain/..." 42 | ) 43 | 44 | "${bazel}" ${TEST_MIGRATION:+"--strict"} --bazelrc=/dev/null test \ 45 | "${common_test_args[@]}" "${test_args[@]}" "${targets[@]}" 46 | -------------------------------------------------------------------------------- /tests/scripts/run_xcompile_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2021 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | scripts_dir="$(dirname "${BASH_SOURCE[0]}")" 19 | source "${scripts_dir}/bazel.sh" 20 | "${bazel}" version 21 | 22 | cd "${scripts_dir}" 23 | 24 | binpath="$("${bazel}" info "${common_args[@]}" bazel-bin)/stdlib_test" 25 | 26 | check_with_image() { 27 | if "${CI:-false}"; then 28 | # macOS GitHub Action Runners do not have docker installed on them. 29 | return 30 | fi 31 | local image="$1" 32 | docker run --rm -it --platform=linux/amd64 \ 33 | --mount "type=bind,source=${binpath},target=/stdlib_test" "${image}" /stdlib_test 34 | } 35 | 36 | echo "" 37 | echo "Testing static linked user libraries and dynamic linked system libraries" 38 | build_args=( 39 | "${common_args[@]}" 40 | --platforms=@toolchains_llvm//platforms:linux-x86_64 41 | --extra_toolchains=@llvm_toolchain_with_sysroot//:cc-toolchain-x86_64-linux 42 | --symlink_prefix=/ 43 | --color=yes 44 | --show_progress_rate_limit=30 45 | ) 46 | "${bazel}" --bazelrc=/dev/null build "${build_args[@]}" //:stdlib_test 47 | file "${binpath}" | tee /dev/stderr | grep -q ELF 48 | check_with_image "gcr.io/distroless/cc-debian11" # Need glibc image for system libraries. 49 | 50 | echo "" 51 | echo "Testing static linked user and system libraries" 52 | build_args+=( 53 | --features=fully_static_link 54 | ) 55 | "${bazel}" --bazelrc=/dev/null build "${build_args[@]}" //:stdlib_test 56 | file "${binpath}" | tee /dev/stderr | grep -q ELF 57 | check_with_image "gcr.io/distroless/static-debian11" 58 | -------------------------------------------------------------------------------- /tests/scripts/suse_leap_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2021 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euox pipefail 17 | 18 | images=( 19 | "opensuse/leap:latest" 20 | ) 21 | 22 | # See note next to the definition of this toolchain in the WORKSPACE file. 23 | toolchain="@llvm_toolchain_13_0_0//:cc-toolchain-x86_64-linux" 24 | 25 | git_root=$(git rev-parse --show-toplevel) 26 | readonly git_root 27 | 28 | echo "git root: ${git_root}" 29 | 30 | for image in "${images[@]}"; do 31 | docker pull "${image}" 32 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src" "${image}" -c """ 33 | set -exuo pipefail 34 | 35 | # Common setup 36 | zypper -n update 37 | zypper -n install curl gcc libc++1 38 | 39 | # Run tests 40 | cd /src 41 | tests/scripts/run_tests.sh -t ${toolchain} 42 | """ 43 | done 44 | -------------------------------------------------------------------------------- /tests/scripts/suse_tumbleweed_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2021 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euox pipefail 17 | 18 | images=( 19 | "opensuse/tumbleweed:latest" 20 | ) 21 | 22 | # See note next to the definition of this toolchain in the WORKSPACE file. 23 | toolchain="@llvm_toolchain_13_0_0//:cc-toolchain-x86_64-linux" 24 | 25 | git_root=$(git rev-parse --show-toplevel) 26 | readonly git_root 27 | 28 | echo "git root: ${git_root}" 29 | 30 | for image in "${images[@]}"; do 31 | docker pull "${image}" 32 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src" "${image}" -c """ 33 | set -exuo pipefail 34 | 35 | # Common setup 36 | zypper -n update 37 | zypper -n install curl gcc libc++1 38 | 39 | # Run tests 40 | cd /src 41 | tests/scripts/run_tests.sh -t ${toolchain} 42 | """ 43 | done 44 | -------------------------------------------------------------------------------- /tests/scripts/ubuntu_20_04_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2020 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | images=( 19 | "ubuntu:20.04" 20 | ) 21 | 22 | git_root=$(git rev-parse --show-toplevel) 23 | readonly git_root 24 | 25 | for image in "${images[@]}"; do 26 | docker pull "${image}" 27 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src:ro" "${image}" -c """ 28 | set -exuo pipefail 29 | 30 | # Common setup 31 | export DEBIAN_FRONTEND=noninteractive 32 | apt-get -qq update 33 | apt-get -qq -y install apt-utils curl libtinfo5 libxml2 pkg-config zlib1g-dev >/dev/null 34 | # The above command gives some verbose output that can not be silenced easily. 35 | # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=288778 36 | 37 | # The WebAssembly tests use an LLVM version that is too new for the GNU libc 38 | # distributed in Ubuntu 20.04. 39 | disable_wasm_tests='-W' 40 | 41 | # Run tests 42 | cd /src 43 | tests/scripts/run_tests.sh \${disable_wasm_tests} 44 | """ 45 | done 46 | -------------------------------------------------------------------------------- /tests/scripts/ubuntu_22_04_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2020 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | images=( 19 | "ubuntu:22.04" 20 | ) 21 | 22 | git_root=$(git rev-parse --show-toplevel) 23 | readonly git_root 24 | 25 | for image in "${images[@]}"; do 26 | docker pull "${image}" 27 | docker run --rm --entrypoint=/bin/bash --env USE_BZLMOD --volume="${git_root}:/src:ro" "${image}" -c """ 28 | set -exuo pipefail 29 | 30 | # Common setup 31 | export DEBIAN_FRONTEND=noninteractive 32 | apt-get -qq update 33 | apt-get -qq -y install curl libtinfo5 libxml2 zlib1g-dev >/dev/null 34 | # The above command gives some verbose output that can not be silenced easily. 35 | # https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=288778 36 | 37 | # Run tests 38 | cd /src 39 | tests/scripts/run_tests.sh 40 | """ 41 | done 42 | -------------------------------------------------------------------------------- /tests/scripts/ubuntu_install_libtinfo.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Ubuntu 24.04 does not have libtinfo5 in its PPAs: 4 | # 5 | # However, the LLVM binary releases hosted up upstream still target Ubuntu 18.04 6 | # as of this writing and contain binaries linked against `libtinfo5`. 7 | # 8 | # This script installs `libtinfo5` using the `.deb` from Ubuntu 22.04's PPAs: 9 | # https://packages.ubuntu.com/jammy-updates/amd64/libtinfo5/download 10 | 11 | set -euo pipefail 12 | 13 | pkg="$(mktemp --suffix=.deb)" 14 | trap 'rm -f "${pkg}"' EXIT 15 | 16 | curl -L https://mirrors.kernel.org/ubuntu/pool/universe/n/ncurses/libtinfo5_6.3-2ubuntu0.1_amd64.deb -o "${pkg}" 17 | sudo dpkg -i "${pkg}" 18 | -------------------------------------------------------------------------------- /tests/stdlib.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Bazel Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0(the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http: // www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include 16 | 17 | void hello() { std::cout << "Hello World!" << std::endl; } 18 | -------------------------------------------------------------------------------- /tests/stdlib.h: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Bazel Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0(the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http: // www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | void hello(); 16 | 17 | void test_pthread_symbols(); 18 | -------------------------------------------------------------------------------- /tests/stdlib_test.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The Bazel Authors. 2 | // 3 | // Licensed under the Apache License, Version 2.0(the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http: // www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | #include "stdlib.h" 16 | 17 | int main() { hello(); } 18 | -------------------------------------------------------------------------------- /tests/test_cxx_standard.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int run_test(int argc, char** argv) { 5 | if (argc != 2) { 6 | std::cout << "Not enough arguments" << std::endl; 7 | return 1; 8 | } 9 | 10 | long expected_version = std::atol(argv[1]); 11 | 12 | if (expected_version == 0) { 13 | std::cout << "Invalid version argument, must be an integer" << std::endl; 14 | return 1; 15 | } 16 | 17 | if (expected_version != __cplusplus) { 18 | std::cout << "Expected version to be " << argv[1] << " but got " << __cplusplus << std::endl; 19 | return 1; 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /tests/test_cxx_standard_main.cc: -------------------------------------------------------------------------------- 1 | int run_test(int argc, char** argv); 2 | 3 | int main(int argc, char** argv) { 4 | return run_test(argc, argv); 5 | } -------------------------------------------------------------------------------- /tests/transitions.bzl: -------------------------------------------------------------------------------- 1 | """Helper transitions for tests.""" 2 | 3 | # Copyright 2022 The Bazel Authors. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This transition function sets `--features=per_object_debug_info` and 18 | # `--fission` as well as the compilation mode. 19 | # 20 | # These three Bazel flags influence whether or not `.dwo` and `.dwp` are 21 | # created. 22 | def _fission_transition_impl(settings, attr): 23 | features = settings["//command_line_option:features"] 24 | if "per_object_debug_info" in features: 25 | features.remove("per_object_debug_info") 26 | 27 | enable_per_object_debug_info = attr.per_object_debug_info 28 | if enable_per_object_debug_info: 29 | features.append("per_object_debug_info") 30 | 31 | compilation_mode = settings["//command_line_option:compilation_mode"] 32 | if attr.override_compilation_mode: 33 | compilation_mode = attr.override_compilation_mode 34 | 35 | return { 36 | "//command_line_option:compilation_mode": compilation_mode, 37 | "//command_line_option:fission": attr.fission, 38 | "//command_line_option:features": features, 39 | } 40 | 41 | fission_transition = transition( 42 | implementation = _fission_transition_impl, 43 | inputs = [ 44 | "//command_line_option:compilation_mode", 45 | "//command_line_option:features", 46 | ], 47 | outputs = [ 48 | "//command_line_option:compilation_mode", 49 | "//command_line_option:features", 50 | "//command_line_option:fission", 51 | ], 52 | ) 53 | 54 | def _dwp_file_impl(ctx): 55 | file = ctx.attr.name 56 | file = ctx.actions.declare_file(file) 57 | ctx.actions.symlink( 58 | output = file, 59 | target_file = ctx.attr.src[0][DebugPackageInfo].dwp_file, 60 | ) 61 | 62 | return [DefaultInfo(files = depset([file]))] 63 | 64 | dwp_file = rule( 65 | implementation = _dwp_file_impl, 66 | attrs = { 67 | "src": attr.label( 68 | cfg = fission_transition, 69 | mandatory = True, 70 | doc = "The actual target to build and grab the .dwp file from.", 71 | providers = [DebugPackageInfo], 72 | ), 73 | # NOTE: we should eventually be able to remove this (see #109). 74 | "per_object_debug_info": attr.bool( 75 | default = True, 76 | ), 77 | "fission": attr.string( 78 | default = "yes", 79 | values = ["yes", "no", "dbg", "fastbuild", "opt"], 80 | ), 81 | # NOTE: this should eventually not be necessary; see #109 for context 82 | # and also: 83 | # - https://reviews.llvm.org/D80391 84 | # - https://github.com/bazelbuild/bazel/issues/14038 85 | # - https://github.com/bazelbuild/rules_cc/pull/115 86 | # 87 | # Essentially, we now need to specify `-g2` explicitly to generate 88 | # `.dwo` files. 89 | "override_compilation_mode": attr.string( 90 | default = "", 91 | mandatory = False, 92 | values = ["dbg", "fastbuild", "opt"], 93 | ), 94 | "_allowlist_function_transition": attr.label( 95 | default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 96 | ), 97 | }, 98 | ) 99 | 100 | def _transition_to_platform_transition_impl(_, attr): 101 | return {"//command_line_option:platforms": str(attr.platform)} 102 | 103 | _transition_to_platform_transition = transition( 104 | implementation = _transition_to_platform_transition_impl, 105 | inputs = [], 106 | outputs = ["//command_line_option:platforms"], 107 | ) 108 | 109 | def _transition_library_to_platform_impl(ctx): 110 | return [ 111 | ctx.attr.lib[0][CcInfo], 112 | ] 113 | 114 | transition_library_to_platform = rule( 115 | implementation = _transition_library_to_platform_impl, 116 | attrs = { 117 | "lib": attr.label(mandatory = True, cfg = _transition_to_platform_transition), 118 | "platform": attr.label(mandatory = True), 119 | "_allowlist_function_transition": attr.label( 120 | default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 121 | ), 122 | }, 123 | ) 124 | 125 | def _transition_binary_to_platform_impl(ctx): 126 | out = ctx.actions.declare_file(ctx.attr.name) 127 | ctx.actions.symlink(output = out, target_file = ctx.file.bin) 128 | return DefaultInfo(files = depset([out])) 129 | 130 | transition_binary_to_platform = rule( 131 | implementation = _transition_binary_to_platform_impl, 132 | attrs = { 133 | "bin": attr.label( 134 | mandatory = True, 135 | allow_single_file = True, 136 | cfg = _transition_to_platform_transition, 137 | ), 138 | "platform": attr.label(mandatory = True), 139 | "_allowlist_function_transition": attr.label( 140 | default = "@bazel_tools//tools/allowlists/function_transition_allowlist", 141 | ), 142 | }, 143 | ) 144 | -------------------------------------------------------------------------------- /tests/wasm/BUILD.bazel: -------------------------------------------------------------------------------- 1 | load("@bazel_skylib//rules:build_test.bzl", "build_test") 2 | load("@rules_cc//cc:defs.bzl", "cc_binary") 3 | load("//:transitions.bzl", "transition_binary_to_platform") 4 | 5 | build_test( 6 | name = "wasm_targets_test", 7 | targets = [ 8 | ":wasm32_strlen", 9 | ":wasm32_strlen_nolibc", 10 | ":wasm64_strlen_nolibc", 11 | ":wasm32_wasip1_strlen", 12 | ], 13 | ) 14 | 15 | cc_binary( 16 | name = "wasm_strlen", 17 | srcs = ["wasm_strlen.c"], 18 | linkopts = ["-Wl,--no-entry"], 19 | tags = ["manual"], 20 | ) 21 | 22 | transition_binary_to_platform( 23 | name = "wasm32_strlen", 24 | bin = ":wasm_strlen", 25 | platform = "@toolchains_llvm//platforms:wasm32", 26 | ) 27 | 28 | cc_binary( 29 | name = "wasm_strlen_nolibc", 30 | srcs = ["wasm_strlen_nolibc.c"], 31 | linkopts = ["-Wl,--no-entry"], 32 | tags = ["manual"], 33 | ) 34 | 35 | transition_binary_to_platform( 36 | name = "wasm32_strlen_nolibc", 37 | bin = ":wasm_strlen_nolibc", 38 | platform = "@toolchains_llvm//platforms:wasm32", 39 | ) 40 | 41 | transition_binary_to_platform( 42 | name = "wasm64_strlen_nolibc", 43 | bin = ":wasm_strlen_nolibc", 44 | platform = "@toolchains_llvm//platforms:wasm64", 45 | ) 46 | 47 | cc_binary( 48 | name = "wasm_strlen_wasi", 49 | srcs = ["wasm_strlen_wasi.c"], 50 | linkopts = ["-Wl,--no-entry"], 51 | tags = ["manual"], 52 | ) 53 | 54 | transition_binary_to_platform( 55 | name = "wasm32_wasip1_strlen", 56 | bin = ":wasm_strlen_wasi", 57 | platform = "@toolchains_llvm//platforms:wasip1-wasm32", 58 | ) 59 | -------------------------------------------------------------------------------- /tests/wasm/wasi_sdk.bzl: -------------------------------------------------------------------------------- 1 | _SYSROOT_BUILD = """ 2 | filegroup( 3 | name = {name}, 4 | srcs = glob(["include/**/*", "lib/**/*", "share/**/*"], allow_empty=True), 5 | visibility = ["//visibility:public"], 6 | ) 7 | """ 8 | 9 | _WASI_SDK_ABIS = [ 10 | "wasm32-wasi", 11 | "wasm32-wasip1", 12 | "wasm32-wasip1-threads", 13 | "wasm32-wasip2", 14 | "wasm32-wasi-threads", 15 | ] 16 | 17 | def _wasi_sdk_sysroots(ctx): 18 | ctx.download_and_extract( 19 | integrity = "sha256-NRcvfSeZSFsVpGsdh/UKWF2RXsZiCA8AXZkVOlCIjwg=", 20 | stripPrefix = "wasi-sysroot-24.0", 21 | url = ["https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/wasi-sysroot-24.0.tar.gz"], 22 | ) 23 | 24 | ctx.file("empty/BUILD.bazel", _SYSROOT_BUILD.format( 25 | name = repr("empty"), 26 | )) 27 | 28 | for abi in _WASI_SDK_ABIS: 29 | ctx.file("%s/BUILD.bazel" % (abi,), _SYSROOT_BUILD.format( 30 | name = repr(abi), 31 | )) 32 | ctx.execute(["mv", "include/" + abi, "%s/include" % (abi,)]) 33 | ctx.execute(["mv", "share/" + abi, "%s/share" % (abi,)]) 34 | 35 | # This is needed for wasm*-unknown-unknown targets 36 | ctx.execute(["cp", "-R", "lib/" + abi, "%s/lib" % (abi,)]) 37 | 38 | # This is needed for wasm*-wasip1 targets 39 | ctx.execute(["mv", "lib/" + abi, "%s/lib/%s" % (abi, abi)]) 40 | 41 | wasi_sdk_sysroots = repository_rule(_wasi_sdk_sysroots) 42 | 43 | def _libclang_rt_wasm32(ctx): 44 | ctx.file("BUILD.bazel", """ 45 | exports_files(glob(["*.a"])) 46 | """) 47 | 48 | ctx.download_and_extract( 49 | integrity = "sha256-fjPA33WLkEabHePKFY4tCn9xk01YhFJbpqNy3gs7Dsc=", 50 | stripPrefix = "libclang_rt.builtins-wasm32-wasi-24.0", 51 | url = ["https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-24/libclang_rt.builtins-wasm32-wasi-24.0.tar.gz"], 52 | ) 53 | 54 | libclang_rt_wasm32 = repository_rule(_libclang_rt_wasm32) 55 | -------------------------------------------------------------------------------- /tests/wasm/wasm_strlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | __attribute__((export_name("strlen"))) 5 | uint32_t wasm_strlen(char *s) { 6 | return strlen(s); 7 | } 8 | -------------------------------------------------------------------------------- /tests/wasm/wasm_strlen_nolibc.c: -------------------------------------------------------------------------------- 1 | __attribute__((export_name("strlen"))) 2 | unsigned long wasm_strlen(char *s) { 3 | unsigned long len = 0; 4 | for (; *s; len++) {} 5 | return len; 6 | } 7 | -------------------------------------------------------------------------------- /tests/wasm/wasm_strlen_wasi.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | uint32_t wasm_strlen(char *s) { 6 | return strlen(s); 7 | } 8 | 9 | int main() { 10 | char *s = "Hello world!"; 11 | printf("strlen(\"%s\") = %d\n", s, wasm_strlen(s)); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /toolchain/BUILD.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # This BUILD file exports the templates and static files needed for dynamic toolchain configuration. 16 | # See internal/configure.bzl for how they are used. 17 | 18 | exports_files( 19 | glob( 20 | ["*"], 21 | exclude = ["BUILD.bazel"], 22 | ), 23 | ) 24 | -------------------------------------------------------------------------------- /toolchain/BUILD.llvm_repo: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | package(default_visibility = ["//visibility:public"]) 16 | 17 | # Some targets may need to directly depend on these files. 18 | exports_files(glob( 19 | [ 20 | "bin/*", 21 | "lib/**", 22 | "include/**", 23 | "share/clang/*", 24 | ], 25 | allow_empty = True, 26 | )) 27 | 28 | ## LLVM toolchain files 29 | 30 | filegroup( 31 | name = "clang", 32 | srcs = [ 33 | "bin/clang", 34 | "bin/clang++", 35 | "bin/clang-cpp", 36 | ], 37 | ) 38 | 39 | filegroup( 40 | name = "ld", 41 | srcs = [ 42 | "bin/ld.lld", 43 | "bin/ld64.lld", 44 | "bin/wasm-ld", 45 | ], 46 | ) 47 | 48 | filegroup( 49 | name = "include", 50 | srcs = glob([ 51 | "include/**/c++/**", 52 | "lib/clang/*/include/**", 53 | ]), 54 | ) 55 | 56 | filegroup( 57 | name = "all_includes", 58 | srcs = glob( 59 | ["include/**"], 60 | allow_empty = True, 61 | ), 62 | ) 63 | 64 | filegroup( 65 | name = "bin", 66 | srcs = glob(["bin/**"]), 67 | ) 68 | 69 | filegroup( 70 | name = "lib", 71 | srcs = glob( 72 | [ 73 | "lib/**/lib*.a", 74 | "lib/clang/*/lib/**/*.a", 75 | "lib/clang/*/lib/**/*.dylib", 76 | # clang_rt.*.o supply crtbegin and crtend sections. 77 | "lib/**/clang_rt.*.o", 78 | ], 79 | allow_empty = True, 80 | exclude = [ 81 | "lib/libLLVM*.a", 82 | "lib/libclang*.a", 83 | "lib/liblld*.a", 84 | ], 85 | ), 86 | # Include the .dylib files in the linker sandbox even though they will 87 | # not be available at runtime to allow sanitizers to work locally. 88 | # Any library linked from the toolchain to be released should be linked statically. 89 | ) 90 | 91 | filegroup( 92 | name = "ar", 93 | srcs = ["bin/llvm-ar"], 94 | ) 95 | 96 | filegroup( 97 | name = "as", 98 | srcs = [ 99 | "bin/clang", 100 | "bin/llvm-as", 101 | ], 102 | ) 103 | 104 | filegroup( 105 | name = "nm", 106 | srcs = ["bin/llvm-nm"], 107 | ) 108 | 109 | filegroup( 110 | name = "objcopy", 111 | srcs = ["bin/llvm-objcopy"], 112 | ) 113 | 114 | filegroup( 115 | name = "objdump", 116 | srcs = ["bin/llvm-objdump"], 117 | ) 118 | 119 | filegroup( 120 | name = "profdata", 121 | srcs = ["bin/llvm-profdata"], 122 | ) 123 | 124 | filegroup( 125 | name = "dwp", 126 | srcs = ["bin/llvm-dwp"], 127 | ) 128 | 129 | filegroup( 130 | name = "ranlib", 131 | srcs = ["bin/llvm-ranlib"], 132 | ) 133 | 134 | filegroup( 135 | name = "readelf", 136 | srcs = ["bin/llvm-readelf"], 137 | ) 138 | 139 | filegroup( 140 | name = "strip", 141 | srcs = ["bin/llvm-strip"], 142 | ) 143 | 144 | filegroup( 145 | name = "symbolizer", 146 | srcs = ["bin/llvm-symbolizer"], 147 | ) 148 | 149 | filegroup( 150 | name = "clang-tidy", 151 | srcs = ["bin/clang-tidy"], 152 | ) 153 | 154 | filegroup( 155 | name = "clang-format", 156 | srcs = ["bin/clang-format"], 157 | ) 158 | 159 | filegroup( 160 | name = "git-clang-format", 161 | srcs = ["bin/git-clang-format"], 162 | ) 163 | 164 | filegroup( 165 | name = "libclang", 166 | srcs = glob( 167 | [ 168 | "lib/libclang.so", 169 | "lib/libclang.dylib", 170 | ], 171 | allow_empty = True, 172 | ), 173 | ) 174 | -------------------------------------------------------------------------------- /toolchain/BUILD.toolchain.tpl: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | package(default_visibility = ["//visibility:public"]) 16 | 17 | load("@bazel_skylib//rules:native_binary.bzl", "native_binary") 18 | load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite") 19 | load("@toolchains_llvm//toolchain/internal:system_module_map.bzl", "system_module_map") 20 | load("%{cc_toolchain_config_bzl}", "cc_toolchain_config") 21 | 22 | # Following filegroup targets are used when not using absolute paths and shared 23 | # between different toolchains. 24 | 25 | # Tools symlinked through this repo. This target is for internal use in the toolchain only. 26 | filegroup( 27 | name = "internal-use-symlinked-tools", 28 | srcs = [%{symlinked_tools} 29 | ], 30 | visibility = ["//visibility:private"], 31 | ) 32 | 33 | # Tools wrapped through this repo. This target is for internal use in the toolchain only. 34 | filegroup( 35 | name = "internal-use-wrapped-tools", 36 | srcs = [ 37 | "%{wrapper_bin_prefix}cc_wrapper.sh", 38 | ], 39 | visibility = ["//visibility:private"], 40 | ) 41 | 42 | # All internal use files. 43 | filegroup( 44 | name = "internal-use-files", 45 | srcs = [ 46 | ":internal-use-symlinked-tools", 47 | ":internal-use-wrapped-tools", 48 | ], 49 | visibility = ["//visibility:private"], 50 | ) 51 | 52 | %{cc_toolchains} 53 | 54 | # Convenience targets from the LLVM toolchain. 55 | %{convenience_targets} 56 | -------------------------------------------------------------------------------- /toolchain/aliases.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2022 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Files that will be made available as convenience targets under the bazel 16 | # toolchain repository. 17 | 18 | aliased_libs = [ 19 | "omp", 20 | ] 21 | 22 | aliased_tools = [ 23 | "clang-apply-replacements", 24 | "clang-format", 25 | "clang-tidy", 26 | "clangd", 27 | "llvm-cov", 28 | "llvm-profdata", 29 | "llvm-symbolizer", 30 | ] 31 | -------------------------------------------------------------------------------- /toolchain/cc_toolchain_config.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load( 16 | "@bazel_tools//tools/cpp:unix_cc_toolchain_config.bzl", 17 | unix_cc_toolchain_config = "cc_toolchain_config", 18 | ) 19 | load( 20 | "//toolchain/internal:common.bzl", 21 | _check_os_arch_keys = "check_os_arch_keys", 22 | _os_arch_pair = "os_arch_pair", 23 | ) 24 | 25 | # Bazel 4.* doesn't support nested starlark functions, so we cannot simplify 26 | # _fmt_flags() by defining it as a nested function. 27 | def _fmt_flags(flags, toolchain_path_prefix): 28 | return [f.format(toolchain_path_prefix = toolchain_path_prefix) for f in flags] 29 | 30 | # Macro for calling cc_toolchain_config from @bazel_tools with setting the 31 | # right paths and flags for the tools. 32 | def cc_toolchain_config( 33 | name, 34 | exec_arch, 35 | exec_os, 36 | target_arch, 37 | target_os, 38 | target_system_name, 39 | toolchain_path_prefix, 40 | tools_path_prefix, 41 | wrapper_bin_prefix, 42 | compiler_configuration, 43 | cxx_builtin_include_directories, 44 | major_llvm_version): 45 | exec_os_arch_key = _os_arch_pair(exec_os, exec_arch) 46 | target_os_arch_key = _os_arch_pair(target_os, target_arch) 47 | _check_os_arch_keys([exec_os_arch_key, target_os_arch_key]) 48 | 49 | # A bunch of variables that get passed straight through to 50 | # `create_cc_toolchain_config_info`. 51 | # TODO: What do these values mean, and are they actually all correct? 52 | ( 53 | toolchain_identifier, 54 | target_cpu, 55 | target_libc, 56 | compiler, 57 | abi_version, 58 | abi_libc_version, 59 | ) = { 60 | "darwin-x86_64": ( 61 | "clang-x86_64-darwin", 62 | "darwin", 63 | "macosx", 64 | "clang", 65 | "darwin_x86_64", 66 | "darwin_x86_64", 67 | ), 68 | "darwin-aarch64": ( 69 | "clang-aarch64-darwin", 70 | "darwin", 71 | "macosx", 72 | "clang", 73 | "darwin_aarch64", 74 | "darwin_aarch64", 75 | ), 76 | "linux-aarch64": ( 77 | "clang-aarch64-linux", 78 | "aarch64", 79 | "glibc_unknown", 80 | "clang", 81 | "clang", 82 | "glibc_unknown", 83 | ), 84 | "linux-armv7": ( 85 | "clang-armv7-linux", 86 | "armv7", 87 | "glibc_unknown", 88 | "clang", 89 | "clang", 90 | "glibc_unknown", 91 | ), 92 | "linux-x86_64": ( 93 | "clang-x86_64-linux", 94 | "k8", 95 | "glibc_unknown", 96 | "clang", 97 | "clang", 98 | "glibc_unknown", 99 | ), 100 | "none-x86_64": ( 101 | "clang-x86_64-none", 102 | "k8", 103 | "unknown", 104 | "clang", 105 | "unknown", 106 | "unknown", 107 | ), 108 | "wasm32": ( 109 | "clang-wasm32", 110 | "wasm32", 111 | "unknown", 112 | "clang", 113 | "unknown", 114 | "unknown", 115 | ), 116 | "wasm64": ( 117 | "clang-wasm64", 118 | "wasm64", 119 | "unknown", 120 | "clang", 121 | "unknown", 122 | "unknown", 123 | ), 124 | "wasip1-wasm32": ( 125 | "clang-wasm32", 126 | "wasm32", 127 | "unknown", 128 | "clang", 129 | "unknown", 130 | "unknown", 131 | ), 132 | "wasip1-wasm64": ( 133 | "clang-wasm64", 134 | "wasm64", 135 | "unknown", 136 | "clang", 137 | "unknown", 138 | "unknown", 139 | ), 140 | }[target_os_arch_key] 141 | 142 | # Unfiltered compiler flags; these are placed at the end of the command 143 | # line, so take precendence over any user supplied flags through --copts or 144 | # such. 145 | unfiltered_compile_flags = [ 146 | # Do not resolve our symlinked resource prefixes to real paths. 147 | "-no-canonical-prefixes", 148 | # Reproducibility 149 | "-Wno-builtin-macro-redefined", 150 | "-D__DATE__=\"redacted\"", 151 | "-D__TIMESTAMP__=\"redacted\"", 152 | "-D__TIME__=\"redacted\"", 153 | ] 154 | 155 | is_xcompile = not (exec_os == target_os and exec_arch == target_arch) 156 | 157 | # Default compiler flags: 158 | compile_flags = [ 159 | "--target=" + target_system_name, 160 | # Security 161 | "-U_FORTIFY_SOURCE", # https://github.com/google/sanitizers/issues/247 162 | "-fstack-protector", 163 | "-fno-omit-frame-pointer", 164 | # Diagnostics 165 | "-fcolor-diagnostics", 166 | "-Wall", 167 | "-Wthread-safety", 168 | "-Wself-assign", 169 | ] 170 | 171 | dbg_compile_flags = ["-g", "-fstandalone-debug"] 172 | 173 | opt_compile_flags = [ 174 | "-g0", 175 | "-O2", 176 | "-D_FORTIFY_SOURCE=1", 177 | "-DNDEBUG", 178 | "-ffunction-sections", 179 | "-fdata-sections", 180 | ] 181 | 182 | link_flags = [ 183 | "--target=" + target_system_name, 184 | "-no-canonical-prefixes", 185 | ] 186 | 187 | stdlib = compiler_configuration["stdlib"] 188 | if stdlib != "none": 189 | link_flags.extend([ 190 | "-lm", 191 | ]) 192 | 193 | # Similar to link_flags, but placed later in the command line such that 194 | # unused symbols are not stripped. 195 | link_libs = [] 196 | libunwind_link_flags = [] 197 | compiler_rt_link_flags = [] 198 | 199 | # Flags for ar. 200 | archive_flags = [] 201 | 202 | # Linker flags: 203 | if exec_os == "darwin" and not is_xcompile: 204 | # lld is experimental for Mach-O, so we use the native ld64 linker. 205 | # TODO: How do we cross-compile from Linux to Darwin? 206 | use_lld = False 207 | link_flags.extend([ 208 | "-headerpad_max_install_names", 209 | "-fobjc-link-runtime", 210 | ]) 211 | 212 | # Use the bundled libtool (llvm-libtool-darwin). 213 | use_libtool = True 214 | 215 | # Pre-installed libtool on macOS has -static as default, but llvm-libtool-darwin needs it 216 | # explicitly. cc_common.create_link_variables does not automatically add this either if 217 | # output_file arg to it is None. 218 | archive_flags.extend([ 219 | "-static", 220 | ]) 221 | elif target_arch in ["wasm32", "wasm64"]: 222 | # lld is invoked as wasm-ld for WebAssembly targets. 223 | use_lld = True 224 | use_libtool = False 225 | else: 226 | # Note that for xcompiling from darwin to linux, the native ld64 is 227 | # not an option because it is not a cross-linker, so lld is the 228 | # only option. 229 | use_lld = True 230 | link_flags.extend([ 231 | "-fuse-ld=lld", 232 | "-Wl,--build-id=md5", 233 | "-Wl,--hash-style=gnu", 234 | "-Wl,-z,relro,-z,now", 235 | ]) 236 | use_libtool = False 237 | 238 | # Flags related to C++ standard. 239 | # The linker has no way of knowing if there are C++ objects; so we 240 | # always link C++ libraries. 241 | cxx_standard = compiler_configuration["cxx_standard"] 242 | conly_flags = compiler_configuration["conly_flags"] 243 | sysroot_path = compiler_configuration["sysroot_path"] 244 | if stdlib == "builtin-libc++" and is_xcompile: 245 | stdlib = "stdc++" 246 | if stdlib == "builtin-libc++": 247 | cxx_flags = [ 248 | "-std=" + cxx_standard, 249 | "-stdlib=libc++", 250 | ] 251 | if major_llvm_version >= 14: 252 | # With C++20, Clang defaults to using C++ rather than Clang modules, 253 | # which breaks Bazel's `use_module_maps` feature, which is used by 254 | # `layering_check`. Since Bazel doesn't support C++ modules yet, it 255 | # is safe to disable them globally until the toolchain shipped by 256 | # Bazel sets this flag on `use_module_maps`. 257 | # https://github.com/llvm/llvm-project/commit/0556138624edf48621dd49a463dbe12e7101f17d 258 | cxx_flags.append("-Xclang") 259 | cxx_flags.append("-fno-cxx-modules") 260 | if use_lld: 261 | # For single-platform builds, we can statically link the bundled 262 | # libraries. 263 | link_flags.extend([ 264 | "-l:libc++.a", 265 | "-l:libc++abi.a", 266 | ]) 267 | compiler_rt_link_flags = ["-rtlib=compiler-rt"] 268 | libunwind_link_flags = [ 269 | "-l:libunwind.a", 270 | # To support libunwind. 271 | "-lpthread", 272 | "-ldl", 273 | ] 274 | else: 275 | # Several system libraries on macOS dynamically link libc++ and 276 | # libc++abi, so static linking them becomes a problem. We need to 277 | # ensure that they are dynamic linked from the system sysroot and 278 | # not static linked from the toolchain, so explicitly have the 279 | # sysroot directory on the search path and then add the toolchain 280 | # directory back after we are done. 281 | link_flags.extend([ 282 | "-L{}/usr/lib".format(sysroot_path), 283 | "-lc++", 284 | "-lc++abi", 285 | "-Bdynamic", 286 | "-L{}lib".format(toolchain_path_prefix), 287 | ]) 288 | libunwind_link_flags = [ 289 | "-Bstatic", 290 | "-lunwind", 291 | ] 292 | 293 | elif stdlib == "libc++": 294 | cxx_flags = [ 295 | "-std=" + cxx_standard, 296 | "-stdlib=libc++", 297 | ] 298 | 299 | link_flags.extend([ 300 | "-l:libc++.a", 301 | "-l:libc++abi.a", 302 | ]) 303 | elif stdlib == "dynamic-stdc++": 304 | cxx_flags = [ 305 | "-std=" + cxx_standard, 306 | "-stdlib=libstdc++", 307 | ] 308 | 309 | link_flags.extend([ 310 | "-lstdc++", 311 | ]) 312 | elif stdlib == "stdc++": 313 | cxx_flags = [ 314 | "-std=" + cxx_standard, 315 | "-stdlib=libstdc++", 316 | ] 317 | 318 | link_flags.extend([ 319 | "-l:libstdc++.a", 320 | ]) 321 | elif stdlib == "libc": 322 | cxx_flags = [ 323 | "-std=" + cxx_standard, 324 | ] 325 | elif stdlib == "none": 326 | cxx_flags = [ 327 | "-nostdlib", 328 | ] 329 | link_flags.extend([ 330 | "-nostdlib", 331 | ]) 332 | else: 333 | fail("Unknown value passed for stdlib: {stdlib}".format(stdlib = stdlib)) 334 | 335 | opt_link_flags = ["-Wl,--gc-sections"] if target_os == "linux" else [] 336 | 337 | # Coverage flags: 338 | coverage_compile_flags = ["-fprofile-instr-generate", "-fcoverage-mapping"] 339 | coverage_link_flags = ["-fprofile-instr-generate"] 340 | 341 | ## NOTE: framework paths is missing here; unix_cc_toolchain_config 342 | ## doesn't seem to have a feature for this. 343 | 344 | ## NOTE: make variables are missing here; unix_cc_toolchain_config doesn't 345 | ## pass these to `create_cc_toolchain_config_info`. 346 | 347 | # The requirements here come from 348 | # https://cs.opensource.google/bazel/bazel/+/master:src/main/starlark/builtins_bzl/common/cc/cc_toolchain_provider_helper.bzl;l=75;drc=f0150efd1cca473640269caaf92b5a23c288089d 349 | # https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/rules/cpp/CcModule.java;l=1257;drc=6743d76f9ecde726d592e88d8914b9db007b1c43 350 | # https://cs.opensource.google/bazel/bazel/+/refs/tags/7.0.0:tools/cpp/unix_cc_toolchain_config.bzl;l=192,201;drc=044a14cca2747aeff258fc71eaeb153c08cb34d5 351 | # NOTE: Ensure these are listed in toolchain_tools in toolchain/internal/common.bzl. 352 | tool_paths = { 353 | "ar": tools_path_prefix + ("llvm-ar" if not use_libtool else "libtool"), 354 | "cpp": tools_path_prefix + "clang-cpp", 355 | "dwp": tools_path_prefix + "llvm-dwp", 356 | "gcc": wrapper_bin_prefix + "cc_wrapper.sh", 357 | "gcov": tools_path_prefix + "llvm-profdata", 358 | "ld": tools_path_prefix + "ld.lld" if use_lld else "/usr/bin/ld", 359 | "llvm-cov": tools_path_prefix + "llvm-cov", 360 | "llvm-profdata": tools_path_prefix + "llvm-profdata", 361 | "nm": tools_path_prefix + "llvm-nm", 362 | "objcopy": tools_path_prefix + "llvm-objcopy", 363 | "objdump": tools_path_prefix + "llvm-objdump", 364 | "strip": tools_path_prefix + "llvm-strip", 365 | } 366 | 367 | # Start-end group linker support: 368 | # This was added to `lld` in this patch: http://reviews.llvm.org/D18814 369 | # 370 | # The oldest version of LLVM that we support is 6.0.0 which was released 371 | # after the above patch was merged, so we just set this to `True` when 372 | # `lld` is being used as the linker. 373 | supports_start_end_lib = use_lld 374 | 375 | # Replace flags with any user-provided overrides. 376 | if compiler_configuration["compile_flags"] != None: 377 | compile_flags = _fmt_flags(compiler_configuration["compile_flags"], toolchain_path_prefix) 378 | if compiler_configuration["cxx_flags"] != None: 379 | cxx_flags = _fmt_flags(compiler_configuration["cxx_flags"], toolchain_path_prefix) 380 | if compiler_configuration["link_flags"] != None: 381 | link_flags = _fmt_flags(compiler_configuration["link_flags"], toolchain_path_prefix) 382 | if compiler_configuration["archive_flags"] != None: 383 | archive_flags = _fmt_flags(compiler_configuration["archive_flags"], toolchain_path_prefix) 384 | if compiler_configuration["link_libs"] != None: 385 | link_libs = _fmt_flags(compiler_configuration["link_libs"], toolchain_path_prefix) 386 | if compiler_configuration["opt_compile_flags"] != None: 387 | opt_compile_flags = _fmt_flags(compiler_configuration["opt_compile_flags"], toolchain_path_prefix) 388 | if compiler_configuration["opt_link_flags"] != None: 389 | opt_link_flags = _fmt_flags(compiler_configuration["opt_link_flags"], toolchain_path_prefix) 390 | if compiler_configuration["dbg_compile_flags"] != None: 391 | dbg_compile_flags = _fmt_flags(compiler_configuration["dbg_compile_flags"], toolchain_path_prefix) 392 | if compiler_configuration["coverage_compile_flags"] != None: 393 | coverage_compile_flags = _fmt_flags(compiler_configuration["coverage_compile_flags"], toolchain_path_prefix) 394 | if compiler_configuration["coverage_link_flags"] != None: 395 | coverage_link_flags = _fmt_flags(compiler_configuration["coverage_link_flags"], toolchain_path_prefix) 396 | if compiler_configuration["unfiltered_compile_flags"] != None: 397 | unfiltered_compile_flags = _fmt_flags(compiler_configuration["unfiltered_compile_flags"], toolchain_path_prefix) 398 | 399 | # Source: https://cs.opensource.google/bazel/bazel/+/master:tools/cpp/unix_cc_toolchain_config.bzl 400 | unix_cc_toolchain_config( 401 | name = name, 402 | cpu = target_cpu, 403 | compiler = compiler, 404 | toolchain_identifier = toolchain_identifier, 405 | host_system_name = exec_arch, 406 | target_system_name = target_system_name, 407 | target_libc = target_libc, 408 | abi_version = abi_version, 409 | abi_libc_version = abi_libc_version, 410 | cxx_builtin_include_directories = cxx_builtin_include_directories, 411 | tool_paths = tool_paths, 412 | compile_flags = compile_flags, 413 | dbg_compile_flags = dbg_compile_flags, 414 | opt_compile_flags = opt_compile_flags, 415 | conly_flags = conly_flags, 416 | cxx_flags = cxx_flags, 417 | link_flags = link_flags + select({str(Label("@toolchains_llvm//toolchain/config:use_libunwind")): libunwind_link_flags, "//conditions:default": []}) + 418 | select({str(Label("@toolchains_llvm//toolchain/config:use_compiler_rt")): compiler_rt_link_flags, "//conditions:default": []}), 419 | archive_flags = archive_flags, 420 | link_libs = link_libs, 421 | opt_link_flags = opt_link_flags, 422 | unfiltered_compile_flags = unfiltered_compile_flags, 423 | coverage_compile_flags = coverage_compile_flags, 424 | coverage_link_flags = coverage_link_flags, 425 | supports_start_end_lib = supports_start_end_lib, 426 | builtin_sysroot = sysroot_path, 427 | ) 428 | -------------------------------------------------------------------------------- /toolchain/cc_wrapper.sh.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2021 The Bazel Authors. All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # OS X relpath is not really working. This is a wrapper script around gcc 18 | # to simulate relpath behavior. 19 | # 20 | # This wrapper uses install_name_tool to replace all paths in the binary 21 | # (bazel-out/.../path/to/original/library.so) by the paths relative to 22 | # the binary. It parses the command line to behave as rpath is supposed 23 | # to work. 24 | # 25 | # See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac 26 | # on how to set those paths for Mach-O binaries. 27 | 28 | # shellcheck disable=SC1083 29 | 30 | set -euo pipefail 31 | 32 | CLEANUP_FILES=() 33 | 34 | function cleanup() { 35 | if [[ ${#CLEANUP_FILES[@]} -gt 0 ]]; then 36 | rm -f "${CLEANUP_FILES[@]}" 37 | fi 38 | } 39 | 40 | trap cleanup EXIT 41 | 42 | # See note in toolchain/internal/configure.bzl where we define 43 | # `wrapper_bin_prefix` for why this wrapper is needed. 44 | 45 | if [[ -f %{toolchain_path_prefix}bin/clang ]]; then 46 | execroot_path="" 47 | elif [[ ${BASH_SOURCE[0]} == "/"* ]]; then 48 | # Some consumers of `CcToolchainConfigInfo` (e.g. `cmake` from rules_foreign_cc) 49 | # change CWD and call $CC (this script) with its absolute path. 50 | # For cases like this, we'll try to find `clang` through an absolute path. 51 | # This script is at _execroot_/external/_repo_name_/bin/cc_wrapper.sh 52 | execroot_path="${BASH_SOURCE[0]%/*/*/*/*}/" 53 | else 54 | echo >&2 "ERROR: could not find clang; PWD=\"${PWD}\"; PATH=\"${PATH}\"." 55 | exit 5 56 | fi 57 | 58 | function sanitize_option() { 59 | local -r opt=$1 60 | if [[ ${opt} == */cc_wrapper.sh ]]; then 61 | printf "%s" "${execroot_path}%{toolchain_path_prefix}bin/clang" 62 | elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]]; then 63 | # shellcheck disable=SC2206 64 | parts=(${opt/=/ }) # Split flag name and value into array. 65 | printf "%s" "${parts[0]}=${execroot_path}${parts[1]}" 66 | else 67 | printf "%s" "${opt}" 68 | fi 69 | } 70 | 71 | cmd=() 72 | for ((i = 0; i <= $#; i++)); do 73 | if [[ ${!i} == @* && -r "${i:1}" ]]; then 74 | # Create a new, sanitized file. 75 | tmpfile=$(mktemp) 76 | CLEANUP_FILES+=("${tmpfile}") 77 | while IFS= read -r opt; do 78 | opt="$( 79 | set -e 80 | sanitize_option "${opt}" 81 | )" 82 | echo "${opt}" >>"${tmpfile}" 83 | done <"${!i:1}" 84 | cmd+=("@${tmpfile}") 85 | else 86 | opt="$( 87 | set -e 88 | sanitize_option "${!i}" 89 | )" 90 | cmd+=("${opt}") 91 | fi 92 | done 93 | 94 | # Call the C++ compiler. 95 | "${cmd[@]}" 96 | -------------------------------------------------------------------------------- /toolchain/config/BUILD.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") 16 | 17 | bool_flag( 18 | name = "libunwind", 19 | build_setting_default = True, 20 | visibility = ["//visibility:public"], 21 | ) 22 | 23 | bool_flag( 24 | name = "compiler-rt", 25 | build_setting_default = True, 26 | visibility = ["//visibility:public"], 27 | ) 28 | 29 | config_setting( 30 | name = "use_libunwind", 31 | flag_values = {":libunwind": "True"}, 32 | visibility = ["//visibility:public"], 33 | ) 34 | 35 | config_setting( 36 | name = "use_compiler_rt", 37 | flag_values = {":compiler-rt": "True"}, 38 | visibility = ["//visibility:public"], 39 | ) 40 | -------------------------------------------------------------------------------- /toolchain/deps.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2020 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 16 | 17 | def bazel_toolchain_dependencies(): 18 | # Load rules_cc if the user has not defined them. 19 | if not native.existing_rule("rules_cc"): 20 | http_archive( 21 | name = "rules_cc", 22 | urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.17/rules_cc-0.0.17.tar.gz"], 23 | sha256 = "abc605dd850f813bb37004b77db20106a19311a96b2da1c92b789da529d28fe1", 24 | strip_prefix = "rules_cc-0.0.17", 25 | ) 26 | 27 | # Load bazel_skylib if the user has not defined them. 28 | if not native.existing_rule("bazel_skylib"): 29 | http_archive( 30 | name = "bazel_skylib", 31 | urls = [ 32 | "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz", 33 | "https://github.com/bazelbuild/bazel-skylib/releases/download/1.7.1/bazel-skylib-1.7.1.tar.gz", 34 | ], 35 | sha256 = "bc283cdfcd526a52c3201279cda4bc298652efa898b10b4db0837dc51652756f", 36 | ) 37 | 38 | # Skip bazel_skylib_workspace because we are not using lib/unittest.bzl 39 | -------------------------------------------------------------------------------- /toolchain/extensions/BUILD.bazel: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bazel-contrib/toolchains_llvm/f1048a300d0be607c7f5092e323bc15b7ef8d8af/toolchain/extensions/BUILD.bazel -------------------------------------------------------------------------------- /toolchain/extensions/llvm.bzl: -------------------------------------------------------------------------------- 1 | """LLVM extension for use with bzlmod""" 2 | 3 | load("@toolchains_llvm//toolchain:rules.bzl", "llvm_toolchain") 4 | load( 5 | "@toolchains_llvm//toolchain/internal:repo.bzl", 6 | _llvm_config_attrs = "llvm_config_attrs", 7 | _llvm_repo_attrs = "llvm_repo_attrs", 8 | ) 9 | load( 10 | "//toolchain/internal:common.bzl", 11 | _is_absolute_path = "is_absolute_path", 12 | ) 13 | 14 | def _root_dict(roots, cls, name, strip_target): 15 | res = {} 16 | for root in roots: 17 | targets = list(root.targets) 18 | if not targets: 19 | targets = [""] 20 | for target in targets: 21 | if res.get(target): 22 | fail("duplicate target '%s' found for %s with name '%s'" % (target, cls, name)) 23 | if bool(root.path) == (root.label): 24 | fail("target '%s' for %s with name '%s' must have either path or label, but not both" % (target, cls, name)) 25 | if root.path: 26 | if not _is_absolute_path(root.path): 27 | fail("target '%s' for %s with name '%s' must have an absolute path value" % (target, cls, name)) 28 | res.update([(target, root.path)]) 29 | continue 30 | label_str = str(root.label) 31 | if strip_target: 32 | label_str = label_str.split(":")[0] 33 | res.update([(target, label_str)]) 34 | 35 | return res 36 | 37 | def _constraint_dict(tags, name): 38 | constraints = {} 39 | 40 | # Gather all the additional constraints for each target 41 | for tag in tags: 42 | targets = list(tag.targets) 43 | if not targets: 44 | targets = [""] 45 | for target in targets: 46 | constraints_for_target = constraints.setdefault(target, []) 47 | constraints_for_target.extend([str(c) for c in tag.constraints]) 48 | 49 | return constraints 50 | 51 | def _llvm_impl_(module_ctx): 52 | for mod in module_ctx.modules: 53 | if not mod.is_root: 54 | fail("Only the root module can use the 'llvm' extension") 55 | toolchain_names = [] 56 | for toolchain_attr in mod.tags.toolchain: 57 | name = toolchain_attr.name 58 | toolchain_names.append(name) 59 | attrs = { 60 | key: getattr(toolchain_attr, key) 61 | for key in dir(toolchain_attr) 62 | if not key.startswith("_") 63 | } 64 | attrs["toolchain_roots"] = _root_dict([root for root in mod.tags.toolchain_root if root.name == name], "toolchain_root", name, True) 65 | attrs["sysroot"] = _root_dict([sysroot for sysroot in mod.tags.sysroot if sysroot.name == name], "sysroot", name, False) 66 | attrs["extra_exec_compatible_with"] = _constraint_dict( 67 | [tag for tag in mod.tags.extra_exec_compatible_with if tag.name == name], 68 | name, 69 | ) 70 | attrs["extra_target_compatible_with"] = _constraint_dict( 71 | [tag for tag in mod.tags.extra_target_compatible_with if tag.name == name], 72 | name, 73 | ) 74 | 75 | llvm_toolchain( 76 | **attrs 77 | ) 78 | 79 | # Check that every defined toolchain_root or sysroot has a corresponding toolchain. 80 | for root in mod.tags.toolchain_root: 81 | if root.name not in toolchain_names: 82 | fail("toolchain_root '%s' does not have a corresponding toolchain" % root.name) 83 | for root in mod.tags.sysroot: 84 | if root.name not in toolchain_names: 85 | fail("sysroot '%s' does not have a corresponding toolchain" % root.name) 86 | 87 | _attrs = { 88 | "name": attr.string(doc = """\ 89 | Base name for the generated repositories, allowing more than one LLVM toolchain to be registered. 90 | """, default = "llvm_toolchain"), 91 | } 92 | _attrs.update(_llvm_config_attrs) 93 | _attrs.update(_llvm_repo_attrs) 94 | 95 | _attrs.pop("toolchain_roots", None) 96 | _attrs.pop("sysroot", None) 97 | 98 | llvm = module_extension( 99 | implementation = _llvm_impl_, 100 | tag_classes = { 101 | "toolchain": tag_class( 102 | attrs = _attrs, 103 | ), 104 | "toolchain_root": tag_class( 105 | attrs = { 106 | "name": attr.string(doc = "Same name as the toolchain tag.", default = "llvm_toolchain"), 107 | "targets": attr.string_list(doc = "Specific targets, if any; empty list means this applies to all."), 108 | "label": attr.label(doc = "Dummy label whose package path is the toolchain root package."), 109 | "path": attr.string(doc = "Absolute path to the toolchain root."), 110 | }, 111 | ), 112 | "sysroot": tag_class( 113 | attrs = { 114 | "name": attr.string(doc = "Same name as the toolchain tag.", default = "llvm_toolchain"), 115 | "targets": attr.string_list(doc = "Specific targets, if any; empty list means this applies to all."), 116 | "label": attr.label(doc = "Label containing the files with its package path as the sysroot path."), 117 | "path": attr.string(doc = "Absolute path to the sysroot."), 118 | }, 119 | ), 120 | "extra_exec_compatible_with": tag_class( 121 | attrs = { 122 | "name": attr.string(doc = "Same name as the toolchain tag.", default = "llvm_toolchain"), 123 | "targets": attr.string_list(doc = "Specific targets, if any; empty list means this applies to all."), 124 | "constraints": attr.label_list(doc = "List of extra constraints to add to exec_compatible_with for the generated toolchains."), 125 | }, 126 | ), 127 | "extra_target_compatible_with": tag_class( 128 | attrs = { 129 | "name": attr.string(doc = "Same name as the toolchain tag.", default = "llvm_toolchain"), 130 | "targets": attr.string_list(doc = "Specific targets, if any; empty list means this applies to all."), 131 | "constraints": attr.label_list(doc = "List of extra constraints to add to target_compatible_with for the generated toolchains."), 132 | }, 133 | ), 134 | }, 135 | ) 136 | -------------------------------------------------------------------------------- /toolchain/internal/BUILD.bazel: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load("@bazel_skylib//rules:diff_test.bzl", "diff_test") 16 | load("llvm_distributions.bzl", "write_distributions") 17 | 18 | exports_files(["template.modulemap"]) 19 | 20 | write_distributions( 21 | name = "llvm_distributions", 22 | testonly = True, 23 | output = "llvm_distributions.out.txt", 24 | select = "llvm_distributions.sel.txt", 25 | visibility = ["//visibility:private"], 26 | ) 27 | 28 | diff_test( 29 | name = "llvm_distributions_output_test", 30 | file1 = "llvm_distributions.golden.out.txt", 31 | file2 = "llvm_distributions.out.txt", 32 | ) 33 | 34 | diff_test( 35 | name = "llvm_distributions_select_test", 36 | file1 = "llvm_distributions.golden.sel.txt", 37 | file2 = "llvm_distributions.sel.txt", 38 | ) 39 | -------------------------------------------------------------------------------- /toolchain/internal/common.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | SUPPORTED_TARGETS = [ 16 | ("linux", "x86_64"), 17 | ("linux", "aarch64"), 18 | ("linux", "armv7"), 19 | ("darwin", "x86_64"), 20 | ("darwin", "aarch64"), 21 | ("none", "wasm32"), 22 | ("none", "wasm64"), 23 | ("none", "x86_64"), 24 | ("wasip1", "wasm32"), 25 | ("wasip1", "wasm64"), 26 | ] 27 | 28 | # These are targets that can build without a sysroot. 29 | SUPPORTED_NO_SYSROOT_TARGETS = [ 30 | ("none", "x86_64"), 31 | ] 32 | 33 | # Map of tool name to its symlinked name in the tools directory. 34 | # See tool_paths in toolchain/cc_toolchain_config.bzl. 35 | _toolchain_tools = { 36 | name: name 37 | for name in [ 38 | "clang-cpp", 39 | "clang-format", 40 | "clang-tidy", 41 | "clangd", 42 | "ld.lld", 43 | "llvm-ar", 44 | "llvm-dwp", 45 | "llvm-profdata", 46 | "llvm-cov", 47 | "llvm-nm", 48 | "llvm-objcopy", 49 | "llvm-objdump", 50 | "llvm-strip", 51 | ] 52 | } 53 | 54 | # Extra tools for Darwin. 55 | _toolchain_tools_darwin = { 56 | # rules_foreign_cc relies on the filename of the linker to set flags. 57 | # Also see archive_flags in cc_toolchain_config.bzl. 58 | # https://github.com/bazelbuild/rules_foreign_cc/blob/5547abc63b12c521113208eea0c5d7f66ba494d4/foreign_cc/built_tools/make_build.bzl#L71 59 | # https://github.com/bazelbuild/rules_foreign_cc/blob/5547abc63b12c521113208eea0c5d7f66ba494d4/foreign_cc/private/cmake_script.bzl#L319 60 | "llvm-libtool-darwin": "libtool", 61 | } 62 | 63 | def exec_os_key(rctx): 64 | info = host_info(rctx) 65 | if info.dist.version == "": 66 | return "%s-%s" % (info.os, info.arch) 67 | else: 68 | return "%s-%s-%s" % (info.dist.name, info.dist.version, info.arch) 69 | 70 | _known_distros = [ 71 | # keep sorted 72 | "almalinux", 73 | "amzn", 74 | "arch", 75 | "centos", 76 | "debian", 77 | "fedora", 78 | "freebsd", 79 | "manjaro", 80 | "ol", 81 | "pop", 82 | "raspbian", 83 | "rhel", 84 | "suse", 85 | "ubuntu", 86 | ] 87 | 88 | def _linux_dist(rctx): 89 | info = {} 90 | for line in rctx.read("/etc/os-release").splitlines(): 91 | parts = line.split("=", 1) 92 | if len(parts) == 1: 93 | continue 94 | info[parts[0]] = parts[1] 95 | 96 | distname = info["ID"].strip('\"') 97 | 98 | if distname not in _known_distros and "ID_LIKE" in info: 99 | for distro in info["ID_LIKE"].strip('\"').split(" "): 100 | if distro in _known_distros: 101 | distname = distro 102 | break 103 | 104 | version = "" 105 | if "VERSION_ID" in info: 106 | version = info["VERSION_ID"].strip('"') 107 | elif "VERSION_CODENAME" in info: 108 | version = info["VERSION_CODENAME"].strip('"') 109 | 110 | return distname, version 111 | 112 | def host_info(rctx): 113 | _os = os(rctx) 114 | _arch = arch(rctx) 115 | 116 | if _os == "linux" and not rctx.attr.exec_os: 117 | dist_name, dist_version = _linux_dist(rctx) 118 | else: 119 | dist_name = os 120 | dist_version = "" 121 | return struct( 122 | arch = _arch, 123 | dist = struct( 124 | name = dist_name, 125 | version = dist_version, 126 | ), 127 | os = _os, 128 | ) 129 | 130 | def os(rctx): 131 | # Less granular host OS name, e.g. linux. 132 | 133 | name = rctx.attr.exec_os 134 | if name: 135 | if name in ("linux", "darwin", "none"): 136 | return name 137 | else: 138 | fail("Unsupported value for exec_os: %s" % name) 139 | return os_from_rctx(rctx) 140 | 141 | def os_from_rctx(rctx): 142 | name = rctx.os.name 143 | if name == "linux": 144 | return "linux" 145 | elif name == "mac os x": 146 | return "darwin" 147 | elif name.startswith("windows"): 148 | return "windows" 149 | fail("Unsupported OS: " + name) 150 | 151 | def os_bzl(os): 152 | # Return the OS string as used in bazel platform constraints. 153 | return {"darwin": "osx", "linux": "linux", "none": "none", "wasip1": "wasi"}[os] 154 | 155 | def arch(rctx): 156 | arch = rctx.attr.exec_arch 157 | if arch: 158 | if arch in ("arm64", "aarch64"): 159 | return "aarch64" 160 | elif arch in ("amd64", "x86_64"): 161 | return "x86_64" 162 | else: 163 | fail("Unsupported value for exec_arch: %s" % arch) 164 | return arch_from_rctx(rctx) 165 | 166 | def arch_from_rctx(rctx): 167 | arch = rctx.os.arch 168 | if arch == "arm64": 169 | return "aarch64" 170 | if arch == "amd64": 171 | return "x86_64" 172 | return arch 173 | 174 | def is_standalone_arch(os, arch): 175 | return os == "none" and arch in ["wasm32", "wasm64"] 176 | 177 | def os_arch_pair(os, arch): 178 | if is_standalone_arch(os, arch): 179 | return arch 180 | return "{}-{}".format(os, arch) 181 | 182 | _supported_os_arch = [os_arch_pair(os, arch) for (os, arch) in SUPPORTED_TARGETS] 183 | 184 | def supported_os_arch_keys(): 185 | return _supported_os_arch 186 | 187 | def check_os_arch_keys(keys): 188 | for k in keys: 189 | if k and k not in _supported_os_arch: 190 | fail("Unsupported {{os}}-{{arch}} key: {key}; valid keys are: {keys}".format( 191 | key = k, 192 | keys = ", ".join(_supported_os_arch), 193 | )) 194 | 195 | def exec_os_arch_dict_value(rctx, attr_name, debug = False): 196 | # Gets a value from a dictionary keyed by host OS and arch. 197 | # Checks for the more specific key, then the less specific, 198 | # and finally the empty key as fallback. 199 | # Returns a tuple of the matching key and value. 200 | 201 | d = getattr(rctx.attr, attr_name) 202 | key1 = exec_os_key(rctx) 203 | if key1 in d: 204 | return (key1, d.get(key1)) 205 | 206 | key2 = os_arch_pair(os(rctx), arch(rctx)) 207 | if debug: 208 | print("`%s` attribute missing for key '%s' in repository '%s'; checking with key '%s'" % (attr_name, key1, rctx.name, key2)) # buildifier: disable=print 209 | if key2 in d: 210 | return (key2, d.get(key2)) 211 | 212 | if debug: 213 | print("`%s` attribute missing for key '%s' in repository '%s'; checking with key ''" % (attr_name, key2, rctx.name)) # buildifier: disable=print 214 | return ("", d.get("")) # Fallback to empty key. 215 | 216 | def canonical_dir_path(path): 217 | if not path.endswith("/"): 218 | return path + "/" 219 | return path 220 | 221 | def is_absolute_path(val): 222 | return val and val[0] == "/" and (len(val) == 1 or val[1] != "/") 223 | 224 | def pkg_name_from_label(label): 225 | s = str(label) 226 | return s[:s.index(":")] 227 | 228 | def pkg_path_from_label(label): 229 | if label.workspace_root: 230 | return label.workspace_root + "/" + label.package 231 | else: 232 | return label.package 233 | 234 | def list_to_string(ls): 235 | if ls == None: 236 | return "None" 237 | return "[{}]".format(", ".join(["\"{}\"".format(d) for d in ls])) 238 | 239 | def attr_dict(attr): 240 | # Returns a mutable dict of attr values from the struct. This is useful to 241 | # return updated attribute values as return values of repository_rule 242 | # implementations. 243 | 244 | tuples = [] 245 | for key in dir(attr): 246 | if not hasattr(attr, key): 247 | fail("key %s not found in attributes" % key) 248 | if key[0] == "_": 249 | # Don't update private attrs. 250 | continue 251 | val = getattr(attr, key) 252 | 253 | # Make mutable copies of frozen types. 254 | typ = type(val) 255 | if typ == "dict": 256 | val = dict(val) 257 | elif typ == "list": 258 | val = list(val) 259 | elif typ == "builtin_function_or_method": 260 | # Functions can not be compared. 261 | continue 262 | 263 | tuples.append((key, val)) 264 | 265 | return dict(tuples) 266 | 267 | def toolchain_tools(os): 268 | tools = dict(_toolchain_tools) 269 | if os == "darwin": 270 | tools.update(_toolchain_tools_darwin) 271 | return tools 272 | -------------------------------------------------------------------------------- /toolchain/internal/llvm_distributions.golden.out.txt: -------------------------------------------------------------------------------- 1 | version: 0.0.0 2 | version: 6.0.0 3 | version: 6.0.1 4 | version: 7.0.0 5 | version: 8.0.0 6 | version: 8.0.1 7 | version: 9.0.0 8 | version: 10.0.0 9 | version: 10.0.1 10 | version: 11.0.0 11 | version: 11.0.1 12 | version: 11.1.0 13 | version: 12.0.0 14 | version: 12.0.1 15 | version: 13.0.0 16 | version: 13.0.1 17 | version: 14.0.0 18 | version: 14.0.1 19 | version: 14.0.2 20 | version: 14.0.3 21 | version: 14.0.4 22 | version: 14.0.5 23 | version: 14.0.6 24 | version: 15.0.0 25 | version: 15.0.1 26 | version: 15.0.2 27 | version: 15.0.3 28 | version: 15.0.4 29 | version: 15.0.5 30 | version: 15.0.6 31 | version: 15.0.7 32 | version: 16.0.0 33 | version: 16.0.1 34 | version: 16.0.2 35 | version: 16.0.3 36 | version: 16.0.4 37 | version: 16.0.5 38 | version: 16.0.6 39 | version: 17.0.1 40 | version: 17.0.2 41 | version: 17.0.3 42 | version: 17.0.4 43 | version: 17.0.5 44 | version: 17.0.6 45 | version: 18.1.0 46 | version: 18.1.1 47 | version: 18.1.2 48 | version: 18.1.3 49 | version: 18.1.4 50 | version: 18.1.5 51 | version: 18.1.6 52 | version: 18.1.7 53 | version: 18.1.8 54 | version: 19.1.0 55 | version: 19.1.1 56 | version: 19.1.2 57 | version: 19.1.3 58 | version: 19.1.4 59 | version: 19.1.5 60 | version: 19.1.6 61 | version: 19.1.7 62 | version: 20.1.0 63 | version: 20.1.1 64 | version: 20.1.2 65 | version: 20.1.3 66 | version: 20.1.4 67 | version: 20.1.5 68 | version: 20.1.6 69 | del: clang+llvm-9.0.0-x86_64-pc-linux-gnu.tar.xz 70 | del: clang+llvm-15.0.2-x86_64-unknown-linux-gnu-sles15.tar.xz 71 | del: clang+llvm-19.1.0-x86_64-pc-windows-msvc.tar.xz 72 | del: clang+llvm-19.1.1-x86_64-pc-windows-msvc.tar.xz 73 | del: clang+llvm-19.1.2-x86_64-pc-windows-msvc.tar.xz 74 | del: clang+llvm-19.1.3-x86_64-pc-windows-msvc.tar.xz 75 | -------------------------------------------------------------------------------- /toolchain/internal/llvm_distributions_select_no_error_test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -euo pipefail 4 | 5 | grep -v "ERROR:" \ 6 | "${TEST_SRCDIR}/_main/toolchain/internal/llvm_distributions.golden.sel.txt" \ 7 | >"${TEST_TMPDIR}/llvm_distributions.golden.sel.no_error.txt" 8 | grep -v "ERROR:" \ 9 | "${TEST_SRCDIR}/_main/toolchain/internal/llvm_distributions.sel.txt" \ 10 | >"${TEST_TMPDIR}/llvm_distributions.sel.no_error.txt" 11 | 12 | if ! diff -U0 \ 13 | "${TEST_TMPDIR}/llvm_distributions.golden.sel.no_error.txt" \ 14 | "${TEST_TMPDIR}/llvm_distributions.sel.no_error.txt"; then 15 | echo "To update golden: " 16 | echo " cp '${TEST_SRCDIR}/_main/toolchain/internal/llvm_distributions.sel.txt' " \ 17 | "'toolchain/internal/llvm_distributions.golden.sel.txt'" 18 | exit 1 19 | fi 20 | -------------------------------------------------------------------------------- /toolchain/internal/repo.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2021 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | load( 15 | "//toolchain/internal:common.bzl", 16 | _os = "os", 17 | _supported_os_arch_keys = "supported_os_arch_keys", 18 | ) 19 | load( 20 | "//toolchain/internal:llvm_distributions.bzl", 21 | _download_llvm = "download_llvm", 22 | ) 23 | 24 | _target_pairs = ", ".join(_supported_os_arch_keys()) 25 | 26 | # Atributes common to both `llvm` and `toolchain` repository rules. 27 | common_attrs = { 28 | "llvm_versions": attr.string_dict( 29 | mandatory = False, 30 | doc = ("LLVM version strings, keyed by host OS release name and architecture, " + 31 | "e.g. darwin-x86_64, darwin-aarch64, ubuntu-20.04-x86_64, etc., or a " + 32 | "less specific OS and arch pair ({}). ".format(_target_pairs) + 33 | "An empty key is used to specify a fallback default for all hosts. " + 34 | "If no `toolchain_roots` is given, then the toolchain will be looked up " + 35 | "in the list of known llvm_distributions using the provided version. " + 36 | "If unset, a default value is set from the `llvm_version` attribute."), 37 | ), 38 | "exec_os": attr.string( 39 | mandatory = False, 40 | doc = "Execution platform OS, if different from host OS.", 41 | ), 42 | "exec_arch": attr.string( 43 | mandatory = False, 44 | doc = "Execution platform architecture, if different from host arch.", 45 | ), 46 | } 47 | 48 | llvm_repo_attrs = dict(common_attrs) 49 | llvm_repo_attrs.update({ 50 | "llvm_version": attr.string( 51 | doc = ("One of the supported versions of LLVM, e.g. 12.0.0; used with the " + 52 | "`auto` value for the `distribution` attribute, and as a default value " + 53 | "for the `llvm_versions` attribute."), 54 | ), 55 | "extra_llvm_distributions": attr.string_dict( 56 | mandatory = False, 57 | doc = ("A dictionary that maps distributions to their SHA256 values. " + 58 | "It allows for simple additon of llvm distributiosn using the " + 59 | "'utils/lvm_checksums.sh' tool. This also allows to use the " + 60 | "distributions lists of future toolchain versions."), 61 | ), 62 | "urls": attr.string_list_dict( 63 | mandatory = False, 64 | doc = ("URLs to LLVM pre-built binary distribution archives, keyed by host OS " + 65 | "release name and architecture, e.g. darwin-x86_64, darwin-aarch64, " + 66 | "ubuntu-20.04-x86_64, etc., or a less specific OS and arch pair " + 67 | "({}). ".format(_target_pairs) + 68 | "May also need the `strip_prefix` attribute. " + 69 | "Consider also setting the `sha256` attribute. An empty key is " + 70 | "used to specify a fallback default for all hosts. This attribute " + 71 | "overrides `distribution`, `llvm_version`, `llvm_mirror` and " + 72 | "`alternative_llvm_sources` attributes if the host OS key is present."), 73 | ), 74 | "sha256": attr.string_dict( 75 | mandatory = False, 76 | doc = "The expected SHA-256 of the file downloaded as per the `urls` attribute.", 77 | ), 78 | "strip_prefix": attr.string_dict( 79 | mandatory = False, 80 | doc = "The prefix to strip from the extracted file from the `urls` attribute.", 81 | ), 82 | "distribution": attr.string( 83 | default = "auto", 84 | doc = ("LLVM pre-built binary distribution filename, must be one " + 85 | "listed on http://releases.llvm.org/download.html for the version " + 86 | "specified in the `llvm_version` attribute. A special value of " + 87 | "'auto' tries to detect the version based on host OS."), 88 | ), 89 | "llvm_mirror": attr.string( 90 | doc = "Base URL for an LLVM release mirror." + 91 | "\n\n" + 92 | "This mirror must follow the same structure as the official LLVM release " + 93 | "sources (`releases.llvm.org` for versions <= 9, `llvm/llvm-project` GitHub " + 94 | "releases for newer versions)." + 95 | "\n\n" + 96 | "If provided, this mirror will be given precedence over the official LLVM release " + 97 | "sources (see: " + 98 | "https://github.com/bazel-contrib/toolchains_llvm/toolchain/internal/llvm_distributions.bzl).", 99 | ), 100 | "alternative_llvm_sources": attr.string_list( 101 | doc = "Patterns for alternative LLVM release sources. Unlike URLs specified for `llvm_mirror` " + 102 | "these do not have to follow the same structure as the official LLVM release sources." + 103 | "\n\n" + 104 | "Patterns may include `{llvm_version}` (which will be substituted for the full LLVM " + 105 | "version, i.e. 13.0.0) and `{basename}` (which will be replaced with the filename " + 106 | "used by the official LLVM release sources for a particular distribution; i.e. " + 107 | "`llvm-13.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz`)." + 108 | "\n\n" + 109 | "As with `llvm_mirror`, these sources will take precedence over the official LLVM " + 110 | "release sources.", 111 | ), 112 | "libclang_rt": attr.label_keyed_string_dict( 113 | mandatory = False, 114 | doc = ("Additional libclang_rt libraries to overlay into the downloaded LLVM " + 115 | "distribution. The key is the label of a libclang_rt library, " + 116 | "and the value is `\"{llvm_target_name}/{library_name}.a\"`."), 117 | ), 118 | "netrc": attr.string( 119 | mandatory = False, 120 | doc = "Path to the netrc file for authenticated LLVM URL downloads.", 121 | ), 122 | "auth_patterns": attr.string_dict( 123 | mandatory = False, 124 | doc = "An optional dict mapping host names to custom authorization patterns.", 125 | ), 126 | }) 127 | 128 | _compiler_configuration_attrs = { 129 | "sysroot": attr.string_dict( 130 | mandatory = False, 131 | doc = ("System path or fileset, for each target OS and arch pair you want to support " + 132 | "({}), ".format(_target_pairs) + 133 | "used to indicate the set of files that form the sysroot for the compiler. " + 134 | "If the value begins with exactly one forward slash '/', then the value is " + 135 | "assumed to be a system path. Else, the value will be assumed to be a label " + 136 | "containing the files and the sysroot path will be taken as the path to the " + 137 | "package of this label."), 138 | ), 139 | "cxx_builtin_include_directories": attr.string_list_dict( 140 | mandatory = False, 141 | doc = ("Additional builtin include directories to be added to the default system " + 142 | "directories, for each target OS and arch pair you want to support " + 143 | "({}); ".format(_target_pairs) + 144 | "see documentation for bazel's create_cc_toolchain_config_info."), 145 | ), 146 | "stdlib": attr.string_dict( 147 | mandatory = False, 148 | doc = ("stdlib implementation, for each target OS and arch pair you want to support " + 149 | "({}), ".format(_target_pairs) + 150 | "linked to the compiled binaries. An empty key can be used to specify a " + 151 | "value for all target pairs. Possible values are `builtin-libc++` (default) " + 152 | "which uses the libc++ shipped with clang, `libc++` which uses libc++ available on " + 153 | "the host or sysroot, `stdc++` which uses libstdc++ available on the host or " + 154 | "sysroot, and `none` which uses `-nostdlib` with the compiler."), 155 | ), 156 | "cxx_standard": attr.string_dict( 157 | mandatory = False, 158 | doc = ("C++ standard, for each target OS and arch pair you want to support " + 159 | "({}), ".format(_target_pairs) + 160 | "passed as `-std` flag to the compiler. An empty key can be used to specify a " + 161 | "value for all target pairs. Default value is c++17."), 162 | ), 163 | # For default values of all the below flags overrides, consult 164 | # cc_toolchain_config.bzl in this directory. 165 | "compile_flags": attr.string_list_dict( 166 | mandatory = False, 167 | doc = ("Override for compile_flags, replacing the default values. " + 168 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 169 | "to the root LLVM distribution directory. Provide one list for each " + 170 | "target OS and arch pair you want to override " + 171 | "({}); empty key overrides all.".format(_target_pairs)), 172 | ), 173 | "conly_flags": attr.string_list_dict( 174 | mandatory = False, 175 | doc = ("Extra flags for compiling C (not C++) files, " + 176 | "for each target OS and arch pair you want to support " + 177 | "({}), ".format(", ".join(_supported_os_arch_keys())) + "."), 178 | ), 179 | "cxx_flags": attr.string_list_dict( 180 | mandatory = False, 181 | doc = ("Override for cxx_flags, replacing the default values. " + 182 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 183 | "to the root LLVM distribution directory. Provide one list for each " + 184 | "target OS and arch pair you want to override " + 185 | "({}); empty key overrides all.".format(_target_pairs)), 186 | ), 187 | "link_flags": attr.string_list_dict( 188 | mandatory = False, 189 | doc = ("Override for link_flags, replacing the default values. " + 190 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 191 | "to the root LLVM distribution directory. Provide one list for each " + 192 | "target OS and arch pair you want to override " + 193 | "({}); empty key overrides all.".format(_target_pairs)), 194 | ), 195 | "archive_flags": attr.string_list_dict( 196 | mandatory = False, 197 | doc = ("Override for archive_flags, replacing the default values. " + 198 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 199 | "to the root LLVM distribution directory. Provide one list for each " + 200 | "target OS and arch pair you want to override " + 201 | "({}); empty key overrides all.".format(_target_pairs)), 202 | ), 203 | "link_libs": attr.string_list_dict( 204 | mandatory = False, 205 | doc = ("Override for link_libs, replacing the default values. " + 206 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 207 | "to the root LLVM distribution directory. Provide one list for each " + 208 | "target OS and arch pair you want to override " + 209 | "({}); empty key overrides all.".format(_target_pairs)), 210 | ), 211 | "opt_compile_flags": attr.string_list_dict( 212 | mandatory = False, 213 | doc = ("Override for opt_compile_flags, replacing the default values. " + 214 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 215 | "to the root LLVM distribution directory. Provide one list for each " + 216 | "target OS and arch pair you want to override " + 217 | "({}); empty key overrides all.".format(_target_pairs)), 218 | ), 219 | "opt_link_flags": attr.string_list_dict( 220 | mandatory = False, 221 | doc = ("Override for opt_link_flags, replacing the default values. " + 222 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 223 | "to the root LLVM distribution directory. Provide one list for each " + 224 | "target OS and arch pair you want to override " + 225 | "({}); empty key overrides all.".format(_target_pairs)), 226 | ), 227 | "dbg_compile_flags": attr.string_list_dict( 228 | mandatory = False, 229 | doc = ("Override for dbg_compile_flags, replacing the default values. " + 230 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 231 | "to the root LLVM distribution directory. Provide one list for each " + 232 | "target OS and arch pair you want to override " + 233 | "({}); empty key overrides all.".format(_target_pairs)), 234 | ), 235 | "coverage_compile_flags": attr.string_list_dict( 236 | mandatory = False, 237 | doc = ("Override for coverage_compile_flags, replacing the default values. " + 238 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 239 | "to the root LLVM distribution directory. Provide one list for each " + 240 | "target OS and arch pair you want to override " + 241 | "({}); empty key overrides all.".format(_target_pairs)), 242 | ), 243 | "coverage_link_flags": attr.string_list_dict( 244 | mandatory = False, 245 | doc = ("Override for coverage_link_flags, replacing the default values. " + 246 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 247 | "to the root LLVM distribution directory. Provide one list for each " + 248 | "target OS and arch pair you want to override " + 249 | "({}); empty key overrides all.".format(_target_pairs)), 250 | ), 251 | "unfiltered_compile_flags": attr.string_list_dict( 252 | mandatory = False, 253 | doc = ("Override for unfiltered_compile_flags, replacing the default values. " + 254 | "`{toolchain_path_prefix}` in the flags will be substituted by the path " + 255 | "to the root LLVM distribution directory. Provide one list for each " + 256 | "target OS and arch pair you want to override " + 257 | "({}); empty key overrides all.".format(_target_pairs)), 258 | ), 259 | "target_settings": attr.string_list_dict( 260 | mandatory = False, 261 | doc = ("Override the toolchain's `target_settings` attribute."), 262 | ), 263 | "extra_compiler_files": attr.label( 264 | mandatory = False, 265 | doc = ("Files to be made available in the sandbox for compile actions. " + 266 | "Mostly useful for providing files containing lists of flags, e.g. " + 267 | "sanitizer ignorelists."), 268 | ), 269 | } 270 | 271 | llvm_config_attrs = dict(common_attrs) 272 | llvm_config_attrs.update(_compiler_configuration_attrs) 273 | llvm_config_attrs.update({ 274 | "toolchain_roots": attr.string_dict( 275 | mandatory = False, 276 | # TODO: Ideally, we should be taking a filegroup label here instead of a package path, but 277 | # we ultimately need to subset the files to be more selective in what we include in the 278 | # sandbox for which operations, and it is not straightforward to subset a filegroup. 279 | doc = ("System or package path, keyed by host OS release name and architecture, e.g. " + 280 | "darwin-x86_64, darwin-aarch64, ubuntu-20.04-x86_64, etc., or a less specific " + 281 | "OS and arch pair ({}), to be used as the LLVM toolchain ".format(_target_pairs) + 282 | "distributions. An empty key can be used to specify a fallback default for " + 283 | "all hosts, e.g. with the llvm_toolchain_repo rule. " + 284 | "If the value begins with exactly one forward slash '/', then the value is " + 285 | "assumed to be a system path and the toolchain is configured to use absolute " + 286 | "paths. Else, the value will be assumed to be a bazel package containing the " + 287 | "filegroup targets as in BUILD.llvm_repo."), 288 | ), 289 | "absolute_paths": attr.bool( 290 | default = False, 291 | doc = "Use absolute paths in the toolchain. Avoids sandbox overhead.", 292 | ), 293 | "extra_exec_compatible_with": attr.string_list_dict( 294 | mandatory = False, 295 | doc = "Extra constraints to be added to exec_compatible_with for each target", 296 | ), 297 | "extra_target_compatible_with": attr.string_list_dict( 298 | mandatory = False, 299 | doc = "Extra constraints to be added to target_compatible_with for each target", 300 | ), 301 | "_cc_toolchain_config_bzl": attr.label( 302 | default = "//toolchain:cc_toolchain_config.bzl", 303 | ), 304 | "_toolchains_bzl_tpl": attr.label( 305 | default = "//toolchain:toolchains.bzl.tpl", 306 | ), 307 | "_build_toolchain_tpl": attr.label( 308 | default = "//toolchain:BUILD.toolchain.tpl", 309 | ), 310 | "_darwin_cc_wrapper_sh_tpl": attr.label( 311 | default = "//toolchain:osx_cc_wrapper.sh.tpl", 312 | ), 313 | "_cc_wrapper_sh_tpl": attr.label( 314 | default = "//toolchain:cc_wrapper.sh.tpl", 315 | ), 316 | }) 317 | 318 | def llvm_repo_impl(rctx): 319 | os = _os(rctx) 320 | if os == "windows": 321 | rctx.file("BUILD.bazel", executable = False) 322 | return None 323 | 324 | rctx.file( 325 | "BUILD.bazel", 326 | content = rctx.read(Label("//toolchain:BUILD.llvm_repo")), 327 | executable = False, 328 | ) 329 | 330 | updated_attrs = _download_llvm(rctx) 331 | 332 | # We try to avoid patches to the downloaded repo so that it is easier for 333 | # users to bring their own LLVM distribution through `http_archive`. If we 334 | # do want to make changes, then we should do it through a patch file, and 335 | # document it for users of toolchain_roots attribute. 336 | 337 | return updated_attrs 338 | -------------------------------------------------------------------------------- /toolchain/internal/sysroot.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load( 16 | "//toolchain/internal:common.bzl", 17 | _canonical_dir_path = "canonical_dir_path", 18 | _is_absolute_path = "is_absolute_path", 19 | _os_arch_pair = "os_arch_pair", 20 | _pkg_name_from_label = "pkg_name_from_label", 21 | _pkg_path_from_label = "pkg_path_from_label", 22 | _supported_targets = "SUPPORTED_TARGETS", 23 | ) 24 | 25 | def _darwin_sdk_path(rctx): 26 | exec_result = rctx.execute(["/usr/bin/xcrun", "--show-sdk-path", "--sdk", "macosx"]) 27 | if exec_result.return_code: 28 | fail("Failed to detect OSX SDK path: \n%s\n%s" % (exec_result.stdout, exec_result.stderr)) 29 | if exec_result.stderr: 30 | print(exec_result.stderr) # buildifier: disable=print 31 | return exec_result.stdout.strip() 32 | 33 | # Default sysroot path can be used when the user has not provided an explicit 34 | # sysroot for the target, and when host platform is the same as target 35 | # platform. 36 | def default_sysroot_path(rctx, os): 37 | if os == "darwin": 38 | return _darwin_sdk_path(rctx) 39 | else: 40 | return "" 41 | 42 | # Return the sysroot path and the label to the files, if sysroot is not a system path. 43 | def _sysroot_path(sysroot_dict, os, arch): 44 | sysroot = sysroot_dict.get(_os_arch_pair(os, arch)) 45 | if not sysroot: 46 | return (None, None) 47 | 48 | # If the sysroot is an absolute path, use it as-is. Check for things that 49 | # start with "/" and not "//" to identify absolute paths, but also support 50 | # passing the sysroot as "/" to indicate the root directory. 51 | if _is_absolute_path(sysroot): 52 | return (sysroot, None) 53 | 54 | label = Label(sysroot) 55 | sysroot_path = _pkg_path_from_label(label) 56 | return (sysroot_path, label) 57 | 58 | # Return dictionaries for paths (relative or absolute) and labels if the 59 | # sysroot needs to be included in the build sandbox. 60 | def sysroot_paths_dict(rctx, sysroot_dict, use_absolute_paths): 61 | paths_dict = dict() 62 | labels_dict = dict() 63 | for (target_os, target_arch) in _supported_targets: 64 | path, label = _sysroot_path( 65 | sysroot_dict, 66 | target_os, 67 | target_arch, 68 | ) 69 | if not path: 70 | continue 71 | 72 | if label and use_absolute_paths: 73 | # Get a label for a regular file in the sysroot package. 74 | # Exact target does not matter. 75 | label = Label(_pkg_name_from_label(label) + ":BUILD.bazel") 76 | path = _canonical_dir_path(str(rctx.path(label).dirname)) 77 | label = None 78 | 79 | target_pair = _os_arch_pair(target_os, target_arch) 80 | paths_dict[target_pair] = path 81 | labels_dict[target_pair] = label 82 | 83 | return paths_dict, labels_dict 84 | -------------------------------------------------------------------------------- /toolchain/internal/system_module_map.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2024 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load("@bazel_skylib//lib:paths.bzl", "paths") 16 | 17 | def _textual_header(file, *, include_prefixes, execroot_prefix): 18 | path = file.path 19 | for include_prefix in include_prefixes: 20 | if path.startswith(include_prefix): 21 | return " textual header \"{}{}\"".format(execroot_prefix, path) 22 | 23 | # The file is not under any of the include prefixes, 24 | return None 25 | 26 | def _umbrella_submodule(path): 27 | return """ 28 | module "{path}" {{ 29 | umbrella "{path}" 30 | }}""".format(path = path) 31 | 32 | def _system_module_map(ctx): 33 | module_map = ctx.actions.declare_file(ctx.attr.name + ".modulemap") 34 | 35 | absolute_path_dirs = [] 36 | relative_include_prefixes = [] 37 | for include_dir in ctx.attr.cxx_builtin_include_directories: 38 | if ctx.attr.sysroot_path and include_dir.startswith("%sysroot%"): 39 | include_dir = ctx.attr.sysroot_path + include_dir[len("%sysroot%"):] 40 | if include_dir.startswith("%workspace%/"): 41 | include_dir = include_dir.removeprefix("%workspace%/") 42 | include_dir = paths.normalize(include_dir).replace("//", "/") 43 | if include_dir.startswith("/"): 44 | absolute_path_dirs.append(include_dir) 45 | else: 46 | relative_include_prefixes.append(include_dir + "/") 47 | 48 | # The builtin include directories are relative to the execroot, but the 49 | # paths in the module map must be relative to the directory that contains 50 | # the module map. 51 | execroot_prefix = (module_map.dirname.count("/") + 1) * "../" 52 | textual_header_closure = lambda file: _textual_header( 53 | file, 54 | include_prefixes = relative_include_prefixes, 55 | execroot_prefix = execroot_prefix, 56 | ) 57 | 58 | template_dict = ctx.actions.template_dict() 59 | template_dict.add_joined( 60 | "%textual_headers%", 61 | ctx.attr.cxx_builtin_include_files[DefaultInfo].files, 62 | join_with = "\n", 63 | map_each = textual_header_closure, 64 | allow_closure = True, 65 | ) 66 | template_dict.add_joined( 67 | "%umbrella_submodules%", 68 | depset(absolute_path_dirs), 69 | join_with = "\n", 70 | map_each = _umbrella_submodule, 71 | ) 72 | 73 | ctx.actions.expand_template( 74 | template = ctx.file._module_map_template, 75 | output = module_map, 76 | computed_substitutions = template_dict, 77 | ) 78 | return DefaultInfo(files = depset([module_map])) 79 | 80 | system_module_map = rule( 81 | doc = """Generates a Clang module map for the toolchain and sysroot headers. 82 | 83 | Files under the configured built-in include directories that are managed by 84 | Bazel are included as textual headers. All directories referenced by 85 | absolute paths are included as umbrella submodules.""", 86 | implementation = _system_module_map, 87 | attrs = { 88 | "cxx_builtin_include_files": attr.label(mandatory = True), 89 | "cxx_builtin_include_directories": attr.string_list(mandatory = True), 90 | "sysroot_path": attr.string(), 91 | "_module_map_template": attr.label( 92 | default = "template.modulemap", 93 | allow_single_file = True, 94 | ), 95 | }, 96 | ) 97 | -------------------------------------------------------------------------------- /toolchain/internal/template.modulemap: -------------------------------------------------------------------------------- 1 | module "crosstool" [system] { 2 | %textual_headers% 3 | %umbrella_submodules% 4 | } 5 | -------------------------------------------------------------------------------- /toolchain/osx_cc_wrapper.sh.tpl: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2015 The Bazel Authors. All rights reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # OS X relpath is not really working. This is a wrapper script around gcc 18 | # to simulate relpath behavior. 19 | # 20 | # This wrapper uses install_name_tool to replace all paths in the binary 21 | # (bazel-out/.../path/to/original/library.so) by the paths relative to 22 | # the binary. It parses the command line to behave as rpath is supposed 23 | # to work. 24 | # 25 | # See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac 26 | # on how to set those paths for Mach-O binaries. 27 | 28 | # shellcheck disable=SC1083 29 | 30 | set -euo pipefail 31 | 32 | INSTALL_NAME_TOOL="/usr/bin/install_name_tool" 33 | 34 | LIBS= 35 | LIB_DIRS= 36 | RPATHS= 37 | OUTPUT= 38 | CLEANUP_FILES=() 39 | 40 | function cleanup() { 41 | if [[ ${#CLEANUP_FILES[@]} -gt 0 ]]; then 42 | rm -f "${CLEANUP_FILES[@]}" 43 | fi 44 | } 45 | 46 | trap cleanup EXIT 47 | 48 | function parse_option() { 49 | local -r opt="$1" 50 | if [[ ${OUTPUT} == "1" ]]; then 51 | OUTPUT=${opt} 52 | elif [[ ${opt} =~ ^-l(.*)$ ]]; then 53 | LIBS="${BASH_REMATCH[1]} ${LIBS}" 54 | elif [[ ${opt} =~ ^-L(.*)$ ]]; then 55 | LIB_DIRS="${BASH_REMATCH[1]} ${LIB_DIRS}" 56 | elif [[ ${opt} =~ ^\@loader_path/(.*)$ ]]; then 57 | RPATHS="${BASH_REMATCH[1]} ${RPATHS}" 58 | elif [[ ${opt} =~ ^-Wl,-rpath,\@loader_path/(.*)$ ]]; then 59 | RPATHS="${BASH_REMATCH[1]} ${RPATHS}" 60 | elif [[ ${opt} == "-o" ]]; then 61 | # output is coming 62 | OUTPUT=1 63 | fi 64 | } 65 | 66 | if [[ -f %{toolchain_path_prefix}bin/clang ]]; then 67 | execroot_path="" 68 | execroot_abs_path="${PWD}/" 69 | elif [[ ${BASH_SOURCE[0]} == "/"* ]]; then 70 | # Some consumers of `CcToolchainConfigInfo` (e.g. `cmake` from rules_foreign_cc) 71 | # change CWD and call $CC (this script) with its absolute path. 72 | # For cases like this, we'll try to find `clang` through an absolute path. 73 | # This script is at _execroot_/external/_repo_name_/bin/cc_wrapper.sh 74 | execroot_path="${BASH_SOURCE[0]%/*/*/*/*}/" 75 | execroot_abs_path="$(cd "${execroot_path}" && pwd -P)/" 76 | else 77 | echo >&2 "ERROR: could not find clang; PWD=\"${PWD}\"; PATH=\"${PATH}\"." 78 | exit 5 79 | fi 80 | 81 | function sanitize_option() { 82 | local -r opt=$1 83 | if [[ ${opt} == */cc_wrapper.sh ]]; then 84 | printf "%s" "${execroot_path}%{toolchain_path_prefix}bin/clang" 85 | elif [[ ${opt} == "-fuse-ld=ld64.lld" ]]; then 86 | echo "--ld-path=${execroot_abs_path}%{toolchain_path_prefix}bin/ld64.lld" 87 | elif [[ ${opt} =~ ^-fsanitize-(ignore|black)list=[^/] ]]; then 88 | # shellcheck disable=SC2206 89 | parts=(${opt/=/ }) # Split flag name and value into array. 90 | printf "%s" "${parts[0]}=${execroot_path}${parts[1]}" 91 | else 92 | printf "%s" "${opt}" 93 | fi 94 | } 95 | 96 | cmd=() 97 | for ((i = 0; i <= $#; i++)); do 98 | if [[ ${!i} == @* && -r "${i:1}" ]]; then 99 | tmpfile=$(mktemp) 100 | CLEANUP_FILES+=("${tmpfile}") 101 | while IFS= read -r opt; do 102 | if [[ ${opt} == "-fuse-ld=ld64.lld" ]]; then 103 | echo "-fuse-ld=lld" >>"${tmpfile}" 104 | fi 105 | opt="$( 106 | set -e 107 | sanitize_option "${opt}" 108 | )" 109 | parse_option "${opt}" >>"${tmpfile}" 110 | done <"${!i:1}" 111 | cmd+=("@${tmpfile}") 112 | else 113 | opt="$( 114 | set -e 115 | sanitize_option "${!i}" 116 | )" 117 | parse_option "${opt}" 118 | cmd+=("${opt}") 119 | fi 120 | done 121 | 122 | # On macOS, we use ld as the linker for single-platform builds (i.e., when not 123 | # cross-compiling). Some applications may remove /usr/bin from PATH before 124 | # calling this script, which would make /usr/bin/ld unreachable. For example, 125 | # rules_rust does not set PATH (unless the user explicitly sets PATH in env 126 | # through attributes) [1] when calling rustc, and rustc does not replace an 127 | # unset PATH with a reasonable default either ([2], [3]), which results in CC 128 | # being called with PATH={sysroot}/{rust_lib}/bin. Note that rules_cc [4] and 129 | # rules_go [5] do ensure that /usr/bin is in PATH. 130 | # [1]: https://github.com/bazelbuild/rules_rust/blob/e589105b4e8181dd1d0d8ccaa0cf3267efb06e86/cargo/cargo_build_script.bzl#L66-L68 131 | # [2]: https://github.com/rust-lang/rust/blob/1c03f0d0ba4fee54b7aa458f4d3ad989d8bf7b34/compiler/rustc_session/src/session.rs#L804-L813 132 | # [3]: https://github.com/rust-lang/rust/blob/1c03f0d0ba4fee54b7aa458f4d3ad989d8bf7b34/compiler/rustc_codegen_ssa/src/back/link.rs#L640-L645 133 | # [4]: https://cs.opensource.google/bazel/bazel/+/master:src/main/java/com/google/devtools/build/lib/bazel/rules/BazelRuleClassProvider.java;l=529;drc=72caead7b428fd50164079956ec368fc54a9567c 134 | # [5]: https://github.com/bazelbuild/rules_go/blob/63dfd99403076331fef0775d52a8039d502d4115/go/private/context.bzl#L434 135 | # Let's restore /usr/bin to PATH in such cases. Note that /usr/bin is not a 136 | # writeable directory on macOS even with sudo privileges, so it should be safe 137 | # to add it to PATH even when the application wants to use a very strict PATH. 138 | if [[ ":${PATH}:" != *":/usr/bin:"* ]]; then 139 | PATH="${PATH}:/usr/bin" 140 | fi 141 | 142 | # Call the C++ compiler. 143 | "${cmd[@]}" 144 | 145 | function get_library_path() { 146 | for libdir in ${LIB_DIRS}; do 147 | if [[ -f "${libdir}/lib$1".so ]]; then 148 | echo "${libdir}/lib$1.so" 149 | elif [[ -f "${libdir}"/lib"$1".dylib ]]; then 150 | echo "${libdir}/lib$1.dylib" 151 | fi 152 | done 153 | } 154 | 155 | # A convenient method to return the actual path even for non symlinks 156 | # and multi-level symlinks. 157 | function get_realpath() { 158 | local previous="$1" 159 | local next 160 | next="$(readlink "${previous}")" 161 | while [[ -n ${next} ]]; do 162 | previous="${next}" 163 | next=$(readlink "${previous}") 164 | done 165 | echo "${previous}" 166 | } 167 | 168 | # Get the path of a lib inside a tool 169 | function get_otool_path() { 170 | # the lib path is the path of the original lib relative to the workspace 171 | get_realpath "$1" | sed 's|^.*/bazel-out/|bazel-out/|' 172 | } 173 | 174 | # Do replacements in the output 175 | for rpath in ${RPATHS}; do 176 | for lib in ${LIBS}; do 177 | unset libname 178 | if [[ -f "$(dirname "${OUTPUT}")/${rpath}/lib${lib}.so" ]]; then 179 | libname="lib${lib}.so" 180 | elif [[ -f "$(dirname "${OUTPUT}")/${rpath}/lib${lib}.dylib" ]]; then 181 | libname="lib${lib}.dylib" 182 | fi 183 | # ${libname-} --> return $libname if defined, or undefined otherwise. This is to make 184 | # this set -e friendly 185 | if [[ -n ${libname-} ]]; then 186 | libpath="$(get_library_path "${lib}")" 187 | if [[ -n ${libpath} ]]; then 188 | otool_path="$(get_otool_path "${libpath}")" 189 | "${INSTALL_NAME_TOOL}" -change "${otool_path}" \ 190 | "@loader_path/${rpath}/${libname}" "${OUTPUT}" 191 | fi 192 | fi 193 | done 194 | done 195 | -------------------------------------------------------------------------------- /toolchain/rules.bzl: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | load( 16 | "//toolchain/internal:configure.bzl", 17 | _llvm_config_impl = "llvm_config_impl", 18 | ) 19 | load( 20 | "//toolchain/internal:repo.bzl", 21 | _common_attrs = "common_attrs", 22 | _llvm_config_attrs = "llvm_config_attrs", 23 | _llvm_repo_attrs = "llvm_repo_attrs", 24 | _llvm_repo_impl = "llvm_repo_impl", 25 | ) 26 | 27 | llvm = repository_rule( 28 | attrs = _llvm_repo_attrs, 29 | local = False, 30 | implementation = _llvm_repo_impl, 31 | ) 32 | 33 | toolchain = repository_rule( 34 | attrs = _llvm_config_attrs, 35 | local = True, 36 | configure = True, 37 | implementation = _llvm_config_impl, 38 | ) 39 | 40 | def llvm_toolchain(name, **kwargs): 41 | if kwargs.get("llvm_version") == kwargs.get("llvm_versions"): 42 | fail("Exactly one of llvm_version or llvm_versions must be set") 43 | 44 | if not kwargs.get("toolchain_roots"): 45 | llvm_args = { 46 | k: v 47 | for k, v in kwargs.items() 48 | if (k not in _llvm_config_attrs.keys()) or (k in _common_attrs.keys()) 49 | } 50 | llvm(name = name + "_llvm", **llvm_args) 51 | 52 | if not kwargs.get("llvm_versions"): 53 | kwargs.update(llvm_versions = {"": kwargs.get("llvm_version")}) 54 | 55 | toolchain_args = { 56 | k: v 57 | for k, v in kwargs.items() 58 | if (k not in _llvm_repo_attrs.keys()) or (k in _common_attrs.keys()) 59 | } 60 | toolchain(name = name, **toolchain_args) 61 | -------------------------------------------------------------------------------- /toolchain/toolchains.bzl.tpl: -------------------------------------------------------------------------------- 1 | # Copyright 2018 The Bazel Authors. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | def llvm_register_toolchains(): 16 | native.register_toolchains( 17 | %{toolchain_labels} 18 | ) 19 | -------------------------------------------------------------------------------- /utils/llvm_checksums.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Copyright 2022 The Bazel Authors. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | set -euo pipefail 17 | 18 | use_github_host=0 19 | tmp_dir= 20 | 21 | while getopts "t:v:gh" opt; do 22 | case "${opt}" in 23 | "t") tmp_dir="${OPTARG}" ;; 24 | "v") llvm_version="${OPTARG}" ;; 25 | "g") use_github_host=1 ;; 26 | "h") 27 | echo "Usage:" 28 | echo "-t - Optional: Specify a temp directory to download distributions to." 29 | echo "-v - Version of clang+llvm to use." 30 | echo "-g - Use github to download releases." 31 | exit 2 32 | ;; 33 | *) 34 | echo "invalid option: -${OPTARG}" 35 | exit 1 36 | ;; 37 | esac 38 | done 39 | 40 | if [[ -z ${llvm_version-} ]]; then 41 | echo "Usage: ${BASH_SOURCE[0]} [-t ] [-g] -v " 42 | exit 1 43 | fi 44 | 45 | cleanup() { 46 | rc=$? 47 | rm -rf "${tmp_dir}" 48 | exit "${rc}" 49 | } 50 | 51 | if [[ -z "${tmp_dir}" ]]; then 52 | tmp_dir="$(mktemp -d)" 53 | echo "Using temp dir: '${tmp_dir}'" 54 | trap 'cleanup' INT HUP QUIT TERM EXIT 55 | elif [[ ! -r "${tmp_dir}" ]]; then 56 | echo "Temp directory does not exist: '${tmp_dir}'." 57 | exit 2 58 | fi 59 | 60 | llvm_host() { 61 | local url_base="releases.llvm.org/${llvm_version}" 62 | output_dir="${tmp_dir}/${url_base}" 63 | wget --recursive --level 1 --directory-prefix="${tmp_dir}" \ 64 | --accept-regex "(clang%2bllvm|LLVM)-.*tar.(xz|gz)$" "http://${url_base}/" 65 | } 66 | 67 | github_host() { 68 | output_dir="${tmp_dir}/${llvm_version}" 69 | mkdir -p "${output_dir}" 70 | ( 71 | cd "${output_dir}" 72 | curl -s "https://api.github.com/repos/llvm/llvm-project/releases/tags/llvmorg-${llvm_version}" | 73 | tee ./releases.json | 74 | jq '.assets[]|select(any(.name; test("^(clang[+]llvm|LLVM)-.*tar.(xz|gz)$")))|.browser_download_url' | 75 | tee ./filtered_urls.txt | 76 | xargs -n1 curl -L -O -C - 77 | ) 78 | } 79 | 80 | if ((use_github_host)); then 81 | github_host 82 | else 83 | llvm_host 84 | fi 85 | 86 | echo "" 87 | echo "====" 88 | echo "Checksums for clang+llvm distributions are (${output_dir}):" 89 | echo " # ${llvm_version}" 90 | find "${output_dir}" -type f \( -name 'clang%2?llvm-*.tar.*' -o -name 'LLVM-*.tar.*' \) \( -name '*.gz' -o -name '*.xz' \) -exec shasum -a 256 {} \; | 91 | sed -e "s@${output_dir}/@@" | 92 | awk '{ printf " \"%s\": \"%s\",\n", $2, $1 }' | 93 | sed -e 's/%2[Bb]/+/' | 94 | sort 95 | --------------------------------------------------------------------------------