commit 408474baa30039b6c5ba35c9545e2edcf644bb3d Author: Siddhartha Bagaria Date: Sat May 12 00:48:27 2018 +0000 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd1297c --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/bazel-* +travis/bazel-* +.bazelrc diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..19a6492 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,20 @@ +os: + - linux + - osx + +sudo: false +dist: trusty + +osx_image: xcode9.3 + +addons: + apt: + sources: + - sourceline: 'deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8' + key_url: 'https://bazel.build/bazel-release.pub.gpg' + packages: + - bazel + +script: + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install bazel; fi + - cd travis && tests/run_tests.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..73d30cd --- /dev/null +++ b/README.md @@ -0,0 +1,62 @@ +LLVM toolchain for Bazel [![Build Status](https://travis-ci.org/grailbio/bazel-toolchain.svg?branch=master)](https://travis-ci.org/grailbio/bazel-toolchain) +================= + +To use this toolchain, include this section in your WORKSPACE: +```python +# Change master to the git tag you want. +http_archive( + name = "com_grail_bazel_toolchain", + strip_prefix = "bazel-toolchain-master", + urls = ["https://github.com/grailbio/bazel-toolchain/archive/master.tar.gz"], +) + +load("@com_grail_bazel_toolchain//toolchain:configure.bzl", "llvm_toolchain") + +llvm_toolchain( + name = "llvm_toolchain", + llvm_version = "6.0.0", + absolute_paths = True, +) +``` + +The in-built dictionary of URLs is good for Ubuntu 16.04 and macOS 10.13. For +other environments, provide your own sources through the `urls` attribute. + +For making changes to default settings for these toolchains, edit the +CROSSTOOL.tpl file. The file is in ASCII protobuf format. + +https://github.com/bazelbuild/bazel/wiki/About-the-CROSSTOOL + +Notes: + +- The LLVM toolchain archive is downloaded and extracted in the named + repository. People elsewhere have used wrapper scripts to avoid symlinking +and get better control of the environment in which the toolchain binaries are +run. + +- Sandboxing the toolchain introduces a significant overhead (100ms per + action). To overcome this, one can use `--experimental_sandbox_fs=/dev/shm`. +However, not all environments might have enough shared memory available to load +all the files in memory. In order to avoid sandboxing the toolchain entirely, +we can use absolute paths. When running bazel actions, these paths will be +available from inside the sandbox as part of the / read-only mount. + +- While the C++ toolchain itself works well with relative paths (except the + performance hit because of sandboxing), the go toolchain needs the linker and +the linked libraries as absolute. This is a limitation of the cpp configuration +fragment provided by skylark and used by the go toolchain. + +- There is no R toolchain yet, so the Makevars file has been repurposed to + provide the right configuration, but only when the configure script for +packages do not override the variables set in the Makevars. + +- The toolchain is almost hermetic but borrows system headers and libraries + from the user's system. If needed, one can package a sysroot for their build +environment and set `builtin_sysroot` in CROSSTOOL. If using relative paths, be +sure to add your sysroot files to the `all_files` attribute of the toolchain. + +Other examples of toolchain configuration: + +https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain + +https://github.com/vsco/bazel-toolchains diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 0000000..5b4c415 --- /dev/null +++ b/WORKSPACE @@ -0,0 +1,30 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +workspace( + name = "com_grail_bazel_toolchain", +) + +load("@com_grail_bazel_toolchain//toolchain:configure.bzl", "llvm_toolchain") + +llvm_toolchain( + name = "llvm_toolchain", + absolute_paths = True, + llvm_version = "6.0.0", +) + +local_repository( + name = "travis", + path = "travis", +) diff --git a/tests/BUILD.bazel b/tests/BUILD.bazel new file mode 100644 index 0000000..d89d99a --- /dev/null +++ b/tests/BUILD.bazel @@ -0,0 +1,18 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +cc_test( + name = "stdlib_test", + srcs = ["stdlib_test.cc"], +) diff --git a/tests/run_tests.sh b/tests/run_tests.sh new file mode 100755 index 0000000..f94bebe --- /dev/null +++ b/tests/run_tests.sh @@ -0,0 +1,17 @@ +set -exuo pipefail + +if [[ $(uname -s) == "Linux" ]]; then + LINKOPT="-Wl,--verbose" +else + LINKOPT="-Wl,-v" +fi + +bazel test \ + --crosstool_top=@llvm_toolchain//:toolchain \ + --copt=-v \ + --linkopt="${LINKOPT}" \ + --color=yes \ + --show_progress_rate_limit=30 \ + --keep_going \ + --test_output=errors \ + //... diff --git a/tests/stdlib_test.cc b/tests/stdlib_test.cc new file mode 100644 index 0000000..e8a1c43 --- /dev/null +++ b/tests/stdlib_test.cc @@ -0,0 +1,17 @@ +// Copyright 2018 The Bazel Authors. +// +// Licensed under the Apache License, Version 2.0(the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http: // www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include + +int main() { std::cout << "Hello World!" << std::endl; } diff --git a/toolchain/BUILD.bazel b/toolchain/BUILD.bazel new file mode 100644 index 0000000..a4338cb --- /dev/null +++ b/toolchain/BUILD.bazel @@ -0,0 +1,26 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This BUILD file exports the templates and static files needed for dynamic toolchain configuration. +# See configure.bzl for how they are used. + +exports_files( + glob( + ["*"], + exclude = [ + "configure.bzl", + "BUILD.bazel", + ], + ), +) diff --git a/toolchain/BUILD.tpl b/toolchain/BUILD.tpl new file mode 100644 index 0000000..5449cd2 --- /dev/null +++ b/toolchain/BUILD.tpl @@ -0,0 +1,162 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +package(default_visibility = ["//visibility:public"]) + +exports_files(["Makevars"]) + +filegroup( + name = "empty", + srcs = [], +) + +filegroup( + name = "cc_wrapper", + srcs = ["cc_wrapper.sh"], +) + +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "k8|clang": ":cc-clang-linux", + "darwin|clang": ":cc-clang-darwin", + }, +) + +load("@com_grail_bazel_toolchain//toolchain:configure.bzl", "conditional_cc_toolchain") + +conditional_cc_toolchain("cc-clang-linux", "k8", False, %{absolute_paths}) +conditional_cc_toolchain("cc-clang-darwin", "darwin", True, %{absolute_paths}) + +filegroup( + name = "clang", + srcs = [ + "bin/clang", + "bin/clang++", + "bin/clang-cpp", + ], +) + +filegroup( + name = "ld", + srcs = [ + "bin/ld.lld", + "bin/ld64.lld" + ], +) + +filegroup( + name = "include", + srcs = glob([ + "include/c++/**", + "lib/clang/*/include/**", + ]), +) + +filegroup( + name = "lib", + srcs = [ + "lib/libc++.a", + "lib/libc++abi.a", + "lib/libunwind.a", + ], +) + +filegroup( + name = "compiler_components", + srcs = [ + ":clang", + ":include", + ], +) + +filegroup( + name = "ar", + srcs = ["bin/llvm-ar"], +) + +filegroup( + name = "as", + srcs = ["bin/llvm-as"], +) + +filegroup( + name = "nm", + srcs = ["bin/llvm-nm"], +) + +filegroup( + name = "objcopy", + srcs = ["bin/llvm-objcopy"], +) + +filegroup( + name = "objdump", + srcs = ["bin/llvm-objdump"], +) + +filegroup( + name = "profdata", + srcs = ["bin/llvm-profdata"], +) + +filegroup( + name = "dwp", + srcs = ["bin/llvm-dwp"], +) + +filegroup( + name = "ranlib", + srcs = ["bin/llvm-ranlib"], +) + +filegroup( + name = "readelf", + srcs = ["bin/llvm-readelf"], +) + +filegroup( + name = "binutils_components", + srcs = [ + ":ar", + ":as", + ":dwp", + ":ld", + ":nm", + ":objcopy", + ":objdump", + ":profdata", + ":ranlib", + ":readelf", + ], +) + +filegroup( + name = "linker_components", + srcs = [ + ":ar", + ":clang", + ":ld", + ":lib", + ], +) + +filegroup( + name = "all_components", + srcs = [ + ":binutils_components", + ":compiler_components", + ":linker_components", + ], +) diff --git a/toolchain/CROSSTOOL.tpl b/toolchain/CROSSTOOL.tpl new file mode 100644 index 0000000..c71fa46 --- /dev/null +++ b/toolchain/CROSSTOOL.tpl @@ -0,0 +1,361 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +major_version: "local" +minor_version: "" +default_target_cpu: "same_as_host" + +default_toolchain { + cpu: "k8" + toolchain_identifier: "clang-linux" +} + +default_toolchain { + cpu: "darwin" + toolchain_identifier: "clang-darwin" +} + +toolchain { + toolchain_identifier: "clang-linux" + abi_version: "local" + abi_libc_version: "local" + compiler: "clang" + host_system_name: "local" + needsPic: false + supports_gold_linker: false + supports_incremental_linker: false + supports_fission: false + supports_interface_shared_objects: false + supports_normalizing_ar: false + supports_start_end_lib: true + target_libc: "local" + target_cpu: "k8" + target_system_name: "local" + + builtin_sysroot: "" + + # Working with symlinks; anticipated to be a future default. + compiler_flag: "-no-canonical-prefixes" + linker_flag: "-no-canonical-prefixes" + + # Reproducibility. + unfiltered_cxx_flag: "-Wno-builtin-macro-redefined" + unfiltered_cxx_flag: "-D__DATE__=\"redacted\"" + unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\"" + unfiltered_cxx_flag: "-D__TIME__=\"redacted\"" + + # Security + compiler_flag: "-U_FORTIFY_SOURCE" + compiler_flag: "-fstack-protector" + compiler_flag: "-fcolor-diagnostics" + compiler_flag: "-fno-omit-frame-pointer" + + # Diagnostics + compiler_flag: "-Wall" + + # C++ + cxx_flag: "-std=c++11" + # The linker has no way of knowing if there are C++ objects; so we always link C++ libraries. + linker_flag: "%{toolchain_path_prefix}lib/libc++.a" + linker_flag: "%{toolchain_path_prefix}lib/libc++abi.a" + linker_flag: "%{toolchain_path_prefix}lib/libunwind.a" + cxx_flag: "-DLIBCXX_USE_COMPILER_RT=YES" + linker_flag: "-rtlib=compiler-rt" + linker_flag: "-lpthread" + linker_flag: "-ldl" # For libunwind + + # Linker + linker_flag: "-lm" + linker_flag: "-fuse-ld=lld" + linker_flag: "-Wl,--build-id=md5" + linker_flag: "-Wl,--hash-style=gnu" + + # Syntax for include directories is mentioned at: + # https://github.com/bazelbuild/bazel/blob/d61a185de8582d29dda7525bb04d8ffc5be3bd11/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java#L125 + cxx_builtin_include_directory: "%{toolchain_path_prefix}include/c++/v1" + cxx_builtin_include_directory: "%{toolchain_path_prefix}lib/clang/%{llvm_version}/include" + cxx_builtin_include_directory: "/include" + cxx_builtin_include_directory: "/usr/include" + cxx_builtin_include_directory: "/usr/local/include" + compiler_flag: "-isystem%{toolchain_path_prefix}include/c++/v1" + compiler_flag: "-isystem%{toolchain_path_prefix}lib/clang/%{llvm_version}/include" + + objcopy_embed_flag: "-I" + objcopy_embed_flag: "binary" + + compiler_flag: "-B%{toolchain_path_prefix}bin" + tool_path {name: "ld" path: "%{tools_path_prefix}bin/ld.lld" } + tool_path {name: "cpp" path: "%{tools_path_prefix}bin/clang-cpp" } + tool_path {name: "dwp" path: "%{tools_path_prefix}bin/llvm-dwp" } + tool_path {name: "gcov" path: "%{tools_path_prefix}bin/llvm-profdata" } + tool_path {name: "nm" path: "%{tools_path_prefix}bin/llvm-nm" } + tool_path {name: "objcopy" path: "%{tools_path_prefix}bin/llvm-objcopy" } + tool_path {name: "objdump" path: "%{tools_path_prefix}bin/llvm-objdump" } + tool_path {name: "strip" path: "/usr/bin/strip" } + tool_path {name: "gcc" path: "%{tools_path_prefix}bin/clang" } + tool_path {name: "ar" path: "%{tools_path_prefix}bin/llvm-ar" } + + compilation_mode_flags { + mode: DBG + compiler_flag: "-g" + } + + compilation_mode_flags { + mode: OPT + compiler_flag: "-g0" + compiler_flag: "-O2" + compiler_flag: "-D_FORTIFY_SOURCE=1" + compiler_flag: "-DNDEBUG" + compiler_flag: "-ffunction-sections" + compiler_flag: "-fdata-sections" + linker_flag: "-Wl,--gc-sections" + } + + linking_mode_flags { mode: DYNAMIC } + + feature { + name: "coverage" + } + feature { + name: "llvm_coverage_map_format" + flag_set { + action: "preprocess-assemble" + action: "c-compile" + action: "c++-compile" + action: "c++-module-compile" + flag_group { + flag: "-fprofile-instr-generate" + flag: "-fcoverage-mapping" + flag: "-g" + } + } + flag_set { + action: "c++-link-dynamic-library" + action: "c++-link-nodeps-dynamic-library" + action: "c++-link-executable" + flag_group { + flag: "-fprofile-instr-generate" + } + } + requires { + feature: "coverage" + } + } + feature { + name: "gcc_coverage_map_format" + flag_set { + action: "preprocess-assemble" + action: "c-compile" + action: "c++-compile" + action: "c++-module-compile" + flag_group { + flag: "-fprofile-arcs" + flag: "-ftest-coverage" + flag: "-g" + } + } + flag_set { + action: "c++-link-dynamic-library" + action: "c++-link-nodeps-dynamic-library" + action: "c++-link-executable" + flag_group { + flag: "-lgcov" + } + } + requires { + feature: "coverage" + } + } +} + +toolchain { + toolchain_identifier: "clang-darwin" + host_system_name: "x86_64-apple-macosx" + target_system_name: "x86_64-apple-macosx" + target_cpu: "darwin" + target_libc: "macosx" + compiler: "clang" + abi_version: "darwin_x86_64" + abi_libc_version: "darwin_x86_64" + needsPic: true + + builtin_sysroot: "" + + # Working with symlinks + compiler_flag: "-no-canonical-prefixes" + linker_flag: "-no-canonical-prefixes" + + # Reproducibility. + unfiltered_cxx_flag: "-Wno-builtin-macro-redefined" + unfiltered_cxx_flag: "-D__DATE__=\"redacted\"" + unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\"" + unfiltered_cxx_flag: "-D__TIME__=\"redacted\"" + + # Security + compiler_flag: "-D_FORTIFY_SOURCE=1" + compiler_flag: "-fstack-protector" + compiler_flag: "-Wthread-safety" + compiler_flag: "-Wself-assign" + compiler_flag: "-fno-omit-frame-pointer" + + # Diagnostics + compiler_flag: "-fcolor-diagnostics" + compiler_flag: "-Wall" + + # C++ + cxx_flag: "-std=c++11" + # The linker has no way of knowing if there are C++ objects; so we always link C++ libraries. + linker_flag: "%{toolchain_path_prefix}lib/libc++.a" + linker_flag: "%{toolchain_path_prefix}lib/libc++abi.a" + linker_flag: "-lpthread" + + # Linker + linker_flag: "-lm" + linker_flag: "-headerpad_max_install_names" + + # Syntax for include directories is mentioned at: + # https://github.com/bazelbuild/bazel/blob/d61a185de8582d29dda7525bb04d8ffc5be3bd11/src/main/java/com/google/devtools/build/lib/rules/cpp/CcToolchain.java#L125 + cxx_builtin_include_directory: "%{toolchain_path_prefix}include/c++/v1" + cxx_builtin_include_directory: "%{toolchain_path_prefix}lib/clang/%{llvm_version}/include" + cxx_builtin_include_directory: "/usr/include" + cxx_builtin_include_directory: "/usr/include/linux" + cxx_builtin_include_directory: "/System/Library/Frameworks" + cxx_builtin_include_directory: "/Library/Frameworks" + #cxx_builtin_include_directory: "/Applications/Xcode.app/Contents/Developer" + compiler_flag: "-isystem%{toolchain_path_prefix}include/c++/v1" + compiler_flag: "-isystem%{toolchain_path_prefix}lib/clang/%{llvm_version}/include" + + objcopy_embed_flag: "-I" + objcopy_embed_flag: "binary" + + compiler_flag: "-B%{toolchain_path_prefix}bin" + tool_path {name: "ld" path: "/usr/bin/ld" } # lld is not ready for macOS. + tool_path {name: "cpp" path: "%{tools_path_prefix}bin/clang-cpp" } + tool_path {name: "dwp" path: "%{tools_path_prefix}bin/llvm-dwp" } + tool_path {name: "gcov" path: "%{tools_path_prefix}bin/llvm-profdata" } + tool_path {name: "nm" path: "%{tools_path_prefix}bin/llvm-nm" } + tool_path {name: "objcopy" path: "%{tools_path_prefix}bin/llvm-objcopy" } + tool_path {name: "objdump" path: "%{tools_path_prefix}bin/llvm-objdump" } + tool_path {name: "strip" path: "/usr/bin/strip" } + tool_path {name: "gcc" path: "%{tools_path_prefix}cc_wrapper.sh" } + tool_path {name: "ar" path: "%{tools_path_prefix}bin/llvm-ar" } + + compilation_mode_flags { + mode: FASTBUILD + compiler_flag: "-O0" + compiler_flag: "-DDEBUG" + } + + compilation_mode_flags { + mode: OPT + compiler_flag: "-g0" + compiler_flag: "-O2" + compiler_flag: "-D_FORTIFY_SOURCE=1" + compiler_flag: "-DNDEBUG" + compiler_flag: "-ffunction-sections" + compiler_flag: "-fdata-sections" + } + + compilation_mode_flags { + mode: DBG + compiler_flag: "-g" + } + + linking_mode_flags { + mode: DYNAMIC + linker_flag: "-undefined" + linker_flag: "dynamic_lookup" + } + + make_variable { + name: "STACK_FRAME_UNLIMITED" + value: "-Wframe-larger-than=100000000 -Wno-vla" + } + + linking_mode_flags { mode: DYNAMIC } + + feature { + name: "framework_paths" + flag_set { + action: "objc-compile" + action: "objc++-compile" + action: "objc-executable" + action: "objc++-executable" + flag_group { + flag: "-F%{framework_paths}" + iterate_over: "framework_paths" + } + } + } + + feature { + name: "coverage" + } + feature { + name: "llvm_coverage_map_format" + flag_set { + action: "preprocess-assemble" + action: "c-compile" + action: "c++-compile" + action: "c++-module-compile" + action: "objc-compile" + action: "objc++-compile" + flag_group { + flag: "-fprofile-instr-generate" + flag: "-fcoverage-mapping" + flag: "-g" + } + } + flag_set { + action: "c++-link-dynamic-library" + action: "c++-link-nodeps-dynamic-library" + action: "c++-link-executable" + action: "objc-executable" + action: "objc++-executable" + flag_group { + flag: "-fprofile-instr-generate" + } + } + requires { + feature: "coverage" + } + } + feature { + name: "gcc_coverage_map_format" + flag_set { + action: "preprocess-assemble" + action: "c-compile" + action: "c++-compile" + action: "c++-module-compile" + action: "objc-compile" + action: "objc++-compile" + flag_group { + flag: "-fprofile-arcs" + flag: "-ftest-coverage" + flag: "-g" + } + } + flag_set { + action: "c++-link-dynamic-library" + action: "c++-link-nodeps-dynamic-library" + action: "c++-link-executable" + flag_group { + flag: "-lgcov" + } + } + requires { + feature: "coverage" + } + } +} diff --git a/toolchain/Makevars.tpl b/toolchain/Makevars.tpl new file mode 100644 index 0000000..d3f268e --- /dev/null +++ b/toolchain/Makevars.tpl @@ -0,0 +1,29 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Make variables if needed by build systems other than bazel, like R. + +CC = %{toolchain_path_prefix}/bin/clang -std=c11 +# Force compile packages with C++11 if they don't explicitly ask; this gives long vector support in Rcpp, etc. +CXX = %{toolchain_path_prefix}/bin/clang++ -std=c++11 +CXX11 = %{toolchain_path_prefix}bin/clang++ +CXX14 = %{toolchain_path_prefix}bin/clang++ +CXX17 = %{toolchain_path_prefix}bin/clang++ + +CXX11STD = -std=c++11 +CXX14STD = -std=c++14 +CXX17STD = -std=c++1z + +LDFLAGS += -fuse-ld=lld %{toolchain_path_prefix}/lib/libc++.a %{toolchain_path_prefix}/lib/libc++abi.a %{toolchain_path_prefix}/lib/libunwind.a -rtlib=compiler-rt -lpthread -ldl +CPPFLAGS += -B%{toolchain_path_prefix}bin -isystem %{toolchain_path_prefix}include/c++/v1 -isystem %{toolchain_path_prefix}lib/clang/%{llvm_version}/include -DLIBCXX_USE_COMPILER_RT=YES diff --git a/toolchain/cc_wrapper.sh.tpl b/toolchain/cc_wrapper.sh.tpl new file mode 100755 index 0000000..9bab189 --- /dev/null +++ b/toolchain/cc_wrapper.sh.tpl @@ -0,0 +1,107 @@ +#!/bin/bash +# +# Copyright 2015 The Bazel Authors. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# OS X relpath is not really working. This is a wrapper script around gcc +# to simulate relpath behavior. +# +# This wrapper uses install_name_tool to replace all paths in the binary +# (bazel-out/.../path/to/original/library.so) by the paths relative to +# the binary. It parses the command line to behave as rpath is supposed +# to work. +# +# See https://blogs.oracle.com/dipol/entry/dynamic_libraries_rpath_and_mac +# on how to set those paths for Mach-O binaries. +# +set -eu + +export PATH=$(pwd -P):/usr/bin +INSTALL_NAME_TOOL="/usr/bin/install_name_tool" + +LIBS= +LIB_DIRS= +RPATHS= +OUTPUT= +# let parse the option list +for i in "$@"; do + if [[ "${OUTPUT}" = "1" ]]; then + OUTPUT=$i + elif [[ "$i" =~ ^-l(.*)$ ]]; then + LIBS="${BASH_REMATCH[1]} $LIBS" + elif [[ "$i" =~ ^-L(.*)$ ]]; then + LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS" + elif [[ "$i" =~ ^-Wl,-rpath,\@loader_path/(.*)$ ]]; then + RPATHS="${BASH_REMATCH[1]} ${RPATHS}" + elif [[ "$i" = "-o" ]]; then + # output is coming + OUTPUT=1 + fi +done + +# Set-up the environment + + +# Call the C++ compiler +%{toolchain_path_prefix}bin/clang "$@" + +function get_library_path() { + for libdir in ${LIB_DIRS}; do + if [ -f ${libdir}/lib$1.so ]; then + echo "${libdir}/lib$1.so" + elif [ -f ${libdir}/lib$1.dylib ]; then + echo "${libdir}/lib$1.dylib" + fi + done +} + +# A convenient method to return the actual path even for non symlinks +# and multi-level symlinks. +function get_realpath() { + local previous="$1" + local next=$(readlink "${previous}") + while [ -n "${next}" ]; do + previous="${next}" + next=$(readlink "${previous}") + done + echo "${previous}" +} + +# Get the path of a lib inside a tool +function get_otool_path() { + # the lib path is the path of the original lib relative to the workspace + get_realpath $1 | sed 's|^.*/bazel-out/|bazel-out/|' +} + +# Do replacements in the output +for rpath in ${RPATHS}; do + for lib in ${LIBS}; do + unset libname + if [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.so" ]; then + libname="lib${lib}.so" + elif [ -f "$(dirname ${OUTPUT})/${rpath}/lib${lib}.dylib" ]; then + libname="lib${lib}.dylib" + fi + # ${libname-} --> return $libname if defined, or undefined otherwise. This is to make + # this set -e friendly + if [[ -n "${libname-}" ]]; then + libpath=$(get_library_path ${lib}) + if [ -n "${libpath}" ]; then + ${INSTALL_NAME_TOOL} -change $(get_otool_path "${libpath}") \ + "@loader_path/${rpath}/${libname}" "${OUTPUT}" + fi + fi + done +done + diff --git a/toolchain/configure.bzl b/toolchain/configure.bzl new file mode 100644 index 0000000..39cb04f --- /dev/null +++ b/toolchain/configure.bzl @@ -0,0 +1,166 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# If a new LLVM version is missing from this list, please add the shasum here +# and send a PR on github. +_llvm_sha256_linux = { + "6.0.0": "cc99fda45b4c740f35d0a367985a2bf55491065a501e2dd5d1ad3f97dcac89da", +} + +_llvm_sha256_darwin = { + "6.0.0": "0ef8e99e9c9b262a53ab8f2821e2391d041615dd3f3ff36fdf5370916b0f4268", +} + +def _download_llvm_preconfigured(rctx): + llvm_version = rctx.attr.llvm_version + + url_base = [] + if rctx.attr.llvm_mirror: + url_base += [rctx.attr.llvm_mirror] + url_base += ["https://releases.llvm.org"] + + if rctx.os.name == "linux": + prefix = "clang+llvm-{0}-x86_64-linux-gnu-ubuntu-16.04".format(llvm_version) + sha256 = _llvm_sha256_linux[llvm_version] + elif rctx.os.name == "mac os x": + prefix = "clang+llvm-{0}-x86_64-apple-darwin".format(llvm_version) + sha256 = _llvm_sha256_darwin[llvm_version] + else: + fail("Unsupported OS: " + rctx.os.name) + + urls = [(base + "/{0}/{1}.tar.xz".format(llvm_version, prefix)).replace("+", "%2B") + for base in url_base] + + rctx.download_and_extract(urls, sha256=sha256, stripPrefix=prefix) + +def _download_llvm(rctx): + if rctx.os.name == "linux": + urls = rctx.attr.urls["linux"] + sha256 = rctx.attr.sha256["linux"] + prefix = rctx.attr.strip_prefix["linux"] + elif rctx.os.name == "mac os x": + urls = rctx.attr.urls["darwin"] + sha256 = rctx.attr.sha256["darwin"] + prefix = rctx.attr.strip_prefix["darwin"] + + rctx.download_and_extract(urls, sha256=sha256, stripPrefix=prefix) + +def _llvm_toolchain_impl(rctx): + repo_path = str(rctx.path("")) + if rctx.attr.absolute_paths: + toolchain_path_prefix = (repo_path + "/") + else: + toolchain_path_prefix = "external/%s/" % rctx.name + + substitutions = { + "%{llvm_version}": rctx.attr.llvm_version, + "%{toolchain_path_prefix}": toolchain_path_prefix, + "%{tools_path_prefix}": (repo_path + "/") if rctx.attr.absolute_paths else "", + "%{absolute_paths}": "True" if rctx.attr.absolute_paths else "False", + } + + rctx.template( + "CROSSTOOL", + Label("@com_grail_bazel_toolchain//toolchain:CROSSTOOL.tpl"), + substitutions) + rctx.template( + "cc_wrapper.sh", + Label("@com_grail_bazel_toolchain//toolchain:cc_wrapper.sh.tpl"), + substitutions) + rctx.template( + "Makevars", + Label("@com_grail_bazel_toolchain//toolchain:Makevars.tpl"), + substitutions) + rctx.template( + "BUILD", + Label("@com_grail_bazel_toolchain//toolchain:BUILD.tpl"), + substitutions) + + # Repository implementation functions can be restarted, keep expensive ops at the end. + if rctx.attr.urls: + _download_llvm(rctx) + else: + _download_llvm_preconfigured(rctx) + +llvm_toolchain = repository_rule( + attrs = { + "llvm_version": attr.string( + default = "6.0.0", + doc = "One of the supported versions of LLVM.", + ), + "llvm_mirror": attr.string( + doc = "Mirror base for LLVM binaries if using the pre-configured URLs.", + ), + "urls": attr.string_list_dict( + mandatory = False, + doc = "URLs for each OS type (linux and darwin) if not using the pre-configured URLs.", + ), + "sha256": attr.string_dict( + default = { + "linux": "", + "darwin": "", + }, + doc = "sha256 of the archive for each OS type.", + ), + "strip_prefix": attr.string_dict( + default = { + "linux": "", + "darwin": "", + }, + doc = "Path prefix to strip from the extracted files.", + ), + "absolute_paths": attr.bool( + default = False, + doc = "Whether to use absolute paths in CROSSTOOL. Avoids sandbox overhead.", + ), + }, + local = False, + implementation = _llvm_toolchain_impl, +) + +def conditional_cc_toolchain(name, cpu, darwin, absolute_paths=False): + # Toolchain macro for BUILD file to use conditional logic. + + if absolute_paths: + native.cc_toolchain( + name = name, + all_files = ":empty", + compiler_files = ":empty", + cpu = "k8", + dwp_files = ":empty", + dynamic_runtime_libs = [":empty"], + linker_files = ":empty", + objcopy_files = ":empty", + static_runtime_libs = [":empty"], + strip_files = ":empty", + supports_param_files = 0 if darwin else 1, + ) + else: + extra_files = [":cc_wrapper"] if darwin else [] + native.filegroup(name = name + "-all-files", srcs = [":all_components"] + extra_files) + native.filegroup(name = name + "-compiler-files", srcs = [":compiler_components"] + extra_files) + native.filegroup(name = name + "-linker-files", srcs = [":linker_components"] + extra_files) + native.cc_toolchain( + name = name, + all_files = name + "-all-files", + compiler_files = name + "-compiler-files", + cpu = "k8", + dwp_files = ":empty", + dynamic_runtime_libs = [":empty"], + linker_files = name + "-linker-files", + objcopy_files = ":objcopy", + static_runtime_libs = [":empty"], + strip_files = ":empty", + supports_param_files = 0 if darwin else 1, + ) diff --git a/travis/WORKSPACE b/travis/WORKSPACE new file mode 100644 index 0000000..282ba68 --- /dev/null +++ b/travis/WORKSPACE @@ -0,0 +1,38 @@ +# Copyright 2018 The Bazel Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +local_repository( + name = "com_grail_bazel_toolchain", + path = "..", +) + +load("@com_grail_bazel_toolchain//toolchain:configure.bzl", "llvm_toolchain") + +llvm_toolchain( + name = "llvm_toolchain", + absolute_paths = True, + llvm_version = "6.0.0", + sha256 = { + "linux": "114e78b2f6db61aaee314c572e07b0d635f653adc5d31bd1cd0bf31a3db4a6e5", + "darwin": "0ef8e99e9c9b262a53ab8f2821e2391d041615dd3f3ff36fdf5370916b0f4268", + }, + strip_prefix = { + "linux": "clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04", + "darwin": "clang+llvm-6.0.0-x86_64-apple-darwin", + }, + urls = { + "linux": ["http://releases.llvm.org/6.0.0/clang+llvm-6.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz"], + "darwin": ["http://releases.llvm.org/6.0.0/clang+llvm-6.0.0-x86_64-apple-darwin.tar.xz"], + }, +) diff --git a/travis/tests b/travis/tests new file mode 120000 index 0000000..6dd24e0 --- /dev/null +++ b/travis/tests @@ -0,0 +1 @@ +../tests \ No newline at end of file