From e057a7cee22e36451e78cbf957a6cd7a3a313c6f Mon Sep 17 00:00:00 2001 From: Paul Wankadia Date: Fri, 25 Feb 2022 01:42:59 +1100 Subject: [PATCH] Make generate_export_header.bzl work for Windows. (#1355) * Make generate_export_header.bzl work for Windows. While I'm here, bring the generated code slightly closer to what CMake would generate nowadays. Fixes #1351. * Fix define. * Fix export_import_condition. * Fix guard. --- BUILD.bazel | 4 +++ WORKSPACE | 9 +++++++ config/generate_export_header.bzl | 44 ++++++++++++++++++++++--------- 3 files changed, 44 insertions(+), 13 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index dce4d64f..4bf5bfc5 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -55,6 +55,10 @@ cc_library( ":windows": [], "//conditions:default": posix_copts, }), + local_defines = select({ + ":windows": ["benchmark_EXPORTS"], + "//conditions:default": [], + }), ) cc_library( diff --git a/WORKSPACE b/WORKSPACE index 949eb98b..bb44e7b7 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -3,6 +3,15 @@ workspace(name = "com_github_google_benchmark") load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository") +http_archive( + name = "platforms", + sha256 = "379113459b0feaf6bfbb584a91874c065078aa673222846ac765f86661c27407", + urls = [ + "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.5/platforms-0.0.5.tar.gz", + "https://github.com/bazelbuild/platforms/releases/download/0.0.5/platforms-0.0.5.tar.gz", + ], +) + http_archive( name = "com_google_absl", sha256 = "f41868f7a938605c92936230081175d1eae87f6ea2c248f41077c8f88316f111", diff --git a/config/generate_export_header.bzl b/config/generate_export_header.bzl index 0d0b671d..35e98716 100644 --- a/config/generate_export_header.bzl +++ b/config/generate_export_header.bzl @@ -36,33 +36,44 @@ # # -*- python -*- -def _make_identifier(s): - result = "" - for i in range(len(s)): - result += s[i] if s[i].isalnum() else "_" - - return result - # Defines the implementation actions to generate_export_header. def _generate_export_header_impl(ctx): + windows_constraint = ctx.attr._windows_constraint[platform_common.ConstraintValueInfo] output = ctx.outputs.out - guard = _make_identifier(output.basename.upper()) + if ctx.target_platform_has_constraint(windows_constraint): + export_attr = "__declspec(dllexport)" + import_attr = "__declspec(dllimport)" + no_export_attr = "" + deprecated_attr = "__declspec(deprecated)" + else: + export_attr = "__attribute__((visibility(\"default\")))" + import_attr = "__attribute__((visibility(\"default\")))" + no_export_attr = "__attribute__((visibility(\"hidden\")))" + deprecated_attr = "__attribute__((__deprecated__))" content = [ - "#ifndef %s" % guard, - "#define %s" % guard, + "#ifndef %s_H" % ctx.attr.export_macro_name, + "#define %s_H" % ctx.attr.export_macro_name, "", "#ifdef %s" % ctx.attr.static_define, "# define %s" % ctx.attr.export_macro_name, "# define %s" % ctx.attr.no_export_macro_name, "#else", - "# define %s __attribute__((visibility(\"default\")))" % ctx.attr.export_macro_name, # noqa - "# define %s __attribute__((visibility(\"hidden\")))" % ctx.attr.no_export_macro_name, # noqa + "# ifndef %s" % ctx.attr.export_macro_name, + "# ifdef %s" % ctx.attr.export_import_condition, + "# define %s %s" % (ctx.attr.export_macro_name, export_attr), + "# else", + "# define %s %s" % (ctx.attr.export_macro_name, import_attr), + "# endif", + "# endif", + "# ifndef %s" % ctx.attr.no_export_macro_name, + "# define %s %s" % (ctx.attr.no_export_macro_name, no_export_attr), + "# endif", "#endif", "", "#ifndef %s" % ctx.attr.deprecated_macro_name, - "# define %s __attribute__ ((__deprecated__))" % ctx.attr.deprecated_macro_name, # noqa + "# define %s %s" % (ctx.attr.deprecated_macro_name, deprecated_attr), "#endif", "", "#ifndef %s" % ctx.attr.export_deprecated_macro_name, @@ -82,12 +93,14 @@ def _generate_export_header_impl(ctx): _generate_export_header_gen = rule( attrs = { "out": attr.output(mandatory = True), + "export_import_condition": attr.string(), "export_macro_name": attr.string(), "deprecated_macro_name": attr.string(), "export_deprecated_macro_name": attr.string(), "no_export_macro_name": attr.string(), "no_export_deprecated_macro_name": attr.string(), "static_define": attr.string(), + "_windows_constraint": attr.label(default = "@platforms//os:windows"), }, output_to_genfiles = True, implementation = _generate_export_header_impl, @@ -97,6 +110,7 @@ def generate_export_header( lib = None, name = None, out = None, + export_import_condition = None, export_macro_name = None, deprecated_macro_name = None, export_deprecated_macro_name = None, @@ -121,6 +135,9 @@ def generate_export_header( name = "__%s_export_h" % lib if out == None: out = "%s_export.h" % lib + if export_import_condition == None: + # CMake does not uppercase the _EXPORTS define. + export_import_condition = "%s_EXPORTS" % lib if export_macro_name == None: export_macro_name = "%s_EXPORT" % lib.upper() if deprecated_macro_name == None: @@ -138,6 +155,7 @@ def generate_export_header( _generate_export_header_gen( name = name, out = out, + export_import_condition = export_import_condition, export_macro_name = export_macro_name, deprecated_macro_name = deprecated_macro_name, export_deprecated_macro_name = export_deprecated_macro_name,