From 94cefefb42f3685c1d64664e6aa9cbaf834b25ee Mon Sep 17 00:00:00 2001 From: Marco Poletti Date: Sun, 9 Aug 2020 11:02:44 -0700 Subject: Automatically detect compiler features when running under Bazel. Before this commit, bazel builds used a hardcoded configuration, but that doesn't work e.g. on Windows where MSVC needs a different config. --- configuration/bazel/BUILD | 8 ++ configuration/bazel/always_inline_attribute.cpp | 7 ++ configuration/bazel/attribute_deprecated.cpp | 5 ++ configuration/bazel/build_defs.bzl | 85 ++++++++++++++++++++++ configuration/bazel/builtin_unreachable.cpp | 13 ++++ .../clang_arbitrary_overload_resolution_bug.cpp | 11 +++ configuration/bazel/constexpr_typeid.cpp | 6 ++ configuration/bazel/cxa_demangle.cpp | 6 ++ configuration/bazel/declspec_deprecated.cpp | 5 ++ configuration/bazel/force_inline.cpp | 7 ++ configuration/bazel/fruit/impl/fruit-config-base.h | 70 ------------------ configuration/bazel/gcc_attribute_deprecated.cpp | 5 ++ configuration/bazel/has_trivial_copy.cpp | 5 ++ configuration/bazel/is_trivially_copyable.cpp | 5 ++ configuration/bazel/max_align_t.cpp | 5 ++ configuration/bazel/msvc_assume.cpp | 13 ++++ .../bazel/std_is_trivially_copy_constructible.cpp | 6 ++ configuration/bazel/std_is_trivially_copyable.cpp | 6 ++ configuration/bazel/std_max_align_t.cpp | 5 ++ configuration/bazel/typeid.cpp | 5 ++ 20 files changed, 208 insertions(+), 70 deletions(-) create mode 100644 configuration/bazel/BUILD create mode 100644 configuration/bazel/always_inline_attribute.cpp create mode 100644 configuration/bazel/attribute_deprecated.cpp create mode 100644 configuration/bazel/build_defs.bzl create mode 100644 configuration/bazel/builtin_unreachable.cpp create mode 100644 configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp create mode 100644 configuration/bazel/constexpr_typeid.cpp create mode 100644 configuration/bazel/cxa_demangle.cpp create mode 100644 configuration/bazel/declspec_deprecated.cpp create mode 100644 configuration/bazel/force_inline.cpp delete mode 100644 configuration/bazel/fruit/impl/fruit-config-base.h create mode 100644 configuration/bazel/gcc_attribute_deprecated.cpp create mode 100644 configuration/bazel/has_trivial_copy.cpp create mode 100644 configuration/bazel/is_trivially_copyable.cpp create mode 100644 configuration/bazel/max_align_t.cpp create mode 100644 configuration/bazel/msvc_assume.cpp create mode 100644 configuration/bazel/std_is_trivially_copy_constructible.cpp create mode 100644 configuration/bazel/std_is_trivially_copyable.cpp create mode 100644 configuration/bazel/std_max_align_t.cpp create mode 100644 configuration/bazel/typeid.cpp (limited to 'configuration/bazel') diff --git a/configuration/bazel/BUILD b/configuration/bazel/BUILD new file mode 100644 index 0000000..112b732 --- /dev/null +++ b/configuration/bazel/BUILD @@ -0,0 +1,8 @@ +load("//third_party/fruit/configuration/bazel:build_defs.bzl", "generate_fruit_config") + +package(default_visibility = ["//third_party/fruit:__subpackages__"]) + +generate_fruit_config( + name = "fruit_config", + check_sources = glob(["*.cpp"]) +) diff --git a/configuration/bazel/always_inline_attribute.cpp b/configuration/bazel/always_inline_attribute.cpp new file mode 100644 index 0000000..e6215af --- /dev/null +++ b/configuration/bazel/always_inline_attribute.cpp @@ -0,0 +1,7 @@ +__attribute__((always_inline)) +void f() { +} + +int main() { + return 0; +} diff --git a/configuration/bazel/attribute_deprecated.cpp b/configuration/bazel/attribute_deprecated.cpp new file mode 100644 index 0000000..245519d --- /dev/null +++ b/configuration/bazel/attribute_deprecated.cpp @@ -0,0 +1,5 @@ +[[deprecated]] void f(); + +int main() { + return 0; +} diff --git a/configuration/bazel/build_defs.bzl b/configuration/bazel/build_defs.bzl new file mode 100644 index 0000000..8d683c4 --- /dev/null +++ b/configuration/bazel/build_defs.bzl @@ -0,0 +1,85 @@ +load("@rules_cc//cc:action_names.bzl", "C_COMPILE_ACTION_NAME") +load("@rules_cc//cc:toolchain_utils.bzl", "find_cpp_toolchain") + +def _generate_fruit_config_impl(ctx): + cc_toolchain = find_cpp_toolchain(ctx) + + feature_configuration = cc_common.configure_features( + ctx = ctx, + cc_toolchain = cc_toolchain, + requested_features = ctx.features, + unsupported_features = ctx.disabled_features, + ) + c_compiler_path = cc_common.get_tool_for_action( + feature_configuration = feature_configuration, + action_name = C_COMPILE_ACTION_NAME, + ) + + check_output_files = [] + for check_source in ctx.files.check_sources: + output_file = ctx.actions.declare_file(check_source.path + ".o") + + c_compile_variables = cc_common.create_compile_variables( + feature_configuration = feature_configuration, + cc_toolchain = cc_toolchain, + user_compile_flags = ctx.fragments.cpp.copts + ctx.fragments.cpp.conlyopts, + source_file = check_source.path, + output_file = output_file.path, + ) + command_line = cc_common.get_memory_inefficient_command_line( + feature_configuration = feature_configuration, + action_name = C_COMPILE_ACTION_NAME, + variables = c_compile_variables, + ) + env = cc_common.get_environment_variables( + feature_configuration = feature_configuration, + action_name = C_COMPILE_ACTION_NAME, + variables = c_compile_variables, + ) + + check_name = check_source.path.split('/')[-1].split('\\')[-1] + check_define = 'FRUIT_HAS_%s' % check_name.upper() + check_output_file = ctx.actions.declare_file(check_source.path + ".h") + + ctx.actions.run_shell( + command = '"$@" &>/dev/null && echo "#define %s 1" >"%s" || echo "#define %s 0" >"%s"; touch "%s"' % ( + check_define, check_output_file.path, check_define, check_output_file.path, output_file.path + ), + arguments = [c_compiler_path] + command_line, + env = env, + inputs = depset( + [check_source], + transitive = [cc_toolchain.all_files], + ), + outputs = [output_file, check_output_file], + ) + check_output_files.append(check_output_file) + + merged_output_file = ctx.actions.declare_file(ctx.label.name + ".h") + ctx.actions.run_shell( + command = '\n'.join([ + '(', + 'echo "#ifndef FRUIT_CONFIG_BASE_H"', + 'echo "#define FRUIT_CONFIG_BASE_H"', + 'echo "#define FRUIT_USES_BOOST 1"', + 'cat %s' % ' '.join([check_output_file.path for check_output_file in check_output_files]), + 'echo "#endif"', + ')>%s' % merged_output_file.path + ]), + inputs = check_output_files, + outputs = [merged_output_file], + ) + + return [ + DefaultInfo(files = depset([merged_output_file])), + ] + +generate_fruit_config = rule( + implementation = _generate_fruit_config_impl, + attrs = { + "check_sources": attr.label_list(allow_files = True), + "_cc_toolchain": attr.label(default = Label("@bazel_tools//tools/cpp:current_cc_toolchain")), + }, + toolchains = ["@bazel_tools//tools/cpp:toolchain_type"], + fragments = ["cpp"], +) \ No newline at end of file diff --git a/configuration/bazel/builtin_unreachable.cpp b/configuration/bazel/builtin_unreachable.cpp new file mode 100644 index 0000000..11d20cf --- /dev/null +++ b/configuration/bazel/builtin_unreachable.cpp @@ -0,0 +1,13 @@ +int f() { + static int x = 1; + if (x == 1) { + return 0; + } else { + __builtin_unreachable(); + // Note: the lack of return here is intentional + } +} + +int main() { + return f(); +} diff --git a/configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp b/configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp new file mode 100644 index 0000000..67b4317 --- /dev/null +++ b/configuration/bazel/clang_arbitrary_overload_resolution_bug.cpp @@ -0,0 +1,11 @@ +template +struct Pair {}; + +struct Map : public Pair, Pair {}; + +template +Value f(Pair*) { return Value(); } + +int main() { + f((Map*)0); +} diff --git a/configuration/bazel/constexpr_typeid.cpp b/configuration/bazel/constexpr_typeid.cpp new file mode 100644 index 0000000..a793377 --- /dev/null +++ b/configuration/bazel/constexpr_typeid.cpp @@ -0,0 +1,6 @@ +#include +int main() { + constexpr static const std::type_info& x = typeid(int); + (void) x; + return 0; +} diff --git a/configuration/bazel/cxa_demangle.cpp b/configuration/bazel/cxa_demangle.cpp new file mode 100644 index 0000000..3e4f57f --- /dev/null +++ b/configuration/bazel/cxa_demangle.cpp @@ -0,0 +1,6 @@ +#include +int main() { + auto* p = abi::__cxa_demangle; + (void) p; + return 0; +} diff --git a/configuration/bazel/declspec_deprecated.cpp b/configuration/bazel/declspec_deprecated.cpp new file mode 100644 index 0000000..79a9f43 --- /dev/null +++ b/configuration/bazel/declspec_deprecated.cpp @@ -0,0 +1,5 @@ +__declspec(deprecated) void f(); + +int main() { + return 0; +} diff --git a/configuration/bazel/force_inline.cpp b/configuration/bazel/force_inline.cpp new file mode 100644 index 0000000..fab42d2 --- /dev/null +++ b/configuration/bazel/force_inline.cpp @@ -0,0 +1,7 @@ +__forceinline +void f() { +} + +int main() { + return 0; +} diff --git a/configuration/bazel/fruit/impl/fruit-config-base.h b/configuration/bazel/fruit/impl/fruit-config-base.h deleted file mode 100644 index 8e7af1d..0000000 --- a/configuration/bazel/fruit/impl/fruit-config-base.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2014 Google Inc. 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. - */ - -#ifndef FRUIT_CONFIG_BASE_H -#define FRUIT_CONFIG_BASE_H - -// Needed for all Clang versions (as of January 2016), not needed for GCC. -// This can also be defined for GCC, but it slightly slows down compile time of code using Fruit. -#define FRUIT_HAS_CLANG_ARBITRARY_OVERLOAD_RESOLUTION_BUG 1 - -// Whether the compiler defines std::max_align_t. -#define FRUIT_HAS_STD_MAX_ALIGN_T 1 - -// Whether the compiler defines ::max_align_t. -// Ignored if FRUIT_HAS_STD_MAX_ALIGN_T is set. -#define FRUIT_HAS_MAX_ALIGN_T 1 - -// Whether the compiler defines std::is_trivially_copyable. -#define FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE 1 - -// Whether the compiler defines __has_trivial_copy. -// Ignored if FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE is set. -#define FRUIT_HAS_HAS_TRIVIAL_COPY 1 - -// Whether the compiler defines __is_trivially_copyable. -// Ignored if FRUIT_HAS_STD_IS_TRIVIALLY_COPYABLE is set. -#define FRUIT_HAS_IS_TRIVIALLY_COPYABLE 1 - -// Whether the compiler defines std::is_trivially_copy_constructible. -#define FRUIT_HAS_STD_IS_TRIVIALLY_COPY_CONSTRUCTIBLE 1 - -// Whether typeid() is available. Typically, it is unless RTTI is disabled. -#define FRUIT_HAS_TYPEID 1 - -// Whether typeid() is constexpr. Typically, it is except in MSVC. -#define FRUIT_HAS_CONSTEXPR_TYPEID 1 - -// Whether abi::__cxa_demangle() is available after including cxxabi.h. -#define FRUIT_HAS_CXA_DEMANGLE 1 - -#define FRUIT_USES_BOOST 1 - -#define FRUIT_HAS_ALWAYS_INLINE_ATTRIBUTE 1 - -#define FRUIT_HAS_FORCEINLINE 0 - -#define FRUIT_HAS_ATTRIBUTE_DEPRECATED 0 - -#define FRUIT_HAS_GCC_ATTRIBUTE_DEPRECATED 1 - -#define FRUIT_HAS_DECLSPEC_DEPRECATED 0 - -#define FRUIT_HAS_MSVC_ASSUME 0 - -#define FRUIT_HAS_BUILTIN_UNREACHABLE 1 - -#endif // FRUIT_CONFIG_BASE_H diff --git a/configuration/bazel/gcc_attribute_deprecated.cpp b/configuration/bazel/gcc_attribute_deprecated.cpp new file mode 100644 index 0000000..6d0bf5f --- /dev/null +++ b/configuration/bazel/gcc_attribute_deprecated.cpp @@ -0,0 +1,5 @@ +void f() __attribute__((deprecated)); + +int main() { + return 0; +} diff --git a/configuration/bazel/has_trivial_copy.cpp b/configuration/bazel/has_trivial_copy.cpp new file mode 100644 index 0000000..b9da7d1 --- /dev/null +++ b/configuration/bazel/has_trivial_copy.cpp @@ -0,0 +1,5 @@ +int main() { + bool b = __has_trivial_copy(int); + (void) b; + return 0; +} diff --git a/configuration/bazel/is_trivially_copyable.cpp b/configuration/bazel/is_trivially_copyable.cpp new file mode 100644 index 0000000..b8b7379 --- /dev/null +++ b/configuration/bazel/is_trivially_copyable.cpp @@ -0,0 +1,5 @@ +int main() { + bool b = __is_trivially_copyable(int); + (void) b; + return 0; +} diff --git a/configuration/bazel/max_align_t.cpp b/configuration/bazel/max_align_t.cpp new file mode 100644 index 0000000..37342f1 --- /dev/null +++ b/configuration/bazel/max_align_t.cpp @@ -0,0 +1,5 @@ +#include +using X = max_align_t; +int main() { + return 0; +} diff --git a/configuration/bazel/msvc_assume.cpp b/configuration/bazel/msvc_assume.cpp new file mode 100644 index 0000000..cd9f6ed --- /dev/null +++ b/configuration/bazel/msvc_assume.cpp @@ -0,0 +1,13 @@ +int f() { + static int x = 1; + if (x == 1) { + return 0; + } else { + __assume(0); + // Note: the lack of return here is intentional + } +} + +int main() { + return f(); +} diff --git a/configuration/bazel/std_is_trivially_copy_constructible.cpp b/configuration/bazel/std_is_trivially_copy_constructible.cpp new file mode 100644 index 0000000..7cb8d5b --- /dev/null +++ b/configuration/bazel/std_is_trivially_copy_constructible.cpp @@ -0,0 +1,6 @@ +#include +int main() { + bool b = std::is_trivially_copy_constructible::value; + (void) b; + return 0; +} diff --git a/configuration/bazel/std_is_trivially_copyable.cpp b/configuration/bazel/std_is_trivially_copyable.cpp new file mode 100644 index 0000000..871b793 --- /dev/null +++ b/configuration/bazel/std_is_trivially_copyable.cpp @@ -0,0 +1,6 @@ +#include +int main() { + bool b = std::is_trivially_copyable::value; + (void) b; + return 0; +} diff --git a/configuration/bazel/std_max_align_t.cpp b/configuration/bazel/std_max_align_t.cpp new file mode 100644 index 0000000..acec695 --- /dev/null +++ b/configuration/bazel/std_max_align_t.cpp @@ -0,0 +1,5 @@ +#include +using X = std::max_align_t; +int main() { + return 0; +} diff --git a/configuration/bazel/typeid.cpp b/configuration/bazel/typeid.cpp new file mode 100644 index 0000000..9621d03 --- /dev/null +++ b/configuration/bazel/typeid.cpp @@ -0,0 +1,5 @@ +#include +int main() { + (void) typeid(int); + return 0; +} -- cgit v1.2.3