diff --git a/.bazelci/presubmit.yml b/.bazelci/presubmit.yml index b194749..0776ded 100644 --- a/.bazelci/presubmit.yml +++ b/.bazelci/presubmit.yml @@ -10,6 +10,8 @@ x_defaults: - "//:all" - "//cc:all" - "//cc/private/rules_impl:all" + - "//cc/private/toolchain:all" + - "//cc/runfiles:all" - "//examples:all" - "//examples/my_c_archive:all" - "//examples/my_c_compile:all" @@ -21,6 +23,7 @@ x_defaults: - "//:all" - "//cc:all" - "//cc/private/rules_impl:all" + - "//cc/private/toolchain:all" - "//examples:all" - "//examples/my_c_archive:all" - "//examples/my_c_compile:all" diff --git a/cc/BUILD b/cc/BUILD index 869b699..9ddacb7 100644 --- a/cc/BUILD +++ b/cc/BUILD @@ -20,6 +20,7 @@ filegroup( name = "all_files_for_testing", srcs = glob(["**"]) + [ "//cc/private/rules_impl:srcs", + "//cc/private/toolchain:srcs", ], ) @@ -51,6 +52,7 @@ filegroup( "**/*.bzl", ]) + [ "//cc/private/rules_impl:bzl_srcs", + "//cc/private/toolchain:bzl_srcs", ], visibility = ["//visibility:public"], ) @@ -62,6 +64,7 @@ filegroup( "**/BUILD", ]) + [ "//cc/private/rules_impl:srcs", + "//cc/private/toolchain:srcs", ], visibility = ["//visibility:public"], ) diff --git a/cc/extensions.bzl b/cc/extensions.bzl index bd02598..72b2dca 100644 --- a/cc/extensions.bzl +++ b/cc/extensions.bzl @@ -13,8 +13,8 @@ # limitations under the License. """Module extension for cc auto configuration.""" -load("@bazel_tools//tools/cpp:cc_configure.bzl", "cc_autoconf", "cc_autoconf_toolchains") load("@bazel_tools//tools/osx:xcode_configure.bzl", "xcode_configure") +load("//cc/private/toolchain:cc_configure.bzl", "cc_autoconf", "cc_autoconf_toolchains") def _cc_configure_impl(_): cc_autoconf_toolchains(name = "local_config_cc_toolchains") diff --git a/cc/private/toolchain/BUILD b/cc/private/toolchain/BUILD new file mode 100644 index 0000000..6915d5b --- /dev/null +++ b/cc/private/toolchain/BUILD @@ -0,0 +1,100 @@ +load("//cc:defs.bzl", "cc_flags_supplier", "cc_library", "compiler_flag") + +# Copyright 2018 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. +# +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +# It is frequently necessary to constrain platforms based on the cc compiler type. +constraint_setting(name = "cc_compiler") + +constraint_value( + name = "clang", + constraint_setting = ":cc_compiler", +) + +constraint_value( + name = "gcc", + constraint_setting = ":cc_compiler", +) + +constraint_value( + name = "msvc", + constraint_setting = ":cc_compiler", +) + +constraint_value( + name = "clang-cl", + constraint_setting = ":cc_compiler", +) + +constraint_value( + name = "mingw", + constraint_setting = ":cc_compiler", +) + +constraint_value( + name = "msys", + constraint_setting = ":cc_compiler", +) + +cc_library( + name = "malloc", +) + +filegroup( + name = "grep-includes", + srcs = ["grep-includes.sh"], +) + +filegroup( + name = "empty", + srcs = [], +) + +filegroup( + name = "bzl_srcs", + srcs = glob(["**/*.bzl"]), +) + +filegroup( + name = "srcs", + srcs = glob(["**"]), +) + +filegroup( + name = "interface_library_builder", + srcs = ["build_interface_so"], +) + +filegroup( + name = "osx_wrapper", + srcs = ["osx_cc_wrapper.sh"], +) + +filegroup( + name = "link_dynamic_library", + srcs = ["link_dynamic_library.sh"], +) + +filegroup( + name = "lib_cc_configure", + srcs = ["lib_cc_configure.bzl"], +) + +compiler_flag(name = "compiler") + +cc_flags_supplier(name = "cc_flags") diff --git a/cc/private/toolchain/BUILD.empty b/cc/private/toolchain/BUILD.empty new file mode 100644 index 0000000..a873d0c --- /dev/null +++ b/cc/private/toolchain/BUILD.empty @@ -0,0 +1,52 @@ +# Copyright 2018 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. + +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_toolchain", "cc_toolchain_suite") + +package(default_visibility = ["//visibility:public"]) + +load(":cc_toolchain_config.bzl", "cc_toolchain_config") + +cc_library( + name = "malloc", +) + +filegroup( + name = "empty", + srcs = [], +) + +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "local": ":local", + "local|local": ":local", + }, +) + +cc_toolchain( + name = "local", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + toolchain_config = ":local_config", + toolchain_identifier = "local", +) + +cc_toolchain_config(name = "local_config") diff --git a/cc/private/toolchain/BUILD.static.freebsd b/cc/private/toolchain/BUILD.static.freebsd new file mode 100644 index 0000000..d8a7b2d --- /dev/null +++ b/cc/private/toolchain/BUILD.static.freebsd @@ -0,0 +1,112 @@ +# Copyright 2018 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. + +# This becomes the BUILD file for @local_config_cc// under FreeBSD. + +package(default_visibility = ["//visibility:public"]) + +load("@rules_cc//cc:defs.bzl", "cc_library", "cc_toolchain", "cc_toolchain_suite") +load(":cc_toolchain_config.bzl", "cc_toolchain_config") + +cc_library( + name = "malloc", +) + +filegroup( + name = "empty", + srcs = [], +) + +# Hardcoded toolchain, legacy behaviour. +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "armeabi-v7a": ":cc-compiler-armeabi-v7a", + "armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a", + "freebsd": ":cc-compiler-freebsd", + "freebsd|compiler": ":cc-compiler-freebsd", + }, +) + +cc_toolchain( + name = "cc-compiler-freebsd", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 0, + toolchain_config = ":local_freebsd", + toolchain_identifier = "local_freebsd", +) + +cc_toolchain_config( + name = "local_freebsd", + cpu = "freebsd", +) + +toolchain( + name = "cc-toolchain-freebsd", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:freebsd", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:freebsd", + ], + toolchain = ":cc-compiler-freebsd", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-armeabi-v7a", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 0, + toolchain_config = ":stub_armeabi-v7a", + toolchain_identifier = "stub_armeabi-v7a", +) + +cc_toolchain_config( + name = "stub_armeabi-v7a", + cpu = "armeabi-v7a", +) + +toolchain( + name = "cc-toolchain-armeabi-v7a", + exec_compatible_with = [ + "@platforms//cpu:arm", + ], + target_compatible_with = [ + "@platforms//cpu:arm", + "@platforms//os:android", + ], + toolchain = ":cc-compiler-armeabi-v7a", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +filegroup( + name = "link_dynamic_library", + srcs = ["link_dynamic_library.sh"], +) diff --git a/cc/private/toolchain/BUILD.toolchains.tpl b/cc/private/toolchain/BUILD.toolchains.tpl new file mode 100644 index 0000000..3fee112 --- /dev/null +++ b/cc/private/toolchain/BUILD.toolchains.tpl @@ -0,0 +1,20 @@ +load("@local_config_platform//:constraints.bzl", "HOST_CONSTRAINTS") + +toolchain( + name = "cc-toolchain-%{name}", + exec_compatible_with = HOST_CONSTRAINTS, + target_compatible_with = HOST_CONSTRAINTS, + toolchain = "@local_config_cc//:cc-compiler-%{name}", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +toolchain( + name = "cc-toolchain-armeabi-v7a", + exec_compatible_with = HOST_CONSTRAINTS, + target_compatible_with = [ + "@platforms//cpu:arm", + "@platforms//os:android", + ], + toolchain = "@local_config_cc//:cc-compiler-armeabi-v7a", + toolchain_type = "@rules_cc//cc:toolchain_type", +) diff --git a/cc/private/toolchain/BUILD.tpl b/cc/private/toolchain/BUILD.tpl new file mode 100644 index 0000000..9241326 --- /dev/null +++ b/cc/private/toolchain/BUILD.tpl @@ -0,0 +1,113 @@ +# Copyright 2016 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. + +# This becomes the BUILD file for @local_config_cc// under non-FreeBSD unixes. + +package(default_visibility = ["//visibility:public"]) + +load(":cc_toolchain_config.bzl", "cc_toolchain_config") +load(":armeabi_cc_toolchain_config.bzl", "armeabi_cc_toolchain_config") +load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite") + +licenses(["notice"]) # Apache 2.0 + +cc_library( + name = "malloc", +) + +filegroup( + name = "empty", + srcs = [], +) + +filegroup( + name = "cc_wrapper", + srcs = ["cc_wrapper.sh"], +) + +filegroup( + name = "compiler_deps", + srcs = glob(["extra_tools/**"], allow_empty = True) + [%{cc_compiler_deps}], +) + +# This is the entry point for --crosstool_top. Toolchains are found +# by lopping off the name of --crosstool_top and searching for +# the "${CPU}" entry in the toolchains attribute. +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "%{name}|%{compiler}": ":cc-compiler-%{name}", + "%{name}": ":cc-compiler-%{name}", + "armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a", + "armeabi-v7a": ":cc-compiler-armeabi-v7a", + }, +) + +cc_toolchain( + name = "cc-compiler-%{name}", + toolchain_identifier = "%{cc_toolchain_identifier}", + toolchain_config = ":%{cc_toolchain_identifier}", + all_files = ":compiler_deps", + ar_files = ":compiler_deps", + as_files = ":compiler_deps", + compiler_files = ":compiler_deps", + dwp_files = ":empty", + linker_files = ":compiler_deps", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = %{supports_param_files}, +) + +cc_toolchain_config( + name = "%{cc_toolchain_identifier}", + cpu = "%{target_cpu}", + compiler = "%{compiler}", + toolchain_identifier = "%{cc_toolchain_identifier}", + host_system_name = "%{host_system_name}", + target_system_name = "%{target_system_name}", + target_libc = "%{target_libc}", + abi_version = "%{abi_version}", + abi_libc_version = "%{abi_libc_version}", + cxx_builtin_include_directories = [%{cxx_builtin_include_directories}], + tool_paths = {%{tool_paths}}, + compile_flags = [%{compile_flags}], + opt_compile_flags = [%{opt_compile_flags}], + dbg_compile_flags = [%{dbg_compile_flags}], + cxx_flags = [%{cxx_flags}], + link_flags = [%{link_flags}], + link_libs = [%{link_libs}], + opt_link_flags = [%{opt_link_flags}], + unfiltered_compile_flags = [%{unfiltered_compile_flags}], + coverage_compile_flags = [%{coverage_compile_flags}], + coverage_link_flags = [%{coverage_link_flags}], + supports_start_end_lib = %{supports_start_end_lib}, +) + +# Android tooling requires a default toolchain for the armeabi-v7a cpu. +cc_toolchain( + name = "cc-compiler-armeabi-v7a", + toolchain_identifier = "stub_armeabi-v7a", + toolchain_config = ":stub_armeabi-v7a", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, +) + +armeabi_cc_toolchain_config(name = "stub_armeabi-v7a") diff --git a/cc/private/toolchain/BUILD.windows.tpl b/cc/private/toolchain/BUILD.windows.tpl new file mode 100644 index 0000000..66dbafd --- /dev/null +++ b/cc/private/toolchain/BUILD.windows.tpl @@ -0,0 +1,316 @@ +# Copyright 2018 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. + +# This becomes the BUILD file for @local_config_cc// under Windows. + +package(default_visibility = ["//visibility:public"]) + +load("@rules_cc//cc:defs.bzl", "cc_toolchain", "cc_toolchain_suite", "cc_library") +load(":windows_cc_toolchain_config.bzl", "cc_toolchain_config") +load(":armeabi_cc_toolchain_config.bzl", "armeabi_cc_toolchain_config") +cc_library( + name = "malloc", +) + +filegroup( + name = "empty", + srcs = [], +) + +filegroup( + name = "mingw_compiler_files", + srcs = [":builtin_include_directory_paths_mingw"] +) + +filegroup( + name = "clangcl_compiler_files", + srcs = [":builtin_include_directory_paths_clangcl"] +) + +filegroup( + name = "msvc_compiler_files", + srcs = [":builtin_include_directory_paths_msvc"] +) + +# Hardcoded toolchain, legacy behaviour. +cc_toolchain_suite( + name = "toolchain", + toolchains = { + "armeabi-v7a|compiler": ":cc-compiler-armeabi-v7a", + "x64_windows|msvc-cl": ":cc-compiler-x64_windows", + "x64_windows|msys-gcc": ":cc-compiler-x64_windows_msys", + "x64_windows|mingw-gcc": ":cc-compiler-x64_windows_mingw", + "x64_windows|clang-cl": ":cc-compiler-x64_windows-clang-cl", + "x64_windows_msys": ":cc-compiler-x64_windows_msys", + "x64_windows": ":cc-compiler-x64_windows", + "armeabi-v7a": ":cc-compiler-armeabi-v7a", + }, +) + +cc_toolchain( + name = "cc-compiler-x64_windows_msys", + toolchain_identifier = "msys_x64", + toolchain_config = ":msys_x64", + all_files = ":empty", + ar_files = ":empty", + as_files = ":mingw_compiler_files", + compiler_files = ":mingw_compiler_files", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, +) + +cc_toolchain_config( + name = "msys_x64", + cpu = "x64_windows", + compiler = "msys-gcc", + host_system_name = "local", + target_system_name = "local", + target_libc = "msys", + abi_version = "local", + abi_libc_version = "local", + cxx_builtin_include_directories = [%{cxx_builtin_include_directories}], + tool_paths = {%{tool_paths}}, + tool_bin_path = "%{tool_bin_path}", + dbg_mode_debug_flag = "%{dbg_mode_debug_flag}", + fastbuild_mode_debug_flag = "%{fastbuild_mode_debug_flag}", +) + +toolchain( + name = "cc-toolchain-x64_windows_msys", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + "@rules_cc//cc/private/toolchain:msys", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], + toolchain = ":cc-compiler-x64_windows_msys", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-x64_windows_mingw", + toolchain_identifier = "msys_x64_mingw", + toolchain_config = ":msys_x64_mingw", + all_files = ":empty", + ar_files = ":empty", + as_files = ":mingw_compiler_files", + compiler_files = ":mingw_compiler_files", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 0, +) + +cc_toolchain_config( + name = "msys_x64_mingw", + cpu = "x64_windows", + compiler = "mingw-gcc", + host_system_name = "local", + target_system_name = "local", + target_libc = "mingw", + abi_version = "local", + abi_libc_version = "local", + tool_bin_path = "%{mingw_tool_bin_path}", + cxx_builtin_include_directories = [%{mingw_cxx_builtin_include_directories}], + tool_paths = {%{mingw_tool_paths}}, + dbg_mode_debug_flag = "%{dbg_mode_debug_flag}", + fastbuild_mode_debug_flag = "%{fastbuild_mode_debug_flag}", +) + +toolchain( + name = "cc-toolchain-x64_windows_mingw", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + "@rules_cc//cc/private/toolchain:mingw", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], + toolchain = ":cc-compiler-x64_windows_mingw", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-x64_windows", + toolchain_identifier = "msvc_x64", + toolchain_config = ":msvc_x64", + all_files = ":empty", + ar_files = ":empty", + as_files = ":msvc_compiler_files", + compiler_files = ":msvc_compiler_files", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, +) + +cc_toolchain_config( + name = "msvc_x64", + cpu = "x64_windows", + compiler = "msvc-cl", + host_system_name = "local", + target_system_name = "local", + target_libc = "msvcrt", + abi_version = "local", + abi_libc_version = "local", + toolchain_identifier = "msvc_x64", + msvc_env_tmp = "%{msvc_env_tmp}", + msvc_env_path = "%{msvc_env_path}", + msvc_env_include = "%{msvc_env_include}", + msvc_env_lib = "%{msvc_env_lib}", + msvc_cl_path = "%{msvc_cl_path}", + msvc_ml_path = "%{msvc_ml_path}", + msvc_link_path = "%{msvc_link_path}", + msvc_lib_path = "%{msvc_lib_path}", + cxx_builtin_include_directories = [%{msvc_cxx_builtin_include_directories}], + tool_paths = { + "ar": "%{msvc_lib_path}", + "ml": "%{msvc_ml_path}", + "cpp": "%{msvc_cl_path}", + "gcc": "%{msvc_cl_path}", + "gcov": "wrapper/bin/msvc_nop.bat", + "ld": "%{msvc_link_path}", + "nm": "wrapper/bin/msvc_nop.bat", + "objcopy": "wrapper/bin/msvc_nop.bat", + "objdump": "wrapper/bin/msvc_nop.bat", + "strip": "wrapper/bin/msvc_nop.bat", + }, + default_link_flags = ["/MACHINE:X64"], + dbg_mode_debug_flag = "%{dbg_mode_debug_flag}", + fastbuild_mode_debug_flag = "%{fastbuild_mode_debug_flag}", +) + +toolchain( + name = "cc-toolchain-x64_windows", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], + toolchain = ":cc-compiler-x64_windows", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-x64_windows-clang-cl", + toolchain_identifier = "clang_cl_x64", + toolchain_config = ":clang_cl_x64", + all_files = ":empty", + ar_files = ":empty", + as_files = ":clangcl_compiler_files", + compiler_files = ":clangcl_compiler_files", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, +) + +cc_toolchain_config( + name = "clang_cl_x64", + cpu = "x64_windows", + compiler = "clang-cl", + host_system_name = "local", + target_system_name = "local", + target_libc = "msvcrt", + abi_version = "local", + abi_libc_version = "local", + toolchain_identifier = "clang_cl_x64", + msvc_env_tmp = "%{clang_cl_env_tmp}", + msvc_env_path = "%{clang_cl_env_path}", + msvc_env_include = "%{clang_cl_env_include}", + msvc_env_lib = "%{clang_cl_env_lib}", + msvc_cl_path = "%{clang_cl_cl_path}", + msvc_ml_path = "%{clang_cl_ml_path}", + msvc_link_path = "%{clang_cl_link_path}", + msvc_lib_path = "%{clang_cl_lib_path}", + cxx_builtin_include_directories = [%{clang_cl_cxx_builtin_include_directories}], + tool_paths = { + "ar": "%{clang_cl_lib_path}", + "ml": "%{clang_cl_ml_path}", + "cpp": "%{clang_cl_cl_path}", + "gcc": "%{clang_cl_cl_path}", + "gcov": "wrapper/bin/msvc_nop.bat", + "ld": "%{clang_cl_link_path}", + "nm": "wrapper/bin/msvc_nop.bat", + "objcopy": "wrapper/bin/msvc_nop.bat", + "objdump": "wrapper/bin/msvc_nop.bat", + "strip": "wrapper/bin/msvc_nop.bat", + }, + default_link_flags = ["/MACHINE:X64", "/DEFAULTLIB:clang_rt.builtins-x86_64.lib"], + dbg_mode_debug_flag = "%{clang_cl_dbg_mode_debug_flag}", + fastbuild_mode_debug_flag = "%{clang_cl_fastbuild_mode_debug_flag}", +) + +toolchain( + name = "cc-toolchain-x64_windows-clang-cl", + exec_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + "@rules_cc//cc/private/toolchain:clang-cl", + ], + target_compatible_with = [ + "@platforms//cpu:x86_64", + "@platforms//os:windows", + ], + toolchain = ":cc-compiler-x64_windows-clang-cl", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +cc_toolchain( + name = "cc-compiler-armeabi-v7a", + toolchain_identifier = "stub_armeabi-v7a", + toolchain_config = ":stub_armeabi-v7a", + all_files = ":empty", + ar_files = ":empty", + as_files = ":empty", + compiler_files = ":empty", + dwp_files = ":empty", + linker_files = ":empty", + objcopy_files = ":empty", + strip_files = ":empty", + supports_param_files = 1, +) + +armeabi_cc_toolchain_config(name = "stub_armeabi-v7a") + +toolchain( + name = "cc-toolchain-armeabi-v7a", + exec_compatible_with = [ + ], + target_compatible_with = [ + "@platforms//cpu:arm", + "@platforms//os:android", + ], + toolchain = ":cc-compiler-armeabi-v7a", + toolchain_type = "@rules_cc//cc:toolchain_type", +) + +filegroup( + name = "link_dynamic_library", + srcs = ["link_dynamic_library.sh"], +) diff --git a/cc/private/toolchain/armeabi_cc_toolchain_config.bzl b/cc/private/toolchain/armeabi_cc_toolchain_config.bzl new file mode 100644 index 0000000..66c5752 --- /dev/null +++ b/cc/private/toolchain/armeabi_cc_toolchain_config.bzl @@ -0,0 +1,82 @@ +# Copyright 2019 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. + +"""A Starlark cc_toolchain configuration rule""" + +load( + "@rules_cc//cc:cc_toolchain_config_lib.bzl", + "feature", + "tool_path", +) + +def _impl(ctx): + toolchain_identifier = "stub_armeabi-v7a" + host_system_name = "armeabi-v7a" + target_system_name = "armeabi-v7a" + target_cpu = "armeabi-v7a" + target_libc = "armeabi-v7a" + compiler = "compiler" + abi_version = "armeabi-v7a" + abi_libc_version = "armeabi-v7a" + cc_target_os = None + builtin_sysroot = None + action_configs = [] + + supports_pic_feature = feature(name = "supports_pic", enabled = True) + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + features = [supports_dynamic_linker_feature, supports_pic_feature] + + cxx_builtin_include_directories = [] + artifact_name_patterns = [] + make_variables = [] + + tool_paths = [ + tool_path(name = "ar", path = "/bin/false"), + tool_path(name = "compat-ld", path = "/bin/false"), + tool_path(name = "cpp", path = "/bin/false"), + tool_path(name = "dwp", path = "/bin/false"), + tool_path(name = "gcc", path = "/bin/false"), + tool_path(name = "gcov", path = "/bin/false"), + tool_path(name = "ld", path = "/bin/false"), + tool_path(name = "nm", path = "/bin/false"), + tool_path(name = "objcopy", path = "/bin/false"), + tool_path(name = "objdump", path = "/bin/false"), + tool_path(name = "strip", path = "/bin/false"), + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = cc_target_os, + ) + +armeabi_cc_toolchain_config = rule( + implementation = _impl, + attrs = {}, + provides = [CcToolchainConfigInfo], +) diff --git a/cc/private/toolchain/build_interface_so b/cc/private/toolchain/build_interface_so new file mode 100644 index 0000000..626e707 --- /dev/null +++ b/cc/private/toolchain/build_interface_so @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ $# != 2 ]]; then + echo "Usage: $0 " 1>&2 + exit 1 +fi + +exec cp $1 $2 diff --git a/cc/private/toolchain/cc_configure.bzl b/cc/private/toolchain/cc_configure.bzl new file mode 100644 index 0000000..c281198 --- /dev/null +++ b/cc/private/toolchain/cc_configure.bzl @@ -0,0 +1,185 @@ +# Copyright 2016 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. +"""Rules for configuring the C++ toolchain (experimental).""" + +load("@bazel_tools//tools/osx:xcode_configure.bzl", "run_xcode_locator") +load( + ":lib_cc_configure.bzl", + "get_cpu_value", + "resolve_labels", +) +load(":osx_cc_configure.bzl", "configure_osx_toolchain") +load(":unix_cc_configure.bzl", "configure_unix_toolchain") +load(":windows_cc_configure.bzl", "configure_windows_toolchain") + +def _generate_cpp_only_build_file(repository_ctx, cpu_value, paths): + repository_ctx.template( + "BUILD", + paths["@rules_cc//cc/private/toolchain:BUILD.toolchains.tpl"], + {"%{name}": cpu_value}, + ) + +def cc_autoconf_toolchains_impl(repository_ctx): + """Generate BUILD file with 'toolchain' targets for the local host C++ toolchain. + + Args: + repository_ctx: repository context + """ + paths = resolve_labels(repository_ctx, [ + "@rules_cc//cc/private/toolchain:BUILD.toolchains.tpl", + "@bazel_tools//tools/osx/crosstool:BUILD.toolchains", + "@bazel_tools//tools/osx/crosstool:osx_archs.bzl", + "@bazel_tools//tools/osx:xcode_locator.m", + ]) + env = repository_ctx.os.environ + cpu_value = get_cpu_value(repository_ctx) + + # Should we try to find C++ toolchain at all? If not, we don't have to generate toolchains for C++ at all. + should_detect_cpp_toolchain = "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" not in env or env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] != "1" + + # Should we unconditionally *not* use xcode? If so, we don't have to run Xcode locator ever. + should_use_cpp_only_toolchain = "BAZEL_USE_CPP_ONLY_TOOLCHAIN" in env and env["BAZEL_USE_CPP_ONLY_TOOLCHAIN"] == "1" + + # Should we unconditionally use xcode? If so, we don't have to run Xcode locator now. + should_use_xcode = "BAZEL_USE_XCODE_TOOLCHAIN" in env and env["BAZEL_USE_XCODE_TOOLCHAIN"] == "1" + + if not should_detect_cpp_toolchain: + repository_ctx.file("BUILD", "# C++ toolchain autoconfiguration was disabled by BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN env variable.") + elif cpu_value == "darwin" and not should_use_cpp_only_toolchain: + xcode_toolchains = [] + + # Only detect xcode if the user didn't tell us it will be there. + if not should_use_xcode: + # TODO(#6926): Unify C++ and ObjC toolchains so we don't have to run xcode locator to generate toolchain targets. + # And also so we don't have to keep this code in sync with @rules_cc//cc/private/toolchain:osx_cc_configure.bzl. + (xcode_toolchains, _xcodeloc_err) = run_xcode_locator( + repository_ctx, + paths["@bazel_tools//tools/osx:xcode_locator.m"], + ) + + if should_use_xcode or xcode_toolchains: + repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:BUILD.toolchains"], "BUILD") + repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:osx_archs.bzl"], "osx_archs.bzl") + else: + _generate_cpp_only_build_file(repository_ctx, cpu_value, paths) + else: + _generate_cpp_only_build_file(repository_ctx, cpu_value, paths) + +cc_autoconf_toolchains = repository_rule( + environ = [ + "BAZEL_USE_CPP_ONLY_TOOLCHAIN", + "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", + ], + implementation = cc_autoconf_toolchains_impl, + configure = True, +) + +def cc_autoconf_impl(repository_ctx, overriden_tools = dict()): + """Generate BUILD file with 'cc_toolchain' targets for the local host C++ toolchain. + + Args: + repository_ctx: repository context + overriden_tools: dict of tool paths to use instead of autoconfigured tools + """ + + env = repository_ctx.os.environ + cpu_value = get_cpu_value(repository_ctx) + if "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" in env and env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] == "1": + paths = resolve_labels(repository_ctx, [ + "@rules_cc//cc/private/toolchain:BUILD.empty", + "@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl", + ]) + repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:empty_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl") + repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:BUILD.empty"], "BUILD") + elif cpu_value == "freebsd": + paths = resolve_labels(repository_ctx, [ + "@rules_cc//cc/private/toolchain:BUILD.static.freebsd", + "@rules_cc//cc/private/toolchain:freebsd_cc_toolchain_config.bzl", + ]) + + # This is defaulting to a static crosstool, we should eventually + # autoconfigure this platform too. Theorically, FreeBSD should be + # straightforward to add but we cannot run it in a docker container so + # skipping until we have proper tests for FreeBSD. + repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:freebsd_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl") + repository_ctx.symlink(paths["@rules_cc//cc/private/toolchain:BUILD.static.freebsd"], "BUILD") + elif cpu_value == "x64_windows": + # TODO(ibiryukov): overriden_tools are only supported in configure_unix_toolchain. + # We might want to add that to Windows too(at least for msys toolchain). + configure_windows_toolchain(repository_ctx) + elif (cpu_value == "darwin" and + ("BAZEL_USE_CPP_ONLY_TOOLCHAIN" not in env or env["BAZEL_USE_CPP_ONLY_TOOLCHAIN"] != "1")): + configure_osx_toolchain(repository_ctx, overriden_tools) + else: + configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools) + +MSVC_ENVVARS = [ + "BAZEL_VC", + "BAZEL_VC_FULL_VERSION", + "BAZEL_VS", + "BAZEL_WINSDK_FULL_VERSION", + "VS90COMNTOOLS", + "VS100COMNTOOLS", + "VS110COMNTOOLS", + "VS120COMNTOOLS", + "VS140COMNTOOLS", + "VS150COMNTOOLS", + "VS160COMNTOOLS", + "TMP", + "TEMP", +] + +cc_autoconf = repository_rule( + environ = [ + "ABI_LIBC_VERSION", + "ABI_VERSION", + "BAZEL_COMPILER", + "BAZEL_HOST_SYSTEM", + "BAZEL_CXXOPTS", + "BAZEL_LINKOPTS", + "BAZEL_LINKLIBS", + "BAZEL_PYTHON", + "BAZEL_SH", + "BAZEL_TARGET_CPU", + "BAZEL_TARGET_LIBC", + "BAZEL_TARGET_SYSTEM", + "BAZEL_USE_CPP_ONLY_TOOLCHAIN", + "BAZEL_USE_XCODE_TOOLCHAIN", + "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN", + "BAZEL_USE_LLVM_NATIVE_COVERAGE", + "BAZEL_LLVM", + "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS", + "USE_CLANG_CL", + "CC", + "CC_CONFIGURE_DEBUG", + "CC_TOOLCHAIN_NAME", + "CPLUS_INCLUDE_PATH", + "GCOV", + "HOMEBREW_RUBY_PATH", + "SYSTEMROOT", + ] + MSVC_ENVVARS, + implementation = cc_autoconf_impl, + configure = True, +) + +# buildifier: disable=unnamed-macro +def cc_configure(): + """A C++ configuration rules that generate the crosstool file.""" + cc_autoconf_toolchains(name = "local_config_cc_toolchains") + cc_autoconf(name = "local_config_cc") + native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain") + native.register_toolchains( + # Use register_toolchain's target pattern expansion to register all toolchains in the package. + "@local_config_cc_toolchains//:all", + ) diff --git a/cc/private/toolchain/cc_toolchain_config.bzl b/cc/private/toolchain/cc_toolchain_config.bzl new file mode 100644 index 0000000..265fce6 --- /dev/null +++ b/cc/private/toolchain/cc_toolchain_config.bzl @@ -0,0 +1,1491 @@ +# Copyright 2019 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. + +"""A Starlark cc_toolchain configuration rule""" + +load( + "@rules_cc//cc:action_names.bzl", + _ASSEMBLE_ACTION_NAME = "ASSEMBLE_ACTION_NAME", + _CLIF_MATCH_ACTION_NAME = "CLIF_MATCH_ACTION_NAME", + _CPP_COMPILE_ACTION_NAME = "CPP_COMPILE_ACTION_NAME", + _CPP_HEADER_PARSING_ACTION_NAME = "CPP_HEADER_PARSING_ACTION_NAME", + _CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME = "CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME", + _CPP_LINK_EXECUTABLE_ACTION_NAME = "CPP_LINK_EXECUTABLE_ACTION_NAME", + _CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME = "CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME", + _CPP_MODULE_CODEGEN_ACTION_NAME = "CPP_MODULE_CODEGEN_ACTION_NAME", + _CPP_MODULE_COMPILE_ACTION_NAME = "CPP_MODULE_COMPILE_ACTION_NAME", + _C_COMPILE_ACTION_NAME = "C_COMPILE_ACTION_NAME", + _LINKSTAMP_COMPILE_ACTION_NAME = "LINKSTAMP_COMPILE_ACTION_NAME", + _LTO_BACKEND_ACTION_NAME = "LTO_BACKEND_ACTION_NAME", + _PREPROCESS_ASSEMBLE_ACTION_NAME = "PREPROCESS_ASSEMBLE_ACTION_NAME", +) +load( + "@rules_cc//cc:cc_toolchain_config_lib.bzl", + "action_config", + "feature", + "flag_group", + "flag_set", + "tool", + "tool_path", + "with_feature_set", +) + +all_compile_actions = [ + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, +] + +all_cpp_compile_actions = [ + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, +] + +preprocessor_compile_actions = [ + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, +] + +codegen_compile_actions = [ + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, +] + +all_link_actions = [ + _CPP_LINK_EXECUTABLE_ACTION_NAME, + _CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME, + _CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME, +] + +def _impl(ctx): + if ctx.attr.disable_static_cc_toolchains: + fail("@rules_cc//cc/private/toolchain:default-toolchain, as well as the cc_toolchains it points " + + "to have been removed. See https://github.com/bazelbuild/bazel/issues/8546.") + + if (ctx.attr.cpu == "darwin"): + toolchain_identifier = "local_darwin" + elif (ctx.attr.cpu == "freebsd"): + toolchain_identifier = "local_freebsd" + elif (ctx.attr.cpu == "local"): + toolchain_identifier = "local_linux" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_clang"): + toolchain_identifier = "local_windows_clang" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_mingw"): + toolchain_identifier = "local_windows_mingw" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + toolchain_identifier = "local_windows_msys64" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64_mingw64"): + toolchain_identifier = "local_windows_msys64_mingw64" + elif (ctx.attr.cpu == "armeabi-v7a"): + toolchain_identifier = "stub_armeabi-v7a" + elif (ctx.attr.cpu == "x64_windows_msvc"): + toolchain_identifier = "vc_14_0_x64" + else: + fail("Unreachable") + + if (ctx.attr.cpu == "armeabi-v7a"): + host_system_name = "armeabi-v7a" + elif (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local" or + ctx.attr.cpu == "x64_windows" or + ctx.attr.cpu == "x64_windows_msvc"): + host_system_name = "local" + else: + fail("Unreachable") + + if (ctx.attr.cpu == "armeabi-v7a"): + target_system_name = "armeabi-v7a" + elif (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local" or + ctx.attr.cpu == "x64_windows" or + ctx.attr.cpu == "x64_windows_msvc"): + target_system_name = "local" + else: + fail("Unreachable") + + if (ctx.attr.cpu == "armeabi-v7a"): + target_cpu = "armeabi-v7a" + elif (ctx.attr.cpu == "darwin"): + target_cpu = "darwin" + elif (ctx.attr.cpu == "freebsd"): + target_cpu = "freebsd" + elif (ctx.attr.cpu == "local"): + target_cpu = "local" + elif (ctx.attr.cpu == "x64_windows"): + target_cpu = "x64_windows" + elif (ctx.attr.cpu == "x64_windows_msvc"): + target_cpu = "x64_windows_msvc" + else: + fail("Unreachable") + + if (ctx.attr.cpu == "armeabi-v7a"): + target_libc = "armeabi-v7a" + elif (ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local" or + ctx.attr.cpu == "x64_windows"): + target_libc = "local" + elif (ctx.attr.cpu == "darwin"): + target_libc = "macosx" + elif (ctx.attr.cpu == "x64_windows_msvc"): + target_libc = "msvcrt140" + else: + fail("Unreachable") + + if (ctx.attr.cpu == "x64_windows_msvc"): + compiler = "cl" + elif (ctx.attr.cpu == "armeabi-v7a" or + ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local"): + compiler = "compiler" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_clang"): + compiler = "windows_clang" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_mingw"): + compiler = "windows_mingw" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + compiler = "windows_msys64" + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64_mingw64"): + compiler = "windows_msys64_mingw64" + else: + fail("Unreachable") + + if (ctx.attr.cpu == "armeabi-v7a"): + abi_version = "armeabi-v7a" + elif (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local" or + ctx.attr.cpu == "x64_windows" or + ctx.attr.cpu == "x64_windows_msvc"): + abi_version = "local" + else: + fail("Unreachable") + + if (ctx.attr.cpu == "armeabi-v7a"): + abi_libc_version = "armeabi-v7a" + elif (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local" or + ctx.attr.cpu == "x64_windows" or + ctx.attr.cpu == "x64_windows_msvc"): + abi_libc_version = "local" + else: + fail("Unreachable") + + cc_target_os = None + + builtin_sysroot = None + + objcopy_embed_data_action = None + if (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local"): + objcopy_embed_data_action = action_config( + action_name = "objcopy_embed_data", + enabled = True, + tools = [tool(path = "/usr/bin/objcopy")], + ) + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_clang"): + objcopy_embed_data_action = action_config( + action_name = "objcopy_embed_data", + enabled = True, + tools = [tool(path = "C:/Program Files (x86)/LLVM/bin/objcopy")], + ) + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_mingw"): + objcopy_embed_data_action = action_config( + action_name = "objcopy_embed_data", + enabled = True, + tools = [tool(path = "C:/mingw/bin/objcopy")], + ) + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64_mingw64"): + objcopy_embed_data_action = action_config( + action_name = "objcopy_embed_data", + enabled = True, + tools = [tool(path = "C:/tools/msys64/mingw64/bin/objcopy")], + ) + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + objcopy_embed_data_action = action_config( + action_name = "objcopy_embed_data", + enabled = True, + tools = [tool(path = "C:/tools/msys64/usr/bin/objcopy")], + ) + + c_compile_action = action_config( + action_name = _C_COMPILE_ACTION_NAME, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = "wrapper/bin/msvc_cl.bat")], + ) + + cpp_compile_action = action_config( + action_name = _CPP_COMPILE_ACTION_NAME, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = "wrapper/bin/msvc_cl.bat")], + ) + + if (ctx.attr.cpu == "armeabi-v7a"): + action_configs = [] + elif (ctx.attr.cpu == "x64_windows_msvc"): + action_configs = [c_compile_action, cpp_compile_action] + elif (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local" or + ctx.attr.cpu == "x64_windows"): + action_configs = [objcopy_embed_data_action] + else: + fail("Unreachable") + + random_seed_feature = feature(name = "random_seed", enabled = True) + + compiler_output_flags_feature = feature( + name = "compiler_output_flags", + flag_sets = [ + flag_set( + actions = [_ASSEMBLE_ACTION_NAME], + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}", "/Zi"], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + ], + ), + flag_set( + actions = [ + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}"], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + flag_group( + flags = ["/Fa%{output_file}"], + expand_if_available = "output_file", + ), + flag_group( + flags = ["/P", "/Fi%{output_file}"], + expand_if_available = "output_file", + ), + ], + ), + ], + ) + + default_link_flags_feature = None + if (ctx.attr.cpu == "local"): + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ + "-lstdc++", + "-Wl,-z,relro,-z,now", + "-no-canonical-prefixes", + "-pass-exit-codes", + ], + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-Wl,--gc-sections"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + elif (ctx.attr.cpu == "freebsd"): + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ + "-lstdc++", + "-Wl,-z,relro,-z,now", + "-no-canonical-prefixes", + ], + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-Wl,--gc-sections"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + elif (ctx.attr.cpu == "darwin"): + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ + "-lstdc++", + "-undefined", + "dynamic_lookup", + "-headerpad_max_install_names", + "-no-canonical-prefixes", + ], + ), + ], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-lstdc++"])], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows_msvc"): + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-m64"])], + ), + ], + ) + + unfiltered_compile_flags_feature = None + if (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd"): + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-no-canonical-prefixes", + "-Wno-builtin-macro-redefined", + "-D__DATE__=\"redacted\"", + "-D__TIMESTAMP__=\"redacted\"", + "-D__TIME__=\"redacted\"", + ], + ), + ], + ), + ], + ) + elif (ctx.attr.cpu == "local"): + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-no-canonical-prefixes", + "-fno-canonical-system-headers", + "-Wno-builtin-macro-redefined", + "-D__DATE__=\"redacted\"", + "-D__TIMESTAMP__=\"redacted\"", + "-D__TIME__=\"redacted\"", + ], + ), + ], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows_msvc"): + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["%{unfiltered_compile_flags}"], + iterate_over = "unfiltered_compile_flags", + expand_if_available = "unfiltered_compile_flags", + ), + ], + ), + ], + ) + + supports_pic_feature = feature(name = "supports_pic", enabled = True) + + default_compile_flags_feature = None + if (ctx.attr.cpu == "darwin"): + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-D_FORTIFY_SOURCE=1", + "-fstack-protector", + "-fcolor-diagnostics", + "-Wall", + "-Wthread-safety", + "-Wself-assign", + "-fno-omit-frame-pointer", + ], + ), + ], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-g"])], + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-g0", + "-O2", + "-DNDEBUG", + "-ffunction-sections", + "-fdata-sections", + ], + ), + ], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = [ + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-std=c++0x"])], + ), + ], + ) + elif (ctx.attr.cpu == "local"): + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-U_FORTIFY_SOURCE", + "-D_FORTIFY_SOURCE=1", + "-fstack-protector", + "-Wall", + "-Wunused-but-set-parameter", + "-Wno-free-nonheap-object", + "-fno-omit-frame-pointer", + ], + ), + ], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-g"])], + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-g0", + "-O2", + "-DNDEBUG", + "-ffunction-sections", + "-fdata-sections", + ], + ), + ], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = [ + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-std=c++0x"])], + ), + ], + ) + elif (ctx.attr.cpu == "freebsd"): + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-U_FORTIFY_SOURCE", + "-D_FORTIFY_SOURCE=1", + "-fstack-protector", + "-Wall", + "-fno-omit-frame-pointer", + ], + ), + ], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-g"])], + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-g0", + "-O2", + "-DNDEBUG", + "-ffunction-sections", + "-fdata-sections", + ], + ), + ], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = [ + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-std=c++0x"])], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows_msvc"): + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = [ + "-m64", + "/D__inline__=__inline", + "/DCOMPILER_MSVC", + "/DNOGDI", + "/DNOMINMAX", + "/DPRAGMA_SUPPORTED", + "/D_WIN32_WINNT=0x0601", + "/D_CRT_SECURE_NO_DEPRECATE", + "/D_CRT_SECURE_NO_WARNINGS", + "/D_SILENCE_STDEXT_HASH_DEPRECATION_WARNINGS", + "/D_USE_MATH_DEFINES", + "/nologo", + "/bigobj", + "/Zm500", + "/J", + "/Gy", + "/GF", + "/W3", + "/EHsc", + "/wd4351", + "/wd4291", + "/wd4250", + "/wd4996", + ], + ), + ], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["/DDEBUG=1", "-g", "/Od", "-Xcompilation-mode=dbg"], + ), + ], + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["/DNDEBUG", "/Od", "-Xcompilation-mode=fastbuild"], + ), + ], + with_features = [with_feature_set(features = ["fastbuild"])], + ), + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["/DNDEBUG", "/O2", "-Xcompilation-mode=opt"], + ), + ], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_clang" or + ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_mingw" or + ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64_mingw64"): + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-std=c++0x"])], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _LINKSTAMP_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [flag_group(flags = ["-std=gnu++0x"])], + ), + ], + ) + + opt_feature = feature(name = "opt") + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + objcopy_embed_flags_feature = feature( + name = "objcopy_embed_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = ["objcopy_embed_data"], + flag_groups = [flag_group(flags = ["-I", "binary"])], + ), + ], + ) + + dbg_feature = feature(name = "dbg") + + user_compile_flags_feature = None + if (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local"): + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows_msvc"): + user_compile_flags_feature = feature( + name = "user_compile_flags", + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + sysroot_feature = None + if (ctx.attr.cpu == "darwin" or + ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local"): + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _LINKSTAMP_COMPILE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _LTO_BACKEND_ACTION_NAME, + _CLIF_MATCH_ACTION_NAME, + _CPP_LINK_EXECUTABLE_ACTION_NAME, + _CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME, + _CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + elif (ctx.attr.cpu == "x64_windows_msvc"): + sysroot_feature = feature( + name = "sysroot", + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + _CPP_LINK_EXECUTABLE_ACTION_NAME, + _CPP_LINK_DYNAMIC_LIBRARY_ACTION_NAME, + _CPP_LINK_NODEPS_DYNAMIC_LIBRARY_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + iterate_over = "sysroot", + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + include_paths_feature = feature( + name = "include_paths", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["/I%{quote_include_paths}"], + iterate_over = "quote_include_paths", + ), + flag_group( + flags = ["/I%{include_paths}"], + iterate_over = "include_paths", + ), + flag_group( + flags = ["/I%{system_include_paths}"], + iterate_over = "system_include_paths", + ), + ], + ), + ], + ) + + dependency_file_feature = feature( + name = "dependency_file", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["/DEPENDENCY_FILE", "%{dependency_file}"], + expand_if_available = "dependency_file", + ), + ], + ), + ], + ) + + compiler_input_flags_feature = feature( + name = "compiler_input_flags", + flag_sets = [ + flag_set( + actions = [ + _ASSEMBLE_ACTION_NAME, + _PREPROCESS_ASSEMBLE_ACTION_NAME, + _C_COMPILE_ACTION_NAME, + _CPP_COMPILE_ACTION_NAME, + _CPP_HEADER_PARSING_ACTION_NAME, + _CPP_MODULE_COMPILE_ACTION_NAME, + _CPP_MODULE_CODEGEN_ACTION_NAME, + ], + flag_groups = [ + flag_group( + flags = ["/c", "%{source_file}"], + expand_if_available = "source_file", + ), + ], + ), + ], + ) + + fastbuild_feature = feature(name = "fastbuild") + + features = None + if (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + features = [ + default_compile_flags_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + objcopy_embed_flags_feature, + ] + elif (ctx.attr.cpu == "darwin"): + features = [ + default_compile_flags_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + supports_pic_feature, + objcopy_embed_flags_feature, + dbg_feature, + opt_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + ] + elif (ctx.attr.cpu == "freebsd" or + ctx.attr.cpu == "local"): + features = [ + default_compile_flags_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + supports_pic_feature, + objcopy_embed_flags_feature, + opt_feature, + dbg_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + ] + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_clang" or + ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_mingw" or + ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64_mingw64"): + features = [ + default_compile_flags_feature, + supports_dynamic_linker_feature, + objcopy_embed_flags_feature, + ] + elif (ctx.attr.cpu == "x64_windows_msvc"): + features = [ + default_link_flags_feature, + random_seed_feature, + default_compile_flags_feature, + include_paths_feature, + dependency_file_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + compiler_output_flags_feature, + compiler_input_flags_feature, + dbg_feature, + fastbuild_feature, + opt_feature, + ] + elif (ctx.attr.cpu == "armeabi-v7a"): + features = [supports_dynamic_linker_feature, supports_pic_feature] + + if (ctx.attr.cpu == "armeabi-v7a"): + cxx_builtin_include_directories = [] + elif (ctx.attr.cpu == "darwin"): + cxx_builtin_include_directories = ["/"] + elif (ctx.attr.cpu == "freebsd"): + cxx_builtin_include_directories = ["/usr/lib/clang", "/usr/local/include", "/usr/include"] + elif (ctx.attr.cpu == "local" or + ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_clang"): + cxx_builtin_include_directories = ["/usr/lib/gcc/", "/usr/local/include", "/usr/include"] + elif (ctx.attr.cpu == "x64_windows_msvc"): + cxx_builtin_include_directories = [ + "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/INCLUDE", + "C:/Program Files (x86)/Windows Kits/10/include/", + "C:/Program Files (x86)/Windows Kits/8.1/include/", + "C:/Program Files (x86)/GnuWin32/include/", + "C:/python_27_amd64/files/include", + ] + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_mingw"): + cxx_builtin_include_directories = ["C:/mingw/include", "C:/mingw/lib/gcc"] + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64_mingw64"): + cxx_builtin_include_directories = ["C:/tools/msys64/mingw64/x86_64-w64-mingw32/include"] + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + cxx_builtin_include_directories = ["C:/tools/msys64/", "/usr/"] + else: + fail("Unreachable") + + artifact_name_patterns = [] + + make_variables = [] + + if (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64_mingw64"): + tool_paths = [ + tool_path( + name = "ar", + path = "C:/tools/msys64/mingw64/bin/ar", + ), + tool_path( + name = "compat-ld", + path = "C:/tools/msys64/mingw64/bin/ld", + ), + tool_path( + name = "cpp", + path = "C:/tools/msys64/mingw64/bin/cpp", + ), + tool_path( + name = "dwp", + path = "C:/tools/msys64/mingw64/bin/dwp", + ), + tool_path( + name = "gcc", + path = "C:/tools/msys64/mingw64/bin/gcc", + ), + tool_path( + name = "gcov", + path = "C:/tools/msys64/mingw64/bin/gcov", + ), + tool_path( + name = "ld", + path = "C:/tools/msys64/mingw64/bin/ld", + ), + tool_path( + name = "nm", + path = "C:/tools/msys64/mingw64/bin/nm", + ), + tool_path( + name = "objcopy", + path = "C:/tools/msys64/mingw64/bin/objcopy", + ), + tool_path( + name = "objdump", + path = "C:/tools/msys64/mingw64/bin/objdump", + ), + tool_path( + name = "strip", + path = "C:/tools/msys64/mingw64/bin/strip", + ), + ] + elif (ctx.attr.cpu == "armeabi-v7a"): + tool_paths = [ + tool_path(name = "ar", path = "/bin/false"), + tool_path(name = "compat-ld", path = "/bin/false"), + tool_path(name = "cpp", path = "/bin/false"), + tool_path(name = "dwp", path = "/bin/false"), + tool_path(name = "gcc", path = "/bin/false"), + tool_path(name = "gcov", path = "/bin/false"), + tool_path(name = "ld", path = "/bin/false"), + tool_path(name = "nm", path = "/bin/false"), + tool_path(name = "objcopy", path = "/bin/false"), + tool_path(name = "objdump", path = "/bin/false"), + tool_path(name = "strip", path = "/bin/false"), + ] + elif (ctx.attr.cpu == "freebsd"): + tool_paths = [ + tool_path(name = "ar", path = "/usr/bin/ar"), + tool_path(name = "compat-ld", path = "/usr/bin/ld"), + tool_path(name = "cpp", path = "/usr/bin/cpp"), + tool_path(name = "dwp", path = "/usr/bin/dwp"), + tool_path(name = "gcc", path = "/usr/bin/clang"), + tool_path(name = "gcov", path = "/usr/bin/gcov"), + tool_path(name = "ld", path = "/usr/bin/ld"), + tool_path(name = "nm", path = "/usr/bin/nm"), + tool_path(name = "objcopy", path = "/usr/bin/objcopy"), + tool_path(name = "objdump", path = "/usr/bin/objdump"), + tool_path(name = "strip", path = "/usr/bin/strip"), + ] + elif (ctx.attr.cpu == "local"): + tool_paths = [ + tool_path(name = "ar", path = "/usr/bin/ar"), + tool_path(name = "compat-ld", path = "/usr/bin/ld"), + tool_path(name = "cpp", path = "/usr/bin/cpp"), + tool_path(name = "dwp", path = "/usr/bin/dwp"), + tool_path(name = "gcc", path = "/usr/bin/gcc"), + tool_path(name = "gcov", path = "/usr/bin/gcov"), + tool_path(name = "ld", path = "/usr/bin/ld"), + tool_path(name = "nm", path = "/usr/bin/nm"), + tool_path(name = "objcopy", path = "/usr/bin/objcopy"), + tool_path(name = "objdump", path = "/usr/bin/objdump"), + tool_path(name = "strip", path = "/usr/bin/strip"), + ] + elif (ctx.attr.cpu == "darwin"): + tool_paths = [ + tool_path(name = "ar", path = "/usr/bin/libtool"), + tool_path(name = "compat-ld", path = "/usr/bin/ld"), + tool_path(name = "cpp", path = "/usr/bin/cpp"), + tool_path(name = "dwp", path = "/usr/bin/dwp"), + tool_path(name = "gcc", path = "osx_cc_wrapper.sh"), + tool_path(name = "gcov", path = "/usr/bin/gcov"), + tool_path(name = "ld", path = "/usr/bin/ld"), + tool_path(name = "nm", path = "/usr/bin/nm"), + tool_path(name = "objcopy", path = "/usr/bin/objcopy"), + tool_path(name = "objdump", path = "/usr/bin/objdump"), + tool_path(name = "strip", path = "/usr/bin/strip"), + ] + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_clang"): + tool_paths = [ + tool_path(name = "ar", path = "C:/mingw/bin/ar"), + tool_path( + name = "compat-ld", + path = "C:/Program Files (x86)/LLVM/bin/ld", + ), + tool_path( + name = "cpp", + path = "C:/Program Files (x86)/LLVM/bin/cpp", + ), + tool_path( + name = "dwp", + path = "C:/Program Files (x86)/LLVM/bin/dwp", + ), + tool_path( + name = "gcc", + path = "C:/Program Files (x86)/LLVM/bin/clang", + ), + tool_path( + name = "gcov", + path = "C:/Program Files (x86)/LLVM/bin/gcov", + ), + tool_path( + name = "ld", + path = "C:/Program Files (x86)/LLVM/bin/ld", + ), + tool_path( + name = "nm", + path = "C:/Program Files (x86)/LLVM/bin/nm", + ), + tool_path( + name = "objcopy", + path = "C:/Program Files (x86)/LLVM/bin/objcopy", + ), + tool_path( + name = "objdump", + path = "C:/Program Files (x86)/LLVM/bin/objdump", + ), + tool_path( + name = "strip", + path = "C:/Program Files (x86)/LLVM/bin/strip", + ), + ] + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_mingw"): + tool_paths = [ + tool_path(name = "ar", path = "C:/mingw/bin/ar"), + tool_path(name = "compat-ld", path = "C:/mingw/bin/ld"), + tool_path(name = "cpp", path = "C:/mingw/bin/cpp"), + tool_path(name = "dwp", path = "C:/mingw/bin/dwp"), + tool_path(name = "gcc", path = "C:/mingw/bin/gcc"), + tool_path(name = "gcov", path = "C:/mingw/bin/gcov"), + tool_path(name = "ld", path = "C:/mingw/bin/ld"), + tool_path(name = "nm", path = "C:/mingw/bin/nm"), + tool_path(name = "objcopy", path = "C:/mingw/bin/objcopy"), + tool_path(name = "objdump", path = "C:/mingw/bin/objdump"), + tool_path(name = "strip", path = "C:/mingw/bin/strip"), + ] + elif (ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "windows_msys64"): + tool_paths = [ + tool_path(name = "ar", path = "C:/tools/msys64/usr/bin/ar"), + tool_path( + name = "compat-ld", + path = "C:/tools/msys64/usr/bin/ld", + ), + tool_path( + name = "cpp", + path = "C:/tools/msys64/usr/bin/cpp", + ), + tool_path( + name = "dwp", + path = "C:/tools/msys64/usr/bin/dwp", + ), + tool_path( + name = "gcc", + path = "C:/tools/msys64/usr/bin/gcc", + ), + tool_path( + name = "gcov", + path = "C:/tools/msys64/usr/bin/gcov", + ), + tool_path(name = "ld", path = "C:/tools/msys64/usr/bin/ld"), + tool_path(name = "nm", path = "C:/tools/msys64/usr/bin/nm"), + tool_path( + name = "objcopy", + path = "C:/tools/msys64/usr/bin/objcopy", + ), + tool_path( + name = "objdump", + path = "C:/tools/msys64/usr/bin/objdump", + ), + tool_path( + name = "strip", + path = "C:/tools/msys64/usr/bin/strip", + ), + ] + elif (ctx.attr.cpu == "x64_windows_msvc"): + tool_paths = [ + tool_path(name = "ar", path = "wrapper/bin/msvc_link.bat"), + tool_path(name = "cpp", path = "wrapper/bin/msvc_cl.bat"), + tool_path(name = "gcc", path = "wrapper/bin/msvc_cl.bat"), + tool_path(name = "gcov", path = "wrapper/bin/msvc_nop.bat"), + tool_path(name = "ld", path = "wrapper/bin/msvc_link.bat"), + tool_path(name = "nm", path = "wrapper/bin/msvc_nop.bat"), + tool_path( + name = "objcopy", + path = "wrapper/bin/msvc_nop.bat", + ), + tool_path( + name = "objdump", + path = "wrapper/bin/msvc_nop.bat", + ), + tool_path( + name = "strip", + path = "wrapper/bin/msvc_nop.bat", + ), + ] + else: + fail("Unreachable") + + out = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write(out, "Fake executable") + return [ + cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = target_cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + make_variables = make_variables, + builtin_sysroot = builtin_sysroot, + cc_target_os = cc_target_os, + ), + DefaultInfo( + executable = out, + ), + ] + +cc_toolchain_config = rule( + implementation = _impl, + attrs = { + "compiler": attr.string(), + "cpu": attr.string(mandatory = True), + "disable_static_cc_toolchains": attr.bool(), + }, + provides = [CcToolchainConfigInfo], + executable = True, +) diff --git a/cc/private/toolchain/clang_installation_error.bat.tpl b/cc/private/toolchain/clang_installation_error.bat.tpl new file mode 100644 index 0000000..e3a61a4 --- /dev/null +++ b/cc/private/toolchain/clang_installation_error.bat.tpl @@ -0,0 +1,24 @@ +:: Copyright 2019 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. + +@echo OFF + +echo. 1>&2 +echo The target you are compiling requires the Clang compiler. 1>&2 +echo Bazel couldn't find a valid Clang installation on your machine. 1>&2 +%{clang_error_message} +echo Please check your installation following https://docs.bazel.build/versions/main/windows.html#using 1>&2 +echo. 1>&2 + +exit /b 1 diff --git a/cc/private/toolchain/empty.cc b/cc/private/toolchain/empty.cc new file mode 100644 index 0000000..4cda5c6 --- /dev/null +++ b/cc/private/toolchain/empty.cc @@ -0,0 +1,15 @@ +// Copyright 2017 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. + +int main() {} diff --git a/cc/private/toolchain/empty_cc_toolchain_config.bzl b/cc/private/toolchain/empty_cc_toolchain_config.bzl new file mode 100644 index 0000000..5d42d06 --- /dev/null +++ b/cc/private/toolchain/empty_cc_toolchain_config.bzl @@ -0,0 +1,42 @@ +# Copyright 2019 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. + +"""A fake C++ toolchain configuration rule""" + +def _impl(ctx): + out = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write(out, "Fake executable") + return [ + cc_common.create_cc_toolchain_config_info( + ctx = ctx, + toolchain_identifier = "local_linux", + host_system_name = "local", + target_system_name = "local", + target_cpu = "local", + target_libc = "local", + compiler = "compiler", + abi_version = "local", + abi_libc_version = "local", + ), + DefaultInfo( + executable = out, + ), + ] + +cc_toolchain_config = rule( + implementation = _impl, + attrs = {}, + provides = [CcToolchainConfigInfo], + executable = True, +) diff --git a/cc/private/toolchain/freebsd_cc_toolchain_config.bzl b/cc/private/toolchain/freebsd_cc_toolchain_config.bzl new file mode 100644 index 0000000..3521d92 --- /dev/null +++ b/cc/private/toolchain/freebsd_cc_toolchain_config.bzl @@ -0,0 +1,307 @@ +# Copyright 2019 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. + +"""A Starlark cc_toolchain configuration rule for freebsd.""" + +load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES") +load( + "@rules_cc//cc:cc_toolchain_config_lib.bzl", + "action_config", + "feature", + "flag_group", + "flag_set", + "tool", + "tool_path", + "with_feature_set", +) + +all_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, + ACTION_NAMES.lto_backend, +] + +all_cpp_compile_actions = [ + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, +] + +all_link_actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, +] + +def _impl(ctx): + cpu = ctx.attr.cpu + compiler = "compiler" + toolchain_identifier = "local_freebsd" if cpu == "freebsd" else "stub_armeabi-v7a" + host_system_name = "local" if cpu == "freebsd" else "armeabi-v7a" + target_system_name = "local" if cpu == "freebsd" else "armeabi-v7a" + target_libc = "local" if cpu == "freebsd" else "armeabi-v7a" + abi_version = "local" if cpu == "freebsd" else "armeabi-v7a" + abi_libc_version = "local" if cpu == "freebsd" else "armeabi-v7a" + + objcopy_embed_data_action = action_config( + action_name = "objcopy_embed_data", + enabled = True, + tools = [tool(path = "/usr/bin/objcopy")], + ) + + action_configs = [objcopy_embed_data_action] if cpu == "freebsd" else [] + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ + "-lstdc++", + "-Wl,-z,relro,-z,now", + "-no-canonical-prefixes", + ], + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-Wl,--gc-sections"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = [ + flag_group( + flags = [ + "-no-canonical-prefixes", + "-Wno-builtin-macro-redefined", + "-D__DATE__=\"redacted\"", + "-D__TIMESTAMP__=\"redacted\"", + "-D__TIME__=\"redacted\"", + ], + ), + ], + ), + ], + ) + + supports_pic_feature = feature(name = "supports_pic", enabled = True) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = [ + flag_group( + flags = [ + "-U_FORTIFY_SOURCE", + "-D_FORTIFY_SOURCE=1", + "-fstack-protector", + "-Wall", + "-fno-omit-frame-pointer", + ], + ), + ], + ), + flag_set( + actions = all_compile_actions, + flag_groups = [flag_group(flags = ["-g"])], + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = all_compile_actions, + flag_groups = [ + flag_group( + flags = [ + "-g0", + "-O2", + "-DNDEBUG", + "-ffunction-sections", + "-fdata-sections", + ], + ), + ], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = all_cpp_compile_actions + [ACTION_NAMES.lto_backend], + flag_groups = [flag_group(flags = ["-std=c++0x"])], + ), + ], + ) + + opt_feature = feature(name = "opt") + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + objcopy_embed_flags_feature = feature( + name = "objcopy_embed_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = ["objcopy_embed_data"], + flag_groups = [flag_group(flags = ["-I", "binary"])], + ), + ], + ) + + dbg_feature = feature(name = "dbg") + + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, + ACTION_NAMES.lto_backend, + ] + all_link_actions, + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + if cpu == "freebsd": + features = [ + default_compile_flags_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + supports_pic_feature, + objcopy_embed_flags_feature, + opt_feature, + dbg_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + ] + else: + features = [supports_dynamic_linker_feature, supports_pic_feature] + + if (cpu == "freebsd"): + cxx_builtin_include_directories = ["/usr/lib/clang", "/usr/local/include", "/usr/include"] + else: + cxx_builtin_include_directories = [] + + if cpu == "freebsd": + tool_paths = [ + tool_path(name = "ar", path = "/usr/bin/ar"), + tool_path(name = "compat-ld", path = "/usr/bin/ld"), + tool_path(name = "cpp", path = "/usr/bin/cpp"), + tool_path(name = "dwp", path = "/usr/bin/dwp"), + tool_path(name = "gcc", path = "/usr/bin/clang"), + tool_path(name = "gcov", path = "/usr/bin/gcov"), + tool_path(name = "ld", path = "/usr/bin/ld"), + tool_path(name = "nm", path = "/usr/bin/nm"), + tool_path(name = "objcopy", path = "/usr/bin/objcopy"), + tool_path(name = "objdump", path = "/usr/bin/objdump"), + tool_path(name = "strip", path = "/usr/bin/strip"), + ] + else: + tool_paths = [ + tool_path(name = "ar", path = "/bin/false"), + tool_path(name = "compat-ld", path = "/bin/false"), + tool_path(name = "cpp", path = "/bin/false"), + tool_path(name = "dwp", path = "/bin/false"), + tool_path(name = "gcc", path = "/bin/false"), + tool_path(name = "gcov", path = "/bin/false"), + tool_path(name = "ld", path = "/bin/false"), + tool_path(name = "nm", path = "/bin/false"), + tool_path(name = "objcopy", path = "/bin/false"), + tool_path(name = "objdump", path = "/bin/false"), + tool_path(name = "strip", path = "/bin/false"), + ] + + out = ctx.actions.declare_file(ctx.label.name) + ctx.actions.write(out, "Fake executable") + return [ + cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + cxx_builtin_include_directories = cxx_builtin_include_directories, + toolchain_identifier = toolchain_identifier, + host_system_name = host_system_name, + target_system_name = target_system_name, + target_cpu = cpu, + target_libc = target_libc, + compiler = compiler, + abi_version = abi_version, + abi_libc_version = abi_libc_version, + tool_paths = tool_paths, + ), + DefaultInfo( + executable = out, + ), + ] + +cc_toolchain_config = rule( + implementation = _impl, + attrs = { + "cpu": attr.string(mandatory = True), + }, + provides = [CcToolchainConfigInfo], + executable = True, +) diff --git a/cc/private/toolchain/grep-includes.sh b/cc/private/toolchain/grep-includes.sh new file mode 100755 index 0000000..ee51361 --- /dev/null +++ b/cc/private/toolchain/grep-includes.sh @@ -0,0 +1,19 @@ +#!/bin/bash +# +# Copyright 2018 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. +# +# TODO(bazel-team): Support include scanning and grep-includes in Bazel +echo "grep-includes is not supported by Bazel" +exit 1 diff --git a/cc/private/toolchain/lib_cc_configure.bzl b/cc/private/toolchain/lib_cc_configure.bzl new file mode 100644 index 0000000..bcd9013 --- /dev/null +++ b/cc/private/toolchain/lib_cc_configure.bzl @@ -0,0 +1,286 @@ +# pylint: disable=g-bad-file-header +# Copyright 2016 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. +"""Base library for configuring the C++ toolchain.""" + +def resolve_labels(repository_ctx, labels): + """Resolves a collection of labels to their paths. + + Label resolution can cause the evaluation of Starlark functions to restart. + For functions with side-effects (like the auto-configuration functions, which + inspect the system and touch the file system), such restarts are costly. + We cannot avoid the restarts, but we can minimize their penalty by resolving + all labels upfront. + + Among other things, doing less work on restarts can cut analysis times by + several seconds and may also prevent tickling kernel conditions that cause + build failures. See https://github.com/bazelbuild/bazel/issues/5196 for + more details. + + Args: + repository_ctx: The context with which to resolve the labels. + labels: Labels to be resolved expressed as a list of strings. + + Returns: + A dictionary with the labels as keys and their paths as values. + """ + return dict([(label, repository_ctx.path(Label(label))) for label in labels]) + +def escape_string(arg): + """Escape percent sign (%) in the string so it can appear in the Crosstool.""" + if arg != None: + return str(arg).replace("%", "%%") + else: + return None + +def split_escaped(string, delimiter): + """Split string on the delimiter unless %-escaped. + + Examples: + Basic usage: + split_escaped("a:b:c", ":") -> [ "a", "b", "c" ] + + Delimeter that is not supposed to be splitten on has to be %-escaped: + split_escaped("a%:b", ":") -> [ "a:b" ] + + Literal % can be represented by escaping it as %%: + split_escaped("a%%b", ":") -> [ "a%b" ] + + Consecutive delimiters produce empty strings: + split_escaped("a::b", ":") -> [ "a", "", "", "b" ] + + Args: + string: The string to be split. + delimiter: Non-empty string not containing %-sign to be used as a + delimiter. + + Returns: + A list of substrings. + """ + if delimiter == "": + fail("Delimiter cannot be empty") + if delimiter.find("%") != -1: + fail("Delimiter cannot contain %-sign") + + i = 0 + result = [] + accumulator = [] + length = len(string) + delimiter_length = len(delimiter) + + if not string: + return [] + + # Iterate over the length of string since Starlark doesn't have while loops + for _ in range(length): + if i >= length: + break + if i + 2 <= length and string[i:i + 2] == "%%": + accumulator.append("%") + i += 2 + elif (i + 1 + delimiter_length <= length and + string[i:i + 1 + delimiter_length] == "%" + delimiter): + accumulator.append(delimiter) + i += 1 + delimiter_length + elif i + delimiter_length <= length and string[i:i + delimiter_length] == delimiter: + result.append("".join(accumulator)) + accumulator = [] + i += delimiter_length + else: + accumulator.append(string[i]) + i += 1 + + # Append the last group still in accumulator + result.append("".join(accumulator)) + return result + +def auto_configure_fail(msg): + """Output failure message when auto configuration fails.""" + red = "\033[0;31m" + no_color = "\033[0m" + fail("\n%sAuto-Configuration Error:%s %s\n" % (red, no_color, msg)) + +def auto_configure_warning(msg): + """Output warning message during auto configuration.""" + yellow = "\033[1;33m" + no_color = "\033[0m" + + # buildifier: disable=print + print("\n%sAuto-Configuration Warning:%s %s\n" % (yellow, no_color, msg)) + +def get_env_var(repository_ctx, name, default = None, enable_warning = True): + """Find an environment variable in system path. Doesn't %-escape the value! + + Args: + repository_ctx: The repository context. + name: Name of the environment variable. + default: Default value to be used when such environment variable is not present. + enable_warning: Show warning if the variable is not present. + Returns: + value of the environment variable or default. + """ + + if name in repository_ctx.os.environ: + return repository_ctx.os.environ[name] + if default != None: + if enable_warning: + auto_configure_warning("'%s' environment variable is not set, using '%s' as default" % (name, default)) + return default + return auto_configure_fail("'%s' environment variable is not set" % name) + +def which(repository_ctx, cmd, default = None): + """A wrapper around repository_ctx.which() to provide a fallback value. Doesn't %-escape the value! + + Args: + repository_ctx: The repository context. + cmd: name of the executable to resolve. + default: Value to be returned when such executable couldn't be found. + Returns: + absolute path to the cmd or default when not found. + """ + result = repository_ctx.which(cmd) + return default if result == None else str(result) + +def which_cmd(repository_ctx, cmd, default = None): + """Find cmd in PATH using repository_ctx.which() and fail if cannot find it. Doesn't %-escape the cmd! + + Args: + repository_ctx: The repository context. + cmd: name of the executable to resolve. + default: Value to be returned when such executable couldn't be found. + Returns: + absolute path to the cmd or default when not found. + """ + result = repository_ctx.which(cmd) + if result != None: + return str(result) + path = get_env_var(repository_ctx, "PATH") + if default != None: + auto_configure_warning("Cannot find %s in PATH, using '%s' as default.\nPATH=%s" % (cmd, default, path)) + return default + auto_configure_fail("Cannot find %s in PATH, please make sure %s is installed and add its directory in PATH.\nPATH=%s" % (cmd, cmd, path)) + return str(result) + +def execute( + repository_ctx, + command, + environment = None, + expect_failure = False): + """Execute a command, return stdout if succeed and throw an error if it fails. Doesn't %-escape the result! + + Args: + repository_ctx: The repository context. + command: command to execute. + environment: dictionary with environment variables to set for the command. + expect_failure: True if the command is expected to fail. + Returns: + stdout of the executed command. + """ + if environment: + result = repository_ctx.execute(command, environment = environment) + else: + result = repository_ctx.execute(command) + if expect_failure != (result.return_code != 0): + if expect_failure: + auto_configure_fail( + "expected failure, command %s, stderr: (%s)" % ( + command, + result.stderr, + ), + ) + else: + auto_configure_fail( + "non-zero exit code: %d, command %s, stderr: (%s)" % ( + result.return_code, + command, + result.stderr, + ), + ) + stripped_stdout = result.stdout.strip() + if not stripped_stdout: + auto_configure_fail( + "empty output from command %s, stderr: (%s)" % (command, result.stderr), + ) + return stripped_stdout + +def get_cpu_value(repository_ctx): + """Compute the cpu_value based on the OS name. Doesn't %-escape the result! + + Args: + repository_ctx: The repository context. + Returns: + One of (darwin, freebsd, x64_windows, ppc, s390x, arm, aarch64, k8, piii) + """ + os_name = repository_ctx.os.name.lower() + if os_name.startswith("mac os"): + return "darwin" + if os_name.find("freebsd") != -1: + return "freebsd" + if os_name.find("windows") != -1: + return "x64_windows" + + # Use uname to figure out whether we are on x86_32 or x86_64 + result = repository_ctx.execute(["uname", "-m"]) + if result.stdout.strip() in ["power", "ppc64le", "ppc", "ppc64"]: + return "ppc" + if result.stdout.strip() in ["s390x"]: + return "s390x" + if result.stdout.strip() in ["arm", "armv7l"]: + return "arm" + if result.stdout.strip() in ["aarch64"]: + return "aarch64" + return "k8" if result.stdout.strip() in ["amd64", "x86_64", "x64"] else "piii" + +def is_cc_configure_debug(repository_ctx): + """Returns True if CC_CONFIGURE_DEBUG is set to 1.""" + env = repository_ctx.os.environ + return "CC_CONFIGURE_DEBUG" in env and env["CC_CONFIGURE_DEBUG"] == "1" + +def build_flags(flags): + """Convert `flags` to a string of flag fields.""" + return "\n".join([" flag: '" + flag + "'" for flag in flags]) + +def get_starlark_list(values): + """Convert a list of string into a string that can be passed to a rule attribute.""" + if not values: + return "" + return "\"" + "\",\n \"".join(values) + "\"" + +def auto_configure_warning_maybe(repository_ctx, msg): + """Output warning message when CC_CONFIGURE_DEBUG is enabled.""" + if is_cc_configure_debug(repository_ctx): + auto_configure_warning(msg) + +def write_builtin_include_directory_paths(repository_ctx, cc, directories, file_suffix = ""): + """Generate output file named 'builtin_include_directory_paths' in the root of the repository.""" + if get_env_var(repository_ctx, "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS", "0", False) == "1": + repository_ctx.file( + "builtin_include_directory_paths" + file_suffix, + """This file is generated by cc_configure and normally contains builtin include directories +that C++ compiler reported. But because BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS was set to 1, +header include directory paths are intentionally not put there. +""", + ) + else: + repository_ctx.file( + "builtin_include_directory_paths" + file_suffix, + """This file is generated by cc_configure and contains builtin include directories +that %s reported. This file is a dependency of every compilation action and +changes to it will be reflected in the action cache key. When some of these +paths change, Bazel will make sure to rerun the action, even though none of +declared action inputs or the action commandline changes. + +%s +""" % (cc, "\n".join(directories)), + ) diff --git a/cc/private/toolchain/libtool_check_unique.cc b/cc/private/toolchain/libtool_check_unique.cc new file mode 100644 index 0000000..340e9a3 --- /dev/null +++ b/cc/private/toolchain/libtool_check_unique.cc @@ -0,0 +1,109 @@ +// Copyright 2020 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. + +#include +#include +#include +#include // NOLINT +#include + +using std::ifstream; +using std::regex; +using std::string; +using std::unordered_set; +using std::vector; + +const regex libRegex = regex(".*\\.a$"); +const regex noArgFlags = + regex("-static|-s|-a|-c|-L|-T|-D|-no_warning_for_no_symbols"); +const regex singleArgFlags = regex("-arch_only|-syslibroot|-o"); + +string getBasename(const string &path) { + // Assumes we're on an OS with "/" as the path separator + auto idx = path.find_last_of("/"); + if (idx == string::npos) { + return path; + } + return path.substr(idx + 1); +} + +vector readFile(const string path) { + vector lines; + ifstream file(path); + string line; + while (std::getline(file, line)) { + if (!line.empty()) { + lines.push_back(line); + } + } + + return lines; +} + +unordered_set parseArgs(vector args) { + unordered_set basenames; + for (auto it = args.begin(); it != args.end(); ++it) { + const string arg = *it; + if (arg == "-filelist") { + ++it; + ifstream list(*it); + for (string line; getline(list, line);) { + const string basename = getBasename(line); + const auto pair = basenames.insert(basename); + if (!pair.second) { + exit(EXIT_FAILURE); + } + } + list.close(); + } else if (arg[0] == '@') { + string paramsFilePath(arg.substr(1)); + auto newBasenames = parseArgs(readFile(paramsFilePath)); + for (auto newBasename : newBasenames) { + const auto pair = basenames.insert(newBasename); + if (!pair.second) { + exit(EXIT_FAILURE); + } + } + } else if (regex_match(arg, noArgFlags)) { + } else if (regex_match(arg, singleArgFlags)) { + ++it; + } else if (arg[0] == '-') { + exit(EXIT_FAILURE); + // Unrecognized flag, let the wrapper deal with it, any flags added to + // libtool.sh should also be added here. + } else if (regex_match(arg, libRegex)) { + // Archive inputs can remain untouched, as they come from other targets. + } else { + const string basename = getBasename(arg); + const auto pair = basenames.insert(basename); + if (!pair.second) { + exit(EXIT_FAILURE); + } + } + } + + return basenames; +} + +// Returns 0 if there are no duplicate basenames in the object files (via +// -filelist, params files, and shell args), 1 otherwise +int main(int argc, const char *argv[]) { + vector args; + // Set i to 1 to skip executable path + for (int i = 1; argv[i] != nullptr; i++) { + args.push_back(argv[i]); + } + parseArgs(args); + return EXIT_SUCCESS; +} diff --git a/cc/private/toolchain/link_dynamic_library.sh b/cc/private/toolchain/link_dynamic_library.sh new file mode 100755 index 0000000..c71d498 --- /dev/null +++ b/cc/private/toolchain/link_dynamic_library.sh @@ -0,0 +1,113 @@ +#!/bin/bash +# +# Copyright 2016 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. + +# This script handles interface library generation for dynamic library +# link action. +# +# Bazel can be configured to generate external interface library script +# to generate interface libraries in CppLinkAction for dynamic libraries. +# This is not needed on Windows (as the "interface" libraries are +# generated by default). This script therefore handles the cases when +# external script is provided, or when no script should be used. + +set -eu + +E_LINKER_COMMAND_NOT_FOUND=12 +E_INTERFACE_BUILDER_NOT_FOUND=13 + + +SUFFIX=".rewritten" + +other_args="" + +if [[ "$#" -eq 1 ]]; then + if [[ "$1" != @* ]]; then + echo "Parameter file must start with @" 1>&2; + exit "$E_LINKER_COMMAND_NOT_FOUND" + fi + + filename=$(echo "$1" | cut -c2-) + first_five_lines=$(head -n 5 $filename) + + # Should generate interface library switch (); if the value is "no", + # following 3 args are ignored (but must be present) + GENERATE_INTERFACE_LIBRARY=$(echo "$first_five_lines" | head -n1 | tail -n1) + # Tool which can generate interface library from dynamic library file + INTERFACE_LIBRARY_BUILDER=$(echo "$first_five_lines" | head -n2 | tail -n1) + # Dynamic library from which we want to generate interface library + DYNAMIC_LIBRARY=$(echo "$first_five_lines" | head -n3 | tail -n1) + # Resulting interface library + INTERFACE_LIBRARY=$(echo "$first_five_lines" | head -n4 | tail -n1) + # The command used to generate the dynamic library + LINKER_COMMAND=$(echo "$first_five_lines" | head -n5 | tail -n1) + + rest_of_lines=$(tail -n +6 $filename) + new_param_file="${filename}${SUFFIX}" + echo "$rest_of_lines" > $new_param_file + other_args="@$new_param_file" + + if [[ ! -e "$LINKER_COMMAND" ]]; then + echo "Linker command ($LINKER_COMMAND) not found." 1>&2; + exit "$E_LINKER_COMMAND_NOT_FOUND" + fi + + if [[ "no" == "$GENERATE_INTERFACE_LIBRARY" ]]; then + INTERFACE_GENERATION=: + else + if [[ ! -e "$INTERFACE_LIBRARY_BUILDER" ]]; then + echo "Interface library builder ($INTERFACE_LIBRARY_BUILDER) + not found." 1>&2; + exit "$E_INTERFACE_BUILDER_NOT_FOUND" + fi + INTERFACE_GENERATION="${INTERFACE_LIBRARY_BUILDER} ${DYNAMIC_LIBRARY} + ${INTERFACE_LIBRARY}" + fi + + ${LINKER_COMMAND} "$other_args" && ${INTERFACE_GENERATION} +else + # TODO(b/113358321): Remove this branch once projects are migrated to not + # splitting the linking command line. + # Should generate interface library switch (); if the value is "no", + # following 3 args are ignored (but must be present) + GENERATE_INTERFACE_LIBRARY="$1" + # Tool which can generate interface library from dynamic library file + INTERFACE_LIBRARY_BUILDER="$2" + # Dynamic library from which we want to generate interface library + DYNAMIC_LIBRARY="$3" + # Resulting interface library + INTERFACE_LIBRARY="$4" + # The command used to generate the dynamic library + LINKER_COMMAND="$5" + shift 5 + if [[ ! -e "$LINKER_COMMAND" ]]; then + echo "Linker command ($LINKER_COMMAND) not found." 1>&2; + exit "$E_LINKER_COMMAND_NOT_FOUND" + fi + + if [[ "no" == "$GENERATE_INTERFACE_LIBRARY" ]]; then + INTERFACE_GENERATION=: + else + if [[ ! -e "$INTERFACE_LIBRARY_BUILDER" ]]; then + echo "Interface library builder ($INTERFACE_LIBRARY_BUILDER) + not found." 1>&2; + exit "$E_INTERFACE_BUILDER_NOT_FOUND" + fi + INTERFACE_GENERATION="${INTERFACE_LIBRARY_BUILDER} ${DYNAMIC_LIBRARY} + ${INTERFACE_LIBRARY}" + fi + + ${LINKER_COMMAND} "$@" && ${INTERFACE_GENERATION} +fi diff --git a/cc/private/toolchain/linux_cc_wrapper.sh.tpl b/cc/private/toolchain/linux_cc_wrapper.sh.tpl new file mode 100644 index 0000000..a83be50 --- /dev/null +++ b/cc/private/toolchain/linux_cc_wrapper.sh.tpl @@ -0,0 +1,25 @@ +#!/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. +# +# Ship the environment to the C++ action +# +set -eu + +# Set-up the environment +%{env} + +# Call the C++ compiler +%{cc} "$@" diff --git a/cc/private/toolchain/msys_gcc_installation_error.bat b/cc/private/toolchain/msys_gcc_installation_error.bat new file mode 100644 index 0000000..25c3553 --- /dev/null +++ b/cc/private/toolchain/msys_gcc_installation_error.bat @@ -0,0 +1,23 @@ +:: Copyright 2018 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. + +@echo OFF + +echo. 1>&2 +echo The target you are compiling requires MSYS gcc / MINGW gcc. 1>&2 +echo Bazel couldn't find gcc installation on your machine. 1>&2 +echo Please install MSYS gcc / MINGW gcc and set BAZEL_SH environment variable 1>&2 +echo. 1>&2 + +exit /b 1 diff --git a/cc/private/toolchain/osx_cc_configure.bzl b/cc/private/toolchain/osx_cc_configure.bzl new file mode 100644 index 0000000..6d45e04 --- /dev/null +++ b/cc/private/toolchain/osx_cc_configure.bzl @@ -0,0 +1,184 @@ +# pylint: disable=g-bad-file-header +# Copyright 2016 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. +"""Configuring the C++ toolchain on macOS.""" + +load("@bazel_tools//tools/osx:xcode_configure.bzl", "run_xcode_locator") +load( + ":lib_cc_configure.bzl", + "escape_string", + "resolve_labels", + "write_builtin_include_directory_paths", +) +load( + ":unix_cc_configure.bzl", + "configure_unix_toolchain", + "get_env", + "get_escaped_cxx_inc_directories", +) + +def _get_escaped_xcode_cxx_inc_directories(repository_ctx, cc, xcode_toolchains): + """Compute the list of default C++ include paths on Xcode-enabled darwin. + + Args: + repository_ctx: The repository context. + cc: The default C++ compiler on the local system. + xcode_toolchains: A list containing the xcode toolchains available + Returns: + include_paths: A list of builtin include paths. + """ + + # TODO(cparsons): Falling back to the default C++ compiler builtin include + # paths shouldn't be unnecessary once all actions are using xcrun. + include_dirs = get_escaped_cxx_inc_directories(repository_ctx, cc, "-xc++") + for toolchain in xcode_toolchains: + include_dirs.append(escape_string(toolchain.developer_dir)) + + # Assume that all paths that point to /Applications/ are built in include paths + include_dirs.append("/Applications/") + return include_dirs + +def compile_cc_file(repository_ctx, src_name, out_name): + xcrun_result = repository_ctx.execute([ + "env", + "-i", + "xcrun", + "--sdk", + "macosx", + "clang", + "-mmacosx-version-min=10.9", + "-std=c++11", + "-lc++", + "-o", + out_name, + src_name, + ], 30) + if (xcrun_result.return_code != 0): + error_msg = ( + "return code {code}, stderr: {err}, stdout: {out}" + ).format( + code = xcrun_result.return_code, + err = xcrun_result.stderr, + out = xcrun_result.stdout, + ) + fail(out_name + " failed to generate. Please file an issue at " + + "https://github.com/bazelbuild/bazel/issues with the following:\n" + + error_msg) + +def configure_osx_toolchain(repository_ctx, overriden_tools): + """Configure C++ toolchain on macOS. + + Args: + repository_ctx: The repository context. + overriden_tools: dictionary of overriden tools. + """ + paths = resolve_labels(repository_ctx, [ + "@rules_cc//cc/private/toolchain:armeabi_cc_toolchain_config.bzl", + "@rules_cc//cc/private/toolchain:osx_cc_wrapper.sh.tpl", + "@rules_cc//cc/private/toolchain:libtool_check_unique.cc", + "@bazel_tools//tools/objc:libtool.sh", + "@bazel_tools//tools/objc:make_hashed_objlist.py", + "@bazel_tools//tools/objc:xcrunwrapper.sh", + "@bazel_tools//tools/osx/crosstool:BUILD.tpl", + "@bazel_tools//tools/osx/crosstool:cc_toolchain_config.bzl", + "@bazel_tools//tools/osx/crosstool:wrapped_clang.cc", + "@bazel_tools//tools/osx:xcode_locator.m", + ]) + + env = repository_ctx.os.environ + should_use_xcode = "BAZEL_USE_XCODE_TOOLCHAIN" in env and env["BAZEL_USE_XCODE_TOOLCHAIN"] == "1" + xcode_toolchains = [] + + # Make the following logic in sync with @rules_cc//cc/private/toolchain:cc_configure.bzl#cc_autoconf_toolchains_impl + (xcode_toolchains, xcodeloc_err) = run_xcode_locator( + repository_ctx, + paths["@bazel_tools//tools/osx:xcode_locator.m"], + ) + if should_use_xcode and not xcode_toolchains: + fail("BAZEL_USE_XCODE_TOOLCHAIN is set to 1 but Bazel couldn't find Xcode installed on the " + + "system. Verify that 'xcode-select -p' is correct.") + if xcode_toolchains: + # For Xcode toolchains, there's no reason to use anything other than + # wrapped_clang, so that we still get the Bazel Xcode placeholder + # substitution and other behavior for actions that invoke this + # cc_wrapper.sh script. The wrapped_clang binary is already hardcoded + # into the Objective-C crosstool actions, anyway, so this ensures that + # the C++ actions behave consistently. + cc = repository_ctx.path("wrapped_clang") + + cc_path = '"$(/usr/bin/dirname "$0")"/wrapped_clang' + repository_ctx.template( + "cc_wrapper.sh", + paths["@rules_cc//cc/private/toolchain:osx_cc_wrapper.sh.tpl"], + { + "%{cc}": escape_string(cc_path), + "%{env}": escape_string(get_env(repository_ctx)), + }, + ) + repository_ctx.symlink( + paths["@rules_cc//cc/private/toolchain:armeabi_cc_toolchain_config.bzl"], + "armeabi_cc_toolchain_config.bzl", + ) + repository_ctx.symlink( + paths["@bazel_tools//tools/objc:xcrunwrapper.sh"], + "xcrunwrapper.sh", + ) + repository_ctx.symlink( + paths["@bazel_tools//tools/objc:libtool.sh"], + "libtool", + ) + repository_ctx.symlink( + paths["@bazel_tools//tools/objc:make_hashed_objlist.py"], + "make_hashed_objlist.py", + ) + repository_ctx.symlink( + paths["@bazel_tools//tools/osx/crosstool:cc_toolchain_config.bzl"], + "cc_toolchain_config.bzl", + ) + libtool_check_unique_src_path = str(repository_ctx.path( + paths["@rules_cc//cc/private/toolchain:libtool_check_unique.cc"], + )) + compile_cc_file(repository_ctx, libtool_check_unique_src_path, "libtool_check_unique") + wrapped_clang_src_path = str(repository_ctx.path( + paths["@bazel_tools//tools/osx/crosstool:wrapped_clang.cc"], + )) + compile_cc_file(repository_ctx, wrapped_clang_src_path, "wrapped_clang") + repository_ctx.symlink("wrapped_clang", "wrapped_clang_pp") + + tool_paths = {} + gcov_path = repository_ctx.os.environ.get("GCOV") + if gcov_path != None: + if not gcov_path.startswith("/"): + gcov_path = repository_ctx.which(gcov_path) + tool_paths["gcov"] = gcov_path + + escaped_include_paths = _get_escaped_xcode_cxx_inc_directories(repository_ctx, cc, xcode_toolchains) + write_builtin_include_directory_paths(repository_ctx, cc, escaped_include_paths) + escaped_cxx_include_directories = [] + for path in escaped_include_paths: + escaped_cxx_include_directories.append((" \"%s\"," % path)) + if xcodeloc_err: + escaped_cxx_include_directories.append("# Error: " + xcodeloc_err + "\n") + repository_ctx.template( + "BUILD", + paths["@bazel_tools//tools/osx/crosstool:BUILD.tpl"], + { + "%{cxx_builtin_include_directories}": "\n".join(escaped_cxx_include_directories), + "%{tool_paths_overrides}": ",\n ".join( + ['"%s": "%s"' % (k, v) for k, v in tool_paths.items()], + ), + }, + ) + else: + configure_unix_toolchain(repository_ctx, cpu_value = "darwin", overriden_tools = overriden_tools) diff --git a/cc/private/toolchain/osx_cc_wrapper.sh b/cc/private/toolchain/osx_cc_wrapper.sh new file mode 100755 index 0000000..8c9c111 --- /dev/null +++ b/cc/private/toolchain/osx_cc_wrapper.sh @@ -0,0 +1,116 @@ +#!/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 + +GCC=/usr/bin/gcc +INSTALL_NAME_TOOL="/usr/bin/install_name_tool" + +LIBS= +LIB_DIRS= +RPATHS= +OUTPUT= + +function parse_option() { + local -r opt="$1" + if [[ "${OUTPUT}" = "1" ]]; then + OUTPUT=$opt + elif [[ "$opt" =~ ^-l(.*)$ ]]; then + LIBS="${BASH_REMATCH[1]} $LIBS" + elif [[ "$opt" =~ ^-L(.*)$ ]]; then + LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS" + elif [[ "$opt" =~ ^-Wl,-rpath,\@loader_path/(.*)$ ]]; then + RPATHS="${BASH_REMATCH[1]} ${RPATHS}" + elif [[ "$opt" = "-o" ]]; then + # output is coming + OUTPUT=1 + fi +} + +# let parse the option list +for i in "$@"; do + if [[ "$i" = @* ]]; then + while IFS= read -r opt + do + parse_option "$opt" + done < "${i:1}" || exit 1 + else + parse_option "$i" + fi +done + +# Call gcc +${GCC} "$@" + +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/cc/private/toolchain/osx_cc_wrapper.sh.tpl b/cc/private/toolchain/osx_cc_wrapper.sh.tpl new file mode 100644 index 0000000..28bd47b --- /dev/null +++ b/cc/private/toolchain/osx_cc_wrapper.sh.tpl @@ -0,0 +1,119 @@ +#!/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 + +INSTALL_NAME_TOOL="/usr/bin/install_name_tool" + +LIBS= +LIB_DIRS= +RPATHS= +OUTPUT= + +function parse_option() { + local -r opt="$1" + if [[ "${OUTPUT}" = "1" ]]; then + OUTPUT=$opt + elif [[ "$opt" =~ ^-l(.*)$ ]]; then + LIBS="${BASH_REMATCH[1]} $LIBS" + elif [[ "$opt" =~ ^-L(.*)$ ]]; then + LIB_DIRS="${BASH_REMATCH[1]} $LIB_DIRS" + elif [[ "$opt" =~ ^-Wl,-rpath,\@loader_path/(.*)$ ]]; then + RPATHS="${BASH_REMATCH[1]} ${RPATHS}" + elif [[ "$opt" = "-o" ]]; then + # output is coming + OUTPUT=1 + fi +} + +# let parse the option list +for i in "$@"; do + if [[ "$i" = @* ]]; then + while IFS= read -r opt + do + parse_option "$opt" + done < "${i:1}" || exit 1 + else + parse_option "$i" + fi +done + +# Set-up the environment +%{env} + +# Call the C++ compiler +%{cc} "$@" + +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/cc/private/toolchain/unix_cc_configure.bzl b/cc/private/toolchain/unix_cc_configure.bzl new file mode 100644 index 0000000..0c936de --- /dev/null +++ b/cc/private/toolchain/unix_cc_configure.bzl @@ -0,0 +1,587 @@ +# pylint: disable=g-bad-file-header +# Copyright 2016 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. +"""Configuring the C++ toolchain on Unix platforms.""" + +load( + ":lib_cc_configure.bzl", + "auto_configure_fail", + "auto_configure_warning", + "auto_configure_warning_maybe", + "escape_string", + "get_env_var", + "get_starlark_list", + "resolve_labels", + "split_escaped", + "which", + "write_builtin_include_directory_paths", +) + +def _uniq(iterable): + """Remove duplicates from a list.""" + + unique_elements = {element: None for element in iterable} + return unique_elements.keys() + +def _prepare_include_path(repo_ctx, path): + """Resolve and sanitize include path before outputting it into the crosstool. + + Args: + repo_ctx: repository_ctx object. + path: an include path to be sanitized. + + Returns: + Sanitized include path that can be written to the crosstoot. Resulting path + is absolute if it is outside the repository and relative otherwise. + """ + + repo_root = str(repo_ctx.path(".")) + + # We're on UNIX, so the path delimiter is '/'. + repo_root += "/" + path = str(repo_ctx.path(path)) + if path.startswith(repo_root): + return escape_string(path[len(repo_root):]) + return escape_string(path) + +def _find_tool(repository_ctx, tool, overriden_tools): + """Find a tool for repository, taking overriden tools into account.""" + if tool in overriden_tools: + return overriden_tools[tool] + return which(repository_ctx, tool, "/usr/bin/" + tool) + +def _get_tool_paths(repository_ctx, overriden_tools): + """Compute the %-escaped path to the various tools""" + return dict({ + k: escape_string(_find_tool(repository_ctx, k, overriden_tools)) + for k in [ + "ar", + "ld", + "cpp", + "gcc", + "dwp", + "gcov", + "nm", + "objcopy", + "objdump", + "strip", + ] + }.items()) + +def _escaped_cplus_include_paths(repository_ctx): + """Use ${CPLUS_INCLUDE_PATH} to compute the %-escaped list of flags for cxxflag.""" + if "CPLUS_INCLUDE_PATH" in repository_ctx.os.environ: + result = [] + for p in repository_ctx.os.environ["CPLUS_INCLUDE_PATH"].split(":"): + p = escape_string(str(repository_ctx.path(p))) # Normalize the path + result.append("-I" + p) + return result + else: + return [] + +_INC_DIR_MARKER_BEGIN = "#include <...>" + +# OSX add " (framework directory)" at the end of line, strip it. +_OSX_FRAMEWORK_SUFFIX = " (framework directory)" +_OSX_FRAMEWORK_SUFFIX_LEN = len(_OSX_FRAMEWORK_SUFFIX) + +def _cxx_inc_convert(path): + """Convert path returned by cc -E xc++ in a complete path. Doesn't %-escape the path!""" + path = path.strip() + if path.endswith(_OSX_FRAMEWORK_SUFFIX): + path = path[:-_OSX_FRAMEWORK_SUFFIX_LEN].strip() + return path + +def get_escaped_cxx_inc_directories(repository_ctx, cc, lang_flag, additional_flags = []): + """Compute the list of default %-escaped C++ include directories. + + Args: + repository_ctx: The repository context. + cc: path to the C compiler. + lang_flag: value for the language flag (c, c++). + additional_flags: additional flags to pass to cc. + Returns: + a list of escaped system include directories. + """ + result = repository_ctx.execute([cc, "-E", lang_flag, "-", "-v"] + additional_flags) + index1 = result.stderr.find(_INC_DIR_MARKER_BEGIN) + if index1 == -1: + return [] + index1 = result.stderr.find("\n", index1) + if index1 == -1: + return [] + index2 = result.stderr.rfind("\n ") + if index2 == -1 or index2 < index1: + return [] + index2 = result.stderr.find("\n", index2 + 1) + if index2 == -1: + inc_dirs = result.stderr[index1 + 1:] + else: + inc_dirs = result.stderr[index1 + 1:index2].strip() + + inc_directories = [ + _prepare_include_path(repository_ctx, _cxx_inc_convert(p)) + for p in inc_dirs.split("\n") + ] + + if _is_compiler_option_supported(repository_ctx, cc, "-print-resource-dir"): + resource_dir = repository_ctx.execute( + [cc, "-print-resource-dir"], + ).stdout.strip() + "/share" + inc_directories.append(_prepare_include_path(repository_ctx, resource_dir)) + + return inc_directories + +def _is_compiler_option_supported(repository_ctx, cc, option): + """Checks that `option` is supported by the C compiler. Doesn't %-escape the option.""" + result = repository_ctx.execute([ + cc, + option, + "-o", + "/dev/null", + "-c", + str(repository_ctx.path("tools/cpp/empty.cc")), + ]) + return result.stderr.find(option) == -1 + +def _is_linker_option_supported(repository_ctx, cc, option, pattern): + """Checks that `option` is supported by the C linker. Doesn't %-escape the option.""" + result = repository_ctx.execute([ + cc, + option, + "-o", + "/dev/null", + str(repository_ctx.path("tools/cpp/empty.cc")), + ]) + return result.stderr.find(pattern) == -1 + +def _find_gold_linker_path(repository_ctx, cc): + """Checks if `gold` is supported by the C compiler. + + Args: + repository_ctx: repository_ctx. + cc: path to the C compiler. + + Returns: + String to put as value to -fuse-ld= flag, or None if gold couldn't be found. + """ + result = repository_ctx.execute([ + cc, + str(repository_ctx.path("tools/cpp/empty.cc")), + "-o", + "/dev/null", + # Some macos clang versions don't fail when setting -fuse-ld=gold, adding + # these lines to force it to. This also means that we will not detect + # gold when only a very old (year 2010 and older) is present. + "-Wl,--start-lib", + "-Wl,--end-lib", + "-fuse-ld=gold", + "-v", + ]) + if result.return_code != 0: + return None + + for line in result.stderr.splitlines(): + if line.find("gold") == -1: + continue + for flag in line.split(" "): + if flag.find("gold") == -1: + continue + if flag.find("--enable-gold") > -1 or flag.find("--with-plugin-ld") > -1: + # skip build configuration options of gcc itself + # TODO(hlopko): Add redhat-like worker on the CI (#9392) + continue + + # flag is '-fuse-ld=gold' for GCC or "/usr/lib/ld.gold" for Clang + # strip space, single quote, and double quotes + flag = flag.strip(" \"'") + + # remove -fuse-ld= from GCC output so we have only the flag value part + flag = flag.replace("-fuse-ld=", "") + return flag + auto_configure_warning( + "CC with -fuse-ld=gold returned 0, but its -v output " + + "didn't contain 'gold', falling back to the default linker.", + ) + return None + +def _add_compiler_option_if_supported(repository_ctx, cc, option): + """Returns `[option]` if supported, `[]` otherwise. Doesn't %-escape the option.""" + return [option] if _is_compiler_option_supported(repository_ctx, cc, option) else [] + +def _add_linker_option_if_supported(repository_ctx, cc, option, pattern): + """Returns `[option]` if supported, `[]` otherwise. Doesn't %-escape the option.""" + return [option] if _is_linker_option_supported(repository_ctx, cc, option, pattern) else [] + +def _get_no_canonical_prefixes_opt(repository_ctx, cc): + # If the compiler sometimes rewrites paths in the .d files without symlinks + # (ie when they're shorter), it confuses Bazel's logic for verifying all + # #included header files are listed as inputs to the action. + + # The '-fno-canonical-system-headers' should be enough, but clang does not + # support it, so we also try '-no-canonical-prefixes' if first option does + # not work. + opt = _add_compiler_option_if_supported( + repository_ctx, + cc, + "-fno-canonical-system-headers", + ) + if len(opt) == 0: + return _add_compiler_option_if_supported( + repository_ctx, + cc, + "-no-canonical-prefixes", + ) + return opt + +def get_env(repository_ctx): + """Convert the environment in a list of export if in Homebrew. Doesn't %-escape the result! + + Args: + repository_ctx: The repository context. + Returns: + empty string or a list of exports in case we're running with homebrew. Don't ask me why. + """ + env = repository_ctx.os.environ + if "HOMEBREW_RUBY_PATH" in env: + return "\n".join([ + "export %s='%s'" % (k, env[k].replace("'", "'\\''")) + for k in env + if k != "_" and k.find(".") == -1 + ]) + else: + return "" + +def _coverage_flags(repository_ctx, darwin): + use_llvm_cov = "1" == get_env_var( + repository_ctx, + "BAZEL_USE_LLVM_NATIVE_COVERAGE", + default = "0", + enable_warning = False, + ) + if darwin or use_llvm_cov: + compile_flags = '"-fprofile-instr-generate", "-fcoverage-mapping"' + link_flags = '"-fprofile-instr-generate"' + else: + # gcc requires --coverage being passed for compilation and linking + # https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#Instrumentation-Options + compile_flags = '"--coverage"' + link_flags = '"--coverage"' + return compile_flags, link_flags + +def _find_generic(repository_ctx, name, env_name, overriden_tools, warn = False, silent = False): + """Find a generic C++ toolchain tool. Doesn't %-escape the result.""" + + if name in overriden_tools: + return overriden_tools[name] + + result = name + env_value = repository_ctx.os.environ.get(env_name) + env_value_with_paren = "" + if env_value != None: + env_value = env_value.strip() + if env_value: + result = env_value + env_value_with_paren = " (%s)" % env_value + if result.startswith("/"): + # Absolute path, maybe we should make this suported by our which function. + return result + result = repository_ctx.which(result) + if result == None: + msg = ("Cannot find %s or %s%s; either correct your path or set the %s" + + " environment variable") % (name, env_name, env_value_with_paren, env_name) + if warn: + if not silent: + auto_configure_warning(msg) + else: + auto_configure_fail(msg) + return result + +def find_cc(repository_ctx, overriden_tools): + return _find_generic(repository_ctx, "gcc", "CC", overriden_tools) + +def configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools): + """Configure C++ toolchain on Unix platforms. + + Args: + repository_ctx: The repository context. + cpu_value: current cpu name. + overriden_tools: overriden tools. + """ + paths = resolve_labels(repository_ctx, [ + "@rules_cc//cc/private/toolchain:BUILD.tpl", + "@rules_cc//cc/private/toolchain:armeabi_cc_toolchain_config.bzl", + "@rules_cc//cc/private/toolchain:unix_cc_toolchain_config.bzl", + "@rules_cc//cc/private/toolchain:linux_cc_wrapper.sh.tpl", + "@rules_cc//cc/private/toolchain:osx_cc_wrapper.sh.tpl", + ]) + + repository_ctx.symlink( + paths["@rules_cc//cc/private/toolchain:unix_cc_toolchain_config.bzl"], + "cc_toolchain_config.bzl", + ) + + repository_ctx.symlink( + paths["@rules_cc//cc/private/toolchain:armeabi_cc_toolchain_config.bzl"], + "armeabi_cc_toolchain_config.bzl", + ) + + repository_ctx.file("tools/cpp/empty.cc", "int main() {}") + darwin = cpu_value == "darwin" + + cc = _find_generic(repository_ctx, "gcc", "CC", overriden_tools) + overriden_tools = dict(overriden_tools) + overriden_tools["gcc"] = cc + overriden_tools["gcov"] = _find_generic( + repository_ctx, + "gcov", + "GCOV", + overriden_tools, + warn = True, + silent = True, + ) + if darwin: + overriden_tools["gcc"] = "cc_wrapper.sh" + overriden_tools["ar"] = "/usr/bin/libtool" + auto_configure_warning_maybe(repository_ctx, "CC used: " + str(cc)) + tool_paths = _get_tool_paths(repository_ctx, overriden_tools) + cc_toolchain_identifier = escape_string(get_env_var( + repository_ctx, + "CC_TOOLCHAIN_NAME", + "local", + False, + )) + + cc_wrapper_src = ( + "@rules_cc//cc/private/toolchain:osx_cc_wrapper.sh.tpl" if darwin else "@rules_cc//cc/private/toolchain:linux_cc_wrapper.sh.tpl" + ) + repository_ctx.template( + "cc_wrapper.sh", + paths[cc_wrapper_src], + { + "%{cc}": escape_string(str(cc)), + "%{env}": escape_string(get_env(repository_ctx)), + }, + ) + + cxx_opts = split_escaped(get_env_var( + repository_ctx, + "BAZEL_CXXOPTS", + "-std=c++0x", + False, + ), ":") + + bazel_linklibs = "-lstdc++:-lm" + bazel_linkopts = "" + link_opts = split_escaped(get_env_var( + repository_ctx, + "BAZEL_LINKOPTS", + bazel_linkopts, + False, + ), ":") + link_libs = split_escaped(get_env_var( + repository_ctx, + "BAZEL_LINKLIBS", + bazel_linklibs, + False, + ), ":") + gold_linker_path = _find_gold_linker_path(repository_ctx, cc) + cc_path = repository_ctx.path(cc) + if not str(cc_path).startswith(str(repository_ctx.path(".")) + "/"): + # cc is outside the repository, set -B + bin_search_flag = ["-B" + escape_string(str(cc_path.dirname))] + else: + # cc is inside the repository, don't set -B. + bin_search_flag = [] + + coverage_compile_flags, coverage_link_flags = _coverage_flags(repository_ctx, darwin) + builtin_include_directories = _uniq( + get_escaped_cxx_inc_directories(repository_ctx, cc, "-xc") + + get_escaped_cxx_inc_directories(repository_ctx, cc, "-xc++", cxx_opts) + + get_escaped_cxx_inc_directories( + repository_ctx, + cc, + "-xc", + _get_no_canonical_prefixes_opt(repository_ctx, cc), + ) + + get_escaped_cxx_inc_directories( + repository_ctx, + cc, + "-xc++", + cxx_opts + _get_no_canonical_prefixes_opt(repository_ctx, cc), + ), + ) + + write_builtin_include_directory_paths(repository_ctx, cc, builtin_include_directories) + repository_ctx.template( + "BUILD", + paths["@rules_cc//cc/private/toolchain:BUILD.tpl"], + { + "%{abi_libc_version}": escape_string(get_env_var( + repository_ctx, + "ABI_LIBC_VERSION", + "local", + False, + )), + "%{abi_version}": escape_string(get_env_var( + repository_ctx, + "ABI_VERSION", + "local", + False, + )), + "%{cc_compiler_deps}": get_starlark_list([":builtin_include_directory_paths"] + ( + [":cc_wrapper"] if darwin else [] + )), + "%{cc_toolchain_identifier}": cc_toolchain_identifier, + "%{compile_flags}": get_starlark_list( + [ + # Security hardening requires optimization. + # We need to undef it as some distributions now have it enabled by default. + "-U_FORTIFY_SOURCE", + "-fstack-protector", + # All warnings are enabled. Maybe enable -Werror as well? + "-Wall", + # Enable a few more warnings that aren't part of -Wall. + ] + ( + _add_compiler_option_if_supported(repository_ctx, cc, "-Wthread-safety") + + _add_compiler_option_if_supported(repository_ctx, cc, "-Wself-assign") + ) + ( + # Disable problematic warnings. + _add_compiler_option_if_supported(repository_ctx, cc, "-Wunused-but-set-parameter") + + # has false positives + _add_compiler_option_if_supported(repository_ctx, cc, "-Wno-free-nonheap-object") + + # Enable coloring even if there's no attached terminal. Bazel removes the + # escape sequences if --nocolor is specified. + _add_compiler_option_if_supported(repository_ctx, cc, "-fcolor-diagnostics") + ) + [ + # Keep stack frames for debugging, even in opt mode. + "-fno-omit-frame-pointer", + ], + ), + "%{compiler}": escape_string(get_env_var( + repository_ctx, + "BAZEL_COMPILER", + "compiler", + False, + )), + "%{coverage_compile_flags}": coverage_compile_flags, + "%{coverage_link_flags}": coverage_link_flags, + "%{cxx_builtin_include_directories}": get_starlark_list(builtin_include_directories), + "%{cxx_flags}": get_starlark_list(cxx_opts + _escaped_cplus_include_paths(repository_ctx)), + "%{dbg_compile_flags}": get_starlark_list(["-g"]), + "%{host_system_name}": escape_string(get_env_var( + repository_ctx, + "BAZEL_HOST_SYSTEM", + "local", + False, + )), + "%{link_flags}": get_starlark_list(( + ["-fuse-ld=" + gold_linker_path] if gold_linker_path else [] + ) + _add_linker_option_if_supported( + repository_ctx, + cc, + "-Wl,-no-as-needed", + "-no-as-needed", + ) + _add_linker_option_if_supported( + repository_ctx, + cc, + "-Wl,-z,relro,-z,now", + "-z", + ) + ( + [ + "-undefined", + "dynamic_lookup", + "-headerpad_max_install_names", + ] if darwin else bin_search_flag + [ + # Gold linker only? Can we enable this by default? + # "-Wl,--warn-execstack", + # "-Wl,--detect-odr-violations" + ] + _add_compiler_option_if_supported( + # Have gcc return the exit code from ld. + repository_ctx, + cc, + "-pass-exit-codes", + ) + ) + link_opts), + "%{link_libs}": get_starlark_list(link_libs), + "%{name}": cpu_value, + "%{opt_compile_flags}": get_starlark_list( + [ + # No debug symbols. + # Maybe we should enable https://gcc.gnu.org/wiki/DebugFission for opt or + # even generally? However, that can't happen here, as it requires special + # handling in Bazel. + "-g0", + + # Conservative choice for -O + # -O3 can increase binary size and even slow down the resulting binaries. + # Profile first and / or use FDO if you need better performance than this. + "-O2", + + # Security hardening on by default. + # Conservative choice; -D_FORTIFY_SOURCE=2 may be unsafe in some cases. + "-D_FORTIFY_SOURCE=1", + + # Disable assertions + "-DNDEBUG", + + # Removal of unused code and data at link time (can this increase binary + # size in some cases?). + "-ffunction-sections", + "-fdata-sections", + ], + ), + "%{opt_link_flags}": get_starlark_list( + [] if darwin else _add_linker_option_if_supported( + repository_ctx, + cc, + "-Wl,--gc-sections", + "-gc-sections", + ), + ), + "%{supports_param_files}": "0" if darwin else "1", + "%{supports_start_end_lib}": "True" if gold_linker_path else "False", + "%{target_cpu}": escape_string(get_env_var( + repository_ctx, + "BAZEL_TARGET_CPU", + cpu_value, + False, + )), + "%{target_libc}": "macosx" if darwin else escape_string(get_env_var( + repository_ctx, + "BAZEL_TARGET_LIBC", + "local", + False, + )), + "%{target_system_name}": escape_string(get_env_var( + repository_ctx, + "BAZEL_TARGET_SYSTEM", + "local", + False, + )), + "%{tool_paths}": ",\n ".join( + ['"%s": "%s"' % (k, v) for k, v in tool_paths.items()], + ), + "%{unfiltered_compile_flags}": get_starlark_list( + _get_no_canonical_prefixes_opt(repository_ctx, cc) + [ + # Make C++ compilation deterministic. Use linkstamping instead of these + # compiler symbols. + "-Wno-builtin-macro-redefined", + "-D__DATE__=\\\"redacted\\\"", + "-D__TIMESTAMP__=\\\"redacted\\\"", + "-D__TIME__=\\\"redacted\\\"", + ], + ), + }, + ) diff --git a/cc/private/toolchain/unix_cc_toolchain_config.bzl b/cc/private/toolchain/unix_cc_toolchain_config.bzl new file mode 100644 index 0000000..4325a68 --- /dev/null +++ b/cc/private/toolchain/unix_cc_toolchain_config.bzl @@ -0,0 +1,1200 @@ +# Copyright 2019 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. + +"""A Starlark cc_toolchain configuration rule""" + +load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES") +load( + "@rules_cc//cc:cc_toolchain_config_lib.bzl", + "feature", + "feature_set", + "flag_group", + "flag_set", + "tool_path", + "variable_with_value", + "with_feature_set", +) + +all_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, + ACTION_NAMES.lto_backend, +] + +all_cpp_compile_actions = [ + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, +] + +preprocessor_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, +] + +codegen_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, +] + +all_link_actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, +] + +lto_index_actions = [ + ACTION_NAMES.lto_index_for_executable, + ACTION_NAMES.lto_index_for_dynamic_library, + ACTION_NAMES.lto_index_for_nodeps_dynamic_library, +] + +def _impl(ctx): + tool_paths = [ + tool_path(name = name, path = path) + for name, path in ctx.attr.tool_paths.items() + ] + action_configs = [] + + supports_pic_feature = feature( + name = "supports_pic", + enabled = True, + ) + supports_start_end_lib_feature = feature( + name = "supports_start_end_lib", + enabled = True, + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = ([ + flag_group( + flags = ctx.attr.compile_flags, + ), + ] if ctx.attr.compile_flags else []), + ), + flag_set( + actions = all_compile_actions, + flag_groups = ([ + flag_group( + flags = ctx.attr.dbg_compile_flags, + ), + ] if ctx.attr.dbg_compile_flags else []), + with_features = [with_feature_set(features = ["dbg"])], + ), + flag_set( + actions = all_compile_actions, + flag_groups = ([ + flag_group( + flags = ctx.attr.opt_compile_flags, + ), + ] if ctx.attr.opt_compile_flags else []), + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = all_cpp_compile_actions + [ACTION_NAMES.lto_backend], + flag_groups = ([ + flag_group( + flags = ctx.attr.cxx_flags, + ), + ] if ctx.attr.cxx_flags else []), + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = ([ + flag_group( + flags = ctx.attr.link_flags, + ), + ] if ctx.attr.link_flags else []), + ), + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = ([ + flag_group( + flags = ctx.attr.opt_link_flags, + ), + ] if ctx.attr.opt_link_flags else []), + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + dbg_feature = feature(name = "dbg") + + opt_feature = feature(name = "opt") + + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ] + all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + fdo_optimize_feature = feature( + name = "fdo_optimize", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "-fprofile-use=%{fdo_profile_path}", + "-fprofile-correction", + ], + expand_if_available = "fdo_profile_path", + ), + ], + ), + ], + provides = ["profile"], + ) + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_compile_actions, + flag_groups = ([ + flag_group( + flags = ctx.attr.unfiltered_compile_flags, + ), + ] if ctx.attr.unfiltered_compile_flags else []), + ), + ], + ) + + library_search_directories_feature = feature( + name = "library_search_directories", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = ["-L%{library_search_directories}"], + iterate_over = "library_search_directories", + expand_if_available = "library_search_directories", + ), + ], + ), + ], + ) + + static_libgcc_feature = feature( + name = "static_libgcc", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.lto_index_for_executable, + ACTION_NAMES.lto_index_for_dynamic_library, + ], + flag_groups = [flag_group(flags = ["-static-libgcc"])], + with_features = [ + with_feature_set(features = ["static_link_cpp_runtimes"]), + ], + ), + ], + ) + + pic_feature = feature( + name = "pic", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group(flags = ["-fPIC"], expand_if_available = "pic"), + ], + ), + ], + ) + + per_object_debug_info_feature = feature( + name = "per_object_debug_info", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["-gsplit-dwarf", "-g"], + expand_if_available = "per_object_debug_info_file", + ), + ], + ), + ], + ) + + preprocessor_defines_feature = feature( + name = "preprocessor_defines", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = ["-D%{preprocessor_defines}"], + iterate_over = "preprocessor_defines", + ), + ], + ), + ], + ) + + cs_fdo_optimize_feature = feature( + name = "cs_fdo_optimize", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.lto_backend], + flag_groups = [ + flag_group( + flags = [ + "-fprofile-use=%{fdo_profile_path}", + "-Wno-profile-instr-unprofiled", + "-Wno-profile-instr-out-of-date", + "-fprofile-correction", + ], + expand_if_available = "fdo_profile_path", + ), + ], + ), + ], + provides = ["csprofile"], + ) + + autofdo_feature = feature( + name = "autofdo", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "-fauto-profile=%{fdo_profile_path}", + "-fprofile-correction", + ], + expand_if_available = "fdo_profile_path", + ), + ], + ), + ], + provides = ["profile"], + ) + + runtime_library_search_directories_feature = feature( + name = "runtime_library_search_directories", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + iterate_over = "runtime_library_search_directories", + flag_groups = [ + flag_group( + flags = [ + "-Wl,-rpath,$EXEC_ORIGIN/%{runtime_library_search_directories}", + ], + expand_if_true = "is_cc_test", + ), + flag_group( + flags = [ + "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}", + ], + expand_if_false = "is_cc_test", + ), + ], + expand_if_available = + "runtime_library_search_directories", + ), + ], + with_features = [ + with_feature_set(features = ["static_link_cpp_runtimes"]), + ], + ), + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + iterate_over = "runtime_library_search_directories", + flag_groups = [ + flag_group( + flags = [ + "-Wl,-rpath,$ORIGIN/%{runtime_library_search_directories}", + ], + ), + ], + expand_if_available = + "runtime_library_search_directories", + ), + ], + with_features = [ + with_feature_set( + not_features = ["static_link_cpp_runtimes"], + ), + ], + ), + ], + ) + + fission_support_feature = feature( + name = "fission_support", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = ["-Wl,--gdb-index"], + expand_if_available = "is_using_fission", + ), + ], + ), + ], + ) + + shared_flag_feature = feature( + name = "shared_flag", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.lto_index_for_dynamic_library, + ACTION_NAMES.lto_index_for_nodeps_dynamic_library, + ], + flag_groups = [flag_group(flags = ["-shared"])], + ), + ], + ) + + random_seed_feature = feature( + name = "random_seed", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["-frandom-seed=%{output_file}"], + expand_if_available = "output_file", + ), + ], + ), + ], + ) + + includes_feature = feature( + name = "includes", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, + ACTION_NAMES.objc_compile, + ACTION_NAMES.objcpp_compile, + ], + flag_groups = [ + flag_group( + flags = ["-include", "%{includes}"], + iterate_over = "includes", + expand_if_available = "includes", + ), + ], + ), + ], + ) + + fdo_instrument_feature = feature( + name = "fdo_instrument", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ] + all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = [ + "-fprofile-generate=%{fdo_instrument_path}", + "-fno-data-sections", + ], + expand_if_available = "fdo_instrument_path", + ), + ], + ), + ], + provides = ["profile"], + ) + + cs_fdo_instrument_feature = feature( + name = "cs_fdo_instrument", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.lto_backend, + ] + all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = [ + "-fcs-profile-generate=%{cs_fdo_instrument_path}", + ], + expand_if_available = "cs_fdo_instrument_path", + ), + ], + ), + ], + provides = ["csprofile"], + ) + + include_paths_feature = feature( + name = "include_paths", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, + ACTION_NAMES.objc_compile, + ACTION_NAMES.objcpp_compile, + ], + flag_groups = [ + flag_group( + flags = ["-iquote", "%{quote_include_paths}"], + iterate_over = "quote_include_paths", + ), + flag_group( + flags = ["-I%{include_paths}"], + iterate_over = "include_paths", + ), + flag_group( + flags = ["-isystem", "%{system_include_paths}"], + iterate_over = "system_include_paths", + ), + ], + ), + ], + ) + + symbol_counts_feature = feature( + name = "symbol_counts", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = [ + "-Wl,--print-symbol-counts=%{symbol_counts_output}", + ], + expand_if_available = "symbol_counts_output", + ), + ], + ), + ], + ) + + llvm_coverage_map_format_feature = feature( + name = "llvm_coverage_map_format", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.objc_compile, + ACTION_NAMES.objcpp_compile, + ], + flag_groups = [ + flag_group( + flags = [ + "-fprofile-instr-generate", + "-fcoverage-mapping", + ], + ), + ], + ), + flag_set( + actions = all_link_actions + lto_index_actions + [ + "objc-executable", + "objc++-executable", + ], + flag_groups = [ + flag_group(flags = ["-fprofile-instr-generate"]), + ], + ), + ], + requires = [feature_set(features = ["coverage"])], + provides = ["profile"], + ) + + strip_debug_symbols_feature = feature( + name = "strip_debug_symbols", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = ["-Wl,-S"], + expand_if_available = "strip_debug_symbols", + ), + ], + ), + ], + ) + + build_interface_libraries_feature = feature( + name = "build_interface_libraries", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.lto_index_for_dynamic_library, + ACTION_NAMES.lto_index_for_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = [ + "%{generate_interface_library}", + "%{interface_library_builder_path}", + "%{interface_library_input_path}", + "%{interface_library_output_path}", + ], + expand_if_available = "generate_interface_library", + ), + ], + with_features = [ + with_feature_set( + features = ["supports_interface_shared_libraries"], + ), + ], + ), + ], + ) + + libraries_to_link_feature = feature( + name = "libraries_to_link", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link", + flag_groups = [ + flag_group( + flags = ["-Wl,--start-lib"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + flag_group( + flags = ["-Wl,-whole-archive"], + expand_if_true = + "libraries_to_link.is_whole_archive", + ), + flag_group( + flags = ["%{libraries_to_link.object_files}"], + iterate_over = "libraries_to_link.object_files", + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file", + ), + ), + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "interface_library", + ), + ), + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "static_library", + ), + ), + flag_group( + flags = ["-l%{libraries_to_link.name}"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "dynamic_library", + ), + ), + flag_group( + flags = ["-l:%{libraries_to_link.name}"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "versioned_dynamic_library", + ), + ), + flag_group( + flags = ["-Wl,-no-whole-archive"], + expand_if_true = "libraries_to_link.is_whole_archive", + ), + flag_group( + flags = ["-Wl,--end-lib"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + ], + expand_if_available = "libraries_to_link", + ), + flag_group( + flags = ["-Wl,@%{thinlto_param_file}"], + expand_if_true = "thinlto_param_file", + ), + ], + ), + ], + ) + + user_link_flags_feature = feature( + name = "user_link_flags", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = ["%{user_link_flags}"], + iterate_over = "user_link_flags", + expand_if_available = "user_link_flags", + ), + ] + ([flag_group(flags = ctx.attr.link_libs)] if ctx.attr.link_libs else []), + ), + ], + ) + + fdo_prefetch_hints_feature = feature( + name = "fdo_prefetch_hints", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.lto_backend, + ], + flag_groups = [ + flag_group( + flags = [ + "-mllvm", + "-prefetch-hints-file=%{fdo_prefetch_hints_path}", + ], + expand_if_available = "fdo_prefetch_hints_path", + ), + ], + ), + ], + ) + + linkstamps_feature = feature( + name = "linkstamps", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = ["%{linkstamp_paths}"], + iterate_over = "linkstamp_paths", + expand_if_available = "linkstamp_paths", + ), + ], + ), + ], + ) + + gcc_coverage_map_format_feature = feature( + name = "gcc_coverage_map_format", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.objc_compile, + ACTION_NAMES.objcpp_compile, + "objc-executable", + "objc++-executable", + ], + flag_groups = [ + flag_group( + flags = ["-fprofile-arcs", "-ftest-coverage"], + expand_if_available = "gcov_gcno_file", + ), + ], + ), + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [flag_group(flags = ["--coverage"])], + ), + ], + requires = [feature_set(features = ["coverage"])], + provides = ["profile"], + ) + + archiver_flags_feature = feature( + name = "archiver_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group(flags = ["rcsD"]), + flag_group( + flags = ["%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link", + flag_groups = [ + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file", + ), + ), + flag_group( + flags = ["%{libraries_to_link.object_files}"], + iterate_over = "libraries_to_link.object_files", + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + ], + expand_if_available = "libraries_to_link", + ), + ], + ), + ], + ) + + force_pic_flags_feature = feature( + name = "force_pic_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.lto_index_for_executable, + ], + flag_groups = [ + flag_group( + flags = ["-pie"], + expand_if_available = "force_pic", + ), + ], + ), + ], + ) + + dependency_file_feature = feature( + name = "dependency_file", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.objc_compile, + ACTION_NAMES.objcpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = ["-MD", "-MF", "%{dependency_file}"], + expand_if_available = "dependency_file", + ), + ], + ), + ], + ) + + dynamic_library_linker_tool_feature = feature( + name = "dynamic_library_linker_tool", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.lto_index_for_dynamic_library, + ACTION_NAMES.lto_index_for_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = [" + cppLinkDynamicLibraryToolPath + "], + expand_if_available = "generate_interface_library", + ), + ], + with_features = [ + with_feature_set( + features = ["supports_interface_shared_libraries"], + ), + ], + ), + ], + ) + + output_execpath_flags_feature = feature( + name = "output_execpath_flags", + flag_sets = [ + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = [ + flag_group( + flags = ["-o", "%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + # Note that we also set --coverage for c++-link-nodeps-dynamic-library. The + # generated code contains references to gcov symbols, and the dynamic linker + # can't resolve them unless the library is linked against gcov. + coverage_feature = feature( + name = "coverage", + provides = ["profile"], + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = ([ + flag_group(flags = ctx.attr.coverage_compile_flags), + ] if ctx.attr.coverage_compile_flags else []), + ), + flag_set( + actions = all_link_actions + lto_index_actions, + flag_groups = ([ + flag_group(flags = ctx.attr.coverage_link_flags), + ] if ctx.attr.coverage_link_flags else []), + ), + ], + ) + + thinlto_feature = feature( + name = "thin_lto", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ] + all_link_actions + lto_index_actions, + flag_groups = [ + flag_group(flags = ["-flto=thin"]), + flag_group( + expand_if_available = "lto_indexing_bitcode_file", + flags = [ + "-Xclang", + "-fthin-link-bitcode=%{lto_indexing_bitcode_file}", + ], + ), + ], + ), + flag_set( + actions = [ACTION_NAMES.linkstamp_compile], + flag_groups = [flag_group(flags = ["-DBUILD_LTO_TYPE=thin"])], + ), + flag_set( + actions = lto_index_actions, + flag_groups = [ + flag_group(flags = [ + "-flto=thin", + "-Wl,-plugin-opt,thinlto-index-only%{thinlto_optional_params_file}", + "-Wl,-plugin-opt,thinlto-emit-imports-files", + "-Wl,-plugin-opt,thinlto-prefix-replace=%{thinlto_prefix_replace}", + ]), + flag_group( + expand_if_available = "thinlto_object_suffix_replace", + flags = [ + "-Wl,-plugin-opt,thinlto-object-suffix-replace=%{thinlto_object_suffix_replace}", + ], + ), + flag_group( + expand_if_available = "thinlto_merged_object_file", + flags = [ + "-Wl,-plugin-opt,obj-path=%{thinlto_merged_object_file}", + ], + ), + ], + ), + flag_set( + actions = [ACTION_NAMES.lto_backend], + flag_groups = [ + flag_group(flags = [ + "-c", + "-fthinlto-index=%{thinlto_index}", + "-o", + "%{thinlto_output_object_file}", + "-x", + "ir", + "%{thinlto_input_bitcode_file}", + ]), + ], + ), + ], + ) + + is_linux = ctx.attr.target_libc != "macosx" + + # TODO(#8303): Mac crosstool should also declare every feature. + if is_linux: + features = [ + dependency_file_feature, + random_seed_feature, + pic_feature, + per_object_debug_info_feature, + preprocessor_defines_feature, + includes_feature, + include_paths_feature, + fdo_instrument_feature, + cs_fdo_instrument_feature, + cs_fdo_optimize_feature, + thinlto_feature, + fdo_prefetch_hints_feature, + autofdo_feature, + build_interface_libraries_feature, + dynamic_library_linker_tool_feature, + symbol_counts_feature, + shared_flag_feature, + linkstamps_feature, + output_execpath_flags_feature, + runtime_library_search_directories_feature, + library_search_directories_feature, + archiver_flags_feature, + force_pic_flags_feature, + fission_support_feature, + strip_debug_symbols_feature, + coverage_feature, + supports_pic_feature, + gcc_coverage_map_format_feature, + llvm_coverage_map_format_feature, + ] + ( + [ + supports_start_end_lib_feature, + ] if ctx.attr.supports_start_end_lib else [] + ) + [ + default_compile_flags_feature, + default_link_flags_feature, + libraries_to_link_feature, + user_link_flags_feature, + static_libgcc_feature, + fdo_optimize_feature, + supports_dynamic_linker_feature, + dbg_feature, + opt_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + ] + else: + features = [ + supports_pic_feature, + ] + ( + [ + supports_start_end_lib_feature, + ] if ctx.attr.supports_start_end_lib else [] + ) + [ + coverage_feature, + default_compile_flags_feature, + default_link_flags_feature, + fdo_optimize_feature, + supports_dynamic_linker_feature, + dbg_feature, + opt_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + gcc_coverage_map_format_feature, + llvm_coverage_map_format_feature, + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories, + toolchain_identifier = ctx.attr.toolchain_identifier, + host_system_name = ctx.attr.host_system_name, + target_system_name = ctx.attr.target_system_name, + target_cpu = ctx.attr.cpu, + target_libc = ctx.attr.target_libc, + compiler = ctx.attr.compiler, + abi_version = ctx.attr.abi_version, + abi_libc_version = ctx.attr.abi_libc_version, + tool_paths = tool_paths, + ) + +cc_toolchain_config = rule( + implementation = _impl, + attrs = { + "abi_libc_version": attr.string(mandatory = True), + "abi_version": attr.string(mandatory = True), + "compile_flags": attr.string_list(), + "compiler": attr.string(mandatory = True), + "coverage_compile_flags": attr.string_list(), + "coverage_link_flags": attr.string_list(), + "cpu": attr.string(mandatory = True), + "cxx_builtin_include_directories": attr.string_list(), + "cxx_flags": attr.string_list(), + "dbg_compile_flags": attr.string_list(), + "host_system_name": attr.string(mandatory = True), + "link_flags": attr.string_list(), + "link_libs": attr.string_list(), + "opt_compile_flags": attr.string_list(), + "opt_link_flags": attr.string_list(), + "supports_start_end_lib": attr.bool(), + "target_libc": attr.string(mandatory = True), + "target_system_name": attr.string(mandatory = True), + "tool_paths": attr.string_dict(), + "toolchain_identifier": attr.string(mandatory = True), + "unfiltered_compile_flags": attr.string_list(), + }, + provides = [CcToolchainConfigInfo], +) diff --git a/cc/private/toolchain/vc_installation_error.bat.tpl b/cc/private/toolchain/vc_installation_error.bat.tpl new file mode 100644 index 0000000..9cdd658 --- /dev/null +++ b/cc/private/toolchain/vc_installation_error.bat.tpl @@ -0,0 +1,24 @@ +:: Copyright 2017 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. + +@echo OFF + +echo. 1>&2 +echo The target you are compiling requires Visual C++ build tools. 1>&2 +echo Bazel couldn't find a valid Visual C++ build tools installation on your machine. 1>&2 +%{vc_error_message} +echo Please check your installation following https://docs.bazel.build/versions/main/windows.html#using 1>&2 +echo. 1>&2 + +exit /b 1 diff --git a/cc/private/toolchain/windows_cc_configure.bzl b/cc/private/toolchain/windows_cc_configure.bzl new file mode 100644 index 0000000..598d4b2 --- /dev/null +++ b/cc/private/toolchain/windows_cc_configure.bzl @@ -0,0 +1,703 @@ +# pylint: disable=g-bad-file-header +# Copyright 2016 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. +"""Configuring the C++ toolchain on Windows.""" + +load( + ":lib_cc_configure.bzl", + "auto_configure_fail", + "auto_configure_warning", + "auto_configure_warning_maybe", + "escape_string", + "execute", + "resolve_labels", + "write_builtin_include_directory_paths", +) + +def _get_path_env_var(repository_ctx, name): + """Returns a path from an environment variable. + + Removes quotes, replaces '/' with '\', and strips trailing '\'s.""" + if name in repository_ctx.os.environ: + value = repository_ctx.os.environ[name] + if value[0] == "\"": + if len(value) == 1 or value[-1] != "\"": + auto_configure_fail("'%s' environment variable has no trailing quote" % name) + value = value[1:-1] + if "/" in value: + value = value.replace("/", "\\") + if value[-1] == "\\": + value = value.rstrip("\\") + return value + else: + return None + +def _get_temp_env(repository_ctx): + """Returns the value of TMP, or TEMP, or if both undefined then C:\\Windows.""" + tmp = _get_path_env_var(repository_ctx, "TMP") + if not tmp: + tmp = _get_path_env_var(repository_ctx, "TEMP") + if not tmp: + tmp = "C:\\Windows\\Temp" + auto_configure_warning( + "neither 'TMP' nor 'TEMP' environment variables are set, using '%s' as default" % tmp, + ) + return tmp + +def _get_escaped_windows_msys_starlark_content(repository_ctx, use_mingw = False): + """Return the content of msys cc toolchain rule.""" + msys_root = "" + bazel_sh = _get_path_env_var(repository_ctx, "BAZEL_SH") + if bazel_sh: + bazel_sh = bazel_sh.replace("\\", "/").lower() + tokens = bazel_sh.rsplit("/", 1) + if tokens[0].endswith("/usr/bin"): + msys_root = tokens[0][:len(tokens[0]) - len("usr/bin")] + elif tokens[0].endswith("/bin"): + msys_root = tokens[0][:len(tokens[0]) - len("bin")] + + prefix = "mingw64" if use_mingw else "usr" + tool_path_prefix = escape_string(msys_root) + prefix + tool_bin_path = tool_path_prefix + "/bin" + tool_path = {} + + for tool in ["ar", "compat-ld", "cpp", "dwp", "gcc", "gcov", "ld", "nm", "objcopy", "objdump", "strip"]: + if msys_root: + tool_path[tool] = tool_bin_path + "/" + tool + else: + tool_path[tool] = "msys_gcc_installation_error.bat" + tool_paths = ",\n ".join(['"%s": "%s"' % (k, v) for k, v in tool_path.items()]) + include_directories = (' "%s/",\n ' % tool_path_prefix) if msys_root else "" + return tool_paths, tool_bin_path, include_directories + +def _get_system_root(repository_ctx): + """Get System root path on Windows, default is C:\\Windows. Doesn't %-escape the result.""" + systemroot = _get_path_env_var(repository_ctx, "SYSTEMROOT") + if not systemroot: + systemroot = "C:\\Windows" + auto_configure_warning_maybe( + repository_ctx, + "SYSTEMROOT is not set, using default SYSTEMROOT=C:\\Windows", + ) + return escape_string(systemroot) + +def _add_system_root(repository_ctx, env): + """Running VCVARSALL.BAT and VCVARSQUERYREGISTRY.BAT need %SYSTEMROOT%\\\\system32 in PATH.""" + if "PATH" not in env: + env["PATH"] = "" + env["PATH"] = env["PATH"] + ";" + _get_system_root(repository_ctx) + "\\system32" + return env + +def _find_vc_path(repository_ctx): + """Find Visual C++ build tools install path. Doesn't %-escape the result.""" + + # 1. Check if BAZEL_VC or BAZEL_VS is already set by user. + bazel_vc = _get_path_env_var(repository_ctx, "BAZEL_VC") + if bazel_vc: + if repository_ctx.path(bazel_vc).exists: + return bazel_vc + else: + auto_configure_warning_maybe( + repository_ctx, + "%BAZEL_VC% is set to non-existent path, ignoring.", + ) + + bazel_vs = _get_path_env_var(repository_ctx, "BAZEL_VS") + if bazel_vs: + if repository_ctx.path(bazel_vs).exists: + bazel_vc = bazel_vs + "\\VC" + if repository_ctx.path(bazel_vc).exists: + return bazel_vc + else: + auto_configure_warning_maybe( + repository_ctx, + "No 'VC' directory found under %BAZEL_VS%, ignoring.", + ) + else: + auto_configure_warning_maybe( + repository_ctx, + "%BAZEL_VS% is set to non-existent path, ignoring.", + ) + + auto_configure_warning_maybe( + repository_ctx, + "Neither %BAZEL_VC% nor %BAZEL_VS% are set, start looking for the latest Visual C++" + + " installed.", + ) + + # 2. Check if VS%VS_VERSION%COMNTOOLS is set, if true then try to find and use + # vcvarsqueryregistry.bat / VsDevCmd.bat to detect VC++. + auto_configure_warning_maybe(repository_ctx, "Looking for VS%VERSION%COMNTOOLS environment variables, " + + "eg. VS140COMNTOOLS") + for vscommontools_env, script in [ + ("VS160COMNTOOLS", "VsDevCmd.bat"), + ("VS150COMNTOOLS", "VsDevCmd.bat"), + ("VS140COMNTOOLS", "vcvarsqueryregistry.bat"), + ("VS120COMNTOOLS", "vcvarsqueryregistry.bat"), + ("VS110COMNTOOLS", "vcvarsqueryregistry.bat"), + ("VS100COMNTOOLS", "vcvarsqueryregistry.bat"), + ("VS90COMNTOOLS", "vcvarsqueryregistry.bat"), + ]: + if vscommontools_env not in repository_ctx.os.environ: + continue + script = _get_path_env_var(repository_ctx, vscommontools_env) + "\\" + script + if not repository_ctx.path(script).exists: + continue + repository_ctx.file( + "get_vc_dir.bat", + "@echo off\n" + + "call \"" + script + "\"\n" + + "echo %VCINSTALLDIR%", + True, + ) + env = _add_system_root(repository_ctx, repository_ctx.os.environ) + vc_dir = execute(repository_ctx, ["./get_vc_dir.bat"], environment = env) + + auto_configure_warning_maybe(repository_ctx, "Visual C++ build tools found at %s" % vc_dir) + return vc_dir + + # 3. User might have purged all environment variables. If so, look for Visual C++ in registry. + # Works for Visual Studio 2017 and older. (Does not work for Visual Studio 2019 Preview.) + # TODO(laszlocsomor): check if "16.0" also has this registry key, after VS 2019 is released. + auto_configure_warning_maybe(repository_ctx, "Looking for Visual C++ through registry") + reg_binary = _get_system_root(repository_ctx) + "\\system32\\reg.exe" + vc_dir = None + for key, suffix in (("VC7", ""), ("VS7", "\\VC")): + for version in ["15.0", "14.0", "12.0", "11.0", "10.0", "9.0", "8.0"]: + if vc_dir: + break + result = repository_ctx.execute([reg_binary, "query", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\VisualStudio\\SxS\\" + key, "/v", version]) + auto_configure_warning_maybe(repository_ctx, "registry query result for VC %s:\n\nSTDOUT(start)\n%s\nSTDOUT(end)\nSTDERR(start):\n%s\nSTDERR(end)\n" % + (version, result.stdout, result.stderr)) + if not result.stderr: + for line in result.stdout.split("\n"): + line = line.strip() + if line.startswith(version) and line.find("REG_SZ") != -1: + vc_dir = line[line.find("REG_SZ") + len("REG_SZ"):].strip() + suffix + if vc_dir: + auto_configure_warning_maybe(repository_ctx, "Visual C++ build tools found at %s" % vc_dir) + return vc_dir + + # 4. Check default directories for VC installation + auto_configure_warning_maybe(repository_ctx, "Looking for default Visual C++ installation directory") + program_files_dir = _get_path_env_var(repository_ctx, "PROGRAMFILES(X86)") + if not program_files_dir: + program_files_dir = "C:\\Program Files (x86)" + auto_configure_warning_maybe( + repository_ctx, + "'PROGRAMFILES(X86)' environment variable is not set, using '%s' as default" % program_files_dir, + ) + for path in [ + "Microsoft Visual Studio\\2019\\Preview\\VC", + "Microsoft Visual Studio\\2019\\BuildTools\\VC", + "Microsoft Visual Studio\\2019\\Community\\VC", + "Microsoft Visual Studio\\2019\\Professional\\VC", + "Microsoft Visual Studio\\2019\\Enterprise\\VC", + "Microsoft Visual Studio\\2017\\BuildTools\\VC", + "Microsoft Visual Studio\\2017\\Community\\VC", + "Microsoft Visual Studio\\2017\\Professional\\VC", + "Microsoft Visual Studio\\2017\\Enterprise\\VC", + "Microsoft Visual Studio 14.0\\VC", + ]: + path = program_files_dir + "\\" + path + if repository_ctx.path(path).exists: + vc_dir = path + break + + if not vc_dir: + auto_configure_warning_maybe(repository_ctx, "Visual C++ build tools not found.") + return None + auto_configure_warning_maybe(repository_ctx, "Visual C++ build tools found at %s" % vc_dir) + return vc_dir + +def _is_vs_2017_or_2019(vc_path): + """Check if the installed VS version is Visual Studio 2017.""" + + # In VS 2017 and 2019, the location of VC is like: + # C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\ + # In VS 2015 or older version, it is like: + # C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\ + return vc_path.find("2017") != -1 or vc_path.find("2019") != -1 + +def _find_vcvars_bat_script(repository_ctx, vc_path): + """Find batch script to set up environment variables for VC. Doesn't %-escape the result.""" + if _is_vs_2017_or_2019(vc_path): + vcvars_script = vc_path + "\\Auxiliary\\Build\\VCVARSALL.BAT" + else: + vcvars_script = vc_path + "\\VCVARSALL.BAT" + + if not repository_ctx.path(vcvars_script).exists: + return None + + return vcvars_script + +def _is_support_vcvars_ver(vc_full_version): + """-vcvars_ver option is supported from version 14.11.25503 (VS 2017 version 15.3).""" + version = [int(i) for i in vc_full_version.split(".")] + min_version = [14, 11, 25503] + return version >= min_version + +def _is_support_winsdk_selection(repository_ctx, vc_path): + """Windows SDK selection is supported with VC 2017 / 2019 or with full VS 2015 installation.""" + if _is_vs_2017_or_2019(vc_path): + return True + + # By checking the source code of VCVARSALL.BAT in VC 2015, we know that + # when devenv.exe or wdexpress.exe exists, VCVARSALL.BAT supports Windows SDK selection. + vc_common_ide = repository_ctx.path(vc_path).dirname.get_child("Common7").get_child("IDE") + for tool in ["devenv.exe", "wdexpress.exe"]: + if vc_common_ide.get_child(tool).exists: + return True + return False + +def setup_vc_env_vars(repository_ctx, vc_path, envvars = [], allow_empty = False, escape = True): + """Get environment variables set by VCVARSALL.BAT script. Doesn't %-escape the result! + + Args: + repository_ctx: the repository_ctx object + vc_path: Visual C++ root directory + envvars: list of envvars to retrieve; default is ["PATH", "INCLUDE", "LIB", "WINDOWSSDKDIR"] + allow_empty: allow unset envvars; if False then report errors for those + escape: if True, escape "\" as "\\" and "%" as "%%" in the envvar values + + Returns: + dictionary of the envvars + """ + if not envvars: + envvars = ["PATH", "INCLUDE", "LIB", "WINDOWSSDKDIR"] + + vcvars_script = _find_vcvars_bat_script(repository_ctx, vc_path) + if not vcvars_script: + auto_configure_fail("Cannot find VCVARSALL.BAT script under %s" % vc_path) + + # Getting Windows SDK version set by user. + # Only supports VC 2017 & 2019 and VC 2015 with full VS installation. + winsdk_version = _get_winsdk_full_version(repository_ctx) + if winsdk_version and not _is_support_winsdk_selection(repository_ctx, vc_path): + auto_configure_warning(("BAZEL_WINSDK_FULL_VERSION=%s is ignored, " + + "because standalone Visual C++ Build Tools 2015 doesn't support specifying Windows " + + "SDK version, please install the full VS 2015 or use VC 2017/2019.") % winsdk_version) + winsdk_version = "" + + # Get VC version set by user. Only supports VC 2017 & 2019. + vcvars_ver = "" + if _is_vs_2017_or_2019(vc_path): + full_version = _get_vc_full_version(repository_ctx, vc_path) + + # Because VCVARSALL.BAT is from the latest VC installed, so we check if the latest + # version supports -vcvars_ver or not. + if _is_support_vcvars_ver(_get_latest_subversion(repository_ctx, vc_path)): + vcvars_ver = "-vcvars_ver=" + full_version + + cmd = "\"%s\" amd64 %s %s" % (vcvars_script, winsdk_version, vcvars_ver) + print_envvars = ",".join(["{k}=%{k}%".format(k = k) for k in envvars]) + repository_ctx.file( + "get_env.bat", + "@echo off\n" + + ("call %s > NUL \n" % cmd) + ("echo %s \n" % print_envvars), + True, + ) + env = _add_system_root(repository_ctx, {k: "" for k in envvars}) + envs = execute(repository_ctx, ["./get_env.bat"], environment = env).split(",") + env_map = {} + for env in envs: + key, value = env.split("=", 1) + env_map[key] = escape_string(value.replace("\\", "\\\\")) if escape else value + if not allow_empty: + _check_env_vars(env_map, cmd, expected = envvars) + return env_map + +def _check_env_vars(env_map, cmd, expected): + for env in expected: + if not env_map.get(env): + auto_configure_fail( + "Setting up VC environment variables failed, %s is not set by the following command:\n %s" % (env, cmd), + ) + +def _get_latest_subversion(repository_ctx, vc_path): + """Get the latest subversion of a VS 2017/2019 installation. + + For VS 2017 & 2019, there could be multiple versions of VC build tools. + The directories are like: + \\Tools\\MSVC\\14.10.24930\\bin\\HostX64\\x64 + \\Tools\\MSVC\\14.16.27023\\bin\\HostX64\\x64 + This function should return 14.16.27023 in this case.""" + versions = [path.basename for path in repository_ctx.path(vc_path + "\\Tools\\MSVC").readdir()] + if len(versions) < 1: + auto_configure_warning_maybe(repository_ctx, "Cannot find any VC installation under BAZEL_VC(%s)" % vc_path) + return None + + # Parse the version string into integers, then sort the integers to prevent textual sorting. + version_list = [] + for version in versions: + parts = [int(i) for i in version.split(".")] + version_list.append((parts, version)) + + version_list = sorted(version_list) + latest_version = version_list[-1][1] + + auto_configure_warning_maybe(repository_ctx, "Found the following VC verisons:\n%s\n\nChoosing the latest version = %s" % ("\n".join(versions), latest_version)) + return latest_version + +def _get_vc_full_version(repository_ctx, vc_path): + """Return the value of BAZEL_VC_FULL_VERSION if defined, otherwise the latest version.""" + if "BAZEL_VC_FULL_VERSION" in repository_ctx.os.environ: + return repository_ctx.os.environ["BAZEL_VC_FULL_VERSION"] + return _get_latest_subversion(repository_ctx, vc_path) + +def _get_winsdk_full_version(repository_ctx): + """Return the value of BAZEL_WINSDK_FULL_VERSION if defined, otherwise an empty string.""" + return repository_ctx.os.environ.get("BAZEL_WINSDK_FULL_VERSION", default = "") + +def _find_msvc_tool(repository_ctx, vc_path, tool): + """Find the exact path of a specific build tool in MSVC. Doesn't %-escape the result.""" + tool_path = None + if _is_vs_2017_or_2019(vc_path): + full_version = _get_vc_full_version(repository_ctx, vc_path) + if full_version: + tool_path = "%s\\Tools\\MSVC\\%s\\bin\\HostX64\\x64\\%s" % (vc_path, full_version, tool) + else: + # For VS 2015 and older version, the tools are under: + # C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64 + tool_path = vc_path + "\\bin\\amd64\\" + tool + + if not tool_path or not repository_ctx.path(tool_path).exists: + return None + + return tool_path.replace("\\", "/") + +def _find_missing_vc_tools(repository_ctx, vc_path): + """Check if any required tool is missing under given VC path.""" + missing_tools = [] + if not _find_vcvars_bat_script(repository_ctx, vc_path): + missing_tools.append("VCVARSALL.BAT") + + for tool in ["cl.exe", "link.exe", "lib.exe", "ml64.exe"]: + if not _find_msvc_tool(repository_ctx, vc_path, tool): + missing_tools.append(tool) + + return missing_tools + +def _is_support_debug_fastlink(repository_ctx, linker): + """Run linker alone to see if it supports /DEBUG:FASTLINK.""" + if _use_clang_cl(repository_ctx): + # LLVM's lld-link.exe doesn't support /DEBUG:FASTLINK. + return False + result = execute(repository_ctx, [linker], expect_failure = True) + return result.find("/DEBUG[:{FASTLINK|FULL|NONE}]") != -1 + +def _find_llvm_path(repository_ctx): + """Find LLVM install path.""" + + # 1. Check if BAZEL_LLVM is already set by user. + bazel_llvm = _get_path_env_var(repository_ctx, "BAZEL_LLVM") + if bazel_llvm: + return bazel_llvm + + auto_configure_warning_maybe(repository_ctx, "'BAZEL_LLVM' is not set, " + + "start looking for LLVM installation on machine.") + + # 2. Look for LLVM installation through registry. + auto_configure_warning_maybe(repository_ctx, "Looking for LLVM installation through registry") + reg_binary = _get_system_root(repository_ctx) + "\\system32\\reg.exe" + llvm_dir = None + result = repository_ctx.execute([reg_binary, "query", "HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\LLVM\\LLVM"]) + auto_configure_warning_maybe(repository_ctx, "registry query result for LLVM:\n\nSTDOUT(start)\n%s\nSTDOUT(end)\nSTDERR(start):\n%s\nSTDERR(end)\n" % + (result.stdout, result.stderr)) + if not result.stderr: + for line in result.stdout.split("\n"): + line = line.strip() + if line.startswith("(Default)") and line.find("REG_SZ") != -1: + llvm_dir = line[line.find("REG_SZ") + len("REG_SZ"):].strip() + if llvm_dir: + auto_configure_warning_maybe(repository_ctx, "LLVM installation found at %s" % llvm_dir) + return llvm_dir + + # 3. Check default directories for LLVM installation + auto_configure_warning_maybe(repository_ctx, "Looking for default LLVM installation directory") + program_files_dir = _get_path_env_var(repository_ctx, "PROGRAMFILES") + if not program_files_dir: + program_files_dir = "C:\\Program Files" + auto_configure_warning_maybe( + repository_ctx, + "'PROGRAMFILES' environment variable is not set, using '%s' as default" % program_files_dir, + ) + path = program_files_dir + "\\LLVM" + if repository_ctx.path(path).exists: + llvm_dir = path + + if not llvm_dir: + auto_configure_warning_maybe(repository_ctx, "LLVM installation not found.") + return None + auto_configure_warning_maybe(repository_ctx, "LLVM installation found at %s" % llvm_dir) + return llvm_dir + +def _find_llvm_tool(repository_ctx, llvm_path, tool): + """Find the exact path of a specific build tool in LLVM. Doesn't %-escape the result.""" + tool_path = llvm_path + "\\bin\\" + tool + + if not repository_ctx.path(tool_path).exists: + return None + + return tool_path.replace("\\", "/") + +def _use_clang_cl(repository_ctx): + """Returns True if USE_CLANG_CL is set to 1.""" + return repository_ctx.os.environ.get("USE_CLANG_CL", default = "0") == "1" + +def _find_missing_llvm_tools(repository_ctx, llvm_path): + """Check if any required tool is missing under given LLVM path.""" + missing_tools = [] + for tool in ["clang-cl.exe", "lld-link.exe", "llvm-lib.exe"]: + if not _find_llvm_tool(repository_ctx, llvm_path, tool): + missing_tools.append(tool) + + return missing_tools + +def _get_clang_version(repository_ctx, clang_cl): + result = repository_ctx.execute([clang_cl, "-v"]) + if result.return_code != 0: + auto_configure_fail("Failed to get clang version by running \"%s -v\"" % clang_cl) + + # Stderr should look like "clang version X.X.X ..." + return result.stderr.splitlines()[0].split(" ")[2] + +def _get_msys_mingw_vars(repository_ctx): + """Get the variables we need to populate the msys/mingw toolchains.""" + tool_paths, tool_bin_path, inc_dir_msys = _get_escaped_windows_msys_starlark_content(repository_ctx) + tool_paths_mingw, tool_bin_path_mingw, inc_dir_mingw = _get_escaped_windows_msys_starlark_content(repository_ctx, use_mingw = True) + write_builtin_include_directory_paths(repository_ctx, "mingw", [inc_dir_mingw], file_suffix = "_mingw") + msys_mingw_vars = { + "%{cxx_builtin_include_directories}": inc_dir_msys, + "%{mingw_cxx_builtin_include_directories}": inc_dir_mingw, + "%{mingw_tool_bin_path}": tool_bin_path_mingw, + "%{mingw_tool_paths}": tool_paths_mingw, + "%{tool_bin_path}": tool_bin_path, + "%{tool_paths}": tool_paths, + } + return msys_mingw_vars + +def _get_msvc_vars(repository_ctx, paths): + """Get the variables we need to populate the MSVC toolchains.""" + msvc_vars = dict() + vc_path = _find_vc_path(repository_ctx) + missing_tools = None + if not vc_path: + repository_ctx.template( + "vc_installation_error.bat", + paths["@rules_cc//cc/private/toolchain:vc_installation_error.bat.tpl"], + {"%{vc_error_message}": ""}, + ) + else: + missing_tools = _find_missing_vc_tools(repository_ctx, vc_path) + if missing_tools: + message = "\r\n".join([ + "echo. 1>&2", + "echo Visual C++ build tools seems to be installed at %s 1>&2" % vc_path, + "echo But Bazel can't find the following tools: 1>&2", + "echo %s 1>&2" % ", ".join(missing_tools), + "echo. 1>&2", + ]) + repository_ctx.template( + "vc_installation_error.bat", + paths["@rules_cc//cc/private/toolchain:vc_installation_error.bat.tpl"], + {"%{vc_error_message}": message}, + ) + + if not vc_path or missing_tools: + write_builtin_include_directory_paths(repository_ctx, "msvc", [], file_suffix = "_msvc") + msvc_vars = { + "%{dbg_mode_debug_flag}": "/DEBUG", + "%{fastbuild_mode_debug_flag}": "/DEBUG", + "%{msvc_cl_path}": "vc_installation_error.bat", + "%{msvc_cxx_builtin_include_directories}": "", + "%{msvc_env_include}": "msvc_not_found", + "%{msvc_env_lib}": "msvc_not_found", + "%{msvc_env_path}": "msvc_not_found", + "%{msvc_env_tmp}": "msvc_not_found", + "%{msvc_lib_path}": "vc_installation_error.bat", + "%{msvc_link_path}": "vc_installation_error.bat", + "%{msvc_ml_path}": "vc_installation_error.bat", + } + return msvc_vars + + env = setup_vc_env_vars(repository_ctx, vc_path) + escaped_paths = escape_string(env["PATH"]) + escaped_include_paths = escape_string(env["INCLUDE"]) + escaped_lib_paths = escape_string(env["LIB"]) + escaped_tmp_dir = escape_string(_get_temp_env(repository_ctx).replace("\\", "\\\\")) + + llvm_path = "" + if _use_clang_cl(repository_ctx): + llvm_path = _find_llvm_path(repository_ctx) + if not llvm_path: + auto_configure_fail("\nUSE_CLANG_CL is set to 1, but Bazel cannot find Clang installation on your system.\n" + + "Please install Clang via http://releases.llvm.org/download.html\n") + cl_path = _find_llvm_tool(repository_ctx, llvm_path, "clang-cl.exe") + link_path = _find_llvm_tool(repository_ctx, llvm_path, "lld-link.exe") + if not link_path: + link_path = _find_msvc_tool(repository_ctx, vc_path, "link.exe") + lib_path = _find_llvm_tool(repository_ctx, llvm_path, "llvm-lib.exe") + if not lib_path: + lib_path = _find_msvc_tool(repository_ctx, vc_path, "lib.exe") + else: + cl_path = _find_msvc_tool(repository_ctx, vc_path, "cl.exe") + link_path = _find_msvc_tool(repository_ctx, vc_path, "link.exe") + lib_path = _find_msvc_tool(repository_ctx, vc_path, "lib.exe") + + msvc_ml_path = _find_msvc_tool(repository_ctx, vc_path, "ml64.exe") + escaped_cxx_include_directories = [] + + for path in escaped_include_paths.split(";"): + if path: + escaped_cxx_include_directories.append("\"%s\"" % path) + if llvm_path: + clang_version = _get_clang_version(repository_ctx, cl_path) + clang_dir = llvm_path + "\\lib\\clang\\" + clang_version + clang_include_path = (clang_dir + "\\include").replace("\\", "\\\\") + escaped_cxx_include_directories.append("\"%s\"" % clang_include_path) + clang_lib_path = (clang_dir + "\\lib\\windows").replace("\\", "\\\\") + escaped_lib_paths = escaped_lib_paths + ";" + clang_lib_path + + support_debug_fastlink = _is_support_debug_fastlink(repository_ctx, link_path) + + write_builtin_include_directory_paths(repository_ctx, "msvc", escaped_cxx_include_directories, file_suffix = "_msvc") + msvc_vars = { + "%{dbg_mode_debug_flag}": "/DEBUG:FULL" if support_debug_fastlink else "/DEBUG", + "%{fastbuild_mode_debug_flag}": "/DEBUG:FASTLINK" if support_debug_fastlink else "/DEBUG", + "%{msvc_cl_path}": cl_path, + "%{msvc_cxx_builtin_include_directories}": " " + ",\n ".join(escaped_cxx_include_directories), + "%{msvc_env_include}": escaped_include_paths, + "%{msvc_env_lib}": escaped_lib_paths, + "%{msvc_env_path}": escaped_paths, + "%{msvc_env_tmp}": escaped_tmp_dir, + "%{msvc_lib_path}": lib_path, + "%{msvc_link_path}": link_path, + "%{msvc_ml_path}": msvc_ml_path, + } + return msvc_vars + +def _get_clang_cl_vars(repository_ctx, paths, msvc_vars): + """Get the variables we need to populate the clang-cl toolchains.""" + llvm_path = _find_llvm_path(repository_ctx) + error_script = None + if msvc_vars["%{msvc_cl_path}"] == "vc_installation_error.bat": + error_script = "vc_installation_error.bat" + elif not llvm_path: + repository_ctx.template( + "clang_installation_error.bat", + paths["@rules_cc//cc/private/toolchain:clang_installation_error.bat.tpl"], + {"%{clang_error_message}": ""}, + ) + error_script = "clang_installation_error.bat" + else: + missing_tools = _find_missing_llvm_tools(repository_ctx, llvm_path) + if missing_tools: + message = "\r\n".join([ + "echo. 1>&2", + "echo LLVM/Clang seems to be installed at %s 1>&2" % llvm_path, + "echo But Bazel can't find the following tools: 1>&2", + "echo %s 1>&2" % ", ".join(missing_tools), + "echo. 1>&2", + ]) + repository_ctx.template( + "clang_installation_error.bat", + paths["@rules_cc//cc/private/toolchain:clang_installation_error.bat.tpl"], + {"%{clang_error_message}": message}, + ) + error_script = "clang_installation_error.bat" + + if error_script: + write_builtin_include_directory_paths(repository_ctx, "clang-cl", [], file_suffix = "_clangcl") + clang_cl_vars = { + "%{clang_cl_cl_path}": error_script, + "%{clang_cl_cxx_builtin_include_directories}": "", + "%{clang_cl_dbg_mode_debug_flag}": "/DEBUG", + "%{clang_cl_env_include}": "clang_cl_not_found", + "%{clang_cl_env_lib}": "clang_cl_not_found", + "%{clang_cl_env_path}": "clang_cl_not_found", + "%{clang_cl_env_tmp}": "clang_cl_not_found", + "%{clang_cl_fastbuild_mode_debug_flag}": "/DEBUG", + "%{clang_cl_lib_path}": error_script, + "%{clang_cl_link_path}": error_script, + "%{clang_cl_ml_path}": error_script, + } + return clang_cl_vars + + clang_cl_path = _find_llvm_tool(repository_ctx, llvm_path, "clang-cl.exe") + lld_link_path = _find_llvm_tool(repository_ctx, llvm_path, "lld-link.exe") + llvm_lib_path = _find_llvm_tool(repository_ctx, llvm_path, "llvm-lib.exe") + + clang_version = _get_clang_version(repository_ctx, clang_cl_path) + clang_dir = llvm_path + "\\lib\\clang\\" + clang_version + clang_include_path = (clang_dir + "\\include").replace("\\", "\\\\") + clang_lib_path = (clang_dir + "\\lib\\windows").replace("\\", "\\\\") + + clang_cl_include_directories = msvc_vars["%{msvc_cxx_builtin_include_directories}"] + (",\n \"%s\"" % clang_include_path) + write_builtin_include_directory_paths(repository_ctx, "clang-cl", [clang_cl_include_directories], file_suffix = "_clangcl") + clang_cl_vars = { + "%{clang_cl_cl_path}": clang_cl_path, + "%{clang_cl_cxx_builtin_include_directories}": clang_cl_include_directories, + # LLVM's lld-link.exe doesn't support /DEBUG:FASTLINK. + "%{clang_cl_dbg_mode_debug_flag}": "/DEBUG", + "%{clang_cl_env_include}": msvc_vars["%{msvc_env_include}"] + ";" + clang_include_path, + "%{clang_cl_env_lib}": msvc_vars["%{msvc_env_lib}"] + ";" + clang_lib_path, + "%{clang_cl_env_path}": msvc_vars["%{msvc_env_path}"], + "%{clang_cl_env_tmp}": msvc_vars["%{msvc_env_tmp}"], + "%{clang_cl_fastbuild_mode_debug_flag}": "/DEBUG", + "%{clang_cl_lib_path}": llvm_lib_path, + "%{clang_cl_link_path}": lld_link_path, + "%{clang_cl_ml_path}": msvc_vars["%{msvc_ml_path}"], + } + return clang_cl_vars + +def configure_windows_toolchain(repository_ctx): + """Configure C++ toolchain on Windows. + + Args: + repository_ctx: The repository context. + """ + paths = resolve_labels(repository_ctx, [ + "@rules_cc//cc/private/toolchain:BUILD.windows.tpl", + "@rules_cc//cc/private/toolchain:windows_cc_toolchain_config.bzl", + "@rules_cc//cc/private/toolchain:armeabi_cc_toolchain_config.bzl", + "@rules_cc//cc/private/toolchain:vc_installation_error.bat.tpl", + "@rules_cc//cc/private/toolchain:msys_gcc_installation_error.bat", + "@rules_cc//cc/private/toolchain:clang_installation_error.bat.tpl", + ]) + + repository_ctx.symlink( + paths["@rules_cc//cc/private/toolchain:windows_cc_toolchain_config.bzl"], + "windows_cc_toolchain_config.bzl", + ) + repository_ctx.symlink( + paths["@rules_cc//cc/private/toolchain:armeabi_cc_toolchain_config.bzl"], + "armeabi_cc_toolchain_config.bzl", + ) + repository_ctx.symlink( + paths["@rules_cc//cc/private/toolchain:msys_gcc_installation_error.bat"], + "msys_gcc_installation_error.bat", + ) + + template_vars = dict() + msvc_vars = _get_msvc_vars(repository_ctx, paths) + template_vars.update(msvc_vars) + template_vars.update(_get_clang_cl_vars(repository_ctx, paths, msvc_vars)) + template_vars.update(_get_msys_mingw_vars(repository_ctx)) + + repository_ctx.template( + "BUILD", + paths["@rules_cc//cc/private/toolchain:BUILD.windows.tpl"], + template_vars, + ) diff --git a/cc/private/toolchain/windows_cc_toolchain_config.bzl b/cc/private/toolchain/windows_cc_toolchain_config.bzl new file mode 100644 index 0000000..7fa2978 --- /dev/null +++ b/cc/private/toolchain/windows_cc_toolchain_config.bzl @@ -0,0 +1,1339 @@ +# Copyright 2019 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. + +"""A Starlark cc_toolchain configuration rule for Windows""" + +load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES") +load( + "@rules_cc//cc:cc_toolchain_config_lib.bzl", + "action_config", + "artifact_name_pattern", + "env_entry", + "env_set", + "feature", + "feature_set", + "flag_group", + "flag_set", + "tool", + "tool_path", + "variable_with_value", + "with_feature_set", +) + +all_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, + ACTION_NAMES.lto_backend, +] + +all_cpp_compile_actions = [ + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.clif_match, +] + +preprocessor_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.clif_match, +] + +codegen_compile_actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, +] + +all_link_actions = [ + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, +] + +def _use_msvc_toolchain(ctx): + return ctx.attr.cpu == "x64_windows" and (ctx.attr.compiler == "msvc-cl" or ctx.attr.compiler == "clang-cl") + +def _impl(ctx): + if _use_msvc_toolchain(ctx): + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "object_file", + prefix = "", + extension = ".obj", + ), + artifact_name_pattern( + category_name = "static_library", + prefix = "", + extension = ".lib", + ), + artifact_name_pattern( + category_name = "alwayslink_static_library", + prefix = "", + extension = ".lo.lib", + ), + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + artifact_name_pattern( + category_name = "dynamic_library", + prefix = "", + extension = ".dll", + ), + artifact_name_pattern( + category_name = "interface_library", + prefix = "", + extension = ".if.lib", + ), + ] + else: + artifact_name_patterns = [ + artifact_name_pattern( + category_name = "executable", + prefix = "", + extension = ".exe", + ), + ] + + if _use_msvc_toolchain(ctx): + cpp_link_nodeps_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_nodeps_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = ctx.attr.msvc_link_path)], + ) + + cpp_link_static_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_static_library, + implies = [ + "nologo", + "archiver_flags", + "input_param_flags", + "linker_param_file", + "msvc_env", + ], + tools = [tool(path = ctx.attr.msvc_lib_path)], + ) + + assemble_action = action_config( + action_name = ACTION_NAMES.assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = ctx.attr.msvc_ml_path)], + ) + + preprocess_assemble_action = action_config( + action_name = ACTION_NAMES.preprocess_assemble, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "nologo", + "msvc_env", + "sysroot", + ], + tools = [tool(path = ctx.attr.msvc_ml_path)], + ) + + c_compile_action = action_config( + action_name = ACTION_NAMES.c_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "nologo", + "msvc_env", + "parse_showincludes", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = ctx.attr.msvc_cl_path)], + ) + + cpp_compile_action = action_config( + action_name = ACTION_NAMES.cpp_compile, + implies = [ + "compiler_input_flags", + "compiler_output_flags", + "default_compile_flags", + "nologo", + "msvc_env", + "parse_showincludes", + "user_compile_flags", + "sysroot", + "unfiltered_compile_flags", + ], + tools = [tool(path = ctx.attr.msvc_cl_path)], + ) + + cpp_link_executable_action = action_config( + action_name = ACTION_NAMES.cpp_link_executable, + implies = [ + "nologo", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + ], + tools = [tool(path = ctx.attr.msvc_link_path)], + ) + + cpp_link_dynamic_library_action = action_config( + action_name = ACTION_NAMES.cpp_link_dynamic_library, + implies = [ + "nologo", + "shared_flag", + "linkstamps", + "output_execpath_flags", + "input_param_flags", + "user_link_flags", + "default_link_flags", + "linker_subsystem_flag", + "linker_param_file", + "msvc_env", + "no_stripping", + "has_configured_linker_path", + "def_file", + ], + tools = [tool(path = ctx.attr.msvc_link_path)], + ) + + action_configs = [ + assemble_action, + preprocess_assemble_action, + c_compile_action, + cpp_compile_action, + cpp_link_executable_action, + cpp_link_dynamic_library_action, + cpp_link_nodeps_dynamic_library_action, + cpp_link_static_library_action, + ] + else: + action_configs = [] + + if _use_msvc_toolchain(ctx): + msvc_link_env_feature = feature( + name = "msvc_link_env", + env_sets = [ + env_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + env_entries = [env_entry(key = "LIB", value = ctx.attr.msvc_env_lib)], + ), + ], + ) + + shared_flag_feature = feature( + name = "shared_flag", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [flag_group(flags = ["/DLL"])], + ), + ], + ) + + determinism_feature = feature( + name = "determinism", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "/wd4117", + "-D__DATE__=\"redacted\"", + "-D__TIMESTAMP__=\"redacted\"", + "-D__TIME__=\"redacted\"", + ] + (["-Wno-builtin-macro-redefined"] if ctx.attr.compiler == "clang-cl" else []), + ), + ], + ), + ], + ) + + sysroot_feature = feature( + name = "sysroot", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + iterate_over = "sysroot", + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + unfiltered_compile_flags_feature = feature( + name = "unfiltered_compile_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{unfiltered_compile_flags}"], + iterate_over = "unfiltered_compile_flags", + expand_if_available = "unfiltered_compile_flags", + ), + ], + ), + ], + ) + + compiler_param_file_feature = feature( + name = "compiler_param_file", + ) + + copy_dynamic_libraries_to_binary_feature = feature( + name = "copy_dynamic_libraries_to_binary", + ) + + input_param_flags_feature = feature( + name = "input_param_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["/IMPLIB:%{interface_library_output_path}"], + expand_if_available = "interface_library_output_path", + ), + ], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{libopts}"], + iterate_over = "libopts", + expand_if_available = "libopts", + ), + ], + ), + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link", + flag_groups = [ + flag_group( + iterate_over = "libraries_to_link.object_files", + flag_groups = [flag_group(flags = ["%{libraries_to_link.object_files}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file_group", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "object_file", + ), + ), + flag_group( + flag_groups = [flag_group(flags = ["%{libraries_to_link.name}"])], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "interface_library", + ), + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["%{libraries_to_link.name}"], + expand_if_false = "libraries_to_link.is_whole_archive", + ), + flag_group( + flags = ["/WHOLEARCHIVE:%{libraries_to_link.name}"], + expand_if_true = "libraries_to_link.is_whole_archive", + ), + ], + expand_if_equal = variable_with_value( + name = "libraries_to_link.type", + value = "static_library", + ), + ), + ], + expand_if_available = "libraries_to_link", + ), + ], + ), + ], + ) + + fastbuild_feature = feature( + name = "fastbuild", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ctx.attr.fastbuild_mode_debug_flag, "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + archiver_flags_feature = feature( + name = "archiver_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + flag_group( + flags = ["/MACHINE:X64"], + ), + ], + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ctx.attr.default_link_flags)], + ), + ], + ) + + static_link_msvcrt_feature = feature(name = "static_link_msvcrt") + + dynamic_link_msvcrt_debug_feature = feature( + name = "dynamic_link_msvcrt_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MDd"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrtd.lib"])], + ), + ], + requires = [feature_set(features = ["dbg"])], + ) + + dbg_feature = feature( + name = "dbg", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Od", "/Z7"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = [ctx.attr.dbg_mode_debug_flag, "/INCREMENTAL:NO"], + ), + ], + ), + ], + implies = ["generate_pdb_file"], + ) + + opt_feature = feature( + name = "opt", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/O2"])], + ), + ], + implies = ["frame_pointer"], + ) + + supports_interface_shared_libraries_feature = feature( + name = "supports_interface_shared_libraries", + enabled = True, + ) + + user_link_flags_feature = feature( + name = "user_link_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{user_link_flags}"], + iterate_over = "user_link_flags", + expand_if_available = "user_link_flags", + ), + ], + ), + ], + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = [ + "/DCOMPILER_MSVC", + "/DNOMINMAX", + "/D_WIN32_WINNT=0x0601", + "/D_CRT_SECURE_NO_DEPRECATE", + "/D_CRT_SECURE_NO_WARNINGS", + "/bigobj", + "/Zm500", + "/EHsc", + "/wd4351", + "/wd4291", + "/wd4250", + "/wd4996", + ], + ), + ], + ), + ], + ) + + msvc_compile_env_feature = feature( + name = "msvc_compile_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ], + env_entries = [env_entry(key = "INCLUDE", value = ctx.attr.msvc_env_include)], + ), + ], + ) + + preprocessor_defines_feature = feature( + name = "preprocessor_defines", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/D%{preprocessor_defines}"], + iterate_over = "preprocessor_defines", + ), + ], + ), + ], + ) + + generate_pdb_file_feature = feature( + name = "generate_pdb_file", + ) + + output_execpath_flags_feature = feature( + name = "output_execpath_flags", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/OUT:%{output_execpath}"], + expand_if_available = "output_execpath", + ), + ], + ), + ], + ) + + dynamic_link_msvcrt_no_debug_feature = feature( + name = "dynamic_link_msvcrt_no_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MD"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:msvcrt.lib"])], + ), + ], + requires = [ + feature_set(features = ["fastbuild"]), + feature_set(features = ["opt"]), + ], + ) + + disable_assertions_feature = feature( + name = "disable_assertions", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/DNDEBUG"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + has_configured_linker_path_feature = feature(name = "has_configured_linker_path") + + supports_dynamic_linker_feature = feature(name = "supports_dynamic_linker", enabled = True) + + no_stripping_feature = feature(name = "no_stripping") + + linker_param_file_feature = feature( + name = "linker_param_file", + flag_sets = [ + flag_set( + actions = all_link_actions + + [ACTION_NAMES.cpp_link_static_library], + flag_groups = [ + flag_group( + flags = ["@%{linker_param_file}"], + expand_if_available = "linker_param_file", + ), + ], + ), + ], + ) + + ignore_noisy_warnings_feature = feature( + name = "ignore_noisy_warnings", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.cpp_link_static_library], + flag_groups = [flag_group(flags = ["/ignore:4221"])], + ), + ], + ) + + no_legacy_features_feature = feature(name = "no_legacy_features") + + parse_showincludes_feature = feature( + name = "parse_showincludes", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_header_parsing, + ], + flag_groups = [flag_group(flags = ["/showIncludes"])], + ), + ], + ) + + static_link_msvcrt_no_debug_feature = feature( + name = "static_link_msvcrt_no_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MT"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmt.lib"])], + ), + ], + requires = [ + feature_set(features = ["fastbuild"]), + feature_set(features = ["opt"]), + ], + ) + + treat_warnings_as_errors_feature = feature( + name = "treat_warnings_as_errors", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/WX"])], + ), + ], + ) + + windows_export_all_symbols_feature = feature(name = "windows_export_all_symbols") + + no_windows_export_all_symbols_feature = feature(name = "no_windows_export_all_symbols") + + include_paths_feature = feature( + name = "include_paths", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ], + flag_groups = [ + flag_group( + flags = ["/I%{quote_include_paths}"], + iterate_over = "quote_include_paths", + ), + flag_group( + flags = ["/I%{include_paths}"], + iterate_over = "include_paths", + ), + flag_group( + flags = ["/I%{system_include_paths}"], + iterate_over = "system_include_paths", + ), + ], + ), + ], + ) + + linkstamps_feature = feature( + name = "linkstamps", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["%{linkstamp_paths}"], + iterate_over = "linkstamp_paths", + expand_if_available = "linkstamp_paths", + ), + ], + ), + ], + ) + + targets_windows_feature = feature( + name = "targets_windows", + enabled = True, + implies = ["copy_dynamic_libraries_to_binary"], + ) + + linker_subsystem_flag_feature = feature( + name = "linker_subsystem_flag", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/SUBSYSTEM:CONSOLE"])], + ), + ], + ) + + static_link_msvcrt_debug_feature = feature( + name = "static_link_msvcrt_debug", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/MTd"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/DEFAULTLIB:libcmtd.lib"])], + ), + ], + requires = [feature_set(features = ["dbg"])], + ) + + frame_pointer_feature = feature( + name = "frame_pointer", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Oy-"])], + ), + ], + ) + + compiler_output_flags_feature = feature( + name = "compiler_output_flags", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.assemble], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}", "/Zi"], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + ], + expand_if_not_available = "output_preprocess_file", + ), + ], + ), + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fo%{output_file}"], + expand_if_not_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + expand_if_not_available = "output_assembly_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/Fa%{output_file}"], + expand_if_available = "output_assembly_file", + ), + ], + expand_if_available = "output_file", + ), + flag_group( + flag_groups = [ + flag_group( + flags = ["/P", "/Fi%{output_file}"], + expand_if_available = "output_preprocess_file", + ), + ], + expand_if_available = "output_file", + ), + ], + ), + ], + ) + + nologo_feature = feature( + name = "nologo", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + flag_groups = [flag_group(flags = ["/nologo"])], + ), + ], + ) + + smaller_binary_feature = feature( + name = "smaller_binary", + enabled = True, + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [flag_group(flags = ["/Gy", "/Gw"])], + with_features = [with_feature_set(features = ["opt"])], + ), + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["/OPT:ICF", "/OPT:REF"])], + with_features = [with_feature_set(features = ["opt"])], + ), + ], + ) + + compiler_input_flags_feature = feature( + name = "compiler_input_flags", + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ], + flag_groups = [ + flag_group( + flags = ["/c", "%{source_file}"], + expand_if_available = "source_file", + ), + ], + ), + ], + ) + + def_file_feature = feature( + name = "def_file", + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [ + flag_group( + flags = ["/DEF:%{def_file_path}", "/ignore:4070"], + expand_if_available = "def_file_path", + ), + ], + ), + ], + ) + + msvc_env_feature = feature( + name = "msvc_env", + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = ctx.attr.msvc_env_path), + env_entry(key = "TMP", value = ctx.attr.msvc_env_tmp), + env_entry(key = "TEMP", value = ctx.attr.msvc_env_tmp), + ], + ), + ], + implies = ["msvc_compile_env", "msvc_link_env"], + ) + features = [ + no_legacy_features_feature, + nologo_feature, + has_configured_linker_path_feature, + no_stripping_feature, + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + default_compile_flags_feature, + msvc_env_feature, + msvc_compile_env_feature, + msvc_link_env_feature, + include_paths_feature, + preprocessor_defines_feature, + parse_showincludes_feature, + generate_pdb_file_feature, + shared_flag_feature, + linkstamps_feature, + output_execpath_flags_feature, + archiver_flags_feature, + input_param_flags_feature, + linker_subsystem_flag_feature, + user_link_flags_feature, + default_link_flags_feature, + linker_param_file_feature, + static_link_msvcrt_feature, + static_link_msvcrt_no_debug_feature, + dynamic_link_msvcrt_no_debug_feature, + static_link_msvcrt_debug_feature, + dynamic_link_msvcrt_debug_feature, + dbg_feature, + fastbuild_feature, + opt_feature, + frame_pointer_feature, + disable_assertions_feature, + determinism_feature, + treat_warnings_as_errors_feature, + smaller_binary_feature, + ignore_noisy_warnings_feature, + user_compile_flags_feature, + sysroot_feature, + unfiltered_compile_flags_feature, + compiler_param_file_feature, + compiler_output_flags_feature, + compiler_input_flags_feature, + def_file_feature, + windows_export_all_symbols_feature, + no_windows_export_all_symbols_feature, + supports_dynamic_linker_feature, + supports_interface_shared_libraries_feature, + ] + else: + targets_windows_feature = feature( + name = "targets_windows", + implies = ["copy_dynamic_libraries_to_binary"], + enabled = True, + ) + + copy_dynamic_libraries_to_binary_feature = feature(name = "copy_dynamic_libraries_to_binary") + + gcc_env_feature = feature( + name = "gcc_env", + enabled = True, + env_sets = [ + env_set( + actions = [ + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ACTION_NAMES.cpp_link_static_library, + ], + env_entries = [ + env_entry(key = "PATH", value = ctx.attr.tool_bin_path), + ], + ), + ], + ) + + default_compile_flags_feature = feature( + name = "default_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [flag_group(flags = ["-std=gnu++0x"])], + ), + ], + ) + + default_link_flags_feature = feature( + name = "default_link_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = all_link_actions, + flag_groups = [flag_group(flags = ["-lstdc++"])], + ), + ], + ) + + supports_dynamic_linker_feature = feature( + name = "supports_dynamic_linker", + enabled = True, + ) + + if ctx.attr.cpu == "x64_windows" and ctx.attr.compiler == "mingw-gcc": + compiler_param_file_feature = feature( + name = "compiler_param_file", + ) + + features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + default_compile_flags_feature, + compiler_param_file_feature, + default_link_flags_feature, + supports_dynamic_linker_feature, + ] + else: + supports_pic_feature = feature( + name = "supports_pic", + enabled = True, + ) + supports_start_end_lib_feature = feature( + name = "supports_start_end_lib", + enabled = True, + ) + + dbg_feature = feature(name = "dbg") + + opt_feature = feature(name = "opt") + + sysroot_feature = feature( + name = "sysroot", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ACTION_NAMES.cpp_link_executable, + ACTION_NAMES.cpp_link_dynamic_library, + ACTION_NAMES.cpp_link_nodeps_dynamic_library, + ], + flag_groups = [ + flag_group( + flags = ["--sysroot=%{sysroot}"], + expand_if_available = "sysroot", + ), + ], + ), + ], + ) + + fdo_optimize_feature = feature( + name = "fdo_optimize", + flag_sets = [ + flag_set( + actions = [ACTION_NAMES.c_compile, ACTION_NAMES.cpp_compile], + flag_groups = [ + flag_group( + flags = [ + "-fprofile-use=%{fdo_profile_path}", + "-fprofile-correction", + ], + expand_if_available = "fdo_profile_path", + ), + ], + ), + ], + provides = ["profile"], + ) + + user_compile_flags_feature = feature( + name = "user_compile_flags", + enabled = True, + flag_sets = [ + flag_set( + actions = [ + ACTION_NAMES.assemble, + ACTION_NAMES.preprocess_assemble, + ACTION_NAMES.linkstamp_compile, + ACTION_NAMES.c_compile, + ACTION_NAMES.cpp_compile, + ACTION_NAMES.cpp_header_parsing, + ACTION_NAMES.cpp_module_compile, + ACTION_NAMES.cpp_module_codegen, + ACTION_NAMES.lto_backend, + ACTION_NAMES.clif_match, + ], + flag_groups = [ + flag_group( + flags = ["%{user_compile_flags}"], + iterate_over = "user_compile_flags", + expand_if_available = "user_compile_flags", + ), + ], + ), + ], + ) + + features = [ + targets_windows_feature, + copy_dynamic_libraries_to_binary_feature, + gcc_env_feature, + supports_pic_feature, + supports_start_end_lib_feature, + default_compile_flags_feature, + default_link_flags_feature, + fdo_optimize_feature, + supports_dynamic_linker_feature, + dbg_feature, + opt_feature, + user_compile_flags_feature, + sysroot_feature, + ] + + tool_paths = [ + tool_path(name = name, path = path) + for name, path in ctx.attr.tool_paths.items() + ] + + return cc_common.create_cc_toolchain_config_info( + ctx = ctx, + features = features, + action_configs = action_configs, + artifact_name_patterns = artifact_name_patterns, + cxx_builtin_include_directories = ctx.attr.cxx_builtin_include_directories, + toolchain_identifier = ctx.attr.toolchain_identifier, + host_system_name = ctx.attr.host_system_name, + target_system_name = ctx.attr.target_system_name, + target_cpu = ctx.attr.cpu, + target_libc = ctx.attr.target_libc, + compiler = ctx.attr.compiler, + abi_version = ctx.attr.abi_version, + abi_libc_version = ctx.attr.abi_libc_version, + tool_paths = tool_paths, + ) + +cc_toolchain_config = rule( + implementation = _impl, + attrs = { + "abi_libc_version": attr.string(), + "abi_version": attr.string(), + "compiler": attr.string(), + "cpu": attr.string(mandatory = True), + "cxx_builtin_include_directories": attr.string_list(), + "dbg_mode_debug_flag": attr.string(), + "default_link_flags": attr.string_list(default = []), + "fastbuild_mode_debug_flag": attr.string(), + "host_system_name": attr.string(), + "msvc_cl_path": attr.string(default = "vc_installation_error.bat"), + "msvc_env_include": attr.string(default = "msvc_not_found"), + "msvc_env_lib": attr.string(default = "msvc_not_found"), + "msvc_env_path": attr.string(default = "msvc_not_found"), + "msvc_env_tmp": attr.string(default = "msvc_not_found"), + "msvc_lib_path": attr.string(default = "vc_installation_error.bat"), + "msvc_link_path": attr.string(default = "vc_installation_error.bat"), + "msvc_ml_path": attr.string(default = "vc_installation_error.bat"), + "target_libc": attr.string(), + "target_system_name": attr.string(), + "tool_bin_path": attr.string(default = "not_found"), + "tool_paths": attr.string_dict(), + "toolchain_identifier": attr.string(), + }, + provides = [CcToolchainConfigInfo], +) diff --git a/cc/repositories.bzl b/cc/repositories.bzl index a841981..5d0c56b 100644 --- a/cc/repositories.bzl +++ b/cc/repositories.bzl @@ -1,10 +1,18 @@ """Repository rules entry point module for rules_cc.""" +# WARNING: This file only exists for backwards-compatibility. +# rules_cc uses the Bazel federation, so please add any new dependencies to +# rules_cc_deps() in +# https://github.com/bazelbuild/bazel-federation/blob/master/repositories.bzl +# Third party dependencies can be added to +# https://github.com/bazelbuild/bazel-federation/blob/master/third_party_repositories.bzl +# Ideally we'd delete this entire file. + load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") -load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe") +load("//cc/private/toolchain:cc_configure.bzl", "cc_configure") def rules_cc_dependencies(): - maybe( + _maybe( http_archive, name = "bazel_skylib", sha256 = "2ea8a5ed2b448baf4a6855d3ce049c4c452a6470b1efd1504fdb7c1c134d220a", @@ -16,7 +24,9 @@ def rules_cc_dependencies(): ) # buildifier: disable=unnamed-macro -def rules_cc_toolchains(*_args): - # Use the auto-configured toolchains defined in @bazel_tools//tools/cpp until they have been - # fully migrated to rules_cc. - pass +def rules_cc_toolchains(*args): + cc_configure(*args) + +def _maybe(repo_rule, name, **kwargs): + if not native.existing_rule(name): + repo_rule(name = name, **kwargs)