aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build-and-test.yml127
-rw-r--r--BUILD.bazel30
-rw-r--r--CMakeLists.txt10
-rw-r--r--bindings/python/google_benchmark/benchmark.cc4
-rw-r--r--include/benchmark/benchmark.h99
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/benchmark.cc2
-rw-r--r--src/benchmark_api_internal.h1
-rw-r--r--src/benchmark_main.cc10
-rw-r--r--src/check.cc11
-rw-r--r--src/check.h7
-rw-r--r--src/commandlineflags.h39
-rw-r--r--src/perf_counters.h14
-rw-r--r--src/statistics.h5
-rw-r--r--src/string_util.h3
-rw-r--r--test/AssemblyTests.cmake1
-rw-r--r--test/BUILD5
-rw-r--r--test/CMakeLists.txt25
-rw-r--r--test/benchmark_gtest.cc2
-rw-r--r--tools/workspace/generate_export_header.bzl148
20 files changed, 465 insertions, 91 deletions
diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml
index 6ff6f49..d7406a7 100644
--- a/.github/workflows/build-and-test.yml
+++ b/.github/workflows/build-and-test.yml
@@ -10,7 +10,7 @@ jobs:
# TODO: add coverage build (requires lcov)
# TODO: add clang + libc++ builds for ubuntu
job:
- name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.compiler }}
+ name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.compiler }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
@@ -18,28 +18,39 @@ jobs:
os: [ubuntu-latest, ubuntu-20.04, macos-latest]
build_type: ['Release', 'Debug']
compiler: [g++, clang++]
- include:
- - displayTargetName: windows-latest-release
- os: windows-latest
- build_type: 'Release'
- - displayTargetName: windows-latest-debug
- os: windows-latest
- build_type: 'Debug'
+ lib: ['shared', 'static']
+
steps:
- uses: actions/checkout@v2
- name: create build environment
run: cmake -E make_directory ${{ runner.workspace }}/_build
+ - name: setup cmake initial cache
+ run: touch compiler-cache.cmake
+
+ - name: setup lto
+ # Workaround for enabling -flto on old GCC versions
+ if: matrix.build_type == 'Release' && startsWith(matrix.compiler, 'g++') && matrix.os != 'macos-latest'
+ run: >
+ echo 'set (CMAKE_CXX_FLAGS -flto CACHE STRING "")' >> compiler-cache.cmake;
+ echo 'set (CMAKE_RANLIB /usr/bin/gcc-ranlib CACHE FILEPATH "")' >> compiler-cache.cmake;
+ echo 'set (CMAKE_AR /usr/bin/gcc-ar CACHE FILEPATH "")' >> compiler-cache.cmake;
+ echo 'set (CMAKE_NM /usr/bin/gcc-nm CACHE FILEPATH "")' >> compiler-cache.cmake;
+
- name: configure cmake
env:
CXX: ${{ matrix.compiler }}
shell: bash
working-directory: ${{ runner.workspace }}/_build
run: >
- cmake $GITHUB_WORKSPACE
+ cmake -C ${{ github.workspace }}/compiler-cache.cmake
+ $GITHUB_WORKSPACE
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+ -DCMAKE_CXX_VISIBILITY_PRESET=hidden
+ -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
- name: build
shell: bash
@@ -51,6 +62,57 @@ jobs:
working-directory: ${{ runner.workspace }}/_build
run: ctest -C ${{ matrix.build_type }} -VV
+ msvc:
+ name: ${{ matrix.os }}.${{ matrix.build_type }}.${{ matrix.lib }}.${{ matrix.msvc }}
+ runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ shell: powershell
+ strategy:
+ fail-fast: false
+ matrix:
+ msvc:
+ - VS-16-2019
+ - VS-17-2022
+ arch:
+ - x64
+ build_type:
+ - Debug
+ - Release
+ lib:
+ - shared
+ - static
+ include:
+ - msvc: VS-16-2019
+ os: windows-2019
+ generator: 'Visual Studio 16 2019'
+ - msvc: VS-17-2022
+ os: windows-2022
+ generator: 'Visual Studio 17 2022'
+
+ steps:
+ - uses: actions/checkout@v2
+
+ - name: configure cmake
+ run: >
+ cmake -S . -B _build/
+ -A ${{ matrix.arch }}
+ -G "${{ matrix.generator }}"
+ -DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
+
+ - name: build
+ run: cmake --build _build/ --config ${{ matrix.build_type }}
+
+ - name: setup test environment
+ # Make sure gmock and benchmark DLLs can be found
+ run: >
+ echo "$((Get-Item .).FullName)/_build/bin/${{ matrix.build_type }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append;
+ echo "$((Get-Item .).FullName)/_build/src/${{ matrix.build_type }}" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append;
+
+ - name: test
+ run: ctest --test-dir _build/ -C ${{ matrix.build_type }} -VV
+
ubuntu-16_04:
name: ubuntu-16.04.${{ matrix.build_type }}.${{ matrix.compiler }}
runs-on: [ubuntu-latest]
@@ -71,15 +133,34 @@ jobs:
- name: create build environment
run: cmake -E make_directory $GITHUB_WORKSPACE/_build
+ - name: setup cmake initial cache
+ run: touch compiler-cache.cmake
+
+ - name: setup lto
+ # Workaround for enabling -flto on old GCC versions
+ # -Wl,--no-as-needed is needed to avoid the following linker error:
+ #
+ # /usr/lib/gcc/x86_64-linux-gnu/5/libstdc++.so: undefined reference to `pthread_create'
+ #
+ if: matrix.build_type == 'Release' && startsWith(matrix.compiler, 'g++')
+ run: >
+ echo 'set (CMAKE_CXX_FLAGS "-Wl,--no-as-needed -flto" CACHE STRING "")' >> compiler-cache.cmake;
+ echo 'set (CMAKE_RANLIB "/usr/bin/gcc-ranlib" CACHE FILEPATH "")' >> compiler-cache.cmake;
+ echo 'set (CMAKE_AR "/usr/bin/gcc-ar" CACHE FILEPATH "")' >> compiler-cache.cmake;
+ echo 'set (CMAKE_NM "/usr/bin/gcc-nm" CACHE FILEPATH "")' >> compiler-cache.cmake;
+
- name: configure cmake
env:
CXX: ${{ matrix.compiler }}
shell: bash
working-directory: ${{ github.workspace }}/_build
run: >
- cmake $GITHUB_WORKSPACE
+ cmake -C ../compiler-cache.cmake ..
-DBENCHMARK_DOWNLOAD_DEPENDENCIES=ON
+ -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
+ -DCMAKE_CXX_VISIBILITY_PRESET=hidden
+ -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
- name: build
shell: bash
@@ -126,16 +207,38 @@ jobs:
- name: create build environment
run: cmake -E make_directory $GITHUB_WORKSPACE/_build
+ - name: setup cmake initial cache
+ run: touch compiler-cache.cmake
+
+ - name: setup lto
+ # Workaround for enabling -flto on old GCC versions
+ # -Wl,--no-as-needed is needed to avoid the following linker error:
+ #
+ # /usr/lib/gcc/x86_64-linux-gnu/6/libstdc++.so: undefined reference to `pthread_create'
+ #
+ if: matrix.build_type == 'Release' && startsWith(matrix.compiler, 'g++')
+ run: >
+ COMPILER=${{ matrix.compiler }};
+ VERSION=${COMPILER#g++-};
+ PREFIX=/usr/bin/gcc;
+ echo "set (CMAKE_CXX_FLAGS \"-Wl,--no-as-needed -flto\" CACHE STRING \"\")" >> compiler-cache.cmake;
+ echo "set (CMAKE_RANLIB \"$PREFIX-ranlib-$VERSION\" CACHE FILEPATH \"\")" >> compiler-cache.cmake;
+ echo "set (CMAKE_AR \"$PREFIX-ar-$VERSION\" CACHE FILEPATH \"\")" >> compiler-cache.cmake;
+ echo "set (CMAKE_NM \"$PREFIX-nm-$VERSION\" CACHE FILEPAT \"\")" >> compiler-cache.cmake;
+
- name: configure cmake
env:
CXX: ${{ matrix.compiler }}
shell: bash
working-directory: ${{ github.workspace }}/_build
run: >
- cmake $GITHUB_WORKSPACE
+ cmake -C ../compiler-cache.cmake ..
+ -DBENCHMARK_DOWNLOAD_DEPENDENCIES=${{ matrix.run_tests }}
-DBENCHMARK_ENABLE_TESTING=${{ matrix.run_tests }}
+ -DBUILD_SHARED_LIBS=${{ matrix.lib == 'shared' }}
-DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
- -DBENCHMARK_DOWNLOAD_DEPENDENCIES=${{ matrix.run_tests }}
+ -DCMAKE_CXX_VISIBILITY_PRESET=hidden
+ -DCMAKE_VISIBILITY_INLINES_HIDDEN=ON
- name: build
shell: bash
diff --git a/BUILD.bazel b/BUILD.bazel
index 904c691..31a7660 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -1,5 +1,22 @@
licenses(["notice"])
+load(
+ "@com_github_google_benchmark//tools:workspace/generate_export_header.bzl",
+ "generate_export_header",
+)
+
+posix_copts = [
+ "-fvisibility=hidden",
+ "-fvisibility-inlines-hidden",
+]
+
+# Generate header to provide ABI export symbols
+generate_export_header(
+ out = "include/benchmark/export.h",
+ lib = "benchmark",
+ static_define = "BENCHMARK_STATIC_DEFINE",
+)
+
config_setting(
name = "qnx",
constraint_values = ["@platforms//os:qnx"],
@@ -27,13 +44,20 @@ cc_library(
],
exclude = ["src/benchmark_main.cc"],
),
- hdrs = ["include/benchmark/benchmark.h"],
+ hdrs = [
+ "include/benchmark/benchmark.h",
+ "include/benchmark/export.h", # From generate_export_header
+ ],
linkopts = select({
":windows": ["-DEFAULTLIB:shlwapi.lib"],
"//conditions:default": ["-pthread"],
}),
strip_include_prefix = "include",
visibility = ["//visibility:public"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": posix_copts,
+ }),
)
cc_library(
@@ -43,6 +67,10 @@ cc_library(
strip_include_prefix = "include",
visibility = ["//visibility:public"],
deps = [":benchmark"],
+ copts = select({
+ ":windows": [],
+ "//conditions:default": posix_copts,
+ }),
)
cc_library(
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b8852e4..cc80702 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -50,7 +50,10 @@ option(BENCHMARK_USE_BUNDLED_GTEST "Use bundled GoogleTest. If disabled, the fin
option(BENCHMARK_ENABLE_LIBPFM "Enable performance counters provided by libpfm" OFF)
-set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
+# Export only public symbols
+set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+set(CMAKE_VISIBILITY_INLINES_HIDDEN ON)
+
if(MSVC)
# As of CMake 3.18, CMAKE_SYSTEM_PROCESSOR is not set properly for MSVC and
# cross-compilation (e.g. Host=x86_64, target=aarch64) requires using the
@@ -123,10 +126,11 @@ set(GENERIC_LIB_VERSION ${VERSION})
string(SUBSTRING ${VERSION} 0 1 GENERIC_LIB_SOVERSION)
# Import our CMake modules
-include(CheckCXXCompilerFlag)
include(AddCXXCompilerFlag)
-include(CXXFeatureCheck)
+include(CheckCXXCompilerFlag)
include(CheckLibraryExists)
+include(CXXFeatureCheck)
+include(GenerateExportHeader)
check_library_exists(rt shm_open "" HAVE_LIB_RT)
diff --git a/bindings/python/google_benchmark/benchmark.cc b/bindings/python/google_benchmark/benchmark.cc
index 02b6ed7..89e44ff 100644
--- a/bindings/python/google_benchmark/benchmark.cc
+++ b/bindings/python/google_benchmark/benchmark.cc
@@ -1,5 +1,7 @@
// Benchmark for Python.
+#include "benchmark/benchmark.h"
+
#include <map>
#include <string>
#include <vector>
@@ -9,8 +11,6 @@
#include "pybind11/stl.h"
#include "pybind11/stl_bind.h"
-#include "benchmark/benchmark.h"
-
PYBIND11_MAKE_OPAQUE(benchmark::UserCounters);
namespace {
diff --git a/include/benchmark/benchmark.h b/include/benchmark/benchmark.h
index 504fae1..2478dae 100644
--- a/include/benchmark/benchmark.h
+++ b/include/benchmark/benchmark.h
@@ -187,6 +187,8 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#include <utility>
#include <vector>
+#include "benchmark/export.h"
+
#if defined(BENCHMARK_HAS_CXX11)
#include <atomic>
#include <initializer_list>
@@ -280,23 +282,29 @@ BENCHMARK(BM_test)->Unit(benchmark::kMillisecond);
#define BENCHMARK_OVERRIDE
#endif
+#if defined(_MSC_VER)
+#pragma warning(push)
+// C4251: <symbol> needs to have dll-interface to be used by clients of class
+#pragma warning(disable : 4251)
+#endif
+
namespace benchmark {
class BenchmarkReporter;
-void Initialize(int* argc, char** argv);
-void Shutdown();
+BENCHMARK_EXPORT void Initialize(int* argc, char** argv);
+BENCHMARK_EXPORT void Shutdown();
// Report to stdout all arguments in 'argv' as unrecognized except the first.
// Returns true there is at least on unrecognized argument (i.e. 'argc' > 1).
-bool ReportUnrecognizedArguments(int argc, char** argv);
+BENCHMARK_EXPORT bool ReportUnrecognizedArguments(int argc, char** argv);
// Returns the current value of --benchmark_filter.
-std::string GetBenchmarkFilter();
+BENCHMARK_EXPORT std::string GetBenchmarkFilter();
// Creates a default display reporter. Used by the library when no display
// reporter is provided, but also made available for external use in case a
// custom reporter should respect the `--benchmark_format` flag as a fallback
-BenchmarkReporter* CreateDefaultDisplayReporter();
+BENCHMARK_EXPORT BenchmarkReporter* CreateDefaultDisplayReporter();
// Generate a list of benchmarks matching the specified --benchmark_filter flag
// and if --benchmark_list_tests is specified return after printing the name
@@ -314,18 +322,19 @@ BenchmarkReporter* CreateDefaultDisplayReporter();
// 'file_reporter' is ignored.
//
// RETURNS: The number of matching benchmarks.
-size_t RunSpecifiedBenchmarks();
-size_t RunSpecifiedBenchmarks(std::string spec);
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks();
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(std::string spec);
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
- std::string spec);
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter);
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter, std::string spec);
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
- BenchmarkReporter* file_reporter);
-size_t RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
- BenchmarkReporter* file_reporter,
- std::string spec);
+BENCHMARK_EXPORT size_t RunSpecifiedBenchmarks(
+ BenchmarkReporter* display_reporter, BenchmarkReporter* file_reporter);
+BENCHMARK_EXPORT size_t
+RunSpecifiedBenchmarks(BenchmarkReporter* display_reporter,
+ BenchmarkReporter* file_reporter, std::string spec);
// If a MemoryManager is registered (via RegisterMemoryManager()),
// it can be used to collect and report allocation metrics for a run of the
@@ -374,9 +383,11 @@ class MemoryManager {
// Register a MemoryManager instance that will be used to collect and report
// allocation measurements for benchmark runs.
+BENCHMARK_EXPORT
void RegisterMemoryManager(MemoryManager* memory_manager);
// Add a key-value pair to output as part of the context stanza in the report.
+BENCHMARK_EXPORT
void AddCustomContext(const std::string& key, const std::string& value);
namespace internal {
@@ -384,14 +395,15 @@ class Benchmark;
class BenchmarkImp;
class BenchmarkFamilies;
+BENCHMARK_EXPORT
void UseCharPointer(char const volatile*);
// Take ownership of the pointer and register the benchmark. Return the
// registered benchmark.
-Benchmark* RegisterBenchmarkInternal(Benchmark*);
+BENCHMARK_EXPORT Benchmark* RegisterBenchmarkInternal(Benchmark*);
// Ensure that the standard streams are properly initialized in every TU.
-int InitializeStreams();
+BENCHMARK_EXPORT int InitializeStreams();
BENCHMARK_UNUSED static int stream_init_anchor = InitializeStreams();
} // namespace internal
@@ -573,7 +585,7 @@ enum AggregationReportMode
// State is passed to a running Benchmark and contains state for the
// benchmark to use.
-class State {
+class BENCHMARK_EXPORT State {
public:
struct StateIterator;
friend struct StateIterator;
@@ -904,7 +916,7 @@ typedef void(Function)(State&);
// be called on this object to change the properties of the benchmark.
// Each method returns "this" so that multiple method calls can
// chained into one expression.
-class Benchmark {
+class BENCHMARK_EXPORT Benchmark {
public:
virtual ~Benchmark();
@@ -1097,7 +1109,6 @@ class Benchmark {
protected:
explicit Benchmark(const char* name);
- Benchmark(Benchmark const&);
void SetName(const char* name);
int ArgsCnt() const;
@@ -1127,7 +1138,17 @@ class Benchmark {
callback_function setup_;
callback_function teardown_;
- Benchmark& operator=(Benchmark const&);
+ Benchmark(Benchmark const&)
+#if defined(BENCHMARK_HAS_CXX11)
+ = delete
+#endif
+ ;
+
+ Benchmark& operator=(Benchmark const&)
+#if defined(BENCHMARK_HAS_CXX11)
+ = delete
+#endif
+ ;
};
} // namespace internal
@@ -1146,12 +1167,12 @@ internal::Benchmark* RegisterBenchmark(const char* name, Lambda&& fn);
// Remove all registered benchmarks. All pointers to previously registered
// benchmarks are invalidated.
-void ClearRegisteredBenchmarks();
+BENCHMARK_EXPORT void ClearRegisteredBenchmarks();
namespace internal {
// The class used to hold all Benchmarks created from static function.
// (ie those created using the BENCHMARK(...) macros.
-class FunctionBenchmark : public Benchmark {
+class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
public:
FunctionBenchmark(const char* name, Function* func)
: Benchmark(name), func_(func) {}
@@ -1444,22 +1465,14 @@ class Fixture : public internal::Benchmark {
#endif
// Helper macro to create a main routine in a test that runs the benchmarks
-#define BENCHMARK_MAIN() \
- int main(int argc, char** argv) { \
- ::benchmark::Initialize(&argc, argv); \
- if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; \
- ::benchmark::RunSpecifiedBenchmarks(); \
- ::benchmark::Shutdown(); \
- return 0; \
- } \
- int main(int, char**)
+#define BENCHMARK_MAIN() BENCHMARK_EXPORT int main(int argc, char** argv)
// ------------------------------------------------------
// Benchmark Reporters
namespace benchmark {
-struct CPUInfo {
+struct BENCHMARK_EXPORT CPUInfo {
struct CacheInfo {
std::string type;
int level;
@@ -1483,7 +1496,7 @@ struct CPUInfo {
};
// Adding Struct for System Information
-struct SystemInfo {
+struct BENCHMARK_EXPORT SystemInfo {
std::string name;
static const SystemInfo& Get();
@@ -1495,7 +1508,7 @@ struct SystemInfo {
// BenchmarkName contains the components of the Benchmark's name
// which allows individual fields to be modified or cleared before
// building the final name using 'str()'.
-struct BenchmarkName {
+struct BENCHMARK_EXPORT BenchmarkName {
std::string function_name;
std::string args;
std::string min_time;
@@ -1514,7 +1527,7 @@ struct BenchmarkName {
// can control the destination of the reports by calling
// RunSpecifiedBenchmarks and passing it a custom reporter object.
// The reporter object must implement the following interface.
-class BenchmarkReporter {
+class BENCHMARK_EXPORT BenchmarkReporter {
public:
struct Context {
CPUInfo const& cpu_info;
@@ -1525,7 +1538,7 @@ class BenchmarkReporter {
Context();
};
- struct Run {
+ struct BENCHMARK_EXPORT Run {
static const int64_t no_repetition_index = -1;
enum RunType { RT_Iteration, RT_Aggregate };
@@ -1670,7 +1683,7 @@ class BenchmarkReporter {
// Simple reporter that outputs benchmark data to the console. This is the
// default reporter used by RunSpecifiedBenchmarks().
-class ConsoleReporter : public BenchmarkReporter {
+class BENCHMARK_EXPORT ConsoleReporter : public BenchmarkReporter {
public:
enum OutputOptions {
OO_None = 0,
@@ -1695,7 +1708,7 @@ class ConsoleReporter : public BenchmarkReporter {
bool printed_header_;
};
-class JSONReporter : public BenchmarkReporter {
+class BENCHMARK_EXPORT JSONReporter : public BenchmarkReporter {
public:
JSONReporter() : first_report_(true) {}
virtual bool ReportContext(const Context& context) BENCHMARK_OVERRIDE;
@@ -1708,7 +1721,7 @@ class JSONReporter : public BenchmarkReporter {
bool first_report_;
};
-class BENCHMARK_DEPRECATED_MSG(
+class BENCHMARK_EXPORT BENCHMARK_DEPRECATED_MSG(
"The CSV Reporter will be removed in a future release") CSVReporter
: public BenchmarkReporter {
public:
@@ -1760,11 +1773,17 @@ inline double GetTimeUnitMultiplier(TimeUnit unit) {
// CreateRange(0, 100, /*multi=*/4),
// CreateDenseRange(0, 4, /*step=*/1),
// });
+BENCHMARK_EXPORT
std::vector<int64_t> CreateRange(int64_t lo, int64_t hi, int multi);
// Creates a list of integer values for the given range and step.
+BENCHMARK_EXPORT
std::vector<int64_t> CreateDenseRange(int64_t start, int64_t limit, int step);
} // namespace benchmark
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
#endif // BENCHMARK_BENCHMARK_H_
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e814a4e..7081312 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -22,10 +22,15 @@ add_library(benchmark::benchmark ALIAS benchmark)
set_target_properties(benchmark PROPERTIES
OUTPUT_NAME "benchmark"
VERSION ${GENERIC_LIB_VERSION}
- SOVERSION ${GENERIC_LIB_SOVERSION}
+ SOVERSION 2
)
target_include_directories(benchmark PUBLIC
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>)
+ $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
+ $<BUILD_INTERFACE:${PROJECT_BINARY_DIR}/include>
+)
+
+generate_export_header(benchmark
+ EXPORT_FILE_NAME ${PROJECT_BINARY_DIR}/include/benchmark/export.h)
# libpfm, if available
if (HAVE_LIBPFM)
@@ -59,7 +64,8 @@ add_library(benchmark::benchmark_main ALIAS benchmark_main)
set_target_properties(benchmark_main PROPERTIES
OUTPUT_NAME "benchmark_main"
VERSION ${GENERIC_LIB_VERSION}
- SOVERSION ${GENERIC_LIB_SOVERSION}
+ SOVERSION 2
+ DEFINE_SYMBOL benchmark_EXPORTS
)
target_link_libraries(benchmark_main PUBLIC benchmark::benchmark)
@@ -107,6 +113,7 @@ if (BENCHMARK_ENABLE_INSTALL)
install(
DIRECTORY "${PROJECT_SOURCE_DIR}/include/benchmark"
+ "${PROJECT_BINARY_DIR}/include/benchmark"
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
FILES_MATCHING PATTERN "*.*h")
diff --git a/src/benchmark.cc b/src/benchmark.cc
index f88d905..3c06c85 100644
--- a/src/benchmark.cc
+++ b/src/benchmark.cc
@@ -126,7 +126,7 @@ BM_DEFINE_int32(v, 0);
namespace internal {
-std::map<std::string, std::string>* global_context = nullptr;
+BENCHMARK_EXPORT std::map<std::string, std::string>* global_context = nullptr;
// FIXME: wouldn't LTO mess this up?
void UseCharPointer(char const volatile*) {}
diff --git a/src/benchmark_api_internal.h b/src/benchmark_api_internal.h
index 94c2b29..8060fe3 100644
--- a/src/benchmark_api_internal.h
+++ b/src/benchmark_api_internal.h
@@ -76,6 +76,7 @@ bool FindBenchmarksInternal(const std::string& re,
bool IsZero(double n);
+BENCHMARK_EXPORT
ConsoleReporter::OutputOptions GetOutputOptions(bool force_no_color = false);
} // end namespace internal
diff --git a/src/benchmark_main.cc b/src/benchmark_main.cc
index b3b2478..9b2c47a 100644
--- a/src/benchmark_main.cc
+++ b/src/benchmark_main.cc
@@ -15,3 +15,13 @@
#include "benchmark/benchmark.h"
BENCHMARK_MAIN();
+
+// MSVC does not allow the definition of dllimport. Thus, define it here instead
+// inline in a macro.
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
+ ::benchmark::RunSpecifiedBenchmarks();
+ ::benchmark::Shutdown();
+ return 0;
+}
diff --git a/src/check.cc b/src/check.cc
new file mode 100644
index 0000000..422b948
--- /dev/null
+++ b/src/check.cc
@@ -0,0 +1,11 @@
+#include "check.h"
+
+namespace benchmark {
+namespace internal {
+
+static AbortHandlerT* handler = &std::abort;
+
+AbortHandlerT*& GetAbortHandler() { return handler; }
+
+} // namespace internal
+} // namespace benchmark
diff --git a/src/check.h b/src/check.h
index 90c7bbf..1129e81 100644
--- a/src/check.h
+++ b/src/check.h
@@ -5,6 +5,7 @@
#include <cstdlib>
#include <ostream>
+#include "benchmark/export.h"
#include "internal_macros.h"
#include "log.h"
@@ -13,10 +14,8 @@ namespace internal {
typedef void(AbortHandlerT)();
-inline AbortHandlerT*& GetAbortHandler() {
- static AbortHandlerT* handler = &std::abort;
- return handler;
-}
+BENCHMARK_EXPORT
+AbortHandlerT*& GetAbortHandler();
BENCHMARK_NORETURN inline void CallAbortHandler() {
GetAbortHandler()();
diff --git a/src/commandlineflags.h b/src/commandlineflags.h
index 5baaf11..7882628 100644
--- a/src/commandlineflags.h
+++ b/src/commandlineflags.h
@@ -5,28 +5,33 @@
#include <map>
#include <string>
+#include "benchmark/export.h"
+
// Macro for referencing flags.
#define FLAG(name) FLAGS_##name
// Macros for declaring flags.
-#define BM_DECLARE_bool(name) extern bool FLAG(name)
-#define BM_DECLARE_int32(name) extern int32_t FLAG(name)
-#define BM_DECLARE_double(name) extern double FLAG(name)
-#define BM_DECLARE_string(name) extern std::string FLAG(name)
+#define BM_DECLARE_bool(name) BENCHMARK_EXPORT extern bool FLAG(name)
+#define BM_DECLARE_int32(name) BENCHMARK_EXPORT extern int32_t FLAG(name)
+#define BM_DECLARE_double(name) BENCHMARK_EXPORT extern double FLAG(name)
+#define BM_DECLARE_string(name) BENCHMARK_EXPORT extern std::string FLAG(name)
#define BM_DECLARE_kvpairs(name) \
- extern std::map<std::string, std::string> FLAG(name)
+ BENCHMARK_EXPORT extern std::map<std::string, std::string> FLAG(name)
// Macros for defining flags.
#define BM_DEFINE_bool(name, default_val) \
- bool FLAG(name) = benchmark::BoolFromEnv(#name, default_val)
+ BENCHMARK_EXPORT bool FLAG(name) = benchmark::BoolFromEnv(#name, default_val)
#define BM_DEFINE_int32(name, default_val) \
- int32_t FLAG(name) = benchmark::Int32FromEnv(#name, default_val)
+ BENCHMARK_EXPORT int32_t FLAG(name) = \
+ benchmark::Int32FromEnv(#name, default_val)
#define BM_DEFINE_double(name, default_val) \
- double FLAG(name) = benchmark::DoubleFromEnv(#name, default_val)
+ BENCHMARK_EXPORT double FLAG(name) = \
+ benchmark::DoubleFromEnv(#name, default_val)
#define BM_DEFINE_string(name, default_val) \
- std::string FLAG(name) = benchmark::StringFromEnv(#name, default_val)
-#define BM_DEFINE_kvpairs(name, default_val) \
- std::map<std::string, std::string> FLAG(name) = \
+ BENCHMARK_EXPORT std::string FLAG(name) = \
+ benchmark::StringFromEnv(#name, default_val)
+#define BM_DEFINE_kvpairs(name, default_val) \
+ BENCHMARK_EXPORT std::map<std::string, std::string> FLAG(name) = \
benchmark::KvPairsFromEnv(#name, default_val)
namespace benchmark {
@@ -35,6 +40,7 @@ namespace benchmark {
//
// If the variable exists, returns IsTruthyFlagValue() value; if not,
// returns the given default value.
+BENCHMARK_EXPORT
bool BoolFromEnv(const char* flag, bool default_val);
// Parses an Int32 from the environment variable corresponding to the given
@@ -42,6 +48,7 @@ bool BoolFromEnv(const char* flag, bool default_val);
//
// If the variable exists, returns ParseInt32() value; if not, returns
// the given default value.
+BENCHMARK_EXPORT
int32_t Int32FromEnv(const char* flag, int32_t default_val);
// Parses an Double from the environment variable corresponding to the given
@@ -49,6 +56,7 @@ int32_t Int32FromEnv(const char* flag, int32_t default_val);
//
// If the variable exists, returns ParseDouble(); if not, returns
// the given default value.
+BENCHMARK_EXPORT
double DoubleFromEnv(const char* flag, double default_val);
// Parses a string from the environment variable corresponding to the given
@@ -56,6 +64,7 @@ double DoubleFromEnv(const char* flag, double default_val);
//
// If variable exists, returns its value; if not, returns
// the given default value.
+BENCHMARK_EXPORT
const char* StringFromEnv(const char* flag, const char* default_val);
// Parses a set of kvpairs from the environment variable corresponding to the
@@ -63,6 +72,7 @@ const char* StringFromEnv(const char* flag, const char* default_val);
//
// If variable exists, returns its value; if not, returns
// the given default value.
+BENCHMARK_EXPORT
std::map<std::string, std::string> KvPairsFromEnv(
const char* flag, std::map<std::string, std::string> default_val);
@@ -75,40 +85,47 @@ std::map<std::string, std::string> KvPairsFromEnv(
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
+BENCHMARK_EXPORT
bool ParseBoolFlag(const char* str, const char* flag, bool* value);
// Parses a string for an Int32 flag, in the form of "--flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
+BENCHMARK_EXPORT
bool ParseInt32Flag(const char* str, const char* flag, int32_t* value);
// Parses a string for a Double flag, in the form of "--flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
+BENCHMARK_EXPORT
bool ParseDoubleFlag(const char* str, const char* flag, double* value);
// Parses a string for a string flag, in the form of "--flag=value".
//
// On success, stores the value of the flag in *value, and returns
// true. On failure, returns false without changing *value.
+BENCHMARK_EXPORT
bool ParseStringFlag(const char* str, const char* flag, std::string* value);
// Parses a string for a kvpairs flag in the form "--flag=key=value,key=value"
//
// On success, stores the value of the flag in *value and returns true. On
// failure returns false, though *value may have been mutated.
+BENCHMARK_EXPORT
bool ParseKeyValueFlag(const char* str, const char* flag,
std::map<std::string, std::string>* value);
// Returns true if the string matches the flag.
+BENCHMARK_EXPORT
bool IsFlag(const char* str, const char* flag);
// Returns true unless value starts with one of: '0', 'f', 'F', 'n' or 'N', or
// some non-alphanumeric character. Also returns false if the value matches
// one of 'no', 'false', 'off' (case-insensitive). As a special case, also
// returns true if value is the empty string.
+BENCHMARK_EXPORT
bool IsTruthyFlagValue(const std::string& value);
} // end namespace benchmark
diff --git a/src/perf_counters.h b/src/perf_counters.h
index 427f08e..680555d 100644
--- a/src/perf_counters.h
+++ b/src/perf_counters.h
@@ -29,6 +29,12 @@
#include <unistd.h>
#endif
+#if defined(_MSC_VER)
+#pragma warning(push)
+// C4251: <symbol> needs to have dll-interface to be used by clients of class
+#pragma warning(disable : 4251)
+#endif
+
namespace benchmark {
namespace internal {
@@ -68,7 +74,7 @@ class PerfCounterValues {
// Collect PMU counters. The object, once constructed, is ready to be used by
// calling read(). PMU counter collection is enabled from the time create() is
// called, to obtain the object, until the object's destructor is called.
-class PerfCounters final {
+class BENCHMARK_EXPORT PerfCounters final {
public:
// True iff this platform supports performance counters.
static const bool kSupported;
@@ -125,7 +131,7 @@ class PerfCounters final {
};
// Typical usage of the above primitives.
-class PerfCountersMeasurement final {
+class BENCHMARK_EXPORT PerfCountersMeasurement final {
public:
PerfCountersMeasurement(const std::vector<std::string>& counter_names);
~PerfCountersMeasurement();
@@ -184,4 +190,8 @@ BENCHMARK_UNUSED static bool perf_init_anchor = PerfCounters::Initialize();
} // namespace internal
} // namespace benchmark
+#if defined(_MSC_VER)
+#pragma warning(pop)
+#endif
+
#endif // BENCHMARK_PERF_COUNTERS_H
diff --git a/src/statistics.h b/src/statistics.h
index a9545a5..b0d2c05 100644
--- a/src/statistics.h
+++ b/src/statistics.h
@@ -25,12 +25,17 @@ namespace benchmark {
// Return a vector containing the mean, median and standard devation information
// (and any user-specified info) for the specified list of reports. If 'reports'
// contains less than two non-errored runs an empty vector is returned
+BENCHMARK_EXPORT
std::vector<BenchmarkReporter::Run> ComputeStats(
const std::vector<BenchmarkReporter::Run>& reports);
+BENCHMARK_EXPORT
double StatisticsMean(const std::vector<double>& v);
+BENCHMARK_EXPORT
double StatisticsMedian(const std::vector<double>& v);
+BENCHMARK_EXPORT
double StatisticsStdDev(const std::vector<double>& v);
+BENCHMARK_EXPORT
double StatisticsCV(const std::vector<double>& v);
} // end namespace benchmark
diff --git a/src/string_util.h b/src/string_util.h
index ff3b7da..4145861 100644
--- a/src/string_util.h
+++ b/src/string_util.h
@@ -5,6 +5,7 @@
#include <string>
#include <utility>
+#include "benchmark/export.h"
#include "internal_macros.h"
namespace benchmark {
@@ -13,6 +14,7 @@ void AppendHumanReadable(int n, std::string* str);
std::string HumanReadableNumber(double n, double one_k = 1024.0);
+BENCHMARK_EXPORT
#if defined(__MINGW32__)
__attribute__((format(__MINGW_PRINTF_FORMAT, 1, 2)))
#elif defined(__GNUC__)
@@ -38,6 +40,7 @@ inline std::string StrCat(Args&&... args) {
return ss.str();
}
+BENCHMARK_EXPORT
std::vector<std::string> StrSplit(const std::string& str, char delim);
// Disable lint checking for this block since it re-implements C functions.
diff --git a/test/AssemblyTests.cmake b/test/AssemblyTests.cmake
index 3d07858..48318bd 100644
--- a/test/AssemblyTests.cmake
+++ b/test/AssemblyTests.cmake
@@ -23,6 +23,7 @@ string(TOUPPER "${CMAKE_CXX_COMPILER_ID}" ASM_TEST_COMPILER)
macro(add_filecheck_test name)
cmake_parse_arguments(ARG "" "" "CHECK_PREFIXES" ${ARGV})
add_library(${name} OBJECT ${name}.cc)
+ target_link_libraries(${name} PRIVATE benchmark::benchmark)
set_target_properties(${name} PROPERTIES COMPILE_FLAGS "-S ${ASM_TEST_FLAGS}")
set(ASM_OUTPUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/${name}.s")
add_custom_target(copy_${name} ALL
diff --git a/test/BUILD b/test/BUILD
index df700a7..70753db 100644
--- a/test/BUILD
+++ b/test/BUILD
@@ -50,9 +50,8 @@ cc_library(
"//:benchmark",
"//:benchmark_internal_headers",
"@com_google_googletest//:gtest",
- ] + (
- ["@com_google_googletest//:gtest_main"] if (test_src[-len("gtest.cc"):] == "gtest.cc") else []
- ),
+ "@com_google_googletest//:gtest_main",
+ ]
# FIXME: Add support for assembly tests to bazel.
# See Issue #556
# https://github.com/google/benchmark/issues/556
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 162af53..205be91 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -1,5 +1,7 @@
# Enable the tests
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+
find_package(Threads REQUIRED)
include(CheckCXXCompilerFlag)
@@ -35,10 +37,11 @@ if (DEFINED BENCHMARK_CXX_LINKER_FLAGS)
endif()
add_library(output_test_helper STATIC output_test_helper.cc output_test.h)
+target_link_libraries(output_test_helper PRIVATE benchmark::benchmark)
macro(compile_benchmark_test name)
add_executable(${name} "${name}.cc")
- target_link_libraries(${name} benchmark::benchmark ${CMAKE_THREAD_LIBS_INIT})
+ target_link_libraries(${name} benchmark::benchmark_main ${CMAKE_THREAD_LIBS_INIT})
endmacro(compile_benchmark_test)
macro(compile_benchmark_test_with_main name)
@@ -48,7 +51,7 @@ endmacro(compile_benchmark_test_with_main)
macro(compile_output_test name)
add_executable(${name} "${name}.cc" output_test.h)
- target_link_libraries(${name} output_test_helper benchmark::benchmark
+ target_link_libraries(${name} output_test_helper benchmark::benchmark_main
${BENCHMARK_CXX_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
endmacro(compile_output_test)
@@ -158,8 +161,8 @@ add_test(NAME user_counters_thousands_test COMMAND user_counters_thousands_test
compile_output_test(memory_manager_test)
add_test(NAME memory_manager_test COMMAND memory_manager_test --benchmark_min_time=0.01)
-check_cxx_compiler_flag(-std=c++03 BENCHMARK_HAS_CXX03_FLAG)
-if (BENCHMARK_HAS_CXX03_FLAG)
+# MSVC does not allow to set the language standard to C++98/03.
+if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
compile_benchmark_test(cxx03_test)
set_target_properties(cxx03_test
PROPERTIES
@@ -170,11 +173,17 @@ if (BENCHMARK_HAS_CXX03_FLAG)
# causing the test to fail to compile. To prevent this we explicitly disable
# the warning.
check_cxx_compiler_flag(-Wno-odr BENCHMARK_HAS_WNO_ODR)
- if (BENCHMARK_ENABLE_LTO AND BENCHMARK_HAS_WNO_ODR)
- set_target_properties(cxx03_test
- PROPERTIES
- LINK_FLAGS "-Wno-odr")
+ check_cxx_compiler_flag(-Wno-lto-type-mismatch BENCHMARK_HAS_WNO_LTO_TYPE_MISMATCH)
+ # Cannot set_target_properties multiple times here because the warnings will
+ # be overwritten on each call
+ set (DISABLE_LTO_WARNINGS "")
+ if (BENCHMARK_HAS_WNO_ODR)
+ set(DISABLE_LTO_WARNINGS "${DISABLE_LTO_WARNINGS} -Wno-odr")
+ endif()
+ if (BENCHMARK_HAS_WNO_LTO_TYPE_MISMATCH)
+ set(DISABLE_LTO_WARNINGS "${DISABLE_LTO_WARNINGS} -Wno-lto-type-mismatch")
endif()
+ set_target_properties(cxx03_test PROPERTIES LINK_FLAGS "${DISABLE_LTO_WARNINGS}")
add_test(NAME cxx03 COMMAND cxx03_test --benchmark_min_time=0.01)
endif()
diff --git a/test/benchmark_gtest.cc b/test/benchmark_gtest.cc
index 14a885b..cfc0a0f 100644
--- a/test/benchmark_gtest.cc
+++ b/test/benchmark_gtest.cc
@@ -8,7 +8,7 @@
namespace benchmark {
namespace internal {
-extern std::map<std::string, std::string>* global_context;
+BENCHMARK_EXPORT extern std::map<std::string, std::string>* global_context;
namespace {
diff --git a/tools/workspace/generate_export_header.bzl b/tools/workspace/generate_export_header.bzl
new file mode 100644
index 0000000..0d0b671
--- /dev/null
+++ b/tools/workspace/generate_export_header.bzl
@@ -0,0 +1,148 @@
+#
+# Originl file is located at:
+# https://github.com/RobotLocomotion/drake/blob/bad032aeb09b13c7f8c87ed64b624c8d1e9adb30/tools/workspace/generate_export_header.bzl
+#
+# All components of Drake are licensed under the BSD 3-Clause License
+# shown below. Where noted in the source code, some portions may
+# be subject to other permissive, non-viral licenses.
+#
+# Copyright 2012-2016 Robot Locomotion Group @ CSAIL
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer. Redistributions
+# in binary form must reproduce the above copyright notice, this list of
+# conditions and the following disclaimer in the documentation and/or
+# other materials provided with the distribution. Neither the name of
+# the Massachusetts Institute of Technology nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# -*- 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):
+ output = ctx.outputs.out
+
+ guard = _make_identifier(output.basename.upper())
+
+ content = [
+ "#ifndef %s" % guard,
+ "#define %s" % guard,
+ "",
+ "#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
+ "#endif",
+ "",
+ "#ifndef %s" % ctx.attr.deprecated_macro_name,
+ "# define %s __attribute__ ((__deprecated__))" % ctx.attr.deprecated_macro_name, # noqa
+ "#endif",
+ "",
+ "#ifndef %s" % ctx.attr.export_deprecated_macro_name,
+ "# define %s %s %s" % (ctx.attr.export_deprecated_macro_name, ctx.attr.export_macro_name, ctx.attr.deprecated_macro_name), # noqa
+ "#endif",
+ "",
+ "#ifndef %s" % ctx.attr.no_export_deprecated_macro_name,
+ "# define %s %s %s" % (ctx.attr.no_export_deprecated_macro_name, ctx.attr.no_export_macro_name, ctx.attr.deprecated_macro_name), # noqa
+ "#endif",
+ "",
+ "#endif",
+ ]
+
+ ctx.actions.write(output = output, content = "\n".join(content) + "\n")
+
+# Defines the rule to generate_export_header.
+_generate_export_header_gen = rule(
+ attrs = {
+ "out": attr.output(mandatory = True),
+ "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(),
+ },
+ output_to_genfiles = True,
+ implementation = _generate_export_header_impl,
+)
+
+def generate_export_header(
+ lib = None,
+ name = None,
+ out = None,
+ export_macro_name = None,
+ deprecated_macro_name = None,
+ export_deprecated_macro_name = None,
+ no_export_macro_name = None,
+ no_export_deprecated_macro_name = None,
+ static_define = None,
+ **kwargs):
+ """Creates a rule to generate an export header for a named library. This
+ is an incomplete implementation of CMake's generate_export_header. (In
+ particular, it assumes a platform that uses
+ __attribute__((visibility("default"))) to decorate exports.)
+
+ By default, the rule will have a mangled name related to the library name,
+ and will produce "<lib>_export.h".
+
+ The CMake documentation of the generate_export_header macro is:
+ https://cmake.org/cmake/help/latest/module/GenerateExportHeader.html
+
+ """
+
+ if name == None:
+ name = "__%s_export_h" % lib
+ if out == None:
+ out = "%s_export.h" % lib
+ if export_macro_name == None:
+ export_macro_name = "%s_EXPORT" % lib.upper()
+ if deprecated_macro_name == None:
+ deprecated_macro_name = "%s_DEPRECATED" % lib.upper()
+ if export_deprecated_macro_name == None:
+ export_deprecated_macro_name = "%s_DEPRECATED_EXPORT" % lib.upper()
+ if no_export_macro_name == None:
+ no_export_macro_name = "%s_NO_EXPORT" % lib.upper()
+ if no_export_deprecated_macro_name == None:
+ no_export_deprecated_macro_name = \
+ "%s_DEPRECATED_NO_EXPORT" % lib.upper()
+ if static_define == None:
+ static_define = "%s_STATIC_DEFINE" % lib.upper()
+
+ _generate_export_header_gen(
+ name = name,
+ out = out,
+ export_macro_name = export_macro_name,
+ deprecated_macro_name = deprecated_macro_name,
+ export_deprecated_macro_name = export_deprecated_macro_name,
+ no_export_macro_name = no_export_macro_name,
+ no_export_deprecated_macro_name = no_export_deprecated_macro_name,
+ static_define = static_define,
+ **kwargs
+ )