bionic benchmarks: export benchmark library

Export libbenchmark for external projects to write benchmarks against.

Change-Id: I3b04a56a62ce517afc0d5e06dc8d28879ada3d30
diff --git a/benchmarks/Android.mk b/benchmarks/Android.mk
index 5ce8542..8f5fd41 100644
--- a/benchmarks/Android.mk
+++ b/benchmarks/Android.mk
@@ -19,6 +19,27 @@
 LOCAL_PATH := $(call my-dir)
 
 # -----------------------------------------------------------------------------
+# Benchmarks library, usable by projects outside this directory.
+# -----------------------------------------------------------------------------
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbenchmark
+LOCAL_CFLAGS += -O2 -Wall -Wextra -Werror
+LOCAL_SRC_FILES := benchmark_main.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+include $(BUILD_STATIC_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := libbenchmark
+LOCAL_CFLAGS += -O2 -Wall -Wextra -Werror
+LOCAL_SRC_FILES := benchmark_main.cpp
+LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
+LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
+LOCAL_MULTILIB := both
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+# -----------------------------------------------------------------------------
 # Benchmarks.
 # -----------------------------------------------------------------------------
 
@@ -30,7 +51,6 @@
     -std=gnu++11 \
 
 benchmark_src_files = \
-    benchmark_main.cpp \
     math_benchmark.cpp \
     pthread_benchmark.cpp \
     semaphore_benchmark.cpp \
@@ -47,10 +67,9 @@
 LOCAL_MODULE_STEM_32 := bionic-benchmarks32
 LOCAL_MODULE_STEM_64 := bionic-benchmarks64
 LOCAL_MULTILIB := both
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CFLAGS += $(benchmark_c_flags)
 LOCAL_SRC_FILES := $(benchmark_src_files) property_benchmark.cpp
-LOCAL_CXX_STL := libc++
+LOCAL_STATIC_LIBRARIES += libbenchmark
 include $(BUILD_EXECUTABLE)
 
 # We don't build a static benchmark executable because it's not usually
@@ -65,11 +84,10 @@
 LOCAL_MODULE_STEM_32 := bionic-benchmarks-glibc32
 LOCAL_MODULE_STEM_64 := bionic-benchmarks-glibc64
 LOCAL_MULTILIB := both
-LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
 LOCAL_CFLAGS += $(benchmark_c_flags)
 LOCAL_LDFLAGS += -lrt
 LOCAL_SRC_FILES := $(benchmark_src_files)
-LOCAL_CXX_STL := libc++
+LOCAL_STATIC_LIBRARIES += libbenchmark
 include $(BUILD_HOST_EXECUTABLE)
 
 ifeq ($(HOST_OS)-$(HOST_ARCH),$(filter $(HOST_OS)-$(HOST_ARCH),linux-x86 linux-x86_64))
diff --git a/benchmarks/benchmark_main.cpp b/benchmarks/benchmark_main.cpp
index 815d56b..7140ab6 100644
--- a/benchmarks/benchmark_main.cpp
+++ b/benchmarks/benchmark_main.cpp
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-#include "benchmark.h"
+#include <benchmark.h>
 
 #include <regex.h>
 #include <stdio.h>
@@ -29,11 +29,15 @@
 static int64_t g_bytes_processed;
 static int64_t g_benchmark_total_time_ns;
 static int64_t g_benchmark_start_time_ns;
+static int g_name_column_width = 20;
 
 typedef std::map<std::string, ::testing::Benchmark*> BenchmarkMap;
 typedef BenchmarkMap::iterator BenchmarkMapIt;
-static BenchmarkMap g_benchmarks;
-static int g_name_column_width = 20;
+
+static BenchmarkMap& Benchmarks() {
+  static BenchmarkMap benchmarks;
+  return benchmarks;
+}
 
 static int Round(int n) {
   int base = 1;
@@ -98,7 +102,7 @@
     exit(EXIT_FAILURE);
   }
 
-  g_benchmarks.insert(std::make_pair(name, this));
+  Benchmarks().insert(std::make_pair(name, this));
 }
 
 void Benchmark::Run() {
@@ -191,18 +195,18 @@
 }
 
 int main(int argc, char* argv[]) {
-  if (g_benchmarks.empty()) {
+  if (Benchmarks().empty()) {
     fprintf(stderr, "No benchmarks registered!\n");
     exit(EXIT_FAILURE);
   }
 
-  for (BenchmarkMapIt it = g_benchmarks.begin(); it != g_benchmarks.end(); ++it) {
+  for (BenchmarkMapIt it = Benchmarks().begin(); it != Benchmarks().end(); ++it) {
     int name_width = static_cast<int>(strlen(it->second->Name()));
     g_name_column_width = std::max(g_name_column_width, name_width);
   }
 
   bool need_header = true;
-  for (BenchmarkMapIt it = g_benchmarks.begin(); it != g_benchmarks.end(); ++it) {
+  for (BenchmarkMapIt it = Benchmarks().begin(); it != Benchmarks().end(); ++it) {
     ::testing::Benchmark* b = it->second;
     if (b->ShouldRun(argc, argv)) {
       if (need_header) {
@@ -217,7 +221,7 @@
   if (need_header) {
     fprintf(stderr, "No matching benchmarks!\n");
     fprintf(stderr, "Available benchmarks:\n");
-    for (BenchmarkMapIt it = g_benchmarks.begin(); it != g_benchmarks.end(); ++it) {
+    for (BenchmarkMapIt it = Benchmarks().begin(); it != Benchmarks().end(); ++it) {
       fprintf(stderr, "  %s\n", it->second->Name());
     }
     exit(EXIT_FAILURE);
diff --git a/benchmarks/benchmark.h b/benchmarks/include/benchmark.h
similarity index 95%
rename from benchmarks/benchmark.h
rename to benchmarks/include/benchmark.h
index d7af50f..7e134a0 100644
--- a/benchmarks/benchmark.h
+++ b/benchmarks/include/benchmark.h
@@ -14,8 +14,10 @@
  * limitations under the License.
  */
 
-#include <stdint.h>
+#ifndef BENCHMARKS_BENCHMARK_H_
+#define BENCHMARKS_BENCHMARK_H_
 
+#include <stdint.h>
 #include <vector>
 
 namespace testing {
@@ -59,3 +61,5 @@
 #define BENCHMARK(f) \
     static ::testing::Benchmark* _benchmark_##f __attribute__((unused)) = \
         (new ::testing::Benchmark(#f, f))
+
+#endif